feat(ci): the coverage union covers ca-pi/tools too (#537) - #545
Merged
Conversation
#521 shipped the rule and the union job for plugins/ca/tools. ca-pi/tools is the other platform-forked tree per tech-stack.md - Windows supervisor and process-tree paths - and was in scope for the RULE with no job to compute it. Mechanical duplication rather than a matrix over trees, for the reason #521 recorded: the audited-graph contract attributes a job's dependency graph BY its working directory, and a templated one resolves to `.`, which nothing audits. Compensating with extra `npm audit` steps breaks the contract pinning the exact audit inventory across ci.yml and docs.yml. Both contracts are right, so one job per tree it is. `ca-pi-checks` audits this same literal directory under the identical path filter. Advisory on the same terms: awaited by ci-passed so a hang stays visible, never in required_results, and both new jobs are named in the sanctioned-advisory assertion. A REAL defect caught while writing the contract: `coverage-blob-ca-*` also matches `coverage-blob-ca-pi-ubuntu-latest`. On any PR touching both trees the ca merge job would have absorbed Pi's blobs and reported a cross-tree union under ca's name - silently, and with an entirely plausible number. Each tree's artifacts now carry an `-os-` terminator so the globs are disjoint. That is asserted by actually globbing each pattern against the other's real artifact names with fnmatch, not by eyeballing strings: the contract fails if a merge job's pattern matches a foreign artifact, AND if it stops matching its own. Verified load-bearing - restoring the colliding names turns test_ci_impact red. Claude-Session: https://claude.ai/code/session_01WJgVfZw7J81PB7mwpHyUxx
The first run failed 20 tests in runner-isolation.test.ts on both hosts. Not a
flake and not a config slip: ca-pi's suite is NOT runnable without an installed
Pi host, and `npm run coverage` - the command tech-stack.md names for this tree -
runs the WHOLE suite.
It passes locally only because a Pi runtime happens to be on this machine's PATH;
on a bare runner those tests fail rather than skip. Verified both directions.
The cells now install the host the same way `ca-pi-tools` does, on node 22.19.0
(ca-pi's engines require it, and measuring on a different runtime would measure a
different code path), with Python present for the bridge.
ONE Pi version rather than that job's {0.80.5, 0.80.10} matrix: this measures
which LINES execute, which does not vary by host version in any way a second cell
would reveal. Pinned to the upper bound of the supported window.
Timeouts raised to 25 minutes to match ca-pi-tools, whose 452s worst cell is
dominated by the same cold Windows global install these now pay.
Claude-Session: https://claude.ai/code/session_01WJgVfZw7J81PB7mwpHyUxx
) The Pi union cell's remaining Windows failure, and the THIRD instance this session of one root cause: a Windows 8.3 short name compared against its long form. canonicalPath resolves with `realpathSync.native`, which expands 8.3 names. The test built both its fixture root and its expectation with plain `realpathSync`, which resolves symlinks but does NOT expand them. On a GitHub runner, where tmpdir() is the RUNNER~1 form, the subject correctly returned the long path and the test demanded the short one: expected 'C:\Users\runneradmin\AppData\Local\Te...' to be 'C:\Users\RUNNER~1\AppData\Local\Temp\...' The implementation was right; the fixture was wrong. Both sites now use `.native`, matching the contract under test - the fixture root especially, since a non-native root hands every case in the file a path the implementation will legitimately disagree with. Invisible on any developer box whose profile path is already 8.3-clean, which is why it took a second host to find - the same reason #539 and #541 hid. 751 ca-pi tests pass. Test-only: ca-pi ships from extensions/, not tools/, so this is no payload change and needs no version bump. Claude-Session: https://claude.ai/code/session_01WJgVfZw7J81PB7mwpHyUxx
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.
Closes #537.
#521 shipped the rule and the union job for
plugins/ca/tools.plugins/ca-pi/toolsis the other platform-forked tree pertech-stack.md— Windows supervisor and process-tree paths — and was in scope for the rule with no job to compute it.Why duplicated rather than a matrix over trees
Exactly the reason #521 recorded, restated here because it looks like avoidable duplication:
matrix.tree-templated one resolves to., which nothing audits.npm auditsteps breaks a second contract, which pins the exact audit inventory acrossci.ymlanddocs.yml.Both contracts are right, so it is one job per tree.
ca-pi-checksaudits this same literal directory under the identical path filter, which is what satisfies the first.Advisory, on the same terms
Awaited by
ci-passedso a hang stays visible, never inrequired_results, and both new jobs are added to the sanctioned-advisory assertion. DECISION-0031's Available reasoning applies unchanged.A real defect caught while writing the contract
coverage-blob-ca-*also matchescoverage-blob-ca-pi-ubuntu-latest.On any PR touching both trees, the
camerge job would have downloaded Pi's blobs alongside its own and reported a cross-tree union under ca's name — silently, and with an entirely plausible number. Nothing would have looked wrong.Each tree's artifacts now carry an
-os-terminator (coverage-blob-ca-os-*,coverage-blob-ca-pi-os-*) so the globs are disjoint.It is asserted by actually globbing each pattern against the other's real artifact names with
fnmatch, rather than by eyeballing the strings — the contract fails if a merge job's pattern matches a foreign artifact, and if it ever stops matching its own:Verification
test_ci_impact.py53 pass.ci.ymlparses.tech-stack.md's per-tree table now says ubuntu+windows for ca-pi instead of "not yet", and documents the namespacing and why it exists.The union figures themselves will appear on this PR's own run —
ca-piis touched, so its cells execute here.