Skip to content

decompose: cut-ledger (split from #293, 2/6) - #345

Merged
MendixMau merged 3 commits into
masterfrom
split-293/cut-ledger
Oct 15, 2026
Merged

MendixMau merged 3 commits into
masterfrom
split-293/cut-ledger

Conversation

@MendixMau

@MendixMau MendixMau commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Split from #293 (2/6). #293's branch is untouched. The files were copied from its head with git checkout origin/claude/youthful-hypatia-qapq73 -- <paths>. This PR is based on master, not stacked on #341: cut-ledger has no code dependency on cut-score, only a prose mention of it.

Direct lane

What changed and why (one paragraph):
bin/cut-ledger.sh with its engine bin/lib/cut-ledger.py writes the cut ledger for one decompose slice. Each crossing edge gets one row with a resolution (resolved / stub / handoff / retire / platform) and its evidence, and the script exits 1 while any edge has no resolution. A slice is not "done because mx check is green", since a stub turns an edge green without carrying its behaviour. Inputs:

  • the source app's catalog refs table, or a --refs TSV
  • a slice file listing whole modules and single documents
  • first-match rules, where evidence is mandatory
  • mx check CE1613 names the catalog never recorded, which become check-only rows
  • the module exporter's --json
  • verbatim --extra rows

Exit 2 covers bad arguments, unreadable inputs and malformed --refs lines.

Changes from #293's copy:

  • The header no longer cites process/decompose-and-rehost-plan-…md or pipelines/mendix-mpr/export-module-mpk.py, because neither is on master; both land in later splits.
  • The field-run line carries the run's real counts. It said 199 refs; the capture shows 346 refs → 308 rows.
  • The review fixes are listed below.

New fixture. tests/wave2/test-cut-ledger.sh has 44 checks. Its input is a captured artifact and nothing in it is hand-written:

  • slice.txt, cut-rules.tsv (43 rules), cut-extra.tsv and the exporter JSON are taken verbatim from Decompose and Rehost pipelines: field runs on FSM and GenAI Showcase, three new skills #293's NativeNote slice run.
  • The rest are line subsets of that run's own files. From its --dump-refs output: 43 of 346 crossing refs, one ledger key per distinct rule plus System. From its mx check log: 10 of 186 CE1613 lines. From its cut-ledger.tsv: the 57 expected rows.
  • The fixture asserts the parsed counts: "43 crossing refs -> 57 ledger rows (20 out, 22 in from the catalog; 2 check-only; 13 extra)" and "handoff 20, platform 1, resolved 24, retire 1, stub 11". The 57 rows must equal the field run's rows in columns 2-8, in the same order.
  • It also checks:
    • the 42 catalog rows carry all 43 refs
    • no rule goes unused
    • the pre-fix exporter transcript yields exactly the field run's "Technician" note
    • removing a rule leaves an UNRESOLVED row and exit 1
    • every refusal and every unreadable input exits 2
    • --dump-refs writes the input back byte for byte
    • --catalog gives the same ledger as --refs
    • the output is deterministic
  • No "Siemens" mention appeared in any captured file.

Field evidence: #293's run on a public Mendix field-service template app, version 9.24.2. The NativeNote slice moved into a fresh Mendix 11.13.0 app: 346 crossing refs → 308 ledger rows, 0 UNRESOLVED, 0.15 s. With the pre-fix exporter JSON, the run's reconciliation flagged a false positive (Technician x2). The fixture reproduces both.

  • No client data anywhere in the diff (leak guard and whole-word name grep are clean)
  • Size cap: 2 instrument files, about 310 lines; fixtures and CHANGELOG are excluded.
  • Test tier reached: T1. test-cut-ledger.sh passes 44/44 on captured input.
  • For a new/changed instrument: golden input is captured. Two-tree layout (.mpr under app/): the script discovers nothing itself; every input is an explicit path. I probed it with synthetic trees: catalogs at <proj>/.mxcli/catalog.db and <proj>/app/.mxcli/catalog.db give the same ledger. No real two-tree project has been run. macOS and Git Bash/Windows: unverified. Everything ran on Linux only; check-portability.sh is clean.
  • CHANGELOG.md line appended (crediting Decompose and Rehost pipelines: field runs on FSM and GenAI Showcase, three new skills #293's field run)

Checks: render-routing.sh --check passes; the baseline is 75,038 words before and after. check-scripts, check-portability, the leak guard, check-no-private-citations and check-pr-discipline are all clean.

Review

The independent review returned MERGE-AFTER-FIX. Commit 4016553 addresses each item:

  1. MEDIUM: uncaught exceptions exited 1, the UNRESOLVED code.
  2. LOW: --refs lines with the wrong field count were silently dropped. Fixed: they are now refused with exit 2, counted, and the first one is named. The fixture case is a captured refs file with one line cut short. Decompose and Rehost pipelines: field runs on FSM and GenAI Showcase, three new skills #293's copy accepts it silently.

Against #293's copy the fixture now fails 6 of 44 checks.

Impact

Row Effect Evidence
Process None new. bin/cut-ledger.sh is an on-demand instrument (exits 1 while any crossing edge is UNRESOLVED); no gate wires it. diff
Dependencies No shared files. Merges clean onto master 868b3cb (git merge-tree). No conflicts with the other PRs in this batch; based on master, not stacked on #341; #346 cites it. Platform: Linux only (two-tree probed synthetically). Reads the catalog refs table in .mxcli/catalog.db (producer: mxcli catalog refresh, left by app-facts.sh) or a --refs TSV, a slice file + rules (human-authored), an mx check log (producer: mx), and the exporter --json (producer: pipelines/mendix-mpr/export-module-mpk.py, which arrives in #342 and is not on master). git merge-tree vs 868b3cb and pairwise; script header
Context cost Unchanged: baseline 73,522 → 73,522 words (budget 80,000); Stage 5 mdl 30,185 → 30,185, lead 25,820 → 25,820 bin/render-routing.sh --check on master 868b3cb vs this head (4016553) merged onto 868b3cb via git merge-tree in a temporary worktree
Behaviour n/a (scripts only). diff touches no skill or agent stub
Runtime None for exec, gates or checks; 0.15 s on the field slice. PR field-evidence section

🤖 Generated with Claude Code

https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw

bin/cut-ledger.sh + bin/lib/cut-ledger.py copied from #293's head; header
no longer cites files not on master and carries the field run's real
counts. New fixture tests/wave2/test-cut-ledger.sh (38 checks) on a
captured line subset of #293's NativeNote slice run (template app):
reproduces that run's own 57 ledger rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
- An unreadable input (missing --rules, nonexistent --catalog, malformed
  --exporter-json) exits 2, not the UNRESOLVED code 1.
- A --refs line with the wrong field count is refused (exit 2, counted,
  first line named) instead of silently dropped.
- test-cut-ledger 38 -> 44.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
@MendixMau
MendixMau marked this pull request as ready for review October 15, 2026 08:42
@MendixMau
MendixMau merged commit 95bf240 into master Oct 15, 2026
2 checks passed
@MendixMau
MendixMau deleted the split-293/cut-ledger branch October 15, 2026 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants