Skip to content

home/ios: the index rig stopped checking the shared corpus at the rename - #405

Open
nyblnet wants to merge 1 commit into
mainfrom
home-ios-corpus-path
Open

home/ios: the index rig stopped checking the shared corpus at the rename#405
nyblnet wants to merge 1 commit into
mainfrom
home-ios-corpus-path

Conversation

@nyblnet

@nyblnet nyblnet commented Aug 29, 2026

Copy link
Copy Markdown
Owner

scripts/test-tray-index.mjs looked for the corpus at tray/fixtures. The tray→home rename moved it to home/fixtures, and the rig went on printing "shared corpus: absent, skipped" — green every run, with the cross-language check silently not happening.

Nothing had drifted, which is luck rather than evidence. Pointed at the real path, the Swift port agrees with all 11 cases and the budgets.

The skip was mine, and it was half right

I wrote that skip and argued for it: a rig that fails until an unrelated branch lands is a rig people learn to ignore. That still holds for a corpus which does not exist yet. It does not hold for one that moved, and the skip could not tell the two apart.

It can now. Before skipping, the rig looks for an expected.json in a fixtures directory elsewhere in the tree. Finding one means this path is stale, and that is a hard failure naming where the corpus actually is.

corpus state before after
in place ran runs — 11 cases agree
moved "absent, skipped", exit 0 exit 1, names the real location
genuinely absent skipped skips, loudly

All three verified by moving the directory and running it.

Why this matters beyond one path

The zone brief already says a rig that only fails on a total revert is not testing the fix. This is that rule one turn further out: a rig that skips when its input moves is not testing anything at all, while still printing a pass. The failure mode is quieter than a wrong assertion, because there is no assertion left to be wrong.

Incidental, and a repeat offender

The new helper's doc comment originally contained a literal * / inside a glob, which closed the block comment early and broke the file — the same trap Accept: */* set in Releases.swift a few days ago. Rewritten to describe the pattern rather than spell it.

Adjacent, not mine

scripts/test-doc-index.mjs still points at tray/doc-index.mjs and dies on it — same rename, same cause, ops zone. PR #399 repairs and registers it, and should land first: it is the JS reference this rig's corpus half is diffed against.

Exercised

The three home rigs (test-tray-bridge, test-tray-index, test-tray-releases), plus a clean xcodegen + simulator build of the host. No Swift changed, so no save round trip was run.

`scripts/test-tray-index.mjs` looked for the corpus at `tray/fixtures`. The
tray→home rename moved it to `home/fixtures` and the rig went on printing
"shared corpus: absent, skipped" — green every run, with the cross-language
check silently not happening, for as long as the rename has been in.

Nothing had drifted, which is luck rather than evidence: pointed at the real
path the Swift port agrees with all 11 cases and the budgets. But the rig was
reporting a pass for work it was no longer doing.

I WROTE THAT SKIP, and argued for it: a rig that fails until an unrelated branch
lands is a rig people learn to ignore. That reasoning still holds for a corpus
that does not exist yet. It does not hold for one that MOVED, and the skip could
not tell the two apart.

So the skip now distinguishes them. Before skipping, the rig looks for an
`expected.json` in a fixtures directory elsewhere in the tree; finding one means
this path is stale, and that is a hard failure naming where the corpus actually
is. Genuinely absent still skips, loudly.

Verified all three states: in place → 11 cases agree; moved → exit 1, "the
shared corpus is not at home/fixtures/ but IS at …"; absent everywhere → exit 0
and skips.

The lesson is the one already in the zone brief, one turn further out: a rig
that only fails on a total revert is not testing the fix — and a rig that skips
when its input moves is not testing anything at all, while still printing a
pass.

One incidental: the doc comment for the new helper originally contained a
literal star-slash inside a glob, which closed the block comment early and broke
the file. Exactly the trap that `Accept: */*` set in Releases.swift a few days
ago. Rewritten to describe the pattern instead of spelling it.

NOT MINE, adjacent: `scripts/test-doc-index.mjs` still points at
`tray/doc-index.mjs` and dies on it. Same rename, same cause, ops zone — PR #399
repairs and registers it.

Exercised: the three home rigs, plus a clean xcodegen + simulator build of the
host. No Swift changed, so no save round trip was run.
@github-actions

Copy link
Copy Markdown

Build size

main (220f7e7) → home-ios-corpus-path (a534866)

app base PR change
bento/slides 669.3 KiB 669.3 KiB 0.0 KiB (0.00%)
bento/spaces 267.6 KiB 267.6 KiB 0.0 KiB (0.00%)
bento/dash 161.3 KiB 161.3 KiB 0.0 KiB (0.00%)

Updated: 2026-08-29T07:36:16Z

@nyblnet

nyblnet commented Aug 29, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #399 — do not merge this. It will be closed when #399 lands, not before.

#399 and this PR fixed the same bug independently and conflict on scripts/test-tray-index.mjs, which is ops' zone (START-HERE.md:51). My process error: I claimed home-ios and edited a file in scripts/, so the board could not show two of us in one function and the integrator's pairwise check found it instead. Both PRs read CLEAN throughout, because that field compares each PR to main and never to another PR.

