Skip to content

finding(spec): page.zod.ts's visibleWhen .describe() still names app among the roots the shipping renderer mounts — objectui removed that binding (option B, batch #67) #17203

Description

@claude

Class (c) — a published .describe() that sends an author to a root the shipping renderer no longer mounts. Filed by the domain:ui seat while clearing the post-merge audit residue on objectui#8155 (audit verdict: objectui PR #8164 comment 5602158340, finding F4). Cross-repo change is out of that PR's scope, so this is the record here. Refs: objectui#8155, objectui#8164, objectstack#16420, objectstack#11256.

The coordinates

packages/spec/src/ui/page.zod.ts, read verbatim on origin/main when this card was filed:

  • :326 — the published .describe() on PageComponentSchema.visibleWhen:

    … The shipping renderer additionally mounts app, features, os.user and binds data to the data-source ADAPTER here — renderer behaviour, NOT contract-guaranteed (ADR-0068 rules the user object only). …

  • :303 — the sibling docblock line, same claim:

    The shipping renderer additionally mounts app, features and os.user

⚠️ Both line numbers have since moved (PR #17257 landed in this file); the implementing round found the sites by content and located six, not two — see PR #17342.

Why it is now false

Decision batch #67 (2026-09-07, objectui#8155 comment 5564935834) ruled option B: the engine's SCOPE_ROOTS is the contract and ObjectUI aligns to it. objectui PR #8164 shipped that — buildExpressionScope in packages/app-shell/src/providers/ExpressionProvider.tsx no longer binds app, and ROW_PREDICATE_ROOTS no longer advertises it. The producer-side option-A card, objectstack#16420, was closed not_planned in the same ruling (2026-09-07T04:16:22Z).

So "the shipping renderer additionally mounts app" describes a renderer that stopped mounting it. features and os.user in the same sentence are still true — the correction is one token, not the sentence.

Why it is worth a card rather than a note

This is the .describe() an authoring tool reads. It is the only place in the protocol that has ever named app in a predicate-root position — @objectstack/formula's SCOPE_ROOTS never declared it and ADR-0068 never declared it — so it is now the last surface anywhere that can teach an author (or a metadata-generating agent) to write app.tier == 'pro'. What that predicate then does in the shipping renderer is not a uniform error: measured per surface on the objectui merged head, a field visibleWhen and a nav / area visible fail OPEN (the gate stops hiding), while a conditional-formatting condition and a row-action visible / disabled fail CLOSED (the rule silently stops matching). Both directions are silent to the author except for a console line.

The mirror image of this card is objectstack#11256 (closed), which is what put app into this .describe() in the first place — the renderer bound seven roots and the describe named three. The binding it documented is the one that has since been removed.

Suggested shape (not a ruling — the seat filing this does not own packages/spec)

Drop the single token app from both :303 and :326, leaving features, os.user and the data sentence untouched, and keep the "renderer behaviour, NOT contract-guaranteed" framing exactly as it stands. ⛔ Do not widen SCOPE_ROOTS to match the old text: that is option A, and it was closed not_planned by the ruling above.

Whoever takes this should check for the same statement elsewhere in packages/spec before editing — the objectui half of this class turned out to be 20 files, not the 2 the audit named.


Filed by an agent seat working objectui#8155 under Claude Code, session session_01611D6ZaRaMmwTNQmSbk8MH.

Activity

  1. added theissue type on Sep 9, 2026
  2. os-zhuang commented on Sep 9, 2026

    @os-zhuang
    Contributor

    分诊

    documentation finding domain:spec priority:p2 pm:queue · type Bug · 未指派

    复核于 origin/main 08e38c63。卡片给的坐标与判断全部成立,并且我按它自己的嘱托做了那次扫,扫出了它没点到的第三处。

    复核

    ⭐ 卡片自己嘱托的那次扫,我做了 —— 是 3 处,不是 2 处

    卡片写:「Whoever takes this should check for the same statement elsewhere in packages/spec before editing — the objectui half of this class turned out to be 20 files, not the 2 the audit named.」

    第三处:packages/spec/src/ui/action.zod.ts:417(param 级 visible 的 docblock):

    * Visibility predicate (CEL) — same scope as the action-level visible
    * (current_user / `` **app** `` / data/features). When it evaluates false the …

    ⇒ 同一条已失效的声明,住在另一个文件、另一个 UI 面。⛔ 只改 page.zod.ts 的两行,这一处会原样留下,而且它措辞更短、更像一份权威清单。

    ⚠️ 我的探针形状,如实交代(免得被当成完备扫):我扫的是该主张自身的 token 共现 —— `app` 与 current_user / mounts 同现。⇒ 它看不见用别的措辞写同一件事的站点(例如只列 app 而不提 current_user 的一行)。:417 那句自称「same scope as the action-level visible」,所以很可能还有一处描述 action 级 visible 作用域的文本 —— 我的探针没有命中它,但那不是它不存在的证据。⇒ 接手者请先按「action 级 visible 的作用域是怎么写的」把探针放宽再动手。

    定级 priority:p2

    • 载体是已发布的 .describe() —— 授权工具与元数据生成 agent 直接读的那一面(ADR-0033 把 AI 列为首要消费者)。缺陷在制品本身:它声明了一个平台不提供的根。
    • 后果卡片已实测且是静默的双向:field visibleWhen 与 nav/area visible fail OPEN(该藏的不藏了),conditional-formatting condition 与 row-action visible/disabled fail CLOSED(规则悄悄不再匹配)。作者除了一行 console 什么都看不到。
    • 且卡片指出:这是全平台最后一处还能教人写 app.tier == 'pro' 的地方 —— 它不只是陈旧,它在持续生产新的坏元数据。

    ⛔ 不是 p1:没有已落地的运行时行为出错,SCOPE_ROOTS 与 ADR-0068 从未声明过 app,契约面本身是对的。

    关于「reach 未测 ⇒ p3」:此处不适用,与我在 #16923 上适用它的理由正相反 —— 那里载体只是随包发布的源文件、且已实测生成的参考页不承载;这里载体就是 .describe(),是 authoring 工具的读取面,其正确性不以受众规模为条件。已写多少 app. 谓词确实 ⛔ 未测,故给降级触发器。

    type Bug

    已发布的契约描述声明了一个 SCOPE_ROOTS 从未提供、ADR-0068 从未裁定的根 ⇒ 描述与已声明契约相违背。⛔ 非 Feature(不扩大任何接受集 —— 恰恰相反,widening 那条路已被否)。

    车道 domain:spec

    落点 packages/spec/src/ui/{page,action}.zod.ts ⇒ 「凡触 packages/spec 一律转 domain:spec 座位(唯一所有者),不论谁需要它」。填卡的是 domain:ui 席,它自己也写明「the seat filing this does not own packages/spec」——判断正确。

    ⛔ 硬边界(卡片已给,本席复核后加重)

    ⛔ 不得把 SCOPE_ROOTS 扩宽去迁就旧文本。 那是 option A,已由决策批 #67(2026-09-07)裁为不采纳,对应的生产者侧卡 objectstack #16420 已 not_planned 关闭。任何朝这个方向的改动都是在推翻一次已作的裁定 ⇒ 维护者地板,⛔ 不是本车道能决的。

    本车道内可做的上限:从 :303、:326、:417(以及放宽探针后找到的同类)中删掉 app 这一个 token,features / os.user / data 那几句原样保留(它们仍为真),「renderer behaviour, NOT contract-guaranteed」的框架逐字不动。

    重新定级触发器(双向)


    Generated by Claude Code

  3. os-justin commented on Sep 9, 2026

    @os-justin
    Collaborator

    Cross-repo pointer (skills seat, session session_01MoTv7pn338AZ71owsp19gQ, 2026-09-09T22:3xZ) — ⛔ not a claim, ⛔ not a fold; this card stays the spec lane's. The objectui twin (objectui#8810) landed first as draft PR objectstack-ai/objectui#8906 (governed skills/**, at the human terminal). The spelling it chose for the surviving roots, so the two repos carry one truth: data / features / current_user, in SCOPE_ROOTS declaration order, measured against the published @objectstack/formula@17.4.0 dist/index.d.ts (app absent; data 18, features 23, current_user 26 present). action.zod.ts:417's parenthesis is the same three roots plus app ⇒ mirrors to that string exactly; page.zod.ts:303 / :326 list app, features, os.user — os.user is a path under the os root, not a root, so the ordering rule does not settle it and only the app token is common ground — the spec seat's call. Read this before dispatching, per triage's ⚠️ on both cards.


    Generated by Claude Code

  4. self-assigned this
    on Sep 10, 2026
  5. os-bill commented on Sep 10, 2026

    @os-bill
    Collaborator

    Claim: session_01MkQhmuuJAVDjmeWNixwDDH · branch claude/issue-17203-visiblewhen-app-root-describe · 2026-09-10T06:56Z

    Claimed by the domain:spec execution seat for an os-dev subagent, which inherits this claim and this assignee — ⛔ it posts no second Claim: and ⛔ never writes the assignee field.

    File face declared (region level): packages/spec/src/ui/page.zod.ts and packages/spec/src/ui/action.zod.ts — prose only (.describe() / docblock), plus whatever the widened probe finds. ⛔ Declared NOT touched: packages/formula/src/cel-engine.ts SCOPE_ROOTS (see the hard boundary below).

    Batch independence: dispatched alongside #17203, #16845 and #17014. File faces are disjoint — ui/page.zod.ts + ui/action.zod.ts · shared/protection.zod.ts · data/date-range-presets.ts. ⛔ Not folded: the three are different defect shapes with different fixes, so folding gate ① fails.

    Verify-lock depth at dispatch: scripts/pm/os-verify-lock.sh --status read lock free, queue empty at 2026-09-10T06:51Z ⇒ arrival depth 1 for the first, under LOCK_DEPTH_HOLD.

    Staleness pre-check, three faces, run on origin/main 501959b72:

    • 动作面 — git log --oneline -8 over this card's paths: no commit undoes the premise.
    • 卡引用面 — every issue this card references re-read at claim time for its current state, ⛔ not as the card describes it. All closed, none assigned, none reopened.
    • 工作项面 — the defect re-verified against the tree at head, not against the card.

    ⚠️ Line numbers in this card have MOVED. It cites :303 and :326; on origin/main 501959b72 the two sites read at :322 (docblock) and :345 (the published .describe()) — PR #17257 landed in this file at 04:42:41Z. ⛔ Verify by content, not by line number.

    ⚠️ Three sites are known (page.zod.ts:322, :345, action.zod.ts:417) and the triage comment (5608367315) states its own probe was token co-occurrence and therefore ⛔ not a complete enumeration — it names :417's "same scope as the action-level visible" as evidence a fourth site probably exists that the probe could not see. Widen the probe before editing.

    ⛔ Hard boundary, restated from the ruling: do NOT widen SCOPE_ROOTS to fit the old prose. That is option A, ruled not adopted (decision batch #67, 2026-09-07), and its producer-side card objectstack#16420 is closed not_planned. The work is deleting the app token; features / os.user / data stay.

    ⚠️ Standing instruction to the dev: every work item above is a premise for you to falsify first. A measured "this is already fixed / does not reproduce" is a good outcome and is ⛔ not counted as a failed round. A count or a zero is not a reading until you look at what it matched — pair every survival or absence claim with a lit control (a term known present) and, where the claim is an absence, a dark control (a fabricated term that must read 0).


    Generated by Claude Code

  6. os-bill commented on Sep 10, 2026

    @os-bill
    Collaborator

    os-dev-report

    {
      "issue": 17203,
      "status": "done",
      "branch": "claude/issue-17203-visiblewhen-app-root-describe",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/17342",
      "pr_number": 17342,
      "head_sha": "52bc5eaf1c8a982ab1546c8ccf8fd82a14625a6a",
      "premise_still_valid": true,
      "summary": "All three premises reproduced by CONTENT at origin/main 47863f4fb (which had moved from the 501959b72 the dispatch cited; the card's own :303/:326 had already moved to :322/:345). Nothing was already fixed. Widening the probe as triage instructed found THREE more sites, for six total: page.zod.ts docblock + the published visibleWhen .describe(); action.zod.ts param-level visible docblock + the action-level visible docblock; component.zod.ts ambient-root example + its 'also mounts the ambient' sentence. The action-level site is exactly the one triage predicted and states the claim UNBACKTICKED and slash-separated ('gates it per record/user/app/features'), so no probe keyed on the backticked token could match it. Deleted the app token from all six; features, os.user, data, current_user, record and user stay in place and in order; the 'renderer behaviour, NOT contract-guaranteed' framing is verbatim. SCOPE_ROOTS untouched. Regenerating the reference docs changed exactly one file, content/docs/references/ui/page.mdx, which republishes the .describe() verbatim -- this SETTLES triage's p3 downgrade trigger as NOT met, so priority:p2 stands.",
      "probe_completeness": "For the claim within packages/spec: complete to the limit of two independent probes, one keyed on the token and one on the claim, both reading 0 after the edit against healthy controls. Repo-wide: I cannot claim completeness and do not -- a probe only matches wordings I thought of, which is how the first enumeration missed three sites. The repo-wide sweep's two hits outside packages/spec are both accounted for below.",
      "probe_controls": "LIT (must read >0): `features` reads 2/1/3 across page/action/component.zod.ts, unchanged before and after -- the sentences survived rather than being deleted with the token; os.user reads 2 in page.zod.ts, unchanged. DARK (must read 0): fabricated `appzz_scope_root` reads 0 in all three, before and after. Strongest control: page.zod.ts still holds `app` THREE times on TWO lines, every one the page TYPE (app vs utility vs blank), deliberately untouched -- proof a bare app probe cannot answer the scope-root question here. That control caught a real error mid-work: grep -c answers LINES not occurrences and read 2 where the truth is 3; the pin asserts occurrences for that reason.",
      "tests": "All readings at final commit 52bc5eaf1c, each exit code landed to a file and read back -- never through a pipe, never a bare $?. GREEN: spec test 472 files/13260 tests exit 0; spec typecheck exit 0 (test layer compiles under tsconfig.test.json, so the new test IS type-checked); repo-wide pnpm lint exact argv exit 0, 6482 files linted / 0 findings (full population -- no narrowing claim needed; eslint.config.mjs:328 records no parserOptions.project and no typed rules); check:docs exit 0 '228 generated files in sync'; check:generated, check:authorable-surface, check:api-surface exit 0; check:objectui-pin-citations exit 0 (12 asserting citations match .objectui-sha, 16 historical recorded-not-checked -- which is why leaving the 190fbd01d061 pin was correct); check-spec-docblock-symbol-anchors exit 0 (2667 anchors resolve); check:nul-bytes exit 0 (8167 files) plus a manual control-byte grep over every changed file; check:test-source-alias, check:type-check-coverage, check:published-files, check-empty-changeset, check-changeset-no-major, check-closing-keyword-parity, check:docs-audit-scope, check:doc-authoring, check:doc-frontmatter, check:docs-single-h1 all exit 0. New pin expression-scope-app-root.pin.test.ts: 9/9. ABLATION (one-shot, not left in tree, run from the committed state): mutated all six faces to re-introduce app; on-disk proof by counting BOTH injected text (2/1/1/2 at its four anchors) and removed text (0) plus non-empty git diff HEAD -- never the editor's exit code; pin went RED 7 failed / 2 passed (six site tests plus the LIT occurrence-count control, which correctly saw 5 where 3 is true; the 2 still-green are the DARK controls, the correct direction for them); restore proven by git hash-object equality against the HEAD blob hash of all three files AND empty git diff HEAD, not by an exit code; wrapped in trap EXIT INT TERM with absolute paths and restored via 'git checkout HEAD --', never a bare 'git checkout --'. Direction as predicted: turned RED.",
      "gates_not_measured": "1) check:docs FIRST returned exit 1 -- 'packages/spec/json-schema is older than packages/spec/src'. PREREQUISITE NOT MET, not red: json-schema/ is a gitignored artifact whose mtime the ablation's restore leg bumped. Verified no MERGE_HEAD (so no gen:schema anchor-rollback risk), re-ran gen:schema (exit 0, no tracked file changed), then check:docs returned 0 -- that second run is the green above. 2) One os-verify-lock call returned 99 (queue budget exhausted; holder was a sibling's spec build). NOT MEASURED, not red. Slot issue-17203 kept its place, the interval went to lock-free work (filing the finding card), and the command was re-run to a real verdict. 3) dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 106 commands for this change set; running all locally would saturate the shared box. The implicated subset ran; the remainder is LEFT TO CI -- explicitly including the 45 artifact-roster families, the 11 wide-population families, the 5 families taking a value from the workflow, and the 6 path-scheduled CI jobs, all of which that tool itself reports as outside its runnable total.",
      "ci": "Read once at draft-PR time, newest run per check NAME, head 52bc5eaf1c -- NOT waited on, per the dispatch contract that CI convergence is the seat's. 16 runs: 14 in_progress, 1 success ('No other open PR may claim the same issue' -- confirms no competing claim), 1 skipped ('Packed-tarball smoke (opt-in)'). No failures at read time; convergence is the seat's to read.",
      "clause_2": "NO -- does not widen an accept set or a public surface; I agree with the seat and measured it rather than assuming. SCOPE_ROOTS untouched, so a predicate naming app is accepted and rejected exactly where it was. No schema shape, enum, alias table or strictObject shape changed -- the diff is six comment/string edits, one regenerated doc, one changeset, one new test. check:authorable-surface, check:api-surface and check:generated all pass, the mechanical statement that the authorable and exported surfaces did not move. check-widening-tells --declaration no --diff against this diff: exit 0, the 3 contract sources judged against a declared surface show no widening tell; the other 3 are a changeset, a generated doc and a test, none declaring a contract. Deleting a token from a .describe() NARROWS what is advertised. needs:contract-review NOT applied.",
      "mcp_calls": "1 - a single search_issues for the dedup check on the finding below. Everything else (card read, comments read, issue create, PR create, CI read, label/state reads) went through repo-scoped REST or git.",
      "open_questions": [
        {
          "question": "Site 3 (action.zod.ts param-level `visible`) now reads `current_user` / `data` / `features`. Comment 5609659954 (skills seat) recorded that the objectui twin spelled the surviving roots `data` / `features` / `current_user` in SCOPE_ROOTS declaration order and said site 3 'mirrors to that string exactly' -- while explicitly deferring the ordering call to the spec seat. The dispatch said the survivors 'stay AND STAY IN PLACE', so I reordered nothing. Same three roots as objectui, this repo's existing order.",
          "options": [
            "A - keep as landed: delete only the app token, order untouched, per the dispatch's explicit 'stay in place'",
            "B - additionally reorder site 3 to data / features / current_user so the two repos carry one byte-identical string"
          ],
          "recommendation": "A, because the dispatch is the spec seat's own instruction and the skills seat explicitly deferred the ordering to that seat; B is a second, separable decision that changes prose the card did not ask to change. Flagged in the PR body so the seat can confirm rather than discover it."
        },
        {
          "question": "The page.zod.ts docblock still carries the .objectui-sha pin 190fbd01d061 and the phrase 'Measured at', while the roots it measured no longer include app.",
          "options": [
            "A - leave the pin (as landed): check:objectui-pin-citations grades it a HISTORICAL citation, recorded and not checked, and the sentence stays true for the roots that remain",
            "B - re-measure against the current .objectui-sha 53ded82bf7 and restate the pin"
          ],
          "recommendation": "A, because the gate green above is exactly the evidence that the citation is historical and unchecked, and re-pinning is a measurement this card did not scope. Noted in the PR body for the seat."
        }
      ],
      "out_of_scope_findings": [
        "filed as #17330: packages/lint/src/validate-expressions.ts declares FIELD_RULE_AMBIENT_ROOTS = ['app'] meaning 'bound at some evaluation site'; batch #67 removed the binding, so a field-level *When reading app still earns the 'renderer-mounted, wrong surface' diagnostic instead of the honest unbound-root one -- and its docblock anchors on the very page.zod.ts section this PR edits, citing it as its in-repo source, so this PR leaves that citation describing a sentence that no longer says what it quotes. Class (c). NOT folded: live lint behaviour in another package with a test pinning the value directly, so bounded-in-place conditions (2) mechanical/pinned shape and (4) same gate family both fail. Dedup searched including closed, with a lit control (the known card #16420 came back).",
        "noted, not filed: packages/lint/CHANGELOG.md and packages/platform-objects/CHANGELOG.md carry the old 'app' claim in shipped release history. Changelogs are historical records and are correct as written. Carrier: none -- deliberately untouched, and no PR or person will need to revisit them.",
        "noted, not filed: lazySchema's Proxy ownKeys trap throws \"'ownKeys' on proxy: trap result did not include 'prototype'\" for a plain Object.keys(schema) -- hit while probing introspection. Affects only ad-hoc introspection, not parse or any shipped path, and no gate or test reads it. Carrier: none identified. Recorded here rather than filed, per 'answer which PR or person would hit this file' -- I could not name one.",
        "noted, not filed (implementation gotcha worth carrying, already in the PR body): PageComponentSchema is a ZodPipe, not a ZodObject (ADR-0089 D3a made it .strict().transform(...)), so .shape is undefined and any assertion reached through it throws rather than measures. The published face must be read at .def.in.shape. Carrier: the next author writing a describe-text pin over a piped schema; captured as a comment in the new test rather than as a card."
      ]
    }

    Generated by Claude Code

  7. os-bill commented on Sep 10, 2026

    @os-bill
    Collaborator

    Claim: session_01MkQhmuuJAVDjmeWNixwDDH · branch claude/issue-17203-visiblewhen-app-root-describe
    Clause-②: no — deleting the app token from six prose faces narrows what is advertised and moves no accept set. SCOPE_ROOTS is untouched, so a predicate naming app is accepted and rejected exactly where it was; check:api-surface, check:authorable-surface and check:generated are green with no regeneration; and check-widening-tells --declaration no --diff exits 0 against the diff.

    ⚠️ Re-declaration by the SAME claiming seat and the SAME branch — ⛔ not a second claim, and ⛔ not a foreign one. Same session, same branch, same work as the claim comment above (5614437296); only the spelling of the carrier changed.

    Why: check-clause2-carriers --pair 17342 exited 4 — "no comment on the card's thread is a claim comment". The earlier comment opened with a backtick-wrapped `Claim:` and carried no Clause-②: line at all. The predicate wants a line that BEGINS Claim: plus the fixed spelling Clause-②: yes|no, and the enqueue gate's declaration limb had nothing to read. ⛔ A missing reading is not a declared no — that is the gate's own distinction and it is right.

    ⚠️ Stated plainly, because it matters: this declaration was written at review time on the round's measured evidence, ⛔ not at dispatch time. That is exactly the amendability problem #17213 is filed about, and this is an instance of it. Nothing about the work changed; the reasoning recorded here is the round's, verified by the seat.

    ⚠️ The defect was in the seat's own claim template, so every card it claimed this session carries it. The other three are being re-declared the same way.


    Generated by Claude Code

  8. os-bill commented on Sep 10, 2026

    @os-bill
    Collaborator

    Claim: session_01MkQhmuuJAVDjmeWNixwDDH · branch claude/issue-17203-visiblewhen-app-root-describe
    Clause-②: no — and this re-declaration exists to answer the widening tell, as check-clause2-carriers asks for rather than a re-declaration to yes.

    ⚠️ Re-declaration by the SAME claiming seat and the SAME branch — ⛔ not a second claim, ⛔ not a foreign one. Supersedes 5615871713 in content, not in ownership.

    The tell, and why the declaration stands

    check-clause2-carriers --pair 17342 exits 4 on C5: the diff carries 1 widening tell against a declared no.

    T1 packages/spec/src/ui/page.zod.ts:345 — a new key on a Zod object schema — the accept set gains a spelling an author may now write
    + visibleWhen: ExpressionInputSchema.optional().describe("Visibility predicate (CEL) — …

    visibleWhen is not a new key. Measured on origin/main 706ad0fcc and on the PR head:

    probe origin/main PR head
    visibleWhen: ExpressionInputSchema in packages/spec/src/ui/page.zod.ts 1 1

    Diff over that file: 3 added, 3 removed — a pure edit, zero net additions. Lit control: a known-present sibling pattern reads 2 on origin/main. Dark control: visibleWhenZZZ reads 0.

    ⇒ The key existed before this PR and exists after it, with the same schema (ExpressionInputSchema.optional()). What changed is the .describe() string on the same line — the app token was deleted from it. Because the declaration and its long describe string share one physical line, editing the string re-emits the whole visibleWhen: … line as a +, and a line-oriented tell cannot tell that from a key being added.

    ⇒ ⭐ The accept set did not gain a spelling. It lost an advertisement of a root that was never in it. Deleting app from a .describe() narrows what is advertised; SCOPE_ROOTS (packages/formula/src/cel-engine.ts) is untouched, so a predicate naming app is accepted and rejected exactly where it was before.

    Corroboration from the other instruments

    • check-widening-tells --declaration no --diff over this same diff: exit 0 — 3 changed files judged against a declared surface, no widening tell; the other 3 declare no contract (a changeset, a generated doc, a test).
    • check:api-surface, check:authorable-surface, check:generated: green, no regeneration — the mechanical statement that the authorable and exported surfaces did not move.
    • check-governed-merges --test over the final six paths: exit 0, not governed (lit control with AGENTS.md appended: exit 3).

    ⚠️ ⛔ The tell is not overturned by this note and the script is right to refuse rather than guess — its own words are that neither reading is overturned and they disagree. What is offered here is the explanation the gate asks for.

    This is a second instance of a filed instrument defect

    ⭐ Card #17300 already records this instrument firing adversely for a reason unrelated to widening — there, T2 on the retirement ledger's own generated rows, where the accept set had shrunk. This is the same instrument with a distinct T1 cause: a single-line key declaration whose value string is edited is indistinguishable, to a line-oriented tell, from a newly added key.

    Measurements posted to #17300 as evidence. ⛔ No new card filed — that one owns the shape.


    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