fix(devx): route the elevation census page to os-regen, and pin the CI gate that is the real guard - #13732
Merged
os-project-manager merged 2 commits intoAug 31, 2026
Conversation
…te that guards it Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
…nsus-anchor-regen-guard
This was referenced Aug 31, 2026
os-project-manager
marked this pull request as ready for review
August 31, 2026 09:05
os-project-manager
deleted the
claude/issue-13646-census-anchor-regen-guard
branch
August 31, 2026 09:32
This was referenced Aug 31, 2026
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 #13646
Both halves ship. But the load-bearing half turned out to already exist, and the
measurement that shows it also changes what the merge-driver half is allowed to be.
Verified on
d32b0f501. Diff is 4 files, +131/−1, and zero lines of.github/workflows/lint.yml— see "No workflow edit" below.⭐ Zone 2 falsified — and so is Zone 1's premise for half 1
Triage ruled that the load-bearing half is "一道「重生成并 diff」的 CI 检查", on the
grounds that it is the only instrument reaching the 13 anchors that went stale with no
conflict marker. That instrument is already in the tree, already required, and already
fires on exactly that case.
scripts/check-system-context-census.mjsre-derives the census from the tree with an ASTwalk and compares it to the committed page — its POPULATION check requires every read site
the census finds to be anchored at its exact
file:line. It runs in.github/workflows/lint.ymlas the joblint, whosename:is the required statuscontext
Lint & Repo Gates(node scripts/check-required-contexts.mjs), onpull_request+merge_group+push:main, with nopaths:filter.Reproducing the card's own silent case on
cc837dbfec— shiftplugin-sharing/src/sharing-service.tsdown 29 lines (main's real delta in the #13625window) and leave the page untouched, which is precisely the
branch-never-touched-that-file shape git merges clean:
Those are the card's own
+29values (625→654,891→920,978→1007,1568→1597,1309→1338) — the gate names every one of them. ⇒ The silent 13 are not silent to CI.What was actually missing: nothing asserted the gate is scheduled
check-self-test-wiredis conditional in the wrong direction for this — it requires thata script CI runs also has its
--self-testrun. Delete both invocations fromlint.ymland it goes green, silently retiring the only instrument that catches a staleanchor. Ablated, with the mutation confirmed on disk (2 invocations → 0):
The production run cannot see its own descheduling, which is exactly why the assertion
belongs in
--self-test. Added there, following the precedentcheck-doc-frontmatter,check-aggregator-rosterandcheck-ci-filter-parityset. Self-test now 37 cases, green.No workflow edit — deliberately
lint.ymlalready invokes both legs, so the pin reads the workflow instead of addingto it. That is the same move
check-doc-frontmatterrecords for its second docs root("
lint.ymlis the repo's busiest file and a second step would have been a thirdconcurrent edit of it"). ⇒ This PR does not touch
lint.ymlat all, so it does notcontend with #13584 and does not consume the slot #13582 is held for.
Half 2 — the merge driver route, scoped to the FILE
Registered in
scripts/regen-artifacts.mjs(the single source of truth) plus.gitattributes, withgen:/check:in the root manifest. This is the firstproduction row owned by ROOT tooling — it exercises the
ownerfield #13585 added,which until now only synthetic self-test cases touched:
content/docs/permissions/**. That glob is not safe: unlike the routed siblingcontent/docs/references/**, which is generated whole,content/docs/permissions/is22 hand-written prose pages around exactly one generated page. The directory route
would defer 21 prose files to OURS and drop the other side's edits silently — the exact
trade
packages/spec/src/migrations/registry.tsis kept out of the table for. Routed asthe file; the glob is recorded in
NOT_DRIVER_MANAGEDso the next author meets thereasoning instead of the omission.
The header's own warning, answered rather than accepted
os-regen-merge.shwarns that a routed path can "merge with exit 0 and zero conflictmarkers while SILENTLY DROPPING one side's changes". Here something still reddens: the
census gate above, on every PR, from a required job, re-deriving from the tree rather than
reading the page back. The driver removes hand-merge rounds; it is never the only signal.
⇒ Triage's ordering constraint ("第 1 项未落地前 ⛔ 不得合入第 2 项") is satisfied — the
CI instrument is in place before the routing, because it was already there.
Nor can the
genleg launder a population change. Injecting a new elevation read siteand running
--fix:--fixre-anchors a pure shift and REFUSES when a site arrived or vanished, so thepre-commit gate — which spawns
check, nevergen— stays red until a human writes the row.A2.1 cost and A2.2 determinism — both hold
node scripts/check-system-context-census.mjs)--fixround trip--fixon a clean tree--fixnew Date()/toISOStringin the script⇒ A2.1 holds (3s is not "minutes"; it was already affordable enough to be running). A2.2
holds — the output is a pure function of the tree, so the check cannot red on itself.
Scope question the card raised: which other generated artifacts are outside the routing?
Measured across all 79 manifests: 21 generator-ish scripts (
gen:*, or a--fix/--updatemode), of which 10 are named as thegenof a driver-managed row. Theremaining 11 are the open set; several are already deliberately excluded
(
gen:migration-registry,gen:authorable-surface-base, and thegen:test-typecheck-debtfamily are all shrink-only or MIXED by declaration). The genuinely unaccounted candidates
are
gen:sdui-lockstep,gen:openapi,gen:skill-refs,gen:skill-docs,gen:sbom,gen:react-blocks, and the per-packagetest-typecheck-debt.jsoncopies outsidepackages/spec. ⛔ Not fixed here — one card, one route. Filed unassigned as #13731,which also links #13335 (
gen:skill-refs) as a previously recorded member of thesame class rather than a duplicate of it.
Verification
Gate family derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no stale-tree warning) on
d32b0f501; all 18 run.check:merge-driver,check:entry-guard,check:pm-dispatch-gates,check:turbo-task-graph,check:pnpm-filter-targets,check:agent-test-spelling,check:cross-package-test-inputs,check:parse-guard, and the census gate itself.check-self-test-wired,check-self-test-workflow-commands,check-aggregator-roster,check-required-contexts,check:filter-alias-parity,check:nul-bytes,check:doc-anchors(self-test + production leg each).
a refusal:
check-test-completeness("there is no local log to hand it … ⛔ It is not ared"), and
check:dual-build-cjs-loads("PREREQUISITE NOT MET — this gate reads builtoutput"; it needs a full
pnpm buildof 100+ packages). Declared narrowing: this PR'sroot-manifest edit adds two keys to the
scriptsmap of aprivate: truenon-workspacemanifest that has no
dist/and no exports either gate reads, so neither can move.CI runs both on a built tree.
files. (1) The population comes from eslint's own config, which states and measures with
a positive control that this repo "never enables type-aware linting … for ANY file" — so
no untouched file's verdict can depend on this diff. (2) File count read from
--format json: 2. (3) Invariance follows from (1)..gitattributesandpackage.jsonare not eslint inputs.
Changeset
skip-changeset. This PR publishes nothing: zeropackages/**, and the only manifesttouched is the root, which is
private: trueand not a workspace member. An emptychangeset is not the alternative here —
check-empty-changesetrejects newly added onesin this repo, and its own ledger records that the label is strictly safer.
Draft for the
domain:devxseat to arm after review.Generated by Claude Code
Generated by Claude Code