From b624c49045c8e1f87b60f828672ffd87f3ac730a Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 18 Sep 2026 15:23:35 +0000 Subject: [PATCH] fix(scripts): replace the stale merge=os-regen rationale with one the tree still shows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../docs/permissions/tenant-audit-census.mdx | 2 +- ...08-tenant-audit-write-call-sites.counts.md | 12 +++++++---- scripts/git-merge-regen.mjs | 20 +++++++++++++------ scripts/tenant-audit-census.mjs | 10 +++++++--- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/content/docs/permissions/tenant-audit-census.mdx b/content/docs/permissions/tenant-audit-census.mdx index c4eb6d23387..df4921fcb1e 100644 --- a/content/docs/permissions/tenant-audit-census.mdx +++ b/content/docs/permissions/tenant-audit-census.mdx @@ -253,7 +253,7 @@ holds still. They are required to be HERE and to say WHEN they were true; their values are not compared. The reasoning, and the measurement behind it, are in `scripts/check-tenant-audit-census.mjs`. -Measured on 2026-09-18 at `02bdeaaf2`. +Measured on 2026-09-18 at `d4cb05cbf`. | corpus scale (not enforced) | count | | :--- | ---: | diff --git a/docs/audits/2026-08-tenant-audit-write-call-sites.counts.md b/docs/audits/2026-08-tenant-audit-write-call-sites.counts.md index c988854b368..87827011354 100644 --- a/docs/audits/2026-08-tenant-audit-write-call-sites.counts.md +++ b/docs/audits/2026-08-tenant-audit-write-call-sites.counts.md @@ -19,9 +19,13 @@ line numbers, so a pure displacement cannot move them. Run the generator with ⚠️ **On a merge conflict here, regenerate — never resolve by hand.** Two branches that each add a write call site produce rows git merges cleanly and totals that -merge cleanly and WRONG. This file is deliberately NOT `merge=os-regen`: that -driver resolves an artefact's `gen:`/`check:` scripts in `@objectstack/spec` -only, and these are root-level tooling. The gate is the backstop — a wrongly +merge cleanly and WRONG. This file is NOT `merge=os-regen`: no `.gitattributes` +row names it, so `git check-attr merge` over it reads `unspecified`. Routing it +would take a `REGEN_ARTIFACTS` row whose `gen:`/`check:` names exist in the +manifest that row declares as owner, and no manifest declares such a pair for +this census — the gate runs straight from the lint workflow. Root-level tooling +is no obstacle by itself: the driver resolves those names in whichever manifest +the row names, the root one included. The gate is the backstop — a wrongly merged file fails `check-tenant-audit-census`, so the error is loud rather than silent, and `node scripts/tenant-audit-census.mjs --write` is the resolution. @@ -76,7 +80,7 @@ holds still. They are required to be HERE and to say WHEN they were true; their values are not compared. The reasoning, and the measurement behind it, are in `scripts/check-tenant-audit-census.mjs`. -Measured on 2026-09-18 at `02bdeaaf2`. +Measured on 2026-09-18 at `d4cb05cbf`. | corpus scale (not enforced) | count | | :--- | ---: | diff --git a/scripts/git-merge-regen.mjs b/scripts/git-merge-regen.mjs index 4506a6d5662..bfc35b89782 100755 --- a/scripts/git-merge-regen.mjs +++ b/scripts/git-merge-regen.mjs @@ -831,12 +831,20 @@ function reconcileScripts() { /** * The owner-resolution rule itself, pinned — the half a live tree cannot show. * - * `reconcileScripts` above is green on this tree for the same reason it was green - * before #13585: every row is spec-owned, so it exercises exactly one manifest and - * would keep passing if the loosening were reverted. These cases read the REAL root - * manifest through the same functions the driver and the `pre-commit` gate use, so - * the root path is measured on every run rather than the first time somebody - * registers a root-owned artifact. + * `reconcileScripts` above no longer rests on a single manifest. Rows that declare + * no owner default to `DEFAULT_OWNER`; rows that declare `ROOT_OWNER` send the + * lookup to the root manifest instead (measured on this tree: 18 rows — 16 + * defaulted, 2 root-owned, none naming `DEFAULT_OWNER` explicitly). The four + * `gen:`/`check:` names those two root-owned rows carry exist ONLY in the root + * manifest, so reverting #13585's loosening would now turn that reconciliation RED + * rather than leave it green. + * + * What a live tree still cannot show is the RULE. Which manifests get exercised is + * a property of whatever the table happens to hold, and a table that fell back to a + * single owner would stop touching the root path with nothing saying so. These + * cases read the REAL root manifest through the same functions the driver and the + * `pre-commit` gate use, so the root path is measured on every run rather than only + * while some row happens to declare it. * * The two-way case is the third one. A permissive lookup — "resolve the name in any * manifest" — passes every other assertion here and fails that one, which is the diff --git a/scripts/tenant-audit-census.mjs b/scripts/tenant-audit-census.mjs index ab418430523..6b1ece899bf 100644 --- a/scripts/tenant-audit-census.mjs +++ b/scripts/tenant-audit-census.mjs @@ -1598,9 +1598,13 @@ export function renderCountsFile(census) { out.push(''); out.push('⚠️ **On a merge conflict here, regenerate — never resolve by hand.** Two branches'); out.push('that each add a write call site produce rows git merges cleanly and totals that'); - out.push('merge cleanly and WRONG. This file is deliberately NOT `merge=os-regen`: that'); - out.push('driver resolves an artefact\'s `gen:`/`check:` scripts in `@objectstack/spec`'); - out.push('only, and these are root-level tooling. The gate is the backstop — a wrongly'); + out.push('merge cleanly and WRONG. This file is NOT `merge=os-regen`: no `.gitattributes`'); + out.push('row names it, so `git check-attr merge` over it reads `unspecified`. Routing it'); + out.push('would take a `REGEN_ARTIFACTS` row whose `gen:`/`check:` names exist in the'); + out.push('manifest that row declares as owner, and no manifest declares such a pair for'); + out.push('this census — the gate runs straight from the lint workflow. Root-level tooling'); + out.push('is no obstacle by itself: the driver resolves those names in whichever manifest'); + out.push('the row names, the root one included. The gate is the backstop — a wrongly'); out.push('merged file fails `check-tenant-audit-census`, so the error is loud rather than'); out.push('silent, and `node scripts/tenant-audit-census.mjs --write` is the resolution.'); out.push('');