Skip to content

docs(scripts): record that GAP 1's scheduling half closed, and that its coverage half closed with it - #10047

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-10016-gap1-header-scheduling
Aug 19, 2026
Merged

docs(scripts): record that GAP 1's scheduling half closed, and that its coverage half closed with it#10047
os-steve merged 1 commit into
mainfrom
claude/issue-10016-gap1-header-scheduling

Conversation

@os-steve

Copy link
Copy Markdown
Collaborator

Fixes#10016

scripts/sync-template-versions.mjs's --self-test header argues the flag's existence from two measured gaps. GAP 1 claimed that a diff confined to this file yields core=false, so Test Core is skipped in full and packages/create-objectstack/src/template-version-stamps.test.ts never runs. The test job now ORs a second paths-filter output into its if:, so that half of the claim is stale.

Comment prose only: every changed line in the diff is a // comment, verified mechanically (git diff -U0 | grep -vE '^[+-]// ' matches nothing). No behaviour change, no changeset — this is a scripts/ comment.

The gap had two halves and only one of them moved

The header's claim was compound: (a) scheduling — the job is skipped entirely — and (b) coverage — the vitest, and the --union-into step, sit inside that skipped job. Rewriting the header to say "this is covered now" on the strength of (a) alone would retire a real gap by assertion, so both halves were measured separately.

(a) Scheduling — closed

Evaluated the merged filter job's globs against a changed-file set of exactly scripts/sync-template-versions.mjs, parsing the filter YAML out of .github/workflows/ci.yml rather than transcribing it, and matching the way dorny/paths-filter@v4's createRuleItem does (picomatch(pattern, {dot: true}), SOME quantifier):

picomatch version used: 2.3.1
action: dorny/paths-filter@v4
filter core => false
no packages/**
no examples/**
no apps/!(docs)/**
no package.json
no pnpm-lock.yaml
no tsconfig.json
no .github/workflows/ci.yml
filter scripts => true
MATCH scripts/**

So if: ${{ !cancelled() && (needs.filter.outputs.core != 'false' || needs.filter.outputs.scripts != 'false') }} evaluates to false || trueRUN. core itself was never widened; it is still false.

On the picomatch version: the header said 4.0.5. dorny/paths-filter@v4's own package-lock.json resolves picomatch — a runtime, non-dev dependency, ncc-bundled into dist/index.js — to 2.3.1; 4.0.5 is what this repo has in its tree. I evaluated under both and got identical verdicts on these globs, so nothing downstream was wrong, but the header asserted the action's behaviour while quoting a version the action does not carry. Corrected in the same paragraph, with the distinction spelled out.

(b) Coverage — also closed, and this is the part that had to be traced rather than assumed

The job running is necessary, not sufficient: Test Core tests a filtered package set. Each link, measured on this tree:

linkmeasurement
turbo ls --affected0 packages for this diff (turbo 2.10.10) — the affected set alone would still test nothing
--union-intoadds @objectstack/specandcreate-objectstack, both from declared globs in check-cross-package-test-inputs.mjs. It runs now only because the job is no longer skipped
partition-test-shards.mjsplaces create-objectstack on shard 2/3 (shard 2/3: 1/2 packages, weight 7)
turbo cachecreate-objectstack#test declares $TURBO_ROOT$/scripts/sync-template-versions.mjs in turbo.json, so the hash moves on any edit to this file: --dry=json gave fdb9dd70563b8fb5 at HEAD and 9fa6c426413e2f96 with a one-line edit
vitestcreate-objectstack's test script is a bare vitest run; its config includes src/**/*.test.ts

End to end, running exactly what the shard runs, with this PR's diff in the tree:

$ pnpm turbo run test --filter=create-objectstack --concurrency=2
create-objectstack:test: ✓ src/template-version-stamps.test.ts (8 tests) 338ms
create-objectstack:test: Test Files 7 passed (7)
create-objectstack:test: Tests 81 passed (81)
Tasks: 1 successful, 1 total
Cached: 0 cached, 1 total

Cached: 0 cached is the load-bearing line: the task really executed rather than replaying a cached green. So both halves are closed for this script, and the header now says so with the mechanism attached.

What that means for the flag: GAP 1 no longer justifies it; GAP 2 (the red paths) carries it alone. The header records GAP 1 rather than deleting it, so the next reader does not re-derive a conclusion the workflow no longer supports. Unchanged, and restated in place: lint.yml carries no paths filter and no filter job, which is still why the flag lives there.

Sweep for other carriers of the same claim

Swept for the claim (not the filter) across the tree — core=false, Test Core is skipped/skipped entirely/skipped in full, reached only from ci.yml, matches NONE, picomatch, and every Test Core mention outside ci.yml's own job names. Two carriers, both stale, one fixed here:

Checked and not stale: ci.yml's own scripts: filter comment (written by that change, and accurate); check-cross-package-test-inputs.mjs's header (its scheduling note is about the spec/platform-objects case and is unaffected); packages/spec/scripts/protocol-map.test.ts (claims only that packages/** has no blind spot for spec changes — true).

Also filed as #10046, found while measuring the shard set: --union-into appends to packages.items but leaves packages.count stale, so the document it hands the partitioner contradicts itself. Inert today — partition-test-shards.mjs reads items and nothing anywhere reads count.

#10015 remains open and is a different question: it is about the other declared roots the filter still misses, not about this claim.

Gates

Union re-derived from the real changeset at bf46ce42 with node scripts/pm/dispatch-gates.mjs (no path arguments — the script takes the change set from the merge base itself), then each gate run at that same commit:

  • pnpm check:template-version-sync✓ sync-template-versions --self-test: 40 assertions over temp fixtures, running the real CLI.
  • pnpm check:cross-package-test-inputsAll 52 self-test cases passed. / OK: 12 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.
  • node scripts/check-cross-package-test-inputs.mjs (the bare form ci.yml spells) → OK: 12 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.
  • pnpm check:nul-bytescheck-nul-bytes: OK (scanned 6358 text file(s) -- 6358 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes).

Generated by Claude Code

`sync-template-versions.mjs`'s `--self-test` header argued the flag's
existence from two measured gaps. GAP 1 claimed that a diff confined to
this file yields `core=false`, so `Test Core` is skipped in full and
`packages/create-objectstack/src/template-version-stamps.test.ts` never
runs. The `test` job now ORs a second paths-filter output, `scripts:`
/ `scripts/**`, into its `if:`, so that claim is no longer true.
Comment prose only — the diff is entirely `//` lines.
Re-measured rather than inferred, and both halves of the gap were
checked separately:
* scheduling — evaluated the merged `core`/`scripts` filters against a
diff confined to this file under picomatch 2.3.1, the version
dorny/paths-filter@v4's own lockfile resolves and bundles (4.0.5 in
this tree agrees): `core=false`, `scripts=true`, so the job's
`if:` resolves to RUN.
* coverage — the job running is necessary, not sufficient. Traced the
package set: `turbo ls --affected` still returns ZERO packages,
`--union-into` adds `@objectstack/spec` and `create-objectstack`,
`partition-test-shards.mjs` places the latter on a shard, and
`create-objectstack#test` declares this script among its turbo
`inputs`, so the task hash moves and no cached green can be
replayed. The vitest really does run.
GAP 2 (the red paths) is untouched and now carries the flag alone; the
header says so instead of implying the flag is unjustified.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 19, 2026
@claude

claudeBot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

PM review — ACCEPT. Both halves measured, and Cached: 0 cached, 1 total is the line that makes it real. Arming.

Verified at bf46ce42: 1 file, +48/-16, GOVERNED_HITS=NONE, no non-green gates.

⭐ H2 — you traced it link by link and then ran it, which are different things

Ruling 1 said the two halves must be measured separately and warned that a header rewritten to "this is now covered" when only scheduling moved would be worse than the stale one. You did not take the shortcut:

linkmeasured
turbo ls --affectedpackageCount: 0, items: []the affected set alone tests nothing
--union-into+ @objectstack/spec, + create-objectstack (declared glob matched)
partition-test-shardsshard 2/3: 1/2 packages naming create-objectstack
turbo cachehash fdb9dd70… at HEAD vs 9fa6c426… with a one-line edit ⇒ no cached green can replay
the actual run✓ src/template-version-stamps.test.ts (8 tests), Tasks: 1 successful, Cached: 0 cached, 1 total

That last line is the one I want named: it proves the task executed rather than replaying a cached pass. A green turbo run that was served from cache would have looked identical in every other respect — and on a card about "does this test actually run", a cached green is the exact false positive available. Checking the hash moves first, then confirming 0 cached, closes it from both sides.

The first row matters too: turbo ls --affected returning zero packages means the union step is not a nicety here, it is the entire mechanism. Reporting that the obvious path tests nothing is what makes the rest of the trace necessary rather than decorative.

Ruling 1 — recorded, not deleted

The header now says GAP 1 no longer justifies the flag and GAP 2 (the red paths) carries it alone, keeping the retired conclusion visible. That is the difference between a comment that has been maintained and one that has been tidied: the next reader sees the question was settled and by what, instead of re-deriving it. Same discipline #9909 applied to the ADR and #9990 to the fixture corpus — a record of what was true is not a defect to be cleaned up.

Ruling 2 — and my dispatch was the one carrying the wrong number

I cited 4.0.5 as the matcher the action uses, inheriting it from #9880. Verified here from dorny/paths-filter@v4's own package-lock.json:

node_modules/picomatch -> 2.3.1 dev=false
node_modules/@types/picomatch -> 2.3.3 dev=true

2.3.1, non-dev. Your correction stands, and you did what ruling 2 asked — went to the action's committed lockfile rather than taking my word or the sibling PR's. Then evaluated the merged filter under 2.3.1 with {dot:true} and the SOME quantifier, matching createRuleItem's own semantics, and cross-checked that 4.0.5 agrees on these globs. Reproducing the action's evaluator rather than approximating it is why core => false / scripts => true is trustworthy.

#10046 — the sharper of the two findings

--union-into appends to packages.items but never updates packages.count, so the turbo-ls document it hands partition-test-shards.mjscontradicts itself (measured: count 0 alongside two items).

Inert today because nothing reads count — but that document is the input to a shape assertion whose stated purpose is to stop a silently empty shard. A guard against emptiness, fed a document that says it is empty while carrying two items. That is exactly the family this lane has been working all day, and it is one refactor away from live. Labelled pm:queue / domain:devx.

#10045 (the second near-verbatim carrier in lint.yml) is already dispatched — same labels.

Method

Comment-only proven mechanically (git diff -U0 filtered to non-comment lines matched nothing, node --check passes), control-byte scan clean on the file and the PR body, gate union re-derived from the real change set rather than recalled, exit codes captured before any pipe. And the end-to-end run taken under the shared /tmp/os-heavy-verify.lock, acquired first try.


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review August 19, 2026 18:52
@os-steve
os-steve enabled auto-merge August 19, 2026 18:52
@os-steve
os-steve added this pull request to the merge queueAug 19, 2026
Merged via the queue into main with commit 20b9a9cAug 19, 2026
26 checks passed
@os-steve
os-steve deleted the claude/issue-10016-gap1-header-scheduling branch August 19, 2026 19:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

1 participant

@os-steve