The composed policy lands in #399, agreed with bento-team-ops:

  • path → home/fixtures
  • absent → hard fail, no skip branch
  • my strayCorpus() survives as a message enricher only — no control flow, no throw
  • process.exitCode with fall-through, so the Swift-diff summary still prints before the failure

Two things I got wrong here, both worth recording:

The skip branch was unreachable, not merely wrong policy. The rig imports home/webext/src/library.js (line 203) and compiles home/ios/BentoIndex.swift (line 291) before the corpus section at 407+. Remove home/ and it dies at exit 2 long before it could skip. ops added the precision that a sparse checkout could keep home/ios and home/webext while excluding only home/fixtures — so "unreachable" is true of the realistic case, not literally every case. That residual case argues for hard-fail too: a rig silently skipping its own subject because someone excluded the subject is the failure being removed.

My strayCorpus() threw, and the throw aborted the rig's other half. Measured: with the corpus moved, swift port agrees and documents compared both print zero times, and the reader's last line is a raw Node stack trace. The 72-document Swift diff — this rig's other, independent guarantee — never reports. That is exactly the defect I had described hours earlier in another file: the error withholds the useful work and steers the reader toward "this rig is broken" rather than "this path is stale". ops caught it in my code.

Why this stays open rather than closing now: #399 is blocked on its maintainer. Closing this first would leave main with a rig that silently skips its corpus and no open PR fixing it. This is the fallback until #399 lands.

nyblnet added a commit that referenced this pull request Aug 30, 2026
Follow-up inside this PR, from review by bento-team-home-ios, which wrote a
six-case harness against the branch and found the first of these.

test-spaces.mjs — registration is --manifest's whole job and no part of the
full runner's, so it is asked only in that mode. Both halves were wrong once.
With no workflow to read, --manifest warned on stderr and then printed a
success line naming the file it had just failed to find; it now fails, because
a mode that cannot see the workflow has done none of its job rather than half.
And the check ran BEFORE the argv parse, so an unregistered rig exited 2 in
full-runner mode too — measured at zero rig-output lines, the eight rigs
withheld from someone who asked for rigs and was told about CI registration.

test-tray-index.mjs — one policy for the shared corpus, composed with PR #405,
which found the same bug in the same function within hours. Absent is a
FAILURE, not a skip: home/fixtures is tracked, and the rig imports
home/webext/src/library.js and compiles home/ios/BentoIndex.swift before
reaching this section, so there is no checkout where it runs and the corpus is
legitimately gone. #405's strayCorpus() probe is kept as a message ENRICHER
only — "MISSING, and one IS at X" sends a reader to fix a path where "MISSING"
sends them hunting a deleted corpus. It throws in #405, which aborted before
the Swift-diff summary and left a raw stack trace as the last thing on screen;
diagnosis belongs in the message, not the control flow. exitCode, not exit().

test-sanitize.ts — the markup-<style> check asserted rules-survive using a
literal substring, which fails on ONE INSERTED SPACE once #402 scopes that
sheet (scopeCss emits scope, selector, space, brace). It now normalises
whitespace and asserts nothing about scoping, so the two PRs are decoupled and
neither owes the other a fix on merge order. Verified both ways: 140/140 with
#402 applied and 140/140 without.

Three traps in that one region, all the same cause — it lives inside
probeSource's template literal, so it is a STRING, not code. A backtick ends
the template, a TypeScript annotation reaches the browser as a syntax error,
and a single backslash-s collapses to a bare 's': the regex became /s+/g and
stripped the letter s out of the markup, which surfaced as the element id
'sv1' coming back as 'v1'. The doubled backslash is load-bearing and now says
so.

Verified: test-sanitize 140/140 with and without #402; test-tray-index 72
documents, corpus 11/11, and exit 1 both when the corpus is moved (naming the
new location) and when it is absent, with the Swift-diff summary still
printing in both; test-doc-index 11/11; test-spaces all eight rigs plus all
six manifest cases; test-release-apps 40/40; test-publish-gate 19/19;
test-validate 44/44.
nyblnet added a commit that referenced this pull request Aug 30, 2026
Three rigs were on disk and in no workflow: test-spaces.mjs (registered via a new --manifest bookkeeping mode), test-doc-index.mjs (also repaired — it had been throwing on main since the tray→home rename) and test-slide-store.ts (bundled through esbuild).

The iOS bridge rig never read exportCopy, the function the arbitrary-write finding was about: 52/52 passed with both its guards deleted. Four shape checks pin it now, three of which fail against that revert.

test-sanitize.ts explained a passing assertion with a false reason — scopeCss's one call site takes el.css, not the markup. Corrected, plus two checks that exercise scopeCss on the field it does guard.

test-tray-index.mjs printed 'absent, skipped' in green while the shared corpus sat at home/fixtures: a skip whose precondition had expired. It fails now, composed with PR #405 — hard fail, with #405's strayCorpus() probe kept as a message enricher rather than a throw, so the Swift-diff summary still prints.

Also decouples the markup-<style> assertion from PR #402's merge order: it normalises whitespace and asserts nothing about scoping. Verified 140/140 both with #402 applied and without.
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.

1 participant