Skip to content

fix: follow-ups to #306 (baseline cost, CRLF, gate wording) - #327

Closed
MendixMau wants to merge 2 commits into
masterfrom
fix/followup-306-change-log
Closed

MendixMau wants to merge 2 commits into
masterfrom
fix/followup-306-change-log

Conversation

@MendixMau

Copy link
Copy Markdown
Owner

Follow-ups from an independent review of the merged #306 (change log, squash 3c34389). Refs #306.

1. Baseline context cost

Problem. #306 made skills/change-intake.md (1,804 words) a baseline file for lead and ba at Stages 2–7, and moved nothing to on-demand to make room. bin/render-routing.sh's budget header says a new baseline row has to be paid for elsewhere.

Fix. The file is split in two:

  • skills/change-intake.md stays baseline, cut to a 299-word core. It keeps the trigger, the row columns and statuses, class → entry artifact, size → ask, a short Owners section (so the existing "change-intake.md → Owners" references in the runbook, agent-roles.md and both agent stubs still resolve), and Done when. It points to the companion file.
  • New on-demand skills/change-intake-detail.md (routing row: lead, ba, architect; Stages 2–7; group spine). It holds the why-table, the wrong-vs-right example, the full Step 1–5 text (class table with the "What changed" column, the size table, the ask table with status paths, Apply, the full Owners table, Prove), the mechanical-check section, and the per-line checks for Done when.

Removed vs moved. Everything from the old file after its header is in the detail file verbatim. The only old lines not carried over word for word are:

  • the old title, **Purpose:** and **Owns:** header lines. They were rewritten for each file's role. Ownership still sits with change-intake.md, and the detail header says so.
  • the heading ## Done when (denominators). Its five bullets moved to the detail file as "Checking each Done-when line", and the core has a condensed version.
  • the Gate-line bullet `Change log:` reads `0 of M … not yet applied`. Gate-check never prints that string, so it is replaced on purpose (item 3).

No rule, denominator or failure example was dropped.

bin/render-routing.sh --check (LC_ALL=C):

  • Baseline tier: 79,997 → 78,492 words (budget 80,000).
  • Stage 2/3 lead: 34,414 → 32,909.
  • ba at Stages 2/3: 29,042 → 27,537.

The budget value is not lowered here, because render-routing.sh is outside this PR's file list. The ratchet rule suggests lowering it at integration.

2. CRLF PROJECT.md

Problem. mxtk_change_log_has_section used grep '^## +change log *$', which never matches ## Change log\r. So on a CRLF register:

  • gate-check printed "no '## Change log' section"
  • sync-project.sh step 2b1a appended a second empty section
  • the scan counted 0 rows

Fix (in bin/lib/change-log.sh only, which covers both callers): both readers drop a trailing \r before matching, as gate-check already does for the tables it reads. The heading test is now a single awk call rather than tr | grep -q, because under the callers' pipefail an early-exiting grep -q can SIGPIPE the producer and turn a hit into a miss.

Fixture. New case T9 in tests/wave2/test-change-log.sh uses a real init scaffold with 4 rows, converted to CRLF. It checks that:

  • the section is found
  • the scan output matches the LF copy byte for byte, with no \r leaking into it
  • the gate line matches the LF copy
  • sync leaves exactly one heading and does not report an append

Against master's change-log.sh, 5 of these cases FAIL. The CRLF scan reads SUMMARY 0… and sync writes 2 headings.

The fixture also drops pipefail. Under it, an early-matching printf "$OUT" | grep -q could SIGPIPE, and T7 "sync says what it appended" failed intermittently on one run. No assertion in the fixture reads an upstream exit code.

3. Done-when wording vs the gate line

The skill expected 0 of M … not yet applied, but when nothing is pending gate-check prints PASS — N change request(s); every one applied with evidence, proven, or rejected (or PASS — 0 change requests logged). The skill text was changed and gate-check was not. The core now says the line "reads PASS", and the detail file quotes both PASS forms. The only change to gate-check.sh is its re-rendered stage map, which now lists change-intake-detail.md.

Not in this PR: exec.sh --cr position

project-bin/exec.sh is owned by another PR. Its --cr flag only works as the first argument, although the usage line says [--commit-first] [--cr CR-NN]. A patch with a leading-flag loop that also refuses a script name starting with -- is handed to the lead for that PR.

Checks run

  • bash tests/wave2/test-change-log.sh bin/gate-check.sh: 47 passed, 0 failed. The same fixture on master: 43 passed, 5 failed (exactly the CRLF cases).
  • test-baseline-pack.sh: 16 ok. test-routing-tier.sh: 12 ok. test-bug12-sync.sh: 61 pass.
  • test-render-routing.sh: 5/5. One earlier run showed 4/5 because of a flaky UNROUTED report that also happens on master. Cause: routing_unrouted_skills in bin/lib/skill-routing.sh runs printf | grep -qxF under pipefail and gets SIGPIPE. That file is outside this PR.
  • bin/render-routing.sh --check: in sync (same flake possible).
  • bin/check-scripts.sh, bin/check-portability.sh, bin/check-no-private-citations.sh, leak guard (LEAKGUARD_ALLOW_NO_DENYLIST=1), bin/check-pr-discipline.sh origin/master: all clean.

Field run

Still owed. The CRLF fix and the split were exercised only on real init-project.sh scaffolds (golden input, as T9 builds it), not on a live project's register.

