fix(scripts): replace the stale merge=os-regen rationale with one the tree still shows - #19075
Merged
Merged
Conversation
… tree still shows The generated counts file explained "why this file is not `merge=os-regen`" with a driver limitation that no longer exists: resolution has read the owner's own manifest since the loosening, and two root-owned rows are registered and routed today. The fact stays (the file is not routed); the reason is replaced with what is measurable on this tree — no `.gitattributes` row names the path, routing would take a registry row whose `gen:`/`check:` names exist in the manifest it declares as owner, and no manifest declares such a pair for this census. `git-merge-regen.mjs` carried the same stale statement one level up: "every row is spec-owned, so it exercises exactly one manifest and would keep passing if the loosening were reverted". Measured from the registry's own data structure, the 18 rows resolve to two owners (16 defaulted, 2 root-owned), and the four names those two rows carry exist only in the root manifest — so a reverted loosening would turn that reconciliation red, not leave it green. What the pinned cases still add is the rule, which no live composition can show. Prose only; no behaviour change. The counts artefact is regenerated, and the unenforced `Measured on … at …` marker moves as it does on any regeneration. Claude-Session: https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3 Co-authored-by: Claude <noreply@anthropic.com>
os-bill
marked this pull request as ready for review
September 18, 2026 16:30
os-elon-musk
pushed a commit
that referenced
this pull request
Sep 18, 2026
…ement Conflict set: exactly ONE line in each generated artefact — the deliberately UNENFORCED `Measured on <date> at <ref>` marker, which sits inside the census page's generated region and in the counts file's corpus-scale block. Both sides were stale; main's side is kept so this merge never asserts a marker older than what landed, and the generator rewrites it in the commit that follows. Everything else text-merged with BOTH intents intact, verified rather than assumed: - scripts/tenant-audit-census.mjs auto-merged with no conflict and now carries #19075's corrected `merge=os-regen` rationale (the emitted "no `.gitattributes` row names it ... Root-level tooling is no obstacle by itself") AND this branch's inline-type-literal placement (inlineEngineDoorOrOther, 9 occurrences). Zero conflict markers. - the counts file holds #19075's new rationale paragraph and this branch's population (227, `declares tenancy off` 1, both new site rows, the 0-by-construction paragraph); #19075's superseded rationale is gone. - the census page holds every hand-written prose edit from this branch, including the claim the placement falsified. Measured: main's ONLY change to that page between this branch's base and origin/main is the one in-region marker line, so there is no hand-written text of main's to carry over. Main still reads population 225 on both artefacts, so #19075 re-baselined nothing and this branch's 225 -> 227 is still the whole change. Regeneration from the merged tree follows as its own commit, per the ordering rule: running a generator while the tree is in MERGE state stamps the PRE-MERGE tip, because `measuredAt()` reads `git rev-parse HEAD`. Claude-Session: https://claude.ai/code/session_019srGWGCBBCBHqcDoRZpQRh Co-authored-by: Claude <noreply@anthropic.com>
os-elon-musk
pushed a commit
that referenced
this pull request
Sep 18, 2026
…rged tree `node scripts/tenant-audit-census.mjs --write`, run AFTER the merge commit so `measuredAt()` reads the merged HEAD rather than the pre-merge tip. The staged diff is exactly two lines — the deliberately UNENFORCED `Measured on ... at ...` marker in each artefact, now naming the merge commit `30def652e` instead of main's `d4cb05cbf`. Nothing else moved, which is the proof the merge resolution was byte-faithful: the generator, run against the merged tree, reproduces both hand-resolved artefacts exactly. Had the semantic merge dropped or mangled a row, a total or #19075's rationale paragraph, this commit would carry it. That also reconciles the two rules that govern this file. `os-regen-merge.sh` requires a non-driver-managed generated artefact to be hand-resolved for the merge commit and ⛔ not regenerated mid-merge (a mid-merge recompute describes a half-merged tree); the file's own header requires a conflict to be resolved BY REGENERATION and ⛔ never by hand. Both hold when the order is: resolve, commit the merge, regenerate, and let the regeneration diff certify the resolution. #19075's corrected rationale re-measured on the merged tree with its own instruments and still true: 0 `.gitattributes` rows name this census (fire control: `strictness-ledger` returns 1, so the zero is not a dead reading), `git check-attr merge` reads `unspecified`, 0 manifests name it in a `scripts` entry, and the lint workflow runs the gate directly. Claude-Session: https://claude.ai/code/session_019srGWGCBBCBHqcDoRZpQRh Co-authored-by: Claude <noreply@anthropic.com>
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 #19007
Clause-②: no
Three same-cause prose statements were left behind when #13585 loosened owner resolution.
Two of them are replaced here with statements this tree still shows; the third is left
alone, because it is the evidence rather than the defect. Prose only — no behaviour
change, and ⛔ no
merge=os-regenregistration is added, ⛔ no.gitattributesrow istouched.
1.
scripts/tenant-audit-census.mjs— the reason emitted INTO the generated counts fileBefore (verbatim, as
renderCountsFile()emitted it):After:
The FACT is kept (this file is not routed). The REASON is replaced, and every clause of
the new one is measurable on this tree:
.gitattributesrow names itgrep -n tenant-audit .gitattributesgit check-attr mergereadsunspecifiedgit check-attr merge -- docs/audits/2026-08-tenant-audit-write-call-sites.counts.mdunspecifiedgen:/check:in its owner's manifestreconcileScripts()fails a row whose names are missing — fired belowpackage.json,scriptskeys AND values.github/workflows/lint.yml, step "Tenant-audit census matches the tree"node scripts/check-tenant-audit-census.mjsREGEN_ARTIFACTSrows declaringowner: ROOT_OWNER, and what git says about themmerge: os-regenFire control for the 0-hit row: the same instrument searching for
strictness-ledger—the neighbouring
.counts.mdthat IS registered — returns 2 hits (gen:andcheck:in
packages/spec). Reachable radius: manifestscriptstext. A known target outsideit: a manifest script that reaches the census through an indirection that never spells
its name (
"gen:x": "node scripts/wrapper.mjs"where the wrapper spawns it) — thisinstrument reads manifests, it never follows a spawn.
2.
scripts/git-merge-regen.mjs— "every row is spec-owned"Before (verbatim):
After (verbatim, plus the paragraph break the replacement adds):
What the paragraph exists to explain — why the pinned owner-resolution cases are needed
even though the live tree is green — is kept, and now rests on something true: the
composition that exercises the root path is a property of today's table, not of the rule.
3.
scripts/git-merge-regen.mjs:769-777— deliberately NOT touchedThat block quotes #13585 correctly. It is the evidence the two statements above drifted
away from, and the diff contains zero lines from it.
The registry re-count, taken from the registry's own data structure
The card reported
4 ROOT_OWNER + 19 named + 41 default = 64. Re-counted by importingscripts/regen-artifacts.mjsand bucketing with the module's ownownerOf(entry) = entry.owner ?? DEFAULT_OWNER, at merge base0ec81857a:owner: ROOT_OWNERDEFAULT_OWNERREGEN_ARTIFACTS(registered; whatreconcileScriptsiterates)NOT_DRIVER_MANAGED(deliberately not registered)Each row reconciles: 2+0+16 = 18, 2+19+12 = 33, 4+19+28 = 51.
Three consequences:
4 + 19is a BOTH-TABLES count. The registration table declaresROOT_OWNERtwice, and both of those rows really are routed(
content/docs/permissions/system-context.mdxandscripts/platform-object-tenancy-census.json, eachmerge: os-regen). The card'sother two
ROOT_OWNERrows areNOT_DRIVER_MANAGEDentries — readingunspecifiedis those rows working as recorded, not a failure to route.
41, and the64total it implies, reproduce under NEITHER instrument: structurallythe defaulted bucket is 16 (registration table) or 28 (both tables), against totals of
18 and 51.
reconcileScriptsitself prints the refutation of "exercises exactly one manifest":all 36 gen:/check: names resolve in their declared owner (@objectstack/spec (packages/spec/package.json), @objectstack/spec-monorepo (package.json))— 36 = 18rows x 2 names, across TWO manifests.
Evidence
Behaviour leg — the generated artefact changes in the prose and nowhere else.
node scripts/tenant-audit-census.mjs --write, then both the committed and theregenerated counts file put through the gate's own
maskUnenforced()(the maskscripts/check-tenant-audit-census.mjsapplies to both sides of its byte comparison):the masked diff is exactly the replaced paragraph, 3 lines out, 7 lines in, nothing else.
The raw diff carries one more line, the
Measured on ... at ...marker, in the countsfile and in the census page. That marker is not attributable to this edit: a
regeneration on the PRISTINE tree, with zero source edits, already moved exactly those
two lines and nothing else. The gate masks its value deliberately
(
UNENFORCED_MEASURED_AT: "The date and the ref are deliberately NOT compared toanything"), its self-test pins "a stale measurement date passes", and the last commit to
touch these artefacts (#18943) carried the same marker bump. Both artefacts are committed
as the generator wrote them.
reconcileScriptsleg, with a fire control. The card said it had not been measuredwhether that reconciliation is still green under today's owner distribution.
node scripts/git-merge-regen.mjs --self-test→ exit 0, including✓ all 36 gen:/check: names resolve in their declared owner.Its CI spelling
pnpm check:merge-driver→ exit 0.through
scripts/ablation-replace.mjs, the root manifest'sgen:system-context-censuskey was renamed. The anchor hit once, the blob moved
(
57ab936beaf0to1074c54635), and the self-test went red naming the row:content/docs/permissions/system-context.mdx → gen:system-context-census [owner @objectstack/spec-monorepo, package.json]. A spec-only resolution could not producethat failure — which is the measured form of "reverting the loosening would now turn it
red".
57ab936beaf0= the HEAD blob,git diff HEADempty,git status --porcelainempty.Gates.
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 64 families from this tree; all 64 were run with the exit code captured before any
pipe, and
--ranreconciles:64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN, every oneexit 0. Five of them first exited on a PREREQUISITE NOT MET (unbuilt
@objectstack/lint,@objectstack/formula,@objectstack/client-react, andgen:schema); the closures werebuilt and all five then passed — none was a finding.
pnpm lintover the whole repo:exit 0 in 1m27s.
pnpm check:nul-bytes: exit 0, plus a direct control-character scan ofboth edited files: 0 hits.
Changeset. Measured rather than assumed: each of the 4 changed paths against every
tracked manifest's
files[]. The root manifest isprivate: true, and all four paths lieoutside every publishable package directory, so nothing already published moves — hence
skip-changeset. Fire control: the same instrument scorespackages/spec/src/index.tsasinside a published surface.
Acceptance notes
Observed while working, out of scope here, not filed:
declaration; the pinned cases it describes (
reconcileOwnership) are about 330 linesbelow.
pnpm check:scripts-symbol-anchorsis green on it, so the repo's own instrumentdoes not read this as a violation. Successor: the next PR editing these self-test blocks.
NOT_DRIVER_MANAGEDdisposition fordocs/audits/**explains itself in terms ofhand-written ledgers and names the strictness
.counts.mdas "the ONE exception", whilea second generated
.counts.md— this census's — sits under the same prefix. Whetherthat one ought to route is the question scripts/tenant-audit-census.mjs states both that its counts file is and is not merge=os-regen #18960 deliberately left open, so this is that
neighbour, not a new card.
disposition reconciliation — a bound that reconciliation states about itself in its own
docblock, and
pnpm check:ratchet-remedy-authority(which owns that population) isgreen.
Generated by Claude Code