feat: The dry-run transcript catalog can mint into a beats chapter - #252
feat: The dry-run transcript catalog can mint into a beats chapter#252michalziolkowski wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
APPROVED. I read the diff across all four rounds, not the record.
WHAT THIS CHANGE IS FOR, in one sentence: the dry-run transcript catalog must be able to name a fixture path inside a BEATS chapter's snapshot sidecar, because every decision claim in the Diff Scope saga is a minted dry-run transcript and a beats chapter is where they now live.
THE LOAD-BEARING ASSUMPTION was mine and it was wrong in round 1, which is the round that earns this approval. The first pass declared the second root as e2e/planning/<storyline>/fixtures/ - the AUTHORED v1 road's convention, and a reasonable read of a repo that contains both roads. My subtask block never said which. The correction to e2e-beats/suites with the full path shape documented - including WHY the tail is not an author's choice, since it carries the hyphenated Playwright project name and the platform from Playwright's default template - is right, and the doc now teaches the next author something the code alone would not have.
THE TEST DESIGN IS BETTER THAN WHAT I ASKED FOR, twice.
First: the literal-pinning case deliberately does NOT compose its expectations from FIXTURE_ROOTS, because a case that composed them would agree with any move of the root. That is the difference between a law and a tautology, and nobody prescribed it.
Second, and this is the one I would have got wrong: I said "if the root-existence test goes red on a tree that does not exist yet, say so rather than creating a directory to satisfy it". The answer was to SPLIT the claim - shape (relative, no leading or trailing slash, no .. escape) asserted unconditionally for every declared root, existence asserted only for roots a scenario actually answers under. The beats root is therefore gated the moment its first scenario lands and is never a knowingly-red case in between. Better than the instruction.
THE BYTES ARE PROVEN, NOT ARGUED. The round-4 scenario's state is rendered through the shipped path, masked with the shipped maskTestBundledCli, and compared against c3-cold-start-cli-Test-Bundled-darwin.txt - a fixture a real device run against the real backend produced and a person reviewed into git. Byte-identical. For a fixture nothing has captured yet that is the strongest available claim, and it is the difference between a mint that will work and a mint we hope will work.
THE fixtureNotMintedYet MARKER: accepted, and it is a design decision rather than an escape hatch. The chicken-and-egg is real - a beats fixture is minted THROUGH the catalog, so the path must be named before bytes exist, while two pre-existing ratchet cases assume the file is already there, and fixture: null can never be minted because null-fixture scenarios are partitioned out before the write branch. What makes the marker acceptable is that it cannot linger: it is typed as literal true so it has no dead-false state, and a new case reds when the marker outlives the mint. The act that writes the bytes is the act that forces the marker off. The author offered to revert it if I would rather have been asked than told; I would not - this is the call the seat was in position to make.
ONE FINDING, not blocking, and it is a CLASS rather than an instance. The scenario hardcodes the chapter's filename inside the fixture path:
e2e-beats/suites/diff-scope/closure/01-asking-costs-nothing.spec.ts-snapshots/first-dry-run-capture-plan-Diff-Scope-Closure-darwin.txt
Three things in that one string belong to another repository and can move without this one noticing: the chapter's FILENAME, the storyline's PLAYWRIGHT PROJECT NAME (hyphenated into the tail), and the slot name. A rename of any of them in sherlo-tester silently orphans this scenario - and a chapter rename is live right now, since the sibling lane is deciding whether chapter 01 becomes the registration chapter. Nothing to change here today: the string is correct, and the root-existence case will red if the ROOT goes away. But the coupling is worth a sentence in the doc naming which repo owns each segment, so the next person to rename a chapter knows this file exists. I am telling the tester lane directly as well - the cross-repo half of the fix is on that side.
PUBLIC-REPO HYGIENE: the added paths name the private sherlo-tester repo's internal layout, which this file already does throughout for the six legacy scenarios. Consistent with what is committed, not new residue. Nothing else added names anything internal.
CI PARITY, and the one thing worth recording: 72 passed, 3 skipped, 0 failed across the four suites touching this surface, and the ratchet was re-run against a REPRESENTATIVE checkout this time - the sibling lane's own worktree, which carries e2e-beats/. Round 2 was ratcheted against a checkout at an ancestor commit predating the beats road, which led to a factual error in the record that was corrected on request, with the stale path named so the next lane does not repeat it. Getting that right the second time is why this approval is on evidence rather than on assertion.
[reviewed-by: diff-scope]
Channel PR for task "diff-scope-cli-transcript-path".
E2E declaration: none - The suites that consume these transcripts are the legacy Test Bundled and Test Bundled Checks, which brain's DECLARED_SUITES cannot name and which a later task in this epic deletes - declaring a gate on a suite that is being retired buys a run against code on its way out. What protects the change instead is stated in the acceptance criteria and is stronger for this shape of work: the six existing scenarios must render byte-for-byte to the paths they render to today, and a new unit test with a must-fail control refuses a scenario whose fixture path lies outside a declared root. The saga's own beats suites cannot be named here either - they do not exist until a later task creates them, and their DECLARED_SUITES rows land with them.
🤖 Generated with brain