Risks

  • Existing projects: no PROJECT.md behaviour change for LF files. A CRLF file that already got a duplicate section from sync keeps it, and that needs a manual delete.
  • An agent that reads only the core has less detail. Each core section points to the detail file, and the routing row fires on "applying or proving a CR".

🤖 Generated with Claude Code

https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw


Generated by Claude Code

1. Baseline cost. skills/change-intake.md (1,804 words) went baseline for
   lead+ba at Stages 2-7 without paying for it elsewhere. It is now a
   299-word core (trigger, row columns, class -> entry artifact,
   size -> ask, owners, Done when). The why-table, the wrong-vs-right
   example, the full class/size/ask tables, apply and prove steps, the
   owners table and the gate-check explanation moved verbatim to new
   on-demand skills/change-intake-detail.md (lead, ba, architect;
   Stages 2-7), with a pointer from the core. Baseline tier
   79,997 -> 78,492 words (render-routing.sh --check, LC_ALL=C).

2. CRLF. mxtk_change_log_has_section never matched "## Change log\r",
   so on a CRLF PROJECT.md gate-check warned "no section",
   sync-project.sh appended a second empty section, and the scan counted
   0 rows. Both readers now drop a trailing \r (awk, so no grep -q
   SIGPIPE under the callers' pipefail). New fixture case T9; 5 of its
   cases fail on the previous change-log.sh. The fixture also drops
   pipefail, which made T7's "sync says what it appended" flaky.

3. Gate wording. "Done when" expected "0 of M ... not yet applied", a
   string gate-check never prints; it now names the PASS line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
…failure line)

- change-intake.md: its Owners section is the single source (now
  carrying the inline-edit / no-UNSYNCED rule); the detail file's Owners
  table says it only expands it. conversion-runbook.md and agent-roles.md
  pointers reworded to name that section.
- gate-check.sh and change-log.sh comments point the "when does this
  block" question at change-intake-detail.md "The mechanical check".
- Core gains the failure line: "Sure, adding it now" -> MDL, no row
  (12 of 12 field changes). Core 299 -> 331 words; baseline tier
  78,492 -> 78,524 (budget 80,000).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
MendixMau pushed a commit that referenced this pull request Oct 13, 2026
…ail; CRLF-safe change log (refs #306)

Review: MERGE (review + fix round + confirmation) — protected text moved verbatim; Owners single source; CRLF registers parsed. Conflict in gate-check.sh's generated stage map resolved by re-rendering (bin/render-routing.sh).
MendixMau added a commit that referenced this pull request Oct 14, 2026
)

Every constituent PR was reviewed by a fresh agent that did not write it (CLAUDE.md "Merging a PR"); only MERGE verdicts joined. CI green on each constituent head and on this head (40814fc); full suites run on the branch.

Review lines (per merged PR):
- #315 context trim — MERGE; 360/385 removed lines found verbatim in their new homes, rest read by hand; baseline 79,997 -> 76,259.
- #316 independent-review + word-budget rules — MERGE-AFTER-FIX (3 rounds), fixes applied as specified.
- #318 page-fidelity displayed text — MERGE after fix round + confirmation.
- #317 interaction-model skill (#291 part 1) — MERGE after fix round + confirmation; no client names leaked.
- #321 PROOF-OF-LOOK per section; final-look not due before derived Stage 6 — MERGE after fix round + confirmation.
- #307 graph-sweep guard; per-BRD conformance ledgers — MERGE after two fix rounds + confirmation.
- #325 extraction-quality section; token-burn fixes — MERGE after fix round + confirmation.
- #310 e2e OQL by alias, negative-span liveness, APP-DOWN, #302 credential regression fix — MERGE after fix round + 3 confirmations.
- #323 inbox promotions — MERGE after fix round + confirmation.
- #308 lint gate BLIND on reverted stock rules — MERGE (FIRST-SEEN reverted) after two fix rounds + confirmation.
- #328 pipefail + grep -q flake — MERGE; 0/30 flakes vs 15/100 on master. Follow-up: run-all resolves bin/lib/ subjects (reviewed, MERGE).
- #319 test-stack-up command-line ownership proof — MERGE after fix round + 2 confirmations.
- #327 change-intake core + on-demand detail; CRLF-safe change log — MERGE after fix round + confirmation.
- #320 follow-ups to #290/#292; Dispatching split out — MERGE after fix round + confirmation.
- #326 status delivery rounds (existing-app mode) — MERGE after fix round + confirmation.
- #312 lint batch 4: SEC014, toolkit CONV009 — MERGE after review + 2 fix rounds + confirmation; field run on mxcli 0.26.
- #324 exec.sh change classes, shared stale-lock takeover, SEC014 note echo — MERGE (joint review); follow-up owed for a takeover race after a mid-takeover crash.
- #322 MxTest after-startup guard, mxcli-run pid check — MERGE (joint review).
- #314 doctor property-set exit code; sync announces its bound — MERGE (joint review).
- #330 review follow-ups (exit 4/5 docs, pipefail, NUL strip) — MERGE-AFTER-FIX, fixes applied; takeover re-check dropped.

Field runs are still owed for most instruments in this batch (stated in each PR).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
@MendixMau

Copy link
Copy Markdown
Owner Author

Landed on master as part of the integration squash #329 (commit 31e90ae), after independent review — its Review: line is in that commit message. Closing as superseded.


Generated by Claude Code

@MendixMau MendixMau closed this Oct 14, 2026
@MendixMau
MendixMau deleted the fix/followup-306-change-log branch October 15, 2026 10:46
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