feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483) - #14056

Merged
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict
Sep 1, 2026
Merged

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483)#14056
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13483

Introduces the fifth liveness-ledger verdict live-elsewhere — dead here by measurement, genuinely enforced in a sibling repo — with criteria the gate executes, and migrates manifest.runtime (the #13479 qualifying-note stopgap) as its first row. Direction was mechanically locked by triage: dead lies about the cross-repo consumer, live is refused by the gate (its repo-local evidence must resolve against this checkout), so a new status is the only exit.

Premise — answered before the fix (the ruled precondition)

What a non-local evidence pointer looks like. The realm-marker grammar the evidence scanner already machine-reads, pointed at the foreign ENFORCER and pinned to a foreign commit in the prose. The shipped template is the migrated row:

cloud: packages/service-cloud/src/plugin-permission-audit.ts#auditPluginPermissions @15f55df + packages/service-cloud/src/routes/package-publish.ts:530 — the marketplace publish gate: an unverified publisher requesting the node tier is hard-rejected with HTTP 422 ...

Repo (realm marker), path plus consuming symbol, enforcement description, and the commit the reading was taken at — the structured pointer the card asked for, carried in the grammar the ledger already has rather than a new JSON shape. I considered a machine-checked foreign-SHA field and rejected it: a shape check cannot distinguish a real reading from a fabricated one, so it would add surface without adding falsifiability; what makes fabrication pointless is the expiry below, which forces a periodic genuine re-reading. Foreign paths stay counted-never-resolved (that boundary is deliberate and load-bearing); any repo-local path such an entry ALSO cites is held to the full scanned-status standard (existence, line bound, symbol anchor, key mention) — the status joins EVIDENCE_SCANNED_STATUSES.

What re-verification discipline applies to a repo this board may not be able to read. The gate cannot read cloud, and this design never asks it to — what CI executes is the SHAPE of the claim and its CLOCK, four criteria enforced by the new scripts/liveness/elsewhere.mts (exit 1 each, proven red through the real gate in the self-tests):

  1. the evidence string must attribute at least one path to a foreign realm — the verdict IS this pointer; without it the status is exactly the unverified label the card's hard constraint names;
  2. evidenceScope must be cross-repo — the verdict is a cross-repo claim by definition;
  3. verifiedAt is REQUIRED — for every other status an undated row is a worklist entry because the file/line/symbol/key-mention checks keep watching the cited code; nothing local can watch a foreign enforcer rot, so an undated elsewhere-claim would be unfalsifiable forever;
  4. the attestation EXPIRES — past 180 days (deliberately the same constant as the ledger-wide staleness threshold, so the freshness policy stays decided in one place; what differs per status is the consequence) the gate goes red demanding re-attestation. Expiry is the only mechanical event this repo can generate about a claim it cannot re-measure, so here — and only here — age is a merge gate rather than a worklist.

Re-attestation means a seat WITH access re-reads the enforcer at its current head, repairs the pointer if it moved, re-pins the commit, and stamps verifiedAt with that reading's date. Re-stamping without re-reading is the "trust the prose note" downgrade the ruling forbids, and the gate guidance says so verbatim. If the window closes and no seat with access can be found, the red build IS the escalation: the row returns to the maintainer (needs-user-decision) to rule whether an unverifiable pointer still counts as evidence. The design degrades into that fork rather than into silence — trust is time-boxed, never institutional.

The access face, measured this run (reported either way, per the dispatch order). Probe: add_repo read request for objectstack-ai/cloud from this dev seat, 2026-09-01. Result: denied — "you don't have access to objectstack-ai/cloud" — the same face #11331 records from #10627 (re-measured 2026-08-26 there). Countervailing record: the board verifiably read cloud twice in the last week — #10812 (cloud at 5b5925a, 2026-08-24) and #12400 (cloud at 15f55df, reading of 2026-08-29, controls held: 15 manifest-property reads findable). So the fork condition — cloud genuinely unreachable for verification — is measured NOT to hold: access is seat-dependent, not absent, and CI-side reachability is not load-bearing in this design. Consequence for this delivery: I could not honestly re-read the enforcer from this seat today, so the migrated row's verifiedAt is 2026-08-29 — the date of the #12400 reading it cites — not a fresh stamp of today's date.

What changed

  • packages/spec/scripts/liveness/elsewhere.mts (new) + elsewhere.test.ts (new) — the criteria, pure and injected-clock, plus the two prescriptions (shape repair vs re-attestation).
  • check-liveness.mts — status joins the scanned set and the vocabulary docs; per-row criteria wiring in classify(); two new failure headings plus an always-printed population line (the two-number discipline); the unknown-status guidance now points a DELIBERATE vocabulary change at this precedent while still forbidding typo-widening.
  • readme-table.mts — STATUS_COLUMNS gains live-elsewhere; StateCountsRow, foldStateCounts, renderStateCounts move together (the artifact-shape rule those files document); guidance de-hardcodes the column count.
  • build-state-counts.mts — total sum includes the new column.
  • packages/spec/liveness/manifest.jsonmanifest.runtime migrates: status live-elsewhere, the foreign pointer above as evidence, verifiedAt 2026-08-29, note rewritten to carry both halves' measurement provenance and the re-attestation contract.
  • packages/spec/liveness/state-counts.md — regenerated (new elsewhere column; manifest now live 22 / dead 15 / elsewhere 1).
  • packages/spec/liveness/README.md — vocabulary table rows for dead (sharpened: dead means no consumer anywhere the census looked) and live-elsewhere; a dedicated criteria section; the stale "no cross-repo value covers cloud" paragraph corrected; the manifest Notes cell re-measured (Dead 21 becomes Dead 20, runtime's disposition updated).
  • check-liveness.test.ts — a new seven-case block through the real gate via ledger-root: control green with the population line, four red criteria legs, the malformed-verifiedAt single-heading boundary, and the scanned-set membership leg; existing pins updated for the five-name vocabulary.
  • readme-table.test.ts — column pins updated; fold and render cases for the fifth column.
  • .changeset/liveness-live-elsewhere-verdict.md — patch for @objectstack/spec (the liveness/ dir ships in the package files whitelist).

Clause-2: no — the diff touches no packages/spec/src/** path (verified on the merge-base diff; ledger plus gate tooling only). File face vs the claim comment, declared: the enumerated list named check-liveness.mts, its tests, evidence.mts, manifest.json, README and changeset; the implementation additionally lands elsewhere.mts plus test (new module in the same claimed directory), readme-table.mts plus test and build-state-counts.mts (the STATUS_COLUMNS artifact-shape sites, mechanically unavoidable for a vocabulary widening), and the regenerated state-counts.md. All inside the two directories the claim's serial-constraint line locks; evidence.mts itself needed no change.

Second consumer (read, not edited)

#11331 is not addressed here and remains open. Its enforce leg lives in the same cloud control plane; the evidence shape generalizes with no per-key machinery — should its fork land as enforce-in-cloud, the manifest.integrity row takes the same form: a cloud: pointer at the verifier, cross-repo scope, dated attestation. Note per the #12400 reading, cloud today PERSISTS integrity and verifies nothing, so that card's fork is genuinely open.

Verification (all at head 5db4407 unless noted)

  • pnpm --filter @objectstack/spec run check:liveness — exit 0; judgment lines: "live-elsewhere: 1 entr(ies) carry the verdict (dead here, enforced in a sibling repo), 1 with a foreign pointer, cross-repo scope, and an attestation of at most 180d old." and the green summary now includes "every live-elsewhere verdict points at a named foreign enforcer under an unexpired attestation"; manifest row reads "38 classified (live 22, dead 15, live-elsewhere 1)".
  • Liveness suites: elsewhere/check-liveness/readme-table at 5db4407 — 3 files, 105 tests passed; evidence and verification suites at 6a8c6f2 (byte-identical files across the merge) — with the full-population run below covering all of them at the merged tree. The six red legs of the new criteria block each proved a real exit 1 through the real gate with the expected finding text.
  • Full @objectstack/spec vitest suite at 44bd1a1 (identical liveness tree; the two spec src files main merged in are covered by this run): 447 files passed, 12013 tests passed, exit 0. Population proof: vitest list counts 12013 tests and includes the liveness self-test files.
  • pnpm --filter @objectstack/spec run typecheck at 44bd1a1 — exit 0 (tsc, scripts program, test program); --listFiles shows both new files inside the scripts program (measured, not assumed).
  • Derived gate union (node scripts/pm/dispatch-gates.mjs, derivation line cites this tree at 44bd1a1): 36 gates run, 33 green by their own printed verdicts, including check:changeset-gate-self-tests, check:doc-authoring, spec check:empty-state, spec check:strictness-ledger, spec check:variant-docs, check:merge-driver, check:page-declaration-shape, check:pm-governed-merges, check:published-files, check:slot-lookup, check:test-source-alias, check:type-source-resolution, check:where-matcher, check:nul-bytes. Ratchet families (liveness, empty-state, strictness-ledger) re-ran green at 5db4407 after the final commit.
  • Declared NOT MEASURED locally, per each gate's own printed verdict: check-test-completeness (exit 3, "record this gate as NOT MEASURED ... not a red" — CI grades the real turbo log), check:dual-build-cjs-loads (exit 3, "PREREQUISITE NOT MET — reads built output ... nothing was measured") and check-dev-prereqs (exit 1, stale/absent dist in a fresh worktree) — both prerequisite classes want a full monorepo build this diff cannot affect (zero package src changes; the gate scripts run from source via tsx and are not part of dist), and CI runs both after its own build.

Out-of-scope findings

  • packages/lint lint-liveness-properties.ts describe() deliberately throws on a status it has not been taught; unreachable today (reaching it requires authorWarn true or experimental, and no live-elsewhere row carries either) but reachable the day such a row opts into authorWarn — filed separately with the designed repair.
  • .claude/skills/spec-property-retirement consumes ledger dead verdicts and should name the new status in its discipline (a dead-here-enforced-elsewhere key now reads live-elsewhere and is never a removal input) — filed separately as documentation drift.

Generated by Claude Code


Generated by Claude Code

…ed in a sibling repo (#13483)
A key enforced only in a sibling repo had no honest verdict: dead lies about
the cross-repo consumer, live is refused by the gate (repo-local evidence must
resolve). The new status carries gate-executable criteria (elsewhere.mts):
a foreign-realm evidence pointer, evidenceScope cross-repo, a REQUIRED dated
attestation, and a 180d expiry that fails the build demanding a re-reading of
the foreign enforcer — never a re-stamp. manifest.runtime migrates as the
first row, attested at the #12400 cloud reading (2026-08-29, cloud @15f55df).
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
… generator comment
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 128 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ada3834add75f6113c567786b4d1ef7c403c59e2packageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Sep 1, 2026
@os-support-ai
os-support-ai marked this pull request as ready for review September 1, 2026 02:05
@os-support-ai
os-support-ai added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 98c0d33Sep 1, 2026
35 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-13483-liveness-live-elsewhere-verdict branch September 1, 2026 02:43
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liveness ledger has no verdict for keys enforced only in a sibling repo — dead misreads as deletable (manifest.runtime case)

2 participants

@os-support-ai@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483) - #14056

Merged
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict
Sep 1, 2026
Merged

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483)#14056
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13483

Introduces the fifth liveness-ledger verdict live-elsewhere — dead here by measurement, genuinely enforced in a sibling repo — with criteria the gate executes, and migrates manifest.runtime (the #13479 qualifying-note stopgap) as its first row. Direction was mechanically locked by triage: dead lies about the cross-repo consumer, live is refused by the gate (its repo-local evidence must resolve against this checkout), so a new status is the only exit.

Premise — answered before the fix (the ruled precondition)

What a non-local evidence pointer looks like. The realm-marker grammar the evidence scanner already machine-reads, pointed at the foreign ENFORCER and pinned to a foreign commit in the prose. The shipped template is the migrated row:

cloud: packages/service-cloud/src/plugin-permission-audit.ts#auditPluginPermissions @15f55df + packages/service-cloud/src/routes/package-publish.ts:530 — the marketplace publish gate: an unverified publisher requesting the node tier is hard-rejected with HTTP 422 ...

Repo (realm marker), path plus consuming symbol, enforcement description, and the commit the reading was taken at — the structured pointer the card asked for, carried in the grammar the ledger already has rather than a new JSON shape. I considered a machine-checked foreign-SHA field and rejected it: a shape check cannot distinguish a real reading from a fabricated one, so it would add surface without adding falsifiability; what makes fabrication pointless is the expiry below, which forces a periodic genuine re-reading. Foreign paths stay counted-never-resolved (that boundary is deliberate and load-bearing); any repo-local path such an entry ALSO cites is held to the full scanned-status standard (existence, line bound, symbol anchor, key mention) — the status joins EVIDENCE_SCANNED_STATUSES.

What re-verification discipline applies to a repo this board may not be able to read. The gate cannot read cloud, and this design never asks it to — what CI executes is the SHAPE of the claim and its CLOCK, four criteria enforced by the new scripts/liveness/elsewhere.mts (exit 1 each, proven red through the real gate in the self-tests):

  1. the evidence string must attribute at least one path to a foreign realm — the verdict IS this pointer; without it the status is exactly the unverified label the card's hard constraint names;
  2. evidenceScope must be cross-repo — the verdict is a cross-repo claim by definition;
  3. verifiedAt is REQUIRED — for every other status an undated row is a worklist entry because the file/line/symbol/key-mention checks keep watching the cited code; nothing local can watch a foreign enforcer rot, so an undated elsewhere-claim would be unfalsifiable forever;
  4. the attestation EXPIRES — past 180 days (deliberately the same constant as the ledger-wide staleness threshold, so the freshness policy stays decided in one place; what differs per status is the consequence) the gate goes red demanding re-attestation. Expiry is the only mechanical event this repo can generate about a claim it cannot re-measure, so here — and only here — age is a merge gate rather than a worklist.

Re-attestation means a seat WITH access re-reads the enforcer at its current head, repairs the pointer if it moved, re-pins the commit, and stamps verifiedAt with that reading's date. Re-stamping without re-reading is the "trust the prose note" downgrade the ruling forbids, and the gate guidance says so verbatim. If the window closes and no seat with access can be found, the red build IS the escalation: the row returns to the maintainer (needs-user-decision) to rule whether an unverifiable pointer still counts as evidence. The design degrades into that fork rather than into silence — trust is time-boxed, never institutional.

The access face, measured this run (reported either way, per the dispatch order). Probe: add_repo read request for objectstack-ai/cloud from this dev seat, 2026-09-01. Result: denied — "you don't have access to objectstack-ai/cloud" — the same face #11331 records from #10627 (re-measured 2026-08-26 there). Countervailing record: the board verifiably read cloud twice in the last week — #10812 (cloud at 5b5925a, 2026-08-24) and #12400 (cloud at 15f55df, reading of 2026-08-29, controls held: 15 manifest-property reads findable). So the fork condition — cloud genuinely unreachable for verification — is measured NOT to hold: access is seat-dependent, not absent, and CI-side reachability is not load-bearing in this design. Consequence for this delivery: I could not honestly re-read the enforcer from this seat today, so the migrated row's verifiedAt is 2026-08-29 — the date of the #12400 reading it cites — not a fresh stamp of today's date.

What changed

  • packages/spec/scripts/liveness/elsewhere.mts (new) + elsewhere.test.ts (new) — the criteria, pure and injected-clock, plus the two prescriptions (shape repair vs re-attestation).
  • check-liveness.mts — status joins the scanned set and the vocabulary docs; per-row criteria wiring in classify(); two new failure headings plus an always-printed population line (the two-number discipline); the unknown-status guidance now points a DELIBERATE vocabulary change at this precedent while still forbidding typo-widening.
  • readme-table.mts — STATUS_COLUMNS gains live-elsewhere; StateCountsRow, foldStateCounts, renderStateCounts move together (the artifact-shape rule those files document); guidance de-hardcodes the column count.
  • build-state-counts.mts — total sum includes the new column.
  • packages/spec/liveness/manifest.jsonmanifest.runtime migrates: status live-elsewhere, the foreign pointer above as evidence, verifiedAt 2026-08-29, note rewritten to carry both halves' measurement provenance and the re-attestation contract.
  • packages/spec/liveness/state-counts.md — regenerated (new elsewhere column; manifest now live 22 / dead 15 / elsewhere 1).
  • packages/spec/liveness/README.md — vocabulary table rows for dead (sharpened: dead means no consumer anywhere the census looked) and live-elsewhere; a dedicated criteria section; the stale "no cross-repo value covers cloud" paragraph corrected; the manifest Notes cell re-measured (Dead 21 becomes Dead 20, runtime's disposition updated).
  • check-liveness.test.ts — a new seven-case block through the real gate via ledger-root: control green with the population line, four red criteria legs, the malformed-verifiedAt single-heading boundary, and the scanned-set membership leg; existing pins updated for the five-name vocabulary.
  • readme-table.test.ts — column pins updated; fold and render cases for the fifth column.
  • .changeset/liveness-live-elsewhere-verdict.md — patch for @objectstack/spec (the liveness/ dir ships in the package files whitelist).

Clause-2: no — the diff touches no packages/spec/src/** path (verified on the merge-base diff; ledger plus gate tooling only). File face vs the claim comment, declared: the enumerated list named check-liveness.mts, its tests, evidence.mts, manifest.json, README and changeset; the implementation additionally lands elsewhere.mts plus test (new module in the same claimed directory), readme-table.mts plus test and build-state-counts.mts (the STATUS_COLUMNS artifact-shape sites, mechanically unavoidable for a vocabulary widening), and the regenerated state-counts.md. All inside the two directories the claim's serial-constraint line locks; evidence.mts itself needed no change.

Second consumer (read, not edited)

#11331 is not addressed here and remains open. Its enforce leg lives in the same cloud control plane; the evidence shape generalizes with no per-key machinery — should its fork land as enforce-in-cloud, the manifest.integrity row takes the same form: a cloud: pointer at the verifier, cross-repo scope, dated attestation. Note per the #12400 reading, cloud today PERSISTS integrity and verifies nothing, so that card's fork is genuinely open.

Verification (all at head 5db4407 unless noted)

  • pnpm --filter @objectstack/spec run check:liveness — exit 0; judgment lines: "live-elsewhere: 1 entr(ies) carry the verdict (dead here, enforced in a sibling repo), 1 with a foreign pointer, cross-repo scope, and an attestation of at most 180d old." and the green summary now includes "every live-elsewhere verdict points at a named foreign enforcer under an unexpired attestation"; manifest row reads "38 classified (live 22, dead 15, live-elsewhere 1)".
  • Liveness suites: elsewhere/check-liveness/readme-table at 5db4407 — 3 files, 105 tests passed; evidence and verification suites at 6a8c6f2 (byte-identical files across the merge) — with the full-population run below covering all of them at the merged tree. The six red legs of the new criteria block each proved a real exit 1 through the real gate with the expected finding text.
  • Full @objectstack/spec vitest suite at 44bd1a1 (identical liveness tree; the two spec src files main merged in are covered by this run): 447 files passed, 12013 tests passed, exit 0. Population proof: vitest list counts 12013 tests and includes the liveness self-test files.
  • pnpm --filter @objectstack/spec run typecheck at 44bd1a1 — exit 0 (tsc, scripts program, test program); --listFiles shows both new files inside the scripts program (measured, not assumed).
  • Derived gate union (node scripts/pm/dispatch-gates.mjs, derivation line cites this tree at 44bd1a1): 36 gates run, 33 green by their own printed verdicts, including check:changeset-gate-self-tests, check:doc-authoring, spec check:empty-state, spec check:strictness-ledger, spec check:variant-docs, check:merge-driver, check:page-declaration-shape, check:pm-governed-merges, check:published-files, check:slot-lookup, check:test-source-alias, check:type-source-resolution, check:where-matcher, check:nul-bytes. Ratchet families (liveness, empty-state, strictness-ledger) re-ran green at 5db4407 after the final commit.
  • Declared NOT MEASURED locally, per each gate's own printed verdict: check-test-completeness (exit 3, "record this gate as NOT MEASURED ... not a red" — CI grades the real turbo log), check:dual-build-cjs-loads (exit 3, "PREREQUISITE NOT MET — reads built output ... nothing was measured") and check-dev-prereqs (exit 1, stale/absent dist in a fresh worktree) — both prerequisite classes want a full monorepo build this diff cannot affect (zero package src changes; the gate scripts run from source via tsx and are not part of dist), and CI runs both after its own build.

Out-of-scope findings

  • packages/lint lint-liveness-properties.ts describe() deliberately throws on a status it has not been taught; unreachable today (reaching it requires authorWarn true or experimental, and no live-elsewhere row carries either) but reachable the day such a row opts into authorWarn — filed separately with the designed repair.
  • .claude/skills/spec-property-retirement consumes ledger dead verdicts and should name the new status in its discipline (a dead-here-enforced-elsewhere key now reads live-elsewhere and is never a removal input) — filed separately as documentation drift.

Generated by Claude Code


Generated by Claude Code

…ed in a sibling repo (#13483)
A key enforced only in a sibling repo had no honest verdict: dead lies about
the cross-repo consumer, live is refused by the gate (repo-local evidence must
resolve). The new status carries gate-executable criteria (elsewhere.mts):
a foreign-realm evidence pointer, evidenceScope cross-repo, a REQUIRED dated
attestation, and a 180d expiry that fails the build demanding a re-reading of
the foreign enforcer — never a re-stamp. manifest.runtime migrates as the
first row, attested at the #12400 cloud reading (2026-08-29, cloud @15f55df).
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
… generator comment
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 128 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ada3834add75f6113c567786b4d1ef7c403c59e2packageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Sep 1, 2026
@os-support-ai
os-support-ai marked this pull request as ready for review September 1, 2026 02:05
@os-support-ai
os-support-ai added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 98c0d33Sep 1, 2026
35 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-13483-liveness-live-elsewhere-verdict branch September 1, 2026 02:43
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liveness ledger has no verdict for keys enforced only in a sibling repo — dead misreads as deletable (manifest.runtime case)

2 participants

@os-support-ai@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483) - #14056

Merged
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict
Sep 1, 2026
Merged

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483)#14056
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13483

Introduces the fifth liveness-ledger verdict live-elsewhere — dead here by measurement, genuinely enforced in a sibling repo — with criteria the gate executes, and migrates manifest.runtime (the #13479 qualifying-note stopgap) as its first row. Direction was mechanically locked by triage: dead lies about the cross-repo consumer, live is refused by the gate (its repo-local evidence must resolve against this checkout), so a new status is the only exit.

Premise — answered before the fix (the ruled precondition)

What a non-local evidence pointer looks like. The realm-marker grammar the evidence scanner already machine-reads, pointed at the foreign ENFORCER and pinned to a foreign commit in the prose. The shipped template is the migrated row:

cloud: packages/service-cloud/src/plugin-permission-audit.ts#auditPluginPermissions @15f55df + packages/service-cloud/src/routes/package-publish.ts:530 — the marketplace publish gate: an unverified publisher requesting the node tier is hard-rejected with HTTP 422 ...

Repo (realm marker), path plus consuming symbol, enforcement description, and the commit the reading was taken at — the structured pointer the card asked for, carried in the grammar the ledger already has rather than a new JSON shape. I considered a machine-checked foreign-SHA field and rejected it: a shape check cannot distinguish a real reading from a fabricated one, so it would add surface without adding falsifiability; what makes fabrication pointless is the expiry below, which forces a periodic genuine re-reading. Foreign paths stay counted-never-resolved (that boundary is deliberate and load-bearing); any repo-local path such an entry ALSO cites is held to the full scanned-status standard (existence, line bound, symbol anchor, key mention) — the status joins EVIDENCE_SCANNED_STATUSES.

What re-verification discipline applies to a repo this board may not be able to read. The gate cannot read cloud, and this design never asks it to — what CI executes is the SHAPE of the claim and its CLOCK, four criteria enforced by the new scripts/liveness/elsewhere.mts (exit 1 each, proven red through the real gate in the self-tests):

  1. the evidence string must attribute at least one path to a foreign realm — the verdict IS this pointer; without it the status is exactly the unverified label the card's hard constraint names;
  2. evidenceScope must be cross-repo — the verdict is a cross-repo claim by definition;
  3. verifiedAt is REQUIRED — for every other status an undated row is a worklist entry because the file/line/symbol/key-mention checks keep watching the cited code; nothing local can watch a foreign enforcer rot, so an undated elsewhere-claim would be unfalsifiable forever;
  4. the attestation EXPIRES — past 180 days (deliberately the same constant as the ledger-wide staleness threshold, so the freshness policy stays decided in one place; what differs per status is the consequence) the gate goes red demanding re-attestation. Expiry is the only mechanical event this repo can generate about a claim it cannot re-measure, so here — and only here — age is a merge gate rather than a worklist.

Re-attestation means a seat WITH access re-reads the enforcer at its current head, repairs the pointer if it moved, re-pins the commit, and stamps verifiedAt with that reading's date. Re-stamping without re-reading is the "trust the prose note" downgrade the ruling forbids, and the gate guidance says so verbatim. If the window closes and no seat with access can be found, the red build IS the escalation: the row returns to the maintainer (needs-user-decision) to rule whether an unverifiable pointer still counts as evidence. The design degrades into that fork rather than into silence — trust is time-boxed, never institutional.

The access face, measured this run (reported either way, per the dispatch order). Probe: add_repo read request for objectstack-ai/cloud from this dev seat, 2026-09-01. Result: denied — "you don't have access to objectstack-ai/cloud" — the same face #11331 records from #10627 (re-measured 2026-08-26 there). Countervailing record: the board verifiably read cloud twice in the last week — #10812 (cloud at 5b5925a, 2026-08-24) and #12400 (cloud at 15f55df, reading of 2026-08-29, controls held: 15 manifest-property reads findable). So the fork condition — cloud genuinely unreachable for verification — is measured NOT to hold: access is seat-dependent, not absent, and CI-side reachability is not load-bearing in this design. Consequence for this delivery: I could not honestly re-read the enforcer from this seat today, so the migrated row's verifiedAt is 2026-08-29 — the date of the #12400 reading it cites — not a fresh stamp of today's date.

What changed

  • packages/spec/scripts/liveness/elsewhere.mts (new) + elsewhere.test.ts (new) — the criteria, pure and injected-clock, plus the two prescriptions (shape repair vs re-attestation).
  • check-liveness.mts — status joins the scanned set and the vocabulary docs; per-row criteria wiring in classify(); two new failure headings plus an always-printed population line (the two-number discipline); the unknown-status guidance now points a DELIBERATE vocabulary change at this precedent while still forbidding typo-widening.
  • readme-table.mts — STATUS_COLUMNS gains live-elsewhere; StateCountsRow, foldStateCounts, renderStateCounts move together (the artifact-shape rule those files document); guidance de-hardcodes the column count.
  • build-state-counts.mts — total sum includes the new column.
  • packages/spec/liveness/manifest.jsonmanifest.runtime migrates: status live-elsewhere, the foreign pointer above as evidence, verifiedAt 2026-08-29, note rewritten to carry both halves' measurement provenance and the re-attestation contract.
  • packages/spec/liveness/state-counts.md — regenerated (new elsewhere column; manifest now live 22 / dead 15 / elsewhere 1).
  • packages/spec/liveness/README.md — vocabulary table rows for dead (sharpened: dead means no consumer anywhere the census looked) and live-elsewhere; a dedicated criteria section; the stale "no cross-repo value covers cloud" paragraph corrected; the manifest Notes cell re-measured (Dead 21 becomes Dead 20, runtime's disposition updated).
  • check-liveness.test.ts — a new seven-case block through the real gate via ledger-root: control green with the population line, four red criteria legs, the malformed-verifiedAt single-heading boundary, and the scanned-set membership leg; existing pins updated for the five-name vocabulary.
  • readme-table.test.ts — column pins updated; fold and render cases for the fifth column.
  • .changeset/liveness-live-elsewhere-verdict.md — patch for @objectstack/spec (the liveness/ dir ships in the package files whitelist).

Clause-2: no — the diff touches no packages/spec/src/** path (verified on the merge-base diff; ledger plus gate tooling only). File face vs the claim comment, declared: the enumerated list named check-liveness.mts, its tests, evidence.mts, manifest.json, README and changeset; the implementation additionally lands elsewhere.mts plus test (new module in the same claimed directory), readme-table.mts plus test and build-state-counts.mts (the STATUS_COLUMNS artifact-shape sites, mechanically unavoidable for a vocabulary widening), and the regenerated state-counts.md. All inside the two directories the claim's serial-constraint line locks; evidence.mts itself needed no change.

Second consumer (read, not edited)

#11331 is not addressed here and remains open. Its enforce leg lives in the same cloud control plane; the evidence shape generalizes with no per-key machinery — should its fork land as enforce-in-cloud, the manifest.integrity row takes the same form: a cloud: pointer at the verifier, cross-repo scope, dated attestation. Note per the #12400 reading, cloud today PERSISTS integrity and verifies nothing, so that card's fork is genuinely open.

Verification (all at head 5db4407 unless noted)

  • pnpm --filter @objectstack/spec run check:liveness — exit 0; judgment lines: "live-elsewhere: 1 entr(ies) carry the verdict (dead here, enforced in a sibling repo), 1 with a foreign pointer, cross-repo scope, and an attestation of at most 180d old." and the green summary now includes "every live-elsewhere verdict points at a named foreign enforcer under an unexpired attestation"; manifest row reads "38 classified (live 22, dead 15, live-elsewhere 1)".
  • Liveness suites: elsewhere/check-liveness/readme-table at 5db4407 — 3 files, 105 tests passed; evidence and verification suites at 6a8c6f2 (byte-identical files across the merge) — with the full-population run below covering all of them at the merged tree. The six red legs of the new criteria block each proved a real exit 1 through the real gate with the expected finding text.
  • Full @objectstack/spec vitest suite at 44bd1a1 (identical liveness tree; the two spec src files main merged in are covered by this run): 447 files passed, 12013 tests passed, exit 0. Population proof: vitest list counts 12013 tests and includes the liveness self-test files.
  • pnpm --filter @objectstack/spec run typecheck at 44bd1a1 — exit 0 (tsc, scripts program, test program); --listFiles shows both new files inside the scripts program (measured, not assumed).
  • Derived gate union (node scripts/pm/dispatch-gates.mjs, derivation line cites this tree at 44bd1a1): 36 gates run, 33 green by their own printed verdicts, including check:changeset-gate-self-tests, check:doc-authoring, spec check:empty-state, spec check:strictness-ledger, spec check:variant-docs, check:merge-driver, check:page-declaration-shape, check:pm-governed-merges, check:published-files, check:slot-lookup, check:test-source-alias, check:type-source-resolution, check:where-matcher, check:nul-bytes. Ratchet families (liveness, empty-state, strictness-ledger) re-ran green at 5db4407 after the final commit.
  • Declared NOT MEASURED locally, per each gate's own printed verdict: check-test-completeness (exit 3, "record this gate as NOT MEASURED ... not a red" — CI grades the real turbo log), check:dual-build-cjs-loads (exit 3, "PREREQUISITE NOT MET — reads built output ... nothing was measured") and check-dev-prereqs (exit 1, stale/absent dist in a fresh worktree) — both prerequisite classes want a full monorepo build this diff cannot affect (zero package src changes; the gate scripts run from source via tsx and are not part of dist), and CI runs both after its own build.

Out-of-scope findings

  • packages/lint lint-liveness-properties.ts describe() deliberately throws on a status it has not been taught; unreachable today (reaching it requires authorWarn true or experimental, and no live-elsewhere row carries either) but reachable the day such a row opts into authorWarn — filed separately with the designed repair.
  • .claude/skills/spec-property-retirement consumes ledger dead verdicts and should name the new status in its discipline (a dead-here-enforced-elsewhere key now reads live-elsewhere and is never a removal input) — filed separately as documentation drift.

Generated by Claude Code


Generated by Claude Code

…ed in a sibling repo (#13483)
A key enforced only in a sibling repo had no honest verdict: dead lies about
the cross-repo consumer, live is refused by the gate (repo-local evidence must
resolve). The new status carries gate-executable criteria (elsewhere.mts):
a foreign-realm evidence pointer, evidenceScope cross-repo, a REQUIRED dated
attestation, and a 180d expiry that fails the build demanding a re-reading of
the foreign enforcer — never a re-stamp. manifest.runtime migrates as the
first row, attested at the #12400 cloud reading (2026-08-29, cloud @15f55df).
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
… generator comment
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 128 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ada3834add75f6113c567786b4d1ef7c403c59e2packageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Sep 1, 2026
@os-support-ai
os-support-ai marked this pull request as ready for review September 1, 2026 02:05
@os-support-ai
os-support-ai added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 98c0d33Sep 1, 2026
35 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-13483-liveness-live-elsewhere-verdict branch September 1, 2026 02:43
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liveness ledger has no verdict for keys enforced only in a sibling repo — dead misreads as deletable (manifest.runtime case)

2 participants

@os-support-ai@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483) - #14056

Merged
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict
Sep 1, 2026
Merged

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483)#14056
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13483

Introduces the fifth liveness-ledger verdict live-elsewhere — dead here by measurement, genuinely enforced in a sibling repo — with criteria the gate executes, and migrates manifest.runtime (the #13479 qualifying-note stopgap) as its first row. Direction was mechanically locked by triage: dead lies about the cross-repo consumer, live is refused by the gate (its repo-local evidence must resolve against this checkout), so a new status is the only exit.

Premise — answered before the fix (the ruled precondition)

What a non-local evidence pointer looks like. The realm-marker grammar the evidence scanner already machine-reads, pointed at the foreign ENFORCER and pinned to a foreign commit in the prose. The shipped template is the migrated row:

cloud: packages/service-cloud/src/plugin-permission-audit.ts#auditPluginPermissions @15f55df + packages/service-cloud/src/routes/package-publish.ts:530 — the marketplace publish gate: an unverified publisher requesting the node tier is hard-rejected with HTTP 422 ...

Repo (realm marker), path plus consuming symbol, enforcement description, and the commit the reading was taken at — the structured pointer the card asked for, carried in the grammar the ledger already has rather than a new JSON shape. I considered a machine-checked foreign-SHA field and rejected it: a shape check cannot distinguish a real reading from a fabricated one, so it would add surface without adding falsifiability; what makes fabrication pointless is the expiry below, which forces a periodic genuine re-reading. Foreign paths stay counted-never-resolved (that boundary is deliberate and load-bearing); any repo-local path such an entry ALSO cites is held to the full scanned-status standard (existence, line bound, symbol anchor, key mention) — the status joins EVIDENCE_SCANNED_STATUSES.

What re-verification discipline applies to a repo this board may not be able to read. The gate cannot read cloud, and this design never asks it to — what CI executes is the SHAPE of the claim and its CLOCK, four criteria enforced by the new scripts/liveness/elsewhere.mts (exit 1 each, proven red through the real gate in the self-tests):

  1. the evidence string must attribute at least one path to a foreign realm — the verdict IS this pointer; without it the status is exactly the unverified label the card's hard constraint names;
  2. evidenceScope must be cross-repo — the verdict is a cross-repo claim by definition;
  3. verifiedAt is REQUIRED — for every other status an undated row is a worklist entry because the file/line/symbol/key-mention checks keep watching the cited code; nothing local can watch a foreign enforcer rot, so an undated elsewhere-claim would be unfalsifiable forever;
  4. the attestation EXPIRES — past 180 days (deliberately the same constant as the ledger-wide staleness threshold, so the freshness policy stays decided in one place; what differs per status is the consequence) the gate goes red demanding re-attestation. Expiry is the only mechanical event this repo can generate about a claim it cannot re-measure, so here — and only here — age is a merge gate rather than a worklist.

Re-attestation means a seat WITH access re-reads the enforcer at its current head, repairs the pointer if it moved, re-pins the commit, and stamps verifiedAt with that reading's date. Re-stamping without re-reading is the "trust the prose note" downgrade the ruling forbids, and the gate guidance says so verbatim. If the window closes and no seat with access can be found, the red build IS the escalation: the row returns to the maintainer (needs-user-decision) to rule whether an unverifiable pointer still counts as evidence. The design degrades into that fork rather than into silence — trust is time-boxed, never institutional.

The access face, measured this run (reported either way, per the dispatch order). Probe: add_repo read request for objectstack-ai/cloud from this dev seat, 2026-09-01. Result: denied — "you don't have access to objectstack-ai/cloud" — the same face #11331 records from #10627 (re-measured 2026-08-26 there). Countervailing record: the board verifiably read cloud twice in the last week — #10812 (cloud at 5b5925a, 2026-08-24) and #12400 (cloud at 15f55df, reading of 2026-08-29, controls held: 15 manifest-property reads findable). So the fork condition — cloud genuinely unreachable for verification — is measured NOT to hold: access is seat-dependent, not absent, and CI-side reachability is not load-bearing in this design. Consequence for this delivery: I could not honestly re-read the enforcer from this seat today, so the migrated row's verifiedAt is 2026-08-29 — the date of the #12400 reading it cites — not a fresh stamp of today's date.

What changed

  • packages/spec/scripts/liveness/elsewhere.mts (new) + elsewhere.test.ts (new) — the criteria, pure and injected-clock, plus the two prescriptions (shape repair vs re-attestation).
  • check-liveness.mts — status joins the scanned set and the vocabulary docs; per-row criteria wiring in classify(); two new failure headings plus an always-printed population line (the two-number discipline); the unknown-status guidance now points a DELIBERATE vocabulary change at this precedent while still forbidding typo-widening.
  • readme-table.mts — STATUS_COLUMNS gains live-elsewhere; StateCountsRow, foldStateCounts, renderStateCounts move together (the artifact-shape rule those files document); guidance de-hardcodes the column count.
  • build-state-counts.mts — total sum includes the new column.
  • packages/spec/liveness/manifest.jsonmanifest.runtime migrates: status live-elsewhere, the foreign pointer above as evidence, verifiedAt 2026-08-29, note rewritten to carry both halves' measurement provenance and the re-attestation contract.
  • packages/spec/liveness/state-counts.md — regenerated (new elsewhere column; manifest now live 22 / dead 15 / elsewhere 1).
  • packages/spec/liveness/README.md — vocabulary table rows for dead (sharpened: dead means no consumer anywhere the census looked) and live-elsewhere; a dedicated criteria section; the stale "no cross-repo value covers cloud" paragraph corrected; the manifest Notes cell re-measured (Dead 21 becomes Dead 20, runtime's disposition updated).
  • check-liveness.test.ts — a new seven-case block through the real gate via ledger-root: control green with the population line, four red criteria legs, the malformed-verifiedAt single-heading boundary, and the scanned-set membership leg; existing pins updated for the five-name vocabulary.
  • readme-table.test.ts — column pins updated; fold and render cases for the fifth column.
  • .changeset/liveness-live-elsewhere-verdict.md — patch for @objectstack/spec (the liveness/ dir ships in the package files whitelist).

Clause-2: no — the diff touches no packages/spec/src/** path (verified on the merge-base diff; ledger plus gate tooling only). File face vs the claim comment, declared: the enumerated list named check-liveness.mts, its tests, evidence.mts, manifest.json, README and changeset; the implementation additionally lands elsewhere.mts plus test (new module in the same claimed directory), readme-table.mts plus test and build-state-counts.mts (the STATUS_COLUMNS artifact-shape sites, mechanically unavoidable for a vocabulary widening), and the regenerated state-counts.md. All inside the two directories the claim's serial-constraint line locks; evidence.mts itself needed no change.

Second consumer (read, not edited)

#11331 is not addressed here and remains open. Its enforce leg lives in the same cloud control plane; the evidence shape generalizes with no per-key machinery — should its fork land as enforce-in-cloud, the manifest.integrity row takes the same form: a cloud: pointer at the verifier, cross-repo scope, dated attestation. Note per the #12400 reading, cloud today PERSISTS integrity and verifies nothing, so that card's fork is genuinely open.

Verification (all at head 5db4407 unless noted)

  • pnpm --filter @objectstack/spec run check:liveness — exit 0; judgment lines: "live-elsewhere: 1 entr(ies) carry the verdict (dead here, enforced in a sibling repo), 1 with a foreign pointer, cross-repo scope, and an attestation of at most 180d old." and the green summary now includes "every live-elsewhere verdict points at a named foreign enforcer under an unexpired attestation"; manifest row reads "38 classified (live 22, dead 15, live-elsewhere 1)".
  • Liveness suites: elsewhere/check-liveness/readme-table at 5db4407 — 3 files, 105 tests passed; evidence and verification suites at 6a8c6f2 (byte-identical files across the merge) — with the full-population run below covering all of them at the merged tree. The six red legs of the new criteria block each proved a real exit 1 through the real gate with the expected finding text.
  • Full @objectstack/spec vitest suite at 44bd1a1 (identical liveness tree; the two spec src files main merged in are covered by this run): 447 files passed, 12013 tests passed, exit 0. Population proof: vitest list counts 12013 tests and includes the liveness self-test files.
  • pnpm --filter @objectstack/spec run typecheck at 44bd1a1 — exit 0 (tsc, scripts program, test program); --listFiles shows both new files inside the scripts program (measured, not assumed).
  • Derived gate union (node scripts/pm/dispatch-gates.mjs, derivation line cites this tree at 44bd1a1): 36 gates run, 33 green by their own printed verdicts, including check:changeset-gate-self-tests, check:doc-authoring, spec check:empty-state, spec check:strictness-ledger, spec check:variant-docs, check:merge-driver, check:page-declaration-shape, check:pm-governed-merges, check:published-files, check:slot-lookup, check:test-source-alias, check:type-source-resolution, check:where-matcher, check:nul-bytes. Ratchet families (liveness, empty-state, strictness-ledger) re-ran green at 5db4407 after the final commit.
  • Declared NOT MEASURED locally, per each gate's own printed verdict: check-test-completeness (exit 3, "record this gate as NOT MEASURED ... not a red" — CI grades the real turbo log), check:dual-build-cjs-loads (exit 3, "PREREQUISITE NOT MET — reads built output ... nothing was measured") and check-dev-prereqs (exit 1, stale/absent dist in a fresh worktree) — both prerequisite classes want a full monorepo build this diff cannot affect (zero package src changes; the gate scripts run from source via tsx and are not part of dist), and CI runs both after its own build.

Out-of-scope findings

  • packages/lint lint-liveness-properties.ts describe() deliberately throws on a status it has not been taught; unreachable today (reaching it requires authorWarn true or experimental, and no live-elsewhere row carries either) but reachable the day such a row opts into authorWarn — filed separately with the designed repair.
  • .claude/skills/spec-property-retirement consumes ledger dead verdicts and should name the new status in its discipline (a dead-here-enforced-elsewhere key now reads live-elsewhere and is never a removal input) — filed separately as documentation drift.

Generated by Claude Code


Generated by Claude Code

…ed in a sibling repo (#13483)
A key enforced only in a sibling repo had no honest verdict: dead lies about
the cross-repo consumer, live is refused by the gate (repo-local evidence must
resolve). The new status carries gate-executable criteria (elsewhere.mts):
a foreign-realm evidence pointer, evidenceScope cross-repo, a REQUIRED dated
attestation, and a 180d expiry that fails the build demanding a re-reading of
the foreign enforcer — never a re-stamp. manifest.runtime migrates as the
first row, attested at the #12400 cloud reading (2026-08-29, cloud @15f55df).
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
… generator comment
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 128 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ada3834add75f6113c567786b4d1ef7c403c59e2packageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Sep 1, 2026
@os-support-ai
os-support-ai marked this pull request as ready for review September 1, 2026 02:05
@os-support-ai
os-support-ai added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 98c0d33Sep 1, 2026
35 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-13483-liveness-live-elsewhere-verdict branch September 1, 2026 02:43
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liveness ledger has no verdict for keys enforced only in a sibling repo — dead misreads as deletable (manifest.runtime case)

2 participants

@os-support-ai@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483) - #14056

Merged
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict
Sep 1, 2026
Merged

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483)#14056
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13483

Introduces the fifth liveness-ledger verdict live-elsewhere — dead here by measurement, genuinely enforced in a sibling repo — with criteria the gate executes, and migrates manifest.runtime (the #13479 qualifying-note stopgap) as its first row. Direction was mechanically locked by triage: dead lies about the cross-repo consumer, live is refused by the gate (its repo-local evidence must resolve against this checkout), so a new status is the only exit.

Premise — answered before the fix (the ruled precondition)

What a non-local evidence pointer looks like. The realm-marker grammar the evidence scanner already machine-reads, pointed at the foreign ENFORCER and pinned to a foreign commit in the prose. The shipped template is the migrated row:

cloud: packages/service-cloud/src/plugin-permission-audit.ts#auditPluginPermissions @15f55df + packages/service-cloud/src/routes/package-publish.ts:530 — the marketplace publish gate: an unverified publisher requesting the node tier is hard-rejected with HTTP 422 ...

Repo (realm marker), path plus consuming symbol, enforcement description, and the commit the reading was taken at — the structured pointer the card asked for, carried in the grammar the ledger already has rather than a new JSON shape. I considered a machine-checked foreign-SHA field and rejected it: a shape check cannot distinguish a real reading from a fabricated one, so it would add surface without adding falsifiability; what makes fabrication pointless is the expiry below, which forces a periodic genuine re-reading. Foreign paths stay counted-never-resolved (that boundary is deliberate and load-bearing); any repo-local path such an entry ALSO cites is held to the full scanned-status standard (existence, line bound, symbol anchor, key mention) — the status joins EVIDENCE_SCANNED_STATUSES.

What re-verification discipline applies to a repo this board may not be able to read. The gate cannot read cloud, and this design never asks it to — what CI executes is the SHAPE of the claim and its CLOCK, four criteria enforced by the new scripts/liveness/elsewhere.mts (exit 1 each, proven red through the real gate in the self-tests):

  1. the evidence string must attribute at least one path to a foreign realm — the verdict IS this pointer; without it the status is exactly the unverified label the card's hard constraint names;
  2. evidenceScope must be cross-repo — the verdict is a cross-repo claim by definition;
  3. verifiedAt is REQUIRED — for every other status an undated row is a worklist entry because the file/line/symbol/key-mention checks keep watching the cited code; nothing local can watch a foreign enforcer rot, so an undated elsewhere-claim would be unfalsifiable forever;
  4. the attestation EXPIRES — past 180 days (deliberately the same constant as the ledger-wide staleness threshold, so the freshness policy stays decided in one place; what differs per status is the consequence) the gate goes red demanding re-attestation. Expiry is the only mechanical event this repo can generate about a claim it cannot re-measure, so here — and only here — age is a merge gate rather than a worklist.

Re-attestation means a seat WITH access re-reads the enforcer at its current head, repairs the pointer if it moved, re-pins the commit, and stamps verifiedAt with that reading's date. Re-stamping without re-reading is the "trust the prose note" downgrade the ruling forbids, and the gate guidance says so verbatim. If the window closes and no seat with access can be found, the red build IS the escalation: the row returns to the maintainer (needs-user-decision) to rule whether an unverifiable pointer still counts as evidence. The design degrades into that fork rather than into silence — trust is time-boxed, never institutional.

The access face, measured this run (reported either way, per the dispatch order). Probe: add_repo read request for objectstack-ai/cloud from this dev seat, 2026-09-01. Result: denied — "you don't have access to objectstack-ai/cloud" — the same face #11331 records from #10627 (re-measured 2026-08-26 there). Countervailing record: the board verifiably read cloud twice in the last week — #10812 (cloud at 5b5925a, 2026-08-24) and #12400 (cloud at 15f55df, reading of 2026-08-29, controls held: 15 manifest-property reads findable). So the fork condition — cloud genuinely unreachable for verification — is measured NOT to hold: access is seat-dependent, not absent, and CI-side reachability is not load-bearing in this design. Consequence for this delivery: I could not honestly re-read the enforcer from this seat today, so the migrated row's verifiedAt is 2026-08-29 — the date of the #12400 reading it cites — not a fresh stamp of today's date.

What changed

  • packages/spec/scripts/liveness/elsewhere.mts (new) + elsewhere.test.ts (new) — the criteria, pure and injected-clock, plus the two prescriptions (shape repair vs re-attestation).
  • check-liveness.mts — status joins the scanned set and the vocabulary docs; per-row criteria wiring in classify(); two new failure headings plus an always-printed population line (the two-number discipline); the unknown-status guidance now points a DELIBERATE vocabulary change at this precedent while still forbidding typo-widening.
  • readme-table.mts — STATUS_COLUMNS gains live-elsewhere; StateCountsRow, foldStateCounts, renderStateCounts move together (the artifact-shape rule those files document); guidance de-hardcodes the column count.
  • build-state-counts.mts — total sum includes the new column.
  • packages/spec/liveness/manifest.jsonmanifest.runtime migrates: status live-elsewhere, the foreign pointer above as evidence, verifiedAt 2026-08-29, note rewritten to carry both halves' measurement provenance and the re-attestation contract.
  • packages/spec/liveness/state-counts.md — regenerated (new elsewhere column; manifest now live 22 / dead 15 / elsewhere 1).
  • packages/spec/liveness/README.md — vocabulary table rows for dead (sharpened: dead means no consumer anywhere the census looked) and live-elsewhere; a dedicated criteria section; the stale "no cross-repo value covers cloud" paragraph corrected; the manifest Notes cell re-measured (Dead 21 becomes Dead 20, runtime's disposition updated).
  • check-liveness.test.ts — a new seven-case block through the real gate via ledger-root: control green with the population line, four red criteria legs, the malformed-verifiedAt single-heading boundary, and the scanned-set membership leg; existing pins updated for the five-name vocabulary.
  • readme-table.test.ts — column pins updated; fold and render cases for the fifth column.
  • .changeset/liveness-live-elsewhere-verdict.md — patch for @objectstack/spec (the liveness/ dir ships in the package files whitelist).

Clause-2: no — the diff touches no packages/spec/src/** path (verified on the merge-base diff; ledger plus gate tooling only). File face vs the claim comment, declared: the enumerated list named check-liveness.mts, its tests, evidence.mts, manifest.json, README and changeset; the implementation additionally lands elsewhere.mts plus test (new module in the same claimed directory), readme-table.mts plus test and build-state-counts.mts (the STATUS_COLUMNS artifact-shape sites, mechanically unavoidable for a vocabulary widening), and the regenerated state-counts.md. All inside the two directories the claim's serial-constraint line locks; evidence.mts itself needed no change.

Second consumer (read, not edited)

#11331 is not addressed here and remains open. Its enforce leg lives in the same cloud control plane; the evidence shape generalizes with no per-key machinery — should its fork land as enforce-in-cloud, the manifest.integrity row takes the same form: a cloud: pointer at the verifier, cross-repo scope, dated attestation. Note per the #12400 reading, cloud today PERSISTS integrity and verifies nothing, so that card's fork is genuinely open.

Verification (all at head 5db4407 unless noted)

  • pnpm --filter @objectstack/spec run check:liveness — exit 0; judgment lines: "live-elsewhere: 1 entr(ies) carry the verdict (dead here, enforced in a sibling repo), 1 with a foreign pointer, cross-repo scope, and an attestation of at most 180d old." and the green summary now includes "every live-elsewhere verdict points at a named foreign enforcer under an unexpired attestation"; manifest row reads "38 classified (live 22, dead 15, live-elsewhere 1)".
  • Liveness suites: elsewhere/check-liveness/readme-table at 5db4407 — 3 files, 105 tests passed; evidence and verification suites at 6a8c6f2 (byte-identical files across the merge) — with the full-population run below covering all of them at the merged tree. The six red legs of the new criteria block each proved a real exit 1 through the real gate with the expected finding text.
  • Full @objectstack/spec vitest suite at 44bd1a1 (identical liveness tree; the two spec src files main merged in are covered by this run): 447 files passed, 12013 tests passed, exit 0. Population proof: vitest list counts 12013 tests and includes the liveness self-test files.
  • pnpm --filter @objectstack/spec run typecheck at 44bd1a1 — exit 0 (tsc, scripts program, test program); --listFiles shows both new files inside the scripts program (measured, not assumed).
  • Derived gate union (node scripts/pm/dispatch-gates.mjs, derivation line cites this tree at 44bd1a1): 36 gates run, 33 green by their own printed verdicts, including check:changeset-gate-self-tests, check:doc-authoring, spec check:empty-state, spec check:strictness-ledger, spec check:variant-docs, check:merge-driver, check:page-declaration-shape, check:pm-governed-merges, check:published-files, check:slot-lookup, check:test-source-alias, check:type-source-resolution, check:where-matcher, check:nul-bytes. Ratchet families (liveness, empty-state, strictness-ledger) re-ran green at 5db4407 after the final commit.
  • Declared NOT MEASURED locally, per each gate's own printed verdict: check-test-completeness (exit 3, "record this gate as NOT MEASURED ... not a red" — CI grades the real turbo log), check:dual-build-cjs-loads (exit 3, "PREREQUISITE NOT MET — reads built output ... nothing was measured") and check-dev-prereqs (exit 1, stale/absent dist in a fresh worktree) — both prerequisite classes want a full monorepo build this diff cannot affect (zero package src changes; the gate scripts run from source via tsx and are not part of dist), and CI runs both after its own build.

Out-of-scope findings

  • packages/lint lint-liveness-properties.ts describe() deliberately throws on a status it has not been taught; unreachable today (reaching it requires authorWarn true or experimental, and no live-elsewhere row carries either) but reachable the day such a row opts into authorWarn — filed separately with the designed repair.
  • .claude/skills/spec-property-retirement consumes ledger dead verdicts and should name the new status in its discipline (a dead-here-enforced-elsewhere key now reads live-elsewhere and is never a removal input) — filed separately as documentation drift.

Generated by Claude Code


Generated by Claude Code

…ed in a sibling repo (#13483)
A key enforced only in a sibling repo had no honest verdict: dead lies about
the cross-repo consumer, live is refused by the gate (repo-local evidence must
resolve). The new status carries gate-executable criteria (elsewhere.mts):
a foreign-realm evidence pointer, evidenceScope cross-repo, a REQUIRED dated
attestation, and a 180d expiry that fails the build demanding a re-reading of
the foreign enforcer — never a re-stamp. manifest.runtime migrates as the
first row, attested at the #12400 cloud reading (2026-08-29, cloud @15f55df).
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
… generator comment
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 128 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ada3834add75f6113c567786b4d1ef7c403c59e2packageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Sep 1, 2026
@os-support-ai
os-support-ai marked this pull request as ready for review September 1, 2026 02:05
@os-support-ai
os-support-ai added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 98c0d33Sep 1, 2026
35 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-13483-liveness-live-elsewhere-verdict branch September 1, 2026 02:43
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liveness ledger has no verdict for keys enforced only in a sibling repo — dead misreads as deletable (manifest.runtime case)

2 participants

@os-support-ai@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483) - #14056

Merged
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict
Sep 1, 2026
Merged

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483)#14056
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13483

Introduces the fifth liveness-ledger verdict live-elsewhere — dead here by measurement, genuinely enforced in a sibling repo — with criteria the gate executes, and migrates manifest.runtime (the #13479 qualifying-note stopgap) as its first row. Direction was mechanically locked by triage: dead lies about the cross-repo consumer, live is refused by the gate (its repo-local evidence must resolve against this checkout), so a new status is the only exit.

Premise — answered before the fix (the ruled precondition)

What a non-local evidence pointer looks like. The realm-marker grammar the evidence scanner already machine-reads, pointed at the foreign ENFORCER and pinned to a foreign commit in the prose. The shipped template is the migrated row:

cloud: packages/service-cloud/src/plugin-permission-audit.ts#auditPluginPermissions @15f55df + packages/service-cloud/src/routes/package-publish.ts:530 — the marketplace publish gate: an unverified publisher requesting the node tier is hard-rejected with HTTP 422 ...

Repo (realm marker), path plus consuming symbol, enforcement description, and the commit the reading was taken at — the structured pointer the card asked for, carried in the grammar the ledger already has rather than a new JSON shape. I considered a machine-checked foreign-SHA field and rejected it: a shape check cannot distinguish a real reading from a fabricated one, so it would add surface without adding falsifiability; what makes fabrication pointless is the expiry below, which forces a periodic genuine re-reading. Foreign paths stay counted-never-resolved (that boundary is deliberate and load-bearing); any repo-local path such an entry ALSO cites is held to the full scanned-status standard (existence, line bound, symbol anchor, key mention) — the status joins EVIDENCE_SCANNED_STATUSES.

What re-verification discipline applies to a repo this board may not be able to read. The gate cannot read cloud, and this design never asks it to — what CI executes is the SHAPE of the claim and its CLOCK, four criteria enforced by the new scripts/liveness/elsewhere.mts (exit 1 each, proven red through the real gate in the self-tests):

  1. the evidence string must attribute at least one path to a foreign realm — the verdict IS this pointer; without it the status is exactly the unverified label the card's hard constraint names;
  2. evidenceScope must be cross-repo — the verdict is a cross-repo claim by definition;
  3. verifiedAt is REQUIRED — for every other status an undated row is a worklist entry because the file/line/symbol/key-mention checks keep watching the cited code; nothing local can watch a foreign enforcer rot, so an undated elsewhere-claim would be unfalsifiable forever;
  4. the attestation EXPIRES — past 180 days (deliberately the same constant as the ledger-wide staleness threshold, so the freshness policy stays decided in one place; what differs per status is the consequence) the gate goes red demanding re-attestation. Expiry is the only mechanical event this repo can generate about a claim it cannot re-measure, so here — and only here — age is a merge gate rather than a worklist.

Re-attestation means a seat WITH access re-reads the enforcer at its current head, repairs the pointer if it moved, re-pins the commit, and stamps verifiedAt with that reading's date. Re-stamping without re-reading is the "trust the prose note" downgrade the ruling forbids, and the gate guidance says so verbatim. If the window closes and no seat with access can be found, the red build IS the escalation: the row returns to the maintainer (needs-user-decision) to rule whether an unverifiable pointer still counts as evidence. The design degrades into that fork rather than into silence — trust is time-boxed, never institutional.

The access face, measured this run (reported either way, per the dispatch order). Probe: add_repo read request for objectstack-ai/cloud from this dev seat, 2026-09-01. Result: denied — "you don't have access to objectstack-ai/cloud" — the same face #11331 records from #10627 (re-measured 2026-08-26 there). Countervailing record: the board verifiably read cloud twice in the last week — #10812 (cloud at 5b5925a, 2026-08-24) and #12400 (cloud at 15f55df, reading of 2026-08-29, controls held: 15 manifest-property reads findable). So the fork condition — cloud genuinely unreachable for verification — is measured NOT to hold: access is seat-dependent, not absent, and CI-side reachability is not load-bearing in this design. Consequence for this delivery: I could not honestly re-read the enforcer from this seat today, so the migrated row's verifiedAt is 2026-08-29 — the date of the #12400 reading it cites — not a fresh stamp of today's date.

What changed

  • packages/spec/scripts/liveness/elsewhere.mts (new) + elsewhere.test.ts (new) — the criteria, pure and injected-clock, plus the two prescriptions (shape repair vs re-attestation).
  • check-liveness.mts — status joins the scanned set and the vocabulary docs; per-row criteria wiring in classify(); two new failure headings plus an always-printed population line (the two-number discipline); the unknown-status guidance now points a DELIBERATE vocabulary change at this precedent while still forbidding typo-widening.
  • readme-table.mts — STATUS_COLUMNS gains live-elsewhere; StateCountsRow, foldStateCounts, renderStateCounts move together (the artifact-shape rule those files document); guidance de-hardcodes the column count.
  • build-state-counts.mts — total sum includes the new column.
  • packages/spec/liveness/manifest.jsonmanifest.runtime migrates: status live-elsewhere, the foreign pointer above as evidence, verifiedAt 2026-08-29, note rewritten to carry both halves' measurement provenance and the re-attestation contract.
  • packages/spec/liveness/state-counts.md — regenerated (new elsewhere column; manifest now live 22 / dead 15 / elsewhere 1).
  • packages/spec/liveness/README.md — vocabulary table rows for dead (sharpened: dead means no consumer anywhere the census looked) and live-elsewhere; a dedicated criteria section; the stale "no cross-repo value covers cloud" paragraph corrected; the manifest Notes cell re-measured (Dead 21 becomes Dead 20, runtime's disposition updated).
  • check-liveness.test.ts — a new seven-case block through the real gate via ledger-root: control green with the population line, four red criteria legs, the malformed-verifiedAt single-heading boundary, and the scanned-set membership leg; existing pins updated for the five-name vocabulary.
  • readme-table.test.ts — column pins updated; fold and render cases for the fifth column.
  • .changeset/liveness-live-elsewhere-verdict.md — patch for @objectstack/spec (the liveness/ dir ships in the package files whitelist).

Clause-2: no — the diff touches no packages/spec/src/** path (verified on the merge-base diff; ledger plus gate tooling only). File face vs the claim comment, declared: the enumerated list named check-liveness.mts, its tests, evidence.mts, manifest.json, README and changeset; the implementation additionally lands elsewhere.mts plus test (new module in the same claimed directory), readme-table.mts plus test and build-state-counts.mts (the STATUS_COLUMNS artifact-shape sites, mechanically unavoidable for a vocabulary widening), and the regenerated state-counts.md. All inside the two directories the claim's serial-constraint line locks; evidence.mts itself needed no change.

Second consumer (read, not edited)

#11331 is not addressed here and remains open. Its enforce leg lives in the same cloud control plane; the evidence shape generalizes with no per-key machinery — should its fork land as enforce-in-cloud, the manifest.integrity row takes the same form: a cloud: pointer at the verifier, cross-repo scope, dated attestation. Note per the #12400 reading, cloud today PERSISTS integrity and verifies nothing, so that card's fork is genuinely open.

Verification (all at head 5db4407 unless noted)

  • pnpm --filter @objectstack/spec run check:liveness — exit 0; judgment lines: "live-elsewhere: 1 entr(ies) carry the verdict (dead here, enforced in a sibling repo), 1 with a foreign pointer, cross-repo scope, and an attestation of at most 180d old." and the green summary now includes "every live-elsewhere verdict points at a named foreign enforcer under an unexpired attestation"; manifest row reads "38 classified (live 22, dead 15, live-elsewhere 1)".
  • Liveness suites: elsewhere/check-liveness/readme-table at 5db4407 — 3 files, 105 tests passed; evidence and verification suites at 6a8c6f2 (byte-identical files across the merge) — with the full-population run below covering all of them at the merged tree. The six red legs of the new criteria block each proved a real exit 1 through the real gate with the expected finding text.
  • Full @objectstack/spec vitest suite at 44bd1a1 (identical liveness tree; the two spec src files main merged in are covered by this run): 447 files passed, 12013 tests passed, exit 0. Population proof: vitest list counts 12013 tests and includes the liveness self-test files.
  • pnpm --filter @objectstack/spec run typecheck at 44bd1a1 — exit 0 (tsc, scripts program, test program); --listFiles shows both new files inside the scripts program (measured, not assumed).
  • Derived gate union (node scripts/pm/dispatch-gates.mjs, derivation line cites this tree at 44bd1a1): 36 gates run, 33 green by their own printed verdicts, including check:changeset-gate-self-tests, check:doc-authoring, spec check:empty-state, spec check:strictness-ledger, spec check:variant-docs, check:merge-driver, check:page-declaration-shape, check:pm-governed-merges, check:published-files, check:slot-lookup, check:test-source-alias, check:type-source-resolution, check:where-matcher, check:nul-bytes. Ratchet families (liveness, empty-state, strictness-ledger) re-ran green at 5db4407 after the final commit.
  • Declared NOT MEASURED locally, per each gate's own printed verdict: check-test-completeness (exit 3, "record this gate as NOT MEASURED ... not a red" — CI grades the real turbo log), check:dual-build-cjs-loads (exit 3, "PREREQUISITE NOT MET — reads built output ... nothing was measured") and check-dev-prereqs (exit 1, stale/absent dist in a fresh worktree) — both prerequisite classes want a full monorepo build this diff cannot affect (zero package src changes; the gate scripts run from source via tsx and are not part of dist), and CI runs both after its own build.

Out-of-scope findings

  • packages/lint lint-liveness-properties.ts describe() deliberately throws on a status it has not been taught; unreachable today (reaching it requires authorWarn true or experimental, and no live-elsewhere row carries either) but reachable the day such a row opts into authorWarn — filed separately with the designed repair.
  • .claude/skills/spec-property-retirement consumes ledger dead verdicts and should name the new status in its discipline (a dead-here-enforced-elsewhere key now reads live-elsewhere and is never a removal input) — filed separately as documentation drift.

Generated by Claude Code


Generated by Claude Code

…ed in a sibling repo (#13483)
A key enforced only in a sibling repo had no honest verdict: dead lies about
the cross-repo consumer, live is refused by the gate (repo-local evidence must
resolve). The new status carries gate-executable criteria (elsewhere.mts):
a foreign-realm evidence pointer, evidenceScope cross-repo, a REQUIRED dated
attestation, and a 180d expiry that fails the build demanding a re-reading of
the foreign enforcer — never a re-stamp. manifest.runtime migrates as the
first row, attested at the #12400 cloud reading (2026-08-29, cloud @15f55df).
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
… generator comment
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 128 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ada3834add75f6113c567786b4d1ef7c403c59e2packageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Sep 1, 2026
@os-support-ai
os-support-ai marked this pull request as ready for review September 1, 2026 02:05
@os-support-ai
os-support-ai added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 98c0d33Sep 1, 2026
35 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-13483-liveness-live-elsewhere-verdict branch September 1, 2026 02:43
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liveness ledger has no verdict for keys enforced only in a sibling repo — dead misreads as deletable (manifest.runtime case)

2 participants

@os-support-ai@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483) - #14056

Merged
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict
Sep 1, 2026
Merged

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483)#14056
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13483

Introduces the fifth liveness-ledger verdict live-elsewhere — dead here by measurement, genuinely enforced in a sibling repo — with criteria the gate executes, and migrates manifest.runtime (the #13479 qualifying-note stopgap) as its first row. Direction was mechanically locked by triage: dead lies about the cross-repo consumer, live is refused by the gate (its repo-local evidence must resolve against this checkout), so a new status is the only exit.

Premise — answered before the fix (the ruled precondition)

What a non-local evidence pointer looks like. The realm-marker grammar the evidence scanner already machine-reads, pointed at the foreign ENFORCER and pinned to a foreign commit in the prose. The shipped template is the migrated row:

cloud: packages/service-cloud/src/plugin-permission-audit.ts#auditPluginPermissions @15f55df + packages/service-cloud/src/routes/package-publish.ts:530 — the marketplace publish gate: an unverified publisher requesting the node tier is hard-rejected with HTTP 422 ...

Repo (realm marker), path plus consuming symbol, enforcement description, and the commit the reading was taken at — the structured pointer the card asked for, carried in the grammar the ledger already has rather than a new JSON shape. I considered a machine-checked foreign-SHA field and rejected it: a shape check cannot distinguish a real reading from a fabricated one, so it would add surface without adding falsifiability; what makes fabrication pointless is the expiry below, which forces a periodic genuine re-reading. Foreign paths stay counted-never-resolved (that boundary is deliberate and load-bearing); any repo-local path such an entry ALSO cites is held to the full scanned-status standard (existence, line bound, symbol anchor, key mention) — the status joins EVIDENCE_SCANNED_STATUSES.

What re-verification discipline applies to a repo this board may not be able to read. The gate cannot read cloud, and this design never asks it to — what CI executes is the SHAPE of the claim and its CLOCK, four criteria enforced by the new scripts/liveness/elsewhere.mts (exit 1 each, proven red through the real gate in the self-tests):

  1. the evidence string must attribute at least one path to a foreign realm — the verdict IS this pointer; without it the status is exactly the unverified label the card's hard constraint names;
  2. evidenceScope must be cross-repo — the verdict is a cross-repo claim by definition;
  3. verifiedAt is REQUIRED — for every other status an undated row is a worklist entry because the file/line/symbol/key-mention checks keep watching the cited code; nothing local can watch a foreign enforcer rot, so an undated elsewhere-claim would be unfalsifiable forever;
  4. the attestation EXPIRES — past 180 days (deliberately the same constant as the ledger-wide staleness threshold, so the freshness policy stays decided in one place; what differs per status is the consequence) the gate goes red demanding re-attestation. Expiry is the only mechanical event this repo can generate about a claim it cannot re-measure, so here — and only here — age is a merge gate rather than a worklist.

Re-attestation means a seat WITH access re-reads the enforcer at its current head, repairs the pointer if it moved, re-pins the commit, and stamps verifiedAt with that reading's date. Re-stamping without re-reading is the "trust the prose note" downgrade the ruling forbids, and the gate guidance says so verbatim. If the window closes and no seat with access can be found, the red build IS the escalation: the row returns to the maintainer (needs-user-decision) to rule whether an unverifiable pointer still counts as evidence. The design degrades into that fork rather than into silence — trust is time-boxed, never institutional.

The access face, measured this run (reported either way, per the dispatch order). Probe: add_repo read request for objectstack-ai/cloud from this dev seat, 2026-09-01. Result: denied — "you don't have access to objectstack-ai/cloud" — the same face #11331 records from #10627 (re-measured 2026-08-26 there). Countervailing record: the board verifiably read cloud twice in the last week — #10812 (cloud at 5b5925a, 2026-08-24) and #12400 (cloud at 15f55df, reading of 2026-08-29, controls held: 15 manifest-property reads findable). So the fork condition — cloud genuinely unreachable for verification — is measured NOT to hold: access is seat-dependent, not absent, and CI-side reachability is not load-bearing in this design. Consequence for this delivery: I could not honestly re-read the enforcer from this seat today, so the migrated row's verifiedAt is 2026-08-29 — the date of the #12400 reading it cites — not a fresh stamp of today's date.

What changed

  • packages/spec/scripts/liveness/elsewhere.mts (new) + elsewhere.test.ts (new) — the criteria, pure and injected-clock, plus the two prescriptions (shape repair vs re-attestation).
  • check-liveness.mts — status joins the scanned set and the vocabulary docs; per-row criteria wiring in classify(); two new failure headings plus an always-printed population line (the two-number discipline); the unknown-status guidance now points a DELIBERATE vocabulary change at this precedent while still forbidding typo-widening.
  • readme-table.mts — STATUS_COLUMNS gains live-elsewhere; StateCountsRow, foldStateCounts, renderStateCounts move together (the artifact-shape rule those files document); guidance de-hardcodes the column count.
  • build-state-counts.mts — total sum includes the new column.
  • packages/spec/liveness/manifest.jsonmanifest.runtime migrates: status live-elsewhere, the foreign pointer above as evidence, verifiedAt 2026-08-29, note rewritten to carry both halves' measurement provenance and the re-attestation contract.
  • packages/spec/liveness/state-counts.md — regenerated (new elsewhere column; manifest now live 22 / dead 15 / elsewhere 1).
  • packages/spec/liveness/README.md — vocabulary table rows for dead (sharpened: dead means no consumer anywhere the census looked) and live-elsewhere; a dedicated criteria section; the stale "no cross-repo value covers cloud" paragraph corrected; the manifest Notes cell re-measured (Dead 21 becomes Dead 20, runtime's disposition updated).
  • check-liveness.test.ts — a new seven-case block through the real gate via ledger-root: control green with the population line, four red criteria legs, the malformed-verifiedAt single-heading boundary, and the scanned-set membership leg; existing pins updated for the five-name vocabulary.
  • readme-table.test.ts — column pins updated; fold and render cases for the fifth column.
  • .changeset/liveness-live-elsewhere-verdict.md — patch for @objectstack/spec (the liveness/ dir ships in the package files whitelist).

Clause-2: no — the diff touches no packages/spec/src/** path (verified on the merge-base diff; ledger plus gate tooling only). File face vs the claim comment, declared: the enumerated list named check-liveness.mts, its tests, evidence.mts, manifest.json, README and changeset; the implementation additionally lands elsewhere.mts plus test (new module in the same claimed directory), readme-table.mts plus test and build-state-counts.mts (the STATUS_COLUMNS artifact-shape sites, mechanically unavoidable for a vocabulary widening), and the regenerated state-counts.md. All inside the two directories the claim's serial-constraint line locks; evidence.mts itself needed no change.

Second consumer (read, not edited)

#11331 is not addressed here and remains open. Its enforce leg lives in the same cloud control plane; the evidence shape generalizes with no per-key machinery — should its fork land as enforce-in-cloud, the manifest.integrity row takes the same form: a cloud: pointer at the verifier, cross-repo scope, dated attestation. Note per the #12400 reading, cloud today PERSISTS integrity and verifies nothing, so that card's fork is genuinely open.

Verification (all at head 5db4407 unless noted)

  • pnpm --filter @objectstack/spec run check:liveness — exit 0; judgment lines: "live-elsewhere: 1 entr(ies) carry the verdict (dead here, enforced in a sibling repo), 1 with a foreign pointer, cross-repo scope, and an attestation of at most 180d old." and the green summary now includes "every live-elsewhere verdict points at a named foreign enforcer under an unexpired attestation"; manifest row reads "38 classified (live 22, dead 15, live-elsewhere 1)".
  • Liveness suites: elsewhere/check-liveness/readme-table at 5db4407 — 3 files, 105 tests passed; evidence and verification suites at 6a8c6f2 (byte-identical files across the merge) — with the full-population run below covering all of them at the merged tree. The six red legs of the new criteria block each proved a real exit 1 through the real gate with the expected finding text.
  • Full @objectstack/spec vitest suite at 44bd1a1 (identical liveness tree; the two spec src files main merged in are covered by this run): 447 files passed, 12013 tests passed, exit 0. Population proof: vitest list counts 12013 tests and includes the liveness self-test files.
  • pnpm --filter @objectstack/spec run typecheck at 44bd1a1 — exit 0 (tsc, scripts program, test program); --listFiles shows both new files inside the scripts program (measured, not assumed).
  • Derived gate union (node scripts/pm/dispatch-gates.mjs, derivation line cites this tree at 44bd1a1): 36 gates run, 33 green by their own printed verdicts, including check:changeset-gate-self-tests, check:doc-authoring, spec check:empty-state, spec check:strictness-ledger, spec check:variant-docs, check:merge-driver, check:page-declaration-shape, check:pm-governed-merges, check:published-files, check:slot-lookup, check:test-source-alias, check:type-source-resolution, check:where-matcher, check:nul-bytes. Ratchet families (liveness, empty-state, strictness-ledger) re-ran green at 5db4407 after the final commit.
  • Declared NOT MEASURED locally, per each gate's own printed verdict: check-test-completeness (exit 3, "record this gate as NOT MEASURED ... not a red" — CI grades the real turbo log), check:dual-build-cjs-loads (exit 3, "PREREQUISITE NOT MET — reads built output ... nothing was measured") and check-dev-prereqs (exit 1, stale/absent dist in a fresh worktree) — both prerequisite classes want a full monorepo build this diff cannot affect (zero package src changes; the gate scripts run from source via tsx and are not part of dist), and CI runs both after its own build.

Out-of-scope findings

  • packages/lint lint-liveness-properties.ts describe() deliberately throws on a status it has not been taught; unreachable today (reaching it requires authorWarn true or experimental, and no live-elsewhere row carries either) but reachable the day such a row opts into authorWarn — filed separately with the designed repair.
  • .claude/skills/spec-property-retirement consumes ledger dead verdicts and should name the new status in its discipline (a dead-here-enforced-elsewhere key now reads live-elsewhere and is never a removal input) — filed separately as documentation drift.

Generated by Claude Code


Generated by Claude Code

…ed in a sibling repo (#13483)
A key enforced only in a sibling repo had no honest verdict: dead lies about
the cross-repo consumer, live is refused by the gate (repo-local evidence must
resolve). The new status carries gate-executable criteria (elsewhere.mts):
a foreign-realm evidence pointer, evidenceScope cross-repo, a REQUIRED dated
attestation, and a 180d expiry that fails the build demanding a re-reading of
the foreign enforcer — never a re-stamp. manifest.runtime migrates as the
first row, attested at the #12400 cloud reading (2026-08-29, cloud @15f55df).
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
… generator comment
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 128 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ada3834add75f6113c567786b4d1ef7c403c59e2packageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Sep 1, 2026
@os-support-ai
os-support-ai marked this pull request as ready for review September 1, 2026 02:05
@os-support-ai
os-support-ai added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 98c0d33Sep 1, 2026
35 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-13483-liveness-live-elsewhere-verdict branch September 1, 2026 02:43
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liveness ledger has no verdict for keys enforced only in a sibling repo — dead misreads as deletable (manifest.runtime case)

2 participants

@os-support-ai@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483) - #14056

Merged
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict
Sep 1, 2026
Merged

feat(spec): live-elsewhere — fifth liveness verdict with gate-executable criteria (#13483)#14056
os-support-ai merged 3 commits into
mainfrom
claude/issue-13483-liveness-live-elsewhere-verdict

Conversation

@claude

@claudeclaudeBot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Fixes#13483

Introduces the fifth liveness-ledger verdict live-elsewhere — dead here by measurement, genuinely enforced in a sibling repo — with criteria the gate executes, and migrates manifest.runtime (the #13479 qualifying-note stopgap) as its first row. Direction was mechanically locked by triage: dead lies about the cross-repo consumer, live is refused by the gate (its repo-local evidence must resolve against this checkout), so a new status is the only exit.

Premise — answered before the fix (the ruled precondition)

What a non-local evidence pointer looks like. The realm-marker grammar the evidence scanner already machine-reads, pointed at the foreign ENFORCER and pinned to a foreign commit in the prose. The shipped template is the migrated row:

cloud: packages/service-cloud/src/plugin-permission-audit.ts#auditPluginPermissions @15f55df + packages/service-cloud/src/routes/package-publish.ts:530 — the marketplace publish gate: an unverified publisher requesting the node tier is hard-rejected with HTTP 422 ...

Repo (realm marker), path plus consuming symbol, enforcement description, and the commit the reading was taken at — the structured pointer the card asked for, carried in the grammar the ledger already has rather than a new JSON shape. I considered a machine-checked foreign-SHA field and rejected it: a shape check cannot distinguish a real reading from a fabricated one, so it would add surface without adding falsifiability; what makes fabrication pointless is the expiry below, which forces a periodic genuine re-reading. Foreign paths stay counted-never-resolved (that boundary is deliberate and load-bearing); any repo-local path such an entry ALSO cites is held to the full scanned-status standard (existence, line bound, symbol anchor, key mention) — the status joins EVIDENCE_SCANNED_STATUSES.

What re-verification discipline applies to a repo this board may not be able to read. The gate cannot read cloud, and this design never asks it to — what CI executes is the SHAPE of the claim and its CLOCK, four criteria enforced by the new scripts/liveness/elsewhere.mts (exit 1 each, proven red through the real gate in the self-tests):

  1. the evidence string must attribute at least one path to a foreign realm — the verdict IS this pointer; without it the status is exactly the unverified label the card's hard constraint names;
  2. evidenceScope must be cross-repo — the verdict is a cross-repo claim by definition;
  3. verifiedAt is REQUIRED — for every other status an undated row is a worklist entry because the file/line/symbol/key-mention checks keep watching the cited code; nothing local can watch a foreign enforcer rot, so an undated elsewhere-claim would be unfalsifiable forever;
  4. the attestation EXPIRES — past 180 days (deliberately the same constant as the ledger-wide staleness threshold, so the freshness policy stays decided in one place; what differs per status is the consequence) the gate goes red demanding re-attestation. Expiry is the only mechanical event this repo can generate about a claim it cannot re-measure, so here — and only here — age is a merge gate rather than a worklist.

Re-attestation means a seat WITH access re-reads the enforcer at its current head, repairs the pointer if it moved, re-pins the commit, and stamps verifiedAt with that reading's date. Re-stamping without re-reading is the "trust the prose note" downgrade the ruling forbids, and the gate guidance says so verbatim. If the window closes and no seat with access can be found, the red build IS the escalation: the row returns to the maintainer (needs-user-decision) to rule whether an unverifiable pointer still counts as evidence. The design degrades into that fork rather than into silence — trust is time-boxed, never institutional.

The access face, measured this run (reported either way, per the dispatch order). Probe: add_repo read request for objectstack-ai/cloud from this dev seat, 2026-09-01. Result: denied — "you don't have access to objectstack-ai/cloud" — the same face #11331 records from #10627 (re-measured 2026-08-26 there). Countervailing record: the board verifiably read cloud twice in the last week — #10812 (cloud at 5b5925a, 2026-08-24) and #12400 (cloud at 15f55df, reading of 2026-08-29, controls held: 15 manifest-property reads findable). So the fork condition — cloud genuinely unreachable for verification — is measured NOT to hold: access is seat-dependent, not absent, and CI-side reachability is not load-bearing in this design. Consequence for this delivery: I could not honestly re-read the enforcer from this seat today, so the migrated row's verifiedAt is 2026-08-29 — the date of the #12400 reading it cites — not a fresh stamp of today's date.

What changed

  • packages/spec/scripts/liveness/elsewhere.mts (new) + elsewhere.test.ts (new) — the criteria, pure and injected-clock, plus the two prescriptions (shape repair vs re-attestation).
  • check-liveness.mts — status joins the scanned set and the vocabulary docs; per-row criteria wiring in classify(); two new failure headings plus an always-printed population line (the two-number discipline); the unknown-status guidance now points a DELIBERATE vocabulary change at this precedent while still forbidding typo-widening.
  • readme-table.mts — STATUS_COLUMNS gains live-elsewhere; StateCountsRow, foldStateCounts, renderStateCounts move together (the artifact-shape rule those files document); guidance de-hardcodes the column count.
  • build-state-counts.mts — total sum includes the new column.
  • packages/spec/liveness/manifest.jsonmanifest.runtime migrates: status live-elsewhere, the foreign pointer above as evidence, verifiedAt 2026-08-29, note rewritten to carry both halves' measurement provenance and the re-attestation contract.
  • packages/spec/liveness/state-counts.md — regenerated (new elsewhere column; manifest now live 22 / dead 15 / elsewhere 1).
  • packages/spec/liveness/README.md — vocabulary table rows for dead (sharpened: dead means no consumer anywhere the census looked) and live-elsewhere; a dedicated criteria section; the stale "no cross-repo value covers cloud" paragraph corrected; the manifest Notes cell re-measured (Dead 21 becomes Dead 20, runtime's disposition updated).
  • check-liveness.test.ts — a new seven-case block through the real gate via ledger-root: control green with the population line, four red criteria legs, the malformed-verifiedAt single-heading boundary, and the scanned-set membership leg; existing pins updated for the five-name vocabulary.
  • readme-table.test.ts — column pins updated; fold and render cases for the fifth column.
  • .changeset/liveness-live-elsewhere-verdict.md — patch for @objectstack/spec (the liveness/ dir ships in the package files whitelist).

Clause-2: no — the diff touches no packages/spec/src/** path (verified on the merge-base diff; ledger plus gate tooling only). File face vs the claim comment, declared: the enumerated list named check-liveness.mts, its tests, evidence.mts, manifest.json, README and changeset; the implementation additionally lands elsewhere.mts plus test (new module in the same claimed directory), readme-table.mts plus test and build-state-counts.mts (the STATUS_COLUMNS artifact-shape sites, mechanically unavoidable for a vocabulary widening), and the regenerated state-counts.md. All inside the two directories the claim's serial-constraint line locks; evidence.mts itself needed no change.

Second consumer (read, not edited)

#11331 is not addressed here and remains open. Its enforce leg lives in the same cloud control plane; the evidence shape generalizes with no per-key machinery — should its fork land as enforce-in-cloud, the manifest.integrity row takes the same form: a cloud: pointer at the verifier, cross-repo scope, dated attestation. Note per the #12400 reading, cloud today PERSISTS integrity and verifies nothing, so that card's fork is genuinely open.

Verification (all at head 5db4407 unless noted)

  • pnpm --filter @objectstack/spec run check:liveness — exit 0; judgment lines: "live-elsewhere: 1 entr(ies) carry the verdict (dead here, enforced in a sibling repo), 1 with a foreign pointer, cross-repo scope, and an attestation of at most 180d old." and the green summary now includes "every live-elsewhere verdict points at a named foreign enforcer under an unexpired attestation"; manifest row reads "38 classified (live 22, dead 15, live-elsewhere 1)".
  • Liveness suites: elsewhere/check-liveness/readme-table at 5db4407 — 3 files, 105 tests passed; evidence and verification suites at 6a8c6f2 (byte-identical files across the merge) — with the full-population run below covering all of them at the merged tree. The six red legs of the new criteria block each proved a real exit 1 through the real gate with the expected finding text.
  • Full @objectstack/spec vitest suite at 44bd1a1 (identical liveness tree; the two spec src files main merged in are covered by this run): 447 files passed, 12013 tests passed, exit 0. Population proof: vitest list counts 12013 tests and includes the liveness self-test files.
  • pnpm --filter @objectstack/spec run typecheck at 44bd1a1 — exit 0 (tsc, scripts program, test program); --listFiles shows both new files inside the scripts program (measured, not assumed).
  • Derived gate union (node scripts/pm/dispatch-gates.mjs, derivation line cites this tree at 44bd1a1): 36 gates run, 33 green by their own printed verdicts, including check:changeset-gate-self-tests, check:doc-authoring, spec check:empty-state, spec check:strictness-ledger, spec check:variant-docs, check:merge-driver, check:page-declaration-shape, check:pm-governed-merges, check:published-files, check:slot-lookup, check:test-source-alias, check:type-source-resolution, check:where-matcher, check:nul-bytes. Ratchet families (liveness, empty-state, strictness-ledger) re-ran green at 5db4407 after the final commit.
  • Declared NOT MEASURED locally, per each gate's own printed verdict: check-test-completeness (exit 3, "record this gate as NOT MEASURED ... not a red" — CI grades the real turbo log), check:dual-build-cjs-loads (exit 3, "PREREQUISITE NOT MET — reads built output ... nothing was measured") and check-dev-prereqs (exit 1, stale/absent dist in a fresh worktree) — both prerequisite classes want a full monorepo build this diff cannot affect (zero package src changes; the gate scripts run from source via tsx and are not part of dist), and CI runs both after its own build.

Out-of-scope findings

  • packages/lint lint-liveness-properties.ts describe() deliberately throws on a status it has not been taught; unreachable today (reaching it requires authorWarn true or experimental, and no live-elsewhere row carries either) but reachable the day such a row opts into authorWarn — filed separately with the designed repair.
  • .claude/skills/spec-property-retirement consumes ledger dead verdicts and should name the new status in its discipline (a dead-here-enforced-elsewhere key now reads live-elsewhere and is never a removal input) — filed separately as documentation drift.

Generated by Claude Code


Generated by Claude Code

…ed in a sibling repo (#13483)
A key enforced only in a sibling repo had no honest verdict: dead lies about
the cross-repo consumer, live is refused by the gate (repo-local evidence must
resolve). The new status carries gate-executable criteria (elsewhere.mts):
a foreign-realm evidence pointer, evidenceScope cross-repo, a REQUIRED dated
attestation, and a 180d expiry that fails the build demanding a re-reading of
the foreign enforcer — never a re-stamp. manifest.runtime migrates as the
first row, attested at the #12400 cloud reading (2026-08-29, cloud @15f55df).
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
… generator comment
Part of #13483
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mciyv38maJ6HYVMiaM26T1
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/spec/liveness/README.md, packages/spec/liveness/manifest.json, packages/spec/liveness/state-counts.md) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 128 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ada3834add75f6113c567786b4d1ef7c403c59e2packageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Sep 1, 2026
@os-support-ai
os-support-ai marked this pull request as ready for review September 1, 2026 02:05
@os-support-ai
os-support-ai added this pull request to the merge queueSep 1, 2026
Merged via the queue into main with commit 98c0d33Sep 1, 2026
35 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-13483-liveness-live-elsewhere-verdict branch September 1, 2026 02:43
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/lteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liveness ledger has no verdict for keys enforced only in a sibling repo — dead misreads as deletable (manifest.runtime case)

2 participants

@os-support-ai@claude