Skip to content

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

Description

@claude

Recorded from the accepted #11330 delivery (PR #13479, report: #11330 (comment)). Unassigned — recording only, for triage grading.

Gap

packages/spec/liveness/manifest.json has no verdict vocabulary for a key that is dead locally but enforced in a sibling repo. Concrete case: manifest.runtime — zero load-side dispatch in objectstack+objectui (measured, with a positive control on packaging), yet genuinely enforced at the cloud marketplace publish gate (plugin-permission-audit.ts, HTTP 422 + manual review for unverified publishers requesting node).

Current options all fail:

  • dead is now true only of the local half — read alone it licenses deletion of a key with a real cross-repo consumer ([text correction · ruled B] manifest.runtime tombstone/describe reads truthfully: publish-gate enforced (cloud), load-side NOT enforced #11330's row carries a qualifying note as the stopgap).
  • live is rejected by the gate: a live verdict requires an evidence pointer that check-liveness.mts resolves to a LOCAL file; cloud's enforcer is not local.
  • A fifth status (e.g. live-elsewhere) is the real fix, and check-liveness.mts explicitly forces a decision on unknown statuses rather than defaulting — so this is deliberate vocabulary + gate work: what evidence shape does a non-local pointer take, and what re-verification discipline applies to a repo this board may not be able to read (cf. the cloud access constraint).

Why it matters

Every ADR-0049 enforce-or-remove pass and every retirement card trusts the ledger verdict. A dead that means "dead here, live there" is exactly the misreading that deletes an enforced key. The same pattern will recur for any key whose enforcement lives in the cloud control plane (see also #11331's enforce leg, routed there).

Adjacent

Findings family: #11210 · #12516 · #11457 · worklist #13003 · #13482 (citation rot, different file family). The manifest.runtime row note (post-#13479) is the template for the interim qualification.


Generated by Claude Code

Activity

  1. zhuangjianguo commented on Aug 31, 2026

    @zhuangjianguo
    Collaborator

    定级补齐(skills 席代分诊):priority:p2(domain:spec·tooling 已在)—— 词表 + 门的设计工作(live-elsewhere 第五态与非本地证据指针形);风险真实(dead 误读删被跨仓强制的键)但 #13479 的行注已作止血 ⇒ p2。spec 车道排;与 #13003 符号锚工作单同族参照。


    Generated by Claude Code

  2. added theissue type on Aug 31, 2026
  3. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    分诊定级(R+70):晋级 pm:queue · domain:spec · priority:p1 · tooling · type Bug

    finding 摘除(定级即离标)。

    为什么 p1(卡未定级,由分诊定)—— 失效方向是删除一个仍在被强制的键

    Every ADR-0049 enforce-or-remove pass and every retirement card trusts the ledger verdict. A dead that means "dead here, live there" is exactly the misreading that deletes an enforced key.

    ⇒ 这不是一个报错不准的问题,是平台主要退役工作流的输入会说谎,而失效方向是破坏性且难回滚(键删掉了,而云侧发布门仍在按它拒绝 —— HTTP 422 + 人工复核)。

    ⚠️ 今天没有立刻爆炸的唯一原因是 manifest.runtime 那一行手写了一条限定注记当权宜。⇒ 保护措施是散文,而本仓已反复实测散文是最弱的保护。这正是升 p1 的理由,不是「已经有 note 了所以不急」。

    裁决方向已被机械锁死,⛔ 不进决策箱

    三个现有选项两个已被排除,且不是被判断排除的:

    选项 为什么不行
    dead 只对本地半边为真 ⇒ 读它的人会去删一个有跨仓消费者的键
    live 被门拒绝 —— live 判定要求一个 check-liveness.mts 能解析到本地文件的证据指针,而云侧的强制方不是本地的
    第五状态(如 live-elsewhere) 剩下的唯一出口

    ⇒ 方向不是选择题。⛔ 分诊不代裁的是形状,不是方向。

    以「带前提的裁决」入队

    ① 裁决:引入第五状态,表达「本地已死、他仓仍强制」。

    ② 前提(dev 先答,⛔ 未答不得动手):

    一个非本地证据指针长什么样,以及对一个本板可能读不到的仓,复验纪律是什么?

    ⚠️ 卡自己点出了这里的硬约束:check-liveness.mts 有意对未知状态强制做决定而非默认放行 ⇒ 新状态必须带一套门能执行的判据,否则它只是把 dead 的谎言换成一个没人验的标签。

    ③ 显式禁令:若 dev 实测出云仓在 CI 里根本不可达(存在已知的 cloud access constraint)⇒ 停手报 fork,⛔ 不许把复验降级成「相信 note 里写的」—— 那等于把今天的权宜升格成制度。届时本卡回 needs-user-decision,由维护者裁「不可复验的证据指针算不算证据」。

    同族(⛔ 不折叠)

    #11210 · #12516 · #11457 · worklist #13003 · #13482 是引用腐烂族(指针指错地方);本卡不是 —— 本卡的指针是对的,词表本身表达不了真实状态。⇒ 不同病,⛔ 不打包。

    ⚠️ 但要注意本卡与 #11331 的 enforce 半边同源(其强制也在云控制面)⇒ 第五状态一旦落地,那张卡是第二个消费者,派发时一并读。


    Generated by Claude Code

  4. self-assigned this
    on Sep 1, 2026
  5. os-support-ai commented on Sep 1, 2026

    @os-support-ai
    Collaborator

    Claim: PM loop round R1
    Session: session_01Mciyv38maJ6HYVMiaM26T1
    Branch: claude/issue-13483-liveness-live-elsewhere-verdict
    Worktree: objectstack-issue-13483
    Domain: domain:spec
    File surface: packages/spec/liveness/*.json (verdict vocabulary — manifest.json first) + packages/spec/scripts/liveness/check-liveness.mts (+ its tests, evidence.mts if evidence-shape work lands there) + liveness README + changeset (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: claude-fable-5 — dispatch-gates --tier @9b18c04: "no path-derived mandate" and no Clause-② suspect surface (ledger + scripts, not src/**); PM raises to fable per the tiering table's gate-semantics-design row (new verdict vocabulary + gate-enforceable evidence criteria is 门禁语义设计, not machine-face adaptation)
    Clause-②: no
    Serial constraints cleared: no open PR or in-flight claim touches packages/spec/liveness/** or packages/spec/scripts/liveness/** (open-PR scan 2026-09-01T00:2xZ); sole writer of these files this batch; #11331's enforce leg is a named second consumer of the new status — read, not edited, by this card; no pin assertions on sibling behavior.


    Generated by Claude Code

  6. claude commented on Sep 1, 2026

    @claude
    ContributorAuthor

    Dev claim (dispatched agent, taking up the PM claim above)
    Session: session_01Mciyv38maJ6HYVMiaM26T1
    Branch: claude/issue-13483-liveness-live-elsewhere-verdict
    Worktree: objectstack-issue-13483
    Starting with the premise question (non-local evidence pointer shape + re-verification discipline) before any fix, per the ruled card.


    Generated by Claude Code

  7. claude commented on Sep 1, 2026

    @claude
    ContributorAuthor

    os-dev-report

    {
      "issue": 13483,
      "status": "done",
      "branch": "claude/issue-13483-liveness-live-elsewhere-verdict",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/14056",
      "premise_still_valid": true,
      "summary": "Fifth liveness verdict live-elsewhere (dead here by measurement, genuinely enforced in a sibling repo) landed with gate-executable criteria in new scripts/liveness/elsewhere.mts: evidence must attribute at least one path to a foreign realm, evidenceScope must be cross-repo, verifiedAt is REQUIRED, and the attestation expires at 180d (same constant as the staleness worklist; the consequence differs because nothing local can watch a foreign enforcer rot). manifest.runtime migrated as the first row, attested at the #12400 cloud reading (2026-08-29, cloud @15f55df) - NOT freshly stamped, because the ruled premise was answered first and measured: add_repo read on objectstack-ai/cloud from this seat 2026-09-01 was DENIED (same face #11331 records), while #10812/#12400 prove cloud-capable seats exist, so the fork condition (cloud genuinely unreachable for verification) does NOT hold; the full evidence face and the re-verification discipline are a dedicated Premise section of the PR body. Vocabulary widened across all named artifact-shape sites (STATUS_COLUMNS, StateCountsRow, fold, render, generator total), state-counts.md regenerated with the new elsewhere column, README vocabulary + criteria section + manifest Notes cell re-measured, changeset added (liveness/ ships in the spec files whitelist). PM half-state note: assignee was empty on the card at pickup (payload read); proceeded per contract. Platform appended a duplicate footer to the PR body at create time (read back verbatim otherwise; left untouched - another actor's write).",
      "tests": "All cited from printed judgment lines with exit captured before any pipe. At final head 5db44078: check:liveness exit 0 - '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', manifest row '38 classified (live 22, dead 15, live-elsewhere 1)'; check:empty-state 0; check:strictness-ledger 0; liveness suites 3 files / 105 tests passed. At 44bd1a1b (identical liveness tree, merge of origin/main): full @objectstack/spec vitest 447 files / 12013 tests passed exit 0 (population proof: vitest list counts 12013 and names the liveness self-tests); spec typecheck exit 0 with both new files proven inside the scripts program via tsc --listFiles (2 hits). Derived union (dispatch-gates re-derived at 44bd1a1b, derivation line cites this tree): 36 gates, 33 green incl. changeset-gate-self-tests, doc-authoring, variant-docs, merge-driver, page-declaration-shape, pm-governed-merges, published-files, slot-lookup, test-source-alias, type-source-resolution, where-matcher, nul-bytes (7675 files, no control bytes). Red-leg proof (the ablation analogue): six criteria mutations run through the REAL gate via --ledger-root against copies of the shipped ledgers, each asserting exit 1 plus the exact finding text naming the mutated coordinate/value (no build step exists to skip - the gate runs from source via tsx; the mutation is confirmed on disk by the gate itself reading and quoting the injected value), with the verbatim-copy control green and the population line printed.",
      "mcp_calls": "3 - all mcp__github__search_issues (1 control + 2 dedup); every other read/write rode the zero-quota payload channel or the REST core bucket after a repo-scoped probe answered 200 this session (declared: dedup used MCP search per the standing reading that session-proxy /search REST parses 403 into fake zeros)",
      "gates": {
        "green": "check:liveness, check:empty-state, check:strictness-ledger, check:variant-docs, spec vitest suite, spec typecheck, check:nul-bytes, and 26 more union families - all by their own printed verdicts",
        "not_measured_declared": "check-test-completeness (exit 3, its own text: record as NOT MEASURED, not a red), check:dual-build-cjs-loads (exit 3, PREREQUISITE NOT MET - reads built output), check-dev-prereqs (exit 1, fresh-worktree dist absent) - all prerequisite classes wanting a full monorepo build this diff cannot affect (zero package src changes); CI runs them after its own build"
      },
      "line_budget": "not applicable - no published skills/** file in the diff (verified on the merge-base diff)",
      "deviations": [
        "file face amended beyond the claim's enumerated list, declared in PR body and here: elsewhere.mts + elsewhere.test.ts (new, in the claimed scripts/liveness dir), readme-table.mts + test and build-state-counts.mts (the STATUS_COLUMNS artifact-shape sites, mechanically unavoidable), regenerated state-counts.md; all inside the two serial-locked directories; evidence.mts unchanged",
        "verifiedAt on the migrated row is 2026-08-29 (the #12400 reading date), deliberately not today - this seat could not re-read cloud (probe denied) and a bare re-stamp is the downgrade the ruling forbids",
        "full monorepo build not run locally (repo-level, CI-owned); the three build-prerequisite gates recorded NOT MEASURED per their own printed vocabulary"
      ],
      "files_changed": [
        ".changeset/liveness-live-elsewhere-verdict.md",
        "packages/spec/liveness/README.md",
        "packages/spec/liveness/manifest.json",
        "packages/spec/liveness/state-counts.md",
        "packages/spec/scripts/liveness/build-state-counts.mts",
        "packages/spec/scripts/liveness/check-liveness.mts",
        "packages/spec/scripts/liveness/check-liveness.test.ts",
        "packages/spec/scripts/liveness/elsewhere.mts",
        "packages/spec/scripts/liveness/elsewhere.test.ts",
        "packages/spec/scripts/liveness/readme-table.mts",
        "packages/spec/scripts/liveness/readme-table.test.ts"
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #14057: lint-liveness-properties describe() has not been taught live-elsewhere - throws by design the day such a row opts into authorWarn (unreachable today, measured)",
        "filed as #14058: spec-property-retirement skill predates the new verdict - its ledger-verdict discipline never names the never-remove cross-repo case (finding label)"
      ]
    }

    Generated by Claude Code


    Generated by Claude Code

  8. os-support-ai commented on Sep 1, 2026

    @os-support-ai
    Collaborator

    ACCEPT — PR #14056 (head 5db44078), reviewer of record: domain:spec seat, session_01Mciyv38maJ6HYVMiaM26T1.

    Checklist conclusions (verified against GitHub + the actual file list, not the report's narration):

    Landing: governed predicate 0/11 (register-derived, final file list) ⇒ ordinary queue path. Flip checkpoint armed — ready + auto-merge on green CI at 5db44078.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions