CSV Cleaver

Verification ledger

What is currently claimed about this application, at what level of evidence, and what remains unverified. Kept because a claim's verification level turned out to matter as much as the claim: three fixes in one development session were reported as done and then falsified by the project manager's testing — each a mechanism verified without verifying the path to it.

Levels:

Nothing may be reported as done unless OBSERVED or TESTED. The falsification record at the bottom is a metric, not a confession box: it says where claims from this project's own development proved unreliable, so a reader can weight the rest accordingly.

Active claims — build 2f9c995 (v2.2.0 candidate)

ClaimLevelEvidence
Splitting is byte-faithful; concatenating output reproduces inputTESTEDsamples_test/every-sample-splits-and-rejoins-byte-for-byte; scanner mutations caught
Nothing on disk is overwritten without consentTESTEDcollision tests + API nothing-already-on-disk-is-replaced; mutation caught
API refuses without token; input modes enforced; loopback onlyOBSERVED + TESTEDlive smoke on real socket (401/400/202/404 on record); 5 API mutations caught
Installer bundles locale data; packaged binary startsOBSERVEDbuild inspects its own image and launches it; It starts: CSV Cleaver 2.2.0 (33ce16b) — the 2026-09-05 smoke build of this branch, whose parenthetical is the pre-bump parent because the version bump was still uncommitted when it built
macOS icon centredOBSERVEDmargins L49 R49 T49 B49 read from shipped icns bytes; generator refuses asymmetry
Get Info shows canonical copyrightOBSERVEDplutil -extract NSHumanReadableCopyright on the built app; re-run on the 2.2.0 smoke image, 2026-09-05: Copyright © 2026 Andrew David Nimmo
One file dialog at a time; stale scans discardedTESTEDclaim-guard + scan-epoch tests; 3 mutations caught. Dialog modality itself is platform behaviour: PENDING-USER below
Dialog cards never outgrow the windowTESTEDlayout-bounds fx test at 420×320; mutation caught. The earlier version of this test measured the drop-shadow and was discarded
Single-line dialog titles cannot clip inkTESTED for shape, PENDING-USER for the pixelstitles are Text nodes, which do not clip by construction; the two prior padding fixes were falsified on a Retina display, so this one is not "done" until seen there
Alt/Option + About reveals hidden languagesTESTED for wiring, PENDING-USER for the keystrokereal KeyEvent driven through the real scene; the focus path from a physical key press cannot be exercised headless
Session survives ⌘Q / Glass Quit / killTESTED for mechanismgeometry-tracking + shutdown-hook tests; the ⌘Q path itself on a live Mac is PENDING-USER
macOS app menu carries Quit (Glass's own)DERIVED + user-observedMacApplication.installDefaultMenus read from bytecode; the user reports Quit present
macOS app menu carries About, translated, opening the About overlayOBSERVED + TESTED + user-verifiedinstalled via the Objective-C runtime (JNA) after the public-API route was proven absent; the fx test reads the item's title back from AppKit and fires it through performActionForItemAtIndex: — AppKit's own click dispatch — asserting the overlay opens. Probe run on record: install → "About CSV Cleaver" → retitle "Acerca de CSV Cleaver" → perform → handler fired
A selected mode/theme pill cannot be switched offTESTED (armed) + user-verifiedthe first guard consumed the press in a same-node handler, which cannot block a control's own behavior — its handler-level test passed while the running app still deselected. Now a capturing scene filter; the test fires the full press/release/click at the real pill and asserts both directions: no guard → deselects, guard → cannot. Live click PENDING-USER
Option-reveal of hidden languages lasts exactly one AboutTESTED + user-verifiedopening plainly or closing conceals; the command-line reveal is a separate session-long flag that concealing never touches; mutation caught
Eight visible languages complete; two hidden ones partial-by-designTESTEDparity/plural/placeholder suites; egg-bundle contract test

| Signing scaffolding inert and wired | OBSERVED + TESTED | unsigned bb package unchanged with the scaffolding in place; entitlements, script wiring and workflow steps pinned by test, two mutations caught. The sufficiency of the entitlements for notarisation is DERIVED until the first signed build — the JNA disable-library-validation need is the expected round-trip, stated in SIGNING.md | | Raw default-locale text operations cannot enter src/ or dev/ (R85) | TESTED | bb locale-lint in CI and pinned by the suite — zero hits and ≥20 files scanned, because a lint over nothing reports clean; six mutations caught, including the lint quietly scanning nothing and losing a pattern | | A Turkish machine keeps Italian: --locale IT and --theme LIGHT parse | TESTED | regressions force tr_TR around the call; mutations restoring the raw folds caught. Before the gate, both were live defects nothing exercised | | The whole suite passes under tr_TR | OBSERVED | bb test-tr green locally and on the Linux CI leg on every run since the gate merged | | The jackson-databind pin is load-bearing at 2.22.2 | TESTED | pin removed → bb audit refused the tree (all seven CVEs, exit 255); restored, bumped, scanned clean over 69 dependencies. Newest stable reitit (0.10.1) still resolves 2.21.1 | | The audit runs on the self-hosted runner and never for a fork PR | OBSERVED | push and scheduled runs green on the runner (first cron firing 2026-09-05); audit.yml has no pull_request trigger; fork-PR approval set to all outside collaborators | | JavaFX 26.0.2 renders every screen as 25.0.4 did | OBSERVED | 18 of 20 bb shots byte-identical across the bump; the done screen differs by ~1% sub-pixel rasterisation, deterministic (26-vs-26 control render 0.00%); suites green on all three CI platforms | | No button is narrower than its label needs | TESTED | layout invariant over five screens at the window's own size, in a shown window; mutation caught — after the test's first version was itself caught passing with the fix removed, and hardened with a deliberately deep fixture path | | Every registered mutation caught | OBSERVED | full bb mutate sweep on the release-2.2.0 tree, 2026-09-05: 58 of 59 caught, the 59th reported STALE — its anchor was the very fold the locale gate migrated, which is the stale check working — re-anchored and caught individually the same day |

Release v2.0.0 — run 31091724587, commit 082779a

ClaimLevelEvidence
Five installers published: AppImage, deb, two dmgs, msiOBSERVEDasset list read back from the GitHub API after publish
SHA256SUMS covers all five; digests are realOBSERVEDAppImage re-downloaded and re-hashed locally; digest matches the published one
The Intel dmg is x86_64, built on the ARM runner under RosettaOBSERVEDx64 JDK in the job log; lipo -archs assertion in the workflow fails on mismatch and passed; the packaged binary started under Rosetta ("It starts: 2.0.0")
The AppImage stage worksOBSERVED twicefirst in an amd64 container against the real script logic (emulation divergences on record in the test script), then live on the runner
CVSS ≥ 7.0 fails the audit; the gate is readOBSERVEDnvd-clojure's startup echo shows the config at the level it reads
The published MSI installs and the application works on real Windows 11user-verifiedinstalled from the release page by the project manager, 2026-08-06 — the first shipped installer confirmed on real hardware rather than a runner
The published Apple Silicon dmg installs and the application works on a real Macuser-verifiedinstalled and tested by the project manager, 2026-08-06. General "works as expected"; the two specific checks below were not named and stay open

Release v2.1.0 — run 31155781836, commit fc51793

All five jobs green on the first attempt — the first release to need no round-trips. Five installers plus SHA256SUMS published; the MSI's digest re-verified by downloading and re-hashing (OBSERVED). Along the way this release's CI surfaced and closed two standing defects: the audit gate's first live catch (a CVSS 7.5 false positive, answered by removing the msgpack jar rather than suppressing — see the commit "What is not on the classpath cannot have a CVE"), and the timestamped-folder flake, which fired under cloverage exactly as its own assertion message was armed to report, and was cured by removing the shared state read it depended on.

Release v2.2.0 — run 33985098661, commit ab40d1d

ClaimLevelEvidence
Five installers plus SHA256SUMS publishedOBSERVEDasset list read back from the GitHub API after publish
The digests are realOBSERVEDthe deb re-downloaded and re-hashed locally; digest matches the published one
The published artefacts are built from the release commitOBSERVEDthe near-miss below is why this line exists

The near-miss worth its own paragraph: minutes before the real release, a stale lightweight v2.2.0 tag reached origin pointing at an August commit — a tree whose branding still said 2.1.0 — and its workflow was already building wrong installers under the right version number. Created, almost certainly, by a bare git tag v2.2.0 in a checkout whose HEAD predated five merged PRs. The run was cancelled mid-build (nothing published; the release list was read back to confirm), the tag deleted and re-created as an annotated tag at the release commit, and the run that followed is the one above. The falsification record's rule — a value written from memory is an assumption wearing a pin's clothes — gains a sibling: **a tag created in a stale checkout is a release of whatever that checkout last saw.** Tag from the commit, not from wherever HEAD happens to be: git tag -a v<x> <sha>.

The update check — commit 5ff3e90

ClaimLevelEvidence
Update check: manual button, opt-in startup, quiet by contract, --no-update-check removes itTESTEDoffline tests replay every answer GitHub can give, including none; 3 mutations caught — newer? inverted, the quiet check nagging, a rebranded fork phoning this repository. The third was caught only after the gate exposed the first version of its test as unable to fail: its non-GitHub URL had a one-segment path that even the mutated regex rejected
Headless/API modes never checkDERIVEDthe check is wired only in start-window!, which headless runs never reach — the same structural guarantee the no-cljfx rule rests on
The live endpoint answers as the tests assumeuser-verified, both pathsup-to-date: the project manager pressed the button against the real endpoint, 2026-08-06. Update-available: an installed 2.0.0 found v2.1.0 the day it was published and its release-page link worked, 2026-08-07. Every status this feature can show has now been seen on real hardware

To verify on the next build (PENDING-USER)

  1. App menu ▸ About — verified by the project manager.
  2. Selected pill stays selected — verified by the project manager.
  3. Option-About reveals for one About only — **verified by the project manager**.
  4. Help and About titles intact at the right edge (Text nodes).
  5. One file dialog at a time; ⌘Q quits cleanly with one open; window position remembered across a ⌘Q.
  6. Check for updates answers — verified by the project manager (up-to-date path). Still open: the startup checkbox sticking across a restart, --no-update-check removing the section, and the bottom spacing of the About card after the tightness fix.
  7. The 2.2.0 smoke dmg installs and runs on a real Mac — **verified by the project manager**, 2026-09-05, before the release was tagged: the first artefact on the JavaFX 26 toolkit, smoke-tested from the branch build of the release commit's tree.

Falsification record

Claims stated as done during development and later disproven by the project manager's testing of the real artefact. All five cluster in desktop-UI and platform-integration territory; none of the engine or API "done" claims has been falsified to date. The pattern in every case: a mechanism was verified without verifying the path to it.

Claim as statedFalsified byRoot cause
"Locale formatting fixed" (first fix)numbers still English in the appfixed one layer (language switch) while the defect had a second home (settings file) and a third (runtime missing locale data)
"Locale formatting fixed" (second fix)same symptom, screenshotsthe artefact's runtime lacked jdk.localedata; every test ran on a full JDK where it cannot be missing
"Icon wired in and verified"Dock screenshot: uncentred"verified" meant the binary launched; nobody had read the icon's pixels — snapshot had silently discarded the centring transform
"Title clipping fixed" (padding)'p' still clipped on Retinapadding widens a Label and moves its text, leaving the same knife-edge; fix verified at 1× for a 2× defect
"Alt reveals hidden languages"keypress did nothinghandlers sat on a node that never has focus; tests dispatched synthetic maps, proving the handler worked if reached, never that anything reached it
"macOS app menu carries About, tested"no such menu item existsDesktop.setAboutHandler handles an event AWT never receives under JavaFX, whose Glass toolkit owns the menu; "tested" meant handlers installed without error
"Selected pill cannot be switched off, TESTED"both pills still clickable to greythe guard consumed the press in a same-node handler, which cannot block a control's own behavior handlers; the test proved the flag was set, not that the toggle was prevented — the seventh instance of mechanism-without-path, caught this time within a day by the PENDING-USER step

Seven falsified claims across roughly twenty substantive reports in the same period. The corrective in force: every claim now carries one of the four levels above, and "done" is reserved for OBSERVED or TESTED.

The release added a second column of falsifier: the first live run. These claims were stated at DERIVED or below and disproven by the machine before any user saw them — the ledger records them because "the scaffolding is wired" had been reported with more confidence than a never-executed branch deserved.

Claim as statedFalsified byRoot cause
"Release workflow wired, TESTED"tag run: zero jobs, no loga generator wrote \1 as byte 0x01; GitHub rejected the whole file; the source-level tests checked for strings, not for validity
"Signing/release scaffolding inert and correct"first Linux release legthe AppImage branch had never executed anywhere: tool never installed, pin URL recalled from memory (404), and an AppDir layout appimagetool rejects
"Actions deprecation bump, versions checked"every job, in seconds13.6 assumed from the old two-part tag pattern; the tag that exists is 13.6.1

The pattern is the same one as above — mechanism verified without the path — plus one refinement worth keeping: a pin, a URL, or a version written from memory is an assumption wearing a pin's clothes. Every such value now gets checked against the live source before it is committed.

Resolution note: the app-menu About found its real implementation afterwards — through the Objective-C runtime, verified by reading AppKit's own state — so the falsified entry above records the false claim, not a permanent impossibility. "Impossible via public API" had been the true part; treating it as the end of the road was the error the project manager corrected.