fix(ci): schedule Test Core for the ten declared cross-package test inputs in content/, docs/, skills/ and .github/workflows/ - #10388
Merged
os-zhuang merged 1 commit intoAug 20, 2026
Conversation
…nputs in content/, docs/, skills/ and .github/workflows/ Generalises the separate filter output #9829 landed for `scripts/` to the four other roots that `CROSS_PACKAGE_TEST_INPUTS` declares: the output is renamed `scripts` -> `crosspkg` and gains `content/**`, the strictness-ledger audit file, `skills/objectstack-formula/**` and `.github/workflows/scaffold-e2e.yml`. Still a SEPARATE output ORed into the `test` job only, never a widening of `core`, which is what makes `content/**` affordable: a docs-only diff starts Test Core, whose package set is the (empty) affected set unioned with the declaring packages -- measured as `create-objectstack` alone on all three content-only commits in the sampled window. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
os-zhuang
marked this pull request as ready for review
August 20, 2026 17:40
os-zhuang
enabled auto-merge
August 20, 2026 17:40
os-zhuang
deleted the
claude/issue-10015-ci-core-filter-cross-package-inputs
branch
August 20, 2026 18:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #10015.
turbo.jsondeclares, per task, the paths outside a package that the package's tests read — 64$TURBO_ROOT$/…entries today, each mirroring aCROSS_PACKAGE_TEST_INPUTSdeclaration. Ten ofthem could not schedule Test Core at PR time, so the
--union-intostep those declarations dependon — a step inside the
testjob — never ran, and the merge queue was the first signal (#7802).This generalises the separate filter output #9829 / #10014 landed for
scripts/to the four otherroots:
scripts→crosspkg, pluscontent/**, the strictness-ledger audit file,skills/objectstack-formula/**and.github/workflows/scaffold-e2e.yml.All measurements below were taken at head
7ca8e1f2eagainst base0bfbeb70c(origin/mainmerged in at that sha; no commit between the card's base and this one touches
ci.yml,turbo.json,sync-template-versions.mjsorcheck-cross-package-test-inputs.mjs).Premise: re-derived, not inherited — and the card's ten are exactly right
Every one of the 64
$TURBO_ROOT$declarations instantiated to a real tracked file and runthrough ci.yml's filters with
picomatch(pattern, {dot: true})— the matcherdorny/paths-filter@v4builds its rules with (src/filter.ts,createRuleItem, defaultpredicate-quantifier: some) — under both 2.3.1 (what the action'spackage.jsonpins andncc-bundles) and 4.0.5 (what this tree's lockfile resolves).
On
0bfbeb70c, 19 of 64 declarations arecore=false; 9 of those are thescripts/rowsalready covered by #10014's output, leaving 10 unschedulable — the card's ten, task for task and
path for path:
The two picomatch majors agree on all 64 rows × 4 filters (
IDENTICAL). That comparator has apositive control: flipping a single verdict cell in one copy makes the same comparator print
DIVERGENT.Two re-derivation deltas from the card, neither of which moves the ten:
0bfbeb70c)$TURBO_ROOT$declarationscore=falsescripts/, already covered by #10014)The card's line numbers for the last three rows shifted (161→166, 195→200, 197→203) because
turbo.jsongained declarations in between; the task and path are identical.The fix schedules what it claims — all ten flip false → true
Same instantiate-to-a-real-tracked-file method, base tree vs this head:
@objectstack/spec#testcontent/docs/references/**content/docs/references/ai/agent.mdx@objectstack/spec#testcontent/docs/api/error-catalog.mdx@objectstack/spec#testdocs/audits/2026-07-unknown-key-strictness-ledger.md@objectstack/cli#testcontent/docs/deployment/cli.mdx@objectstack/cli#testcontent/docs/deployment/index.mdx@objectstack/cli#testcontent/docs/permissions/authentication.mdx@objectstack/dogfood#testcontent/docs/protocol/kernel/realtime-protocol.mdx@objectstack/formula#testskills/objectstack-formula/**skills/objectstack-formula/SKILL.mdcreate-objectstack#testcontent/**content/blog/context-window-is-the-constraint.mdxcreate-objectstack#test.github/workflows/scaffold-e2e.ymlflipped false -> true: 10 · unchanged: 54 · flipped true -> false: 0, and on this head theharness prints
UNSCHEDULABLE … 0 of 64under both picomatch majors. That zero's positivecontrol is the identical harness on the base tree printing
10 of 64.It does not over-schedule — swept over every tracked file
testgate matchesEvery gained file traced to one of the four patterns I added —
content/**434, the ledger file 1,skills/objectstack-formula/**2,scaffold-e2e.yml1 —UNATTRIBUTED: 0. Both zero-hits arecontrolled: swapping the two trees makes the same census report
LOST: 438, and withholdingcontent/**from the attribution list makes the same probe reportUNATTRIBUTED: 434. Bothpicomatch majors produce a byte-identical census.
Scheduling volume, per root, re-measured
Replaying the last 100 first-parent commits of
mainat0bfbeb70cthrough the same matcher:scripts/**(already landed)content/**docs/audits/2026-07-…-ledger.mdskills/objectstack-formula/**.github/workflows/scaffold-e2e.ymland the roots not taken, priced on the same window:
docs/**5,skills/**2,.github/workflows/**3. Nine of the ten declarations are a single file or a single subtree, sonaming the declared path costs zero here where the root would have cost ten between them.
Why
content/**is affordable, and why it is not narrowableIt is not narrowable:
create-objectstack#testdeclarescontent/**verbatim(
src/template-consistency.test.tsreads doc frontmatter to decide which templates are internal), sono narrower entry covers that row — the same argument #10014 made for
scripts/**.It is affordable because this is a separate output ORed into the
testjob only, never awidening of
core: Build Core, Dogfood and Temporal Conformance stay filtered exactly as they are.A docs-only diff starts Test Core, whose package set is
turbo ls --affected(empty for such adiff) unioned with the packages whose declarations matched. Measured through the real
--union-intoon all three newly-scheduled commits:One package's suite, and it is the package that declared the input — i.e. exactly the coverage the
declaration was bought for, not a docs PR running the core suite.
Second file: prose my own rename falsified
scripts/sync-template-versions.mjs's "GAP 1 — SCHEDULING, NOW CLOSED" block names the outputliterally (
`scripts:` / `'scripts/**'`, and`core=false`, `scripts=true`). Renaming theoutput makes those two sentences false, so they are corrected in the same commit. Substance
unchanged —
scripts/**is still an entry and the OR is still there; only the output's name moved.Known residual, filed rather than fixed here
The five entries are a second recognizer of the declarations, kept in step by hand: nothing
fails today when a declaration lands in a root no entry covers. Closing that is a mechanism
decision (derive the entries at CI time — unblocked now that #9826 has merged — versus a static
parity gate), which is why it is #10379 and not a rider on this PR. The workflow comment says so at
the point of use.
Gates
Re-derived from the real diff with
node scripts/pm/dispatch-gates.mjs(no paths passed — it takesthe change set from the merge base itself). That run named two families the path-hypothetical run
did not, both pulled in by the
sync-template-versions.mjsedit. All named families run at7ca8e1f2e, each verdict quoted from the gate's own output line:check:filter-alias-paritywas named in the dispatch prompt but not by the derivation, and thederivation is right: it guards ObjectQL's
where/filter/filters/$filterwire-alias slots(#8002), nothing to do with
dorny/paths-filter. Not run.These are all pure source-text scanners — none builds or reads
dist/— so per the resource rulesthey were run outside
os-verify-lock.sh, deliberately and declared here. Nothing in this diffcompiles.
Clause ② — declared, and not reached. The path limb is
packages/spec/src/**; this diff is.github/workflows/ci.ymlandscripts/sync-template-versions.mjs. On content: no contractaccept/reject behaviour changes and no public surface widens — the change is CI scheduling only.
No changeset (
skip-changeset):.github/workflows/**and a rootscripts/*.mjscommentpublish nothing. Judged by publish surface, not habit — nothing here reaches a
packages/*thatships.
Generated by Claude Code