Uh oh!
There was an error while loading. Please reload this page.
Hold the isSystem census page to the code: committed AST census, population gate, converted anchors - #13051
Open
os-elon wants to merge 9 commits into
Open
Hold the isSystem census page to the code: committed AST census, population gate, converted anchors#13051os-elon wants to merge 9 commits into
os-elon wants to merge 9 commits into
Conversation
`main` moved under the open PR and the page's live numbers went stale: * +5 line rot in `plugin-security/src/security-plugin.ts` (the import block #13065 added at :66 pushed every anchored read down five lines), plus the `field.zod.ts` `readonly` citation `--fix` re-anchored mechanically. * Six decomposition-table counts re-measured against the merged tree: lines 1804->1810, in tests 1010->1012, in sources 794->798, identifier appearances 809->813, keys 308->310, comments/strings 356->358. The census population itself did NOT move: 109 elevation read sites in 20 packages across 45 files, before and after. The gate, its criterion and its self-test are untouched -- the page's numbers were made true, not the check made lenient. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
os-elon
marked this pull request as ready for review
August 29, 2026 04:54
os-elon
enabled auto-merge
August 29, 2026 04:55
github-merge-queueBot
removed this pull request from the merge queue due to failed status checks
Aug 29, 2026
Uh oh!
There was an error while loading. Please reload this page.
… census page The six raw text counts (lines carrying the identifier, the test/source split, identifier appearances, object-literal keys, the prose remainder) are properties of the whole corpus, not of the elevation population the page certifies. They move whenever any file under packages/ or examples/ gains or loses a line mentioning isSystem -- a test, a seed object, a comment -- and because CI scores a PR's MERGE with main and the merge queue re-derives that merge against a newer main on every attempt, a page carrying them races a moving target. Measured on this branch: three unrelated merges to main moved those six numbers eight times in one night, while every census-derived figure held flat across the same refs -- 109 sites, 20 packages, 45 files, 6 ledger subtractions, 21/115/9 role counts, at db39dfc, 8a483b3, ca1965f and the merged tree. So they move out of DECLARED_COUNTS into UNENFORCED_TEXT_COUNTS: still required to be PRESENT on the page and to carry a dated measurement marker, never compared. The POPULATION, RESOLUTION and CLASSIFICATION checks and every census-derived count are untouched, and an empty census still refuses. Seven self-test cases pin the new criterion, two of them over the real lists: every entry of DECLARED_COUNTS must hold still under a whole-corpus text drift, and all six UNENFORCED_TEXT_COUNTS must move under it -- so re-adding a text count to the enforced list fails the self-test by name. Also re-anchors permission-set-projection.ts:987 to :1009 (pure line rot from today's main, repaired by --fix).
github-merge-queueBot
removed this pull request from the merge queue due to failed status checks
Aug 29, 2026
Uh oh!
There was an error while loading. Please reload this page.
Contributor
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 33242330316 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
This was referenced Aug 29, 2026
This was referenced Aug 29, 2026
fix(client): declare the response the meta reset door actually sends on both
deleteItem twins
#13148 Open
Merged
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 freeto 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#12962
content/docs/permissions/system-context.mdxcalls itself "the authority" and says it is "built by census over the whole repo, not by recall". Nothing held it to either claim. This PR ships the census as a committed instrument, four gates over it, and the anchor conversion those gates keep true — in one PR, so the conversion is verified rather than asserted.What landed
scripts/isystem-census.mjsExecutionContext.isSystemreads (--jsonfor the whole thing)scripts/doc-line-anchors.mjsfile:lineanchors in docs prose — the second page costs a ledger, not a parserscripts/check-system-context-census.mjs--self-test, and a--fixthat repairs rot and refuses to repair populationcontent/docs/permissions/system-context.mdx.github/workflows/lint.ymlDocs anchors resolve to real headingsstepThe census is an AST walk, and that is measured rather than asserted
The card measured a regex pass silently losing 6 real sites in
report-service.tsto a quote desync and 11 more to(ctx?.session as any)?.isSystemcasts. The census parses throughscripts/ts-parse.mjs(so a file that does not parse refuses instead of scoring clean) and classifies every appearance of the identifier by where the parser puts it.Re-derived at
8cb96ec41b, independently of the page:That reproduces the page's headline exactly, so the card's premise holds: 109 sites across 20 packages, 45 files. The 6 subtracted reads are the
Object.isSystem/EmailTemplate.isSystem/Environment.isSystemcollision; the subtraction ledger is keyed by (file, receiver) and carries no line numbers, because a ledger of line numbers rots exactly like the anchors this exists to stop rotting — and it rots invisibly, since a stale row still subtracts a live site.Gate B is the mandatory one, and the reason is the card's own sentence
Four checks run:
The 28 deliberate non-read anchors (the four
isSystemdeclarations, thesys_-prefix helpers, the guard block row 2 cites, the prose targets in the "does NOT do" table) sit inNON_READ_ANCHORS, and each row carries a needle rather than a line: a literal that must appear on exactly one line of the file. The gate locates the line and requires the page to name it. So every one of the 145 anchors is enforced and mechanically repairable, and the ledger is self-retiring — a needle matching zero lines, or two, is a finding.Ablation — predicted, then observed
Both legs mutated in place so line counts did not move (a whole-line delete would have shifted every anchor below it and drowned the reading). No rebuild is in the loop: these scripts read and parse source directly, nothing resolves through a
dist/. Each leg proved its mutation on disk by counting the removed and injected text, restored withgit checkout HEAD -- (absolute path)under a trap, and verified the restore by blob hash against the HEAD blob plus an emptygit diff HEAD.A — a site deleted from the code, its row left standing (
if (context?.isSystem) return allFields;neutralised insecurity-plugin.ts). Predicted: the Classification check names the orphaned anchor and the census-derived counts drop by one. Observed, exactly:B — a read site arrives with no row (a metadata-field read in
explain-engine.tsre-pointed at a context receiver). Predicted: Population names the site, the census ledger reports its now-stale row, counts move up. Observed, and with the control that matters:⭐ That last line is the card's thesis reproduced mechanically: under a mutation that adds an unanchored elevation read, every anchor still resolves and an anchor-only gate is all green, while the population check names the site by
file:line.The green control is the page as it now stands: the same gate exits 0 on it. And the gate's own matching rules — the thing a clean tree cannot tell working from weakened — are covered by
--self-testcases (21 at that commit, 27 after round 2 below), including the green control, both red controls above, ambiguity, out-of-range, three ledger failure modes, and the--fixrefusal.The anchor conversion
Ruling kept: the spelling stays a mechanically resolvable path suffix (
objectql/src/engine.ts, never a bareengine.tswhere the basename is ambiguous). 13 anchors moved:security-plugin.ts4287/4438/4516/3800,sharing-plugin.ts:991, and fiverest-server.tsanchors — all repaired by--fix, which maps a file's anchors to its census sites in line order only when the two counts agree;registry.ts:450(a/**line) to theapplySystemFieldsdeclaration at:459;crud-nodes.ts:314(a comment) to thestampSystemInsertOwnercall at:318; and row 2's2483–2630brace-to-brace range, replaced by a single anchor at the step 3.5 comment, since}admits no unique needle.Where it is wired, and why not a new gate step
Folded as two commands into the existing
Docs anchors resolve to real headingsstep, per the triage's preferred route. That job carries no paths filter, so the census runs on code-only PRs — the ones that add a read site, which is the whole point — and the fold costs no new check context, no newcheck:*manifest key and no new required-status entry for one page. The--self-testinvocation is whatcheck:self-test-wiredrequires; it verifies green.Not done here, deliberately
The mechanism generalises to any docs page carrying
file:lineanchors, anddoc-line-anchors.mjsis shaped so a second page is cheap — but no second page is converted here. Startup scope discipline; that is its own card.Verification
The first round's evidence, all at
687ed07a84:node scripts/check-system-context-census.mjs --self-test—all cases passed(21 cases)node scripts/check-system-context-census.mjs—OK — 109 elevation read sites in 20 packages across 45 files, all anchored; 145 anchors resolve, 27 declared non-readnode scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, 5 paths, 48 families): 42 runnable-here gates exit 0, includingcheck:doc-anchors,check:doc-authoring,check:docs-single-h1,check:doc-frontmatter,check:role-word,check:entry-guard,check:parse-guard,check:self-test-wired,check:step-collectors,check:required-contexts,check:ci-filter-parity,check:nul-bytesbare-root-worklist --self-testOK (40 recorded verdicts, none stale),check:pm-dispatch-gates834 cases passcheck:type-check-debtafter building the package closure:check-type-check-coverage: OK — 65/78 workspace packages type-checkedturbo run build:check:doc-formula-expressions,check:doc-security-posture,pnpm --filter @objectstack/spec check:docs,check:skill-examples(260 prose examples type-check) — all exit 0pnpm lint—VERDICT command-exit 0, no eslint outputRepair round — the gate failed on its own page, and the page's numbers were made true
The first CI run went red on exactly one of 39 checks:
node scripts/check-system-context-census.mjs, this PR's own gate, on this PR's own page. Two declared counts disagreed with the census by one (table-lines-total1804 vs 1805,table-lines-tests1010 vs 1011).The counter was not what changed — the declaration went stale under a moving
main. On the branch tree alone the gate exits 0 and the census reportslines 1804 (tests 1010, sources 794), exactly what the page says. CI evaluates the PR's merge withmain, andmainhad landed#13026(cf71d73f84, 00:25Z) after the declarations were written. That commit adds one corpus line:One line in a test file, so it counts in
linesTotaland inlinesInTests: the two+1s are the same line counted twice.total − testsstayed 794 — the non-test half never moved, which is whytable-lines-sourceswas not among the findings.mainmerged into the branch here (a merge commit, never a rebase; the base is nowdb39dfc1c9), and every figure re-derived after the merge — a number derived before it is stale by the time it is pushed. Against that tree two further main-side commits move the counts again:#13060(one more test line) and#13065(four source lines insecurity-plugin.ts, plus a five-line import block at:66that pushed all eight of that file's anchors down by five).Repaired, and only in the two shapes the failure admits — the page's numbers made true, the criterion untouched:
security-plugin.ts1387→1392,1409→1414,1560→1565,2486→2491,3803→3808,4290→4295,4441→4446,4519→4524, andfield.zod.ts:1436→1440(that one rewritten by--fix).1804→1810, in tests1010→1012, in non-test sources794→798, identifier appearances809→813, keys308→310, comments/strings356→358.The census population did not move: 109 elevation read sites in 20 packages across 45 files, before the merge and after. No tolerance was widened, no declaration deleted, no check relaxed; the gate, its criterion and its 20 self-test cases are byte-identical.
Proved in both directions with the same command on the same tree, exit status captured before any pipe:
Re-run at the final commit
3128edb8df:node scripts/check-system-context-census.mjs --self-test—check-system-context-census --self-test: all cases passednode scripts/check-system-context-census.mjs—check-system-context-census: OK — 109 elevation read sites in 20 packages across 45 files, all anchored; 145 anchors resolve, 27 declared non-read.check:nul-bytes—check-nul-bytes: OK (scanned 7284 text file(s) ... no raw ASCII control bytes)check:doc-anchors,check:doc-authoring,check:docs-single-h1,check:docs-redirects,check:role-word,check-doc-frontmatter,check-docs-section-name,check-doc-route-spelling,check-section-landing-index— all exit 0table-lines-*,table-appearances,table-keysandtable-prosedeclarations are whole-corpus text counts including tests, so any PR that adds or removes a line mentioningisSystemanywhere underpackages/orexamples/moves them — and because CI scores the merge commit, an open PR can be turned red by a merge tomainit never touched. That is what happened here. The anchor and population checks are self-repairing in the same situation (--fixhandles pure rot); these six text counts are not.⇒ That warning became the blocker it describes, and round 2 below is the fix.
Round 2 — the six whole-corpus text counts stop being ENFORCED (PM ruling, option B)
The warning above became the blocker it predicted, and the PM reversed its own ruling to direct option B into this PR.
merge-queue-triageposts a comment naming the failing job when it ejects a build, a sibling PR ejected in the same window has exactly that comment, and this PR has none. Why it is not in the queue is unexplained, and nothing here rests on it. What is measured, and what the ruling rests on: the declared counts were stale against today'smain, so a merge attempt reds on them whenever it happens. CI scores the PR's merge withmain, and the merge queue re-derives that merge against a newermainon every attempt, in a repo that merges roughly eighteen times a working day. That makes these six counts a landing hazard rather than a maintenance cost — which is true whether or not an ejection ever occurred.The diagnosis was confirmed before anything was changed
Merged today's
mainin (a merge commit, ⛔ never a rebase) and ran the gate on the merged tree first. Exit 1, on exactly the predicted declarations:permission-set-projection.ts:987had rotted to:1009. So option B alone would not have made this PR green — the anchor still had to be repaired. It was, by--fix, which re-anchored it and left every count alone.⭐ The measurement that decides it: what moves, and what does not
Every figure the page declares, re-derived by the committed census over five trees: this PR's original base, the pre-queue
main, two latermains, and the merged tree this PR now carries.db39dfc1c98a483b38b8ca1965f2b556470d86bf⭐ Not one census-derived figure moved across any of the five trees, while the text counts moved again in the very window this PR sat out — and they had already moved six times the night before (#13026, then #13060 and #13065: 1804→1810, 1010→1012, 794→798, 809→813, 308→310, 356→358). The three columns to the right of
db39dfc1c9are three unrelated merges this PR never touched.linesInSources,identifierAppearancesand the object-literalkeycount all move with any non-test source edit that mentions the flag, and the night before they all moved.db39dfc1c9→8a483b38b8moved exactly 1 of 109 anchors, and the other three hops moved 0. So anchor rot is real but roughly an order of magnitude rarer than text-count churn, and one--fixinvocation repairs it against six hand re-measurements. B removes the expensive half; it does not promise zero repair rounds.What changed
DECLARED_COUNTSinto a newUNENFORCED_TEXT_COUNTS, with the measurement above recorded beside them.[unenforced-count-missing]. Only the comparison is dropped, so "not enforced" cannot decay into "not there".measured on DATE at REFmarker, or the gate refuses with[unenforced-counts-undated]. ⛔ The date and the ref are deliberately not compared to anything — requiring them to be fresh would re-introduce the churn this removes.The self-test case ZONE 1 rule 4 owes, and it watches the criterion rather than restating it
Seven cases were added (21 → 27), and the two that matter run over the real
DECLARED_COUNTSandUNENFORCED_TEXT_COUNTS, not a fixture stand-in:The drift is what an unrelated merge does here: one test line naming the flag, one non-test source line carrying an
isSystem: truekey, one comment. Move a text count back into the enforced list and the first case fails naming it by id; delete a row from the unenforced list and the second case fails for being vacuous. The other five pin the behaviour: a stale text count is not a finding, a vanished row is, an undated table is, and an anchor rot or a population change still reds on the very same page.Both directions, on the real tree, at the final commit
Four mutations of the tree at
edfb39846a, each proving the mutation landed on disk before reading anything, each restored withgit checkout HEAD -- (absolute path)under a trap and verified by blob hash against the HEAD blob plus an emptygit diff HEAD. Shapes predicted in the script before it ran; all four matched.⛔ No rebuild leg is owed and none was faked: the gate runs as
node scripts/check-system-context-census.mjsand readsscripts/and the tracked sources directly — nothing resolves through a packageexportsmap or adist/.linesTotal 1812 linesInTests 1014. Under the old gate this was exit 1 with two[declared-count]errors[site-without-a-row], 8[anchor-is-not-a-read-site], 1[ledger-row-unused][site-without-a-row] ...security-plugin.ts:6983plusheadline-sites says 109, the census says 110,table-reads says 115, the census says 116, and five more[unenforced-count-missing]namingtable-lines-tests, and[unenforced-counts-undated]⭐ The third row is the answer to "did B weaken the gate": the surviving role counts caught the probe's declaration and read, and the population check named the new site by
file:line.Verification, at the final commit
edfb39846aThe union was re-run after the last commit, and the gate families were re-derived at that commit (
dispatch-gates --repo objectstack-ai/objectstack, 5 paths, 49 families — identical to the pre-merge derivation, no new family). Exit codes captured before any pipe (redirect to a file, thenEXIT=$?, then read the file); ⛔ noPIPESTATUSanywhere.node scripts/check-system-context-census.mjs—check-system-context-census: OK — 109 elevation read sites in 20 packages across 45 files, all anchored; 145 anchors resolve, 27 declared non-read.node scripts/check-system-context-census.mjs --self-test—check-system-context-census --self-test: all cases passed(27 cases)node scripts/pm/bare-root-worklist.mjs --self-testexit 0,pnpm check:pm-dispatch-gatesexit 0check:doc-anchors,check:doc-authoring,check:docs-single-h1,check:docs-redirects,check:role-word,check:docs-audit-scope,check-doc-frontmatter,check-docs-section-name,check-doc-route-spelling,check-section-landing-index,check:entry-guard,check:parse-guard,check:self-test-wired,check:watch-hint-literal,check:ci-filter-parity,check:step-collectors,check:required-contexts,check:nul-bytesturbo run build:check:doc-formula-expressions,check:doc-security-posture,pnpm --filter @objectstack/spec check:docs(231 generated files in sync),check:skill-examples(260 prose examples type-check)check:nul-bytes—check-nul-bytes: OK (scanned 7292 text file(s) ... no raw ASCII control bytes), plus a direct control-byte scan of both changed filescheck:type-check-debtis not reported here in either direction. It answers a standalone run with a refusal —--re-measure cannot run: 23 workspace dependenc(ies) ... have no built type entry point on disk— which is explicitly not a finding, and clearing it means building the whole workspace, which is CI's run. This round's diff contains no TypeScript, so nothing in it can move a TypeScript debt number.pnpm lintwas narrowed to the changed files, and here is why that narrowing is a measurement rather than a skip: (a) the linted population is read from ESLint itself, not guessed —--format jsonreportscontent/docs/permissions/system-context.mdxas "File ignored because no matching configuration was supplied", so the population of this diff is the single filescripts/check-system-context-census.mjs; (b) the count is read from that same JSON: 2 entries, 1 actually linted, 0 errors, 0 warnings; (c) untouched files cannot move, because this repo runs oneeslint.config.mjswhich "never enables type-aware linting (noparserOptions.project, no typed@typescript-eslintrules) for ANY file" (its own words, at line 327), and that config is not in this diff.skip-changeset: this PR changes docs,scripts/and one workflow step. No package source, so it publishes nothing.Related: #12802 corrected the anchors and deliberately left the enforcement unbuilt; #12942 held
lint.ymland the rootpackage.jsonwhen the card was written and has since landed, though this PR needed neither.Repair round authored in Claude Code session https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
Generated by Claude Code