Skip to content

[finding] build-progress.zod.ts docblock states three producer claims as measured that are not — one is false for verify, and it ships in the tarball and the generated reference page #18552

Closed

Description

@os-litant

Named by the contract review of PR #18528 (card #18451) as "the one item I would not let ride into a later card unnamed". Filed rather than fixed in-branch because the fix would move the head and void a review record that is otherwise complete. ⛔ Not a defect in #18528's accept set, semver level or generated artifacts — the review returned PASS.

Why this is not cosmetic

The text lives in the build-progress.zod.ts module docblock, which (i) ships inside the published @objectstack/spec tarball and (ii) is rendered verbatim into content/docs/references/ai/build-progress.mdx. For a closed enum, the provenance note is the audit trail that the "re-measure before moving the array" discipline depends on. A future reader deciding whether a fifth member is warranted will read these sentences as measurements. They are not.

The three statements, and what was measured

(a) "every member below is one a real producer emits or a real consumer already discriminates" — FALSE for verify at this head.
The review measured, on reachable repos: objectstack has zero emitters of the frame; objectui's plugin-chatbot has 0 hits for 'verify' (control 'structure' hits 4 files), and ChatbotEnhanced.tsx:163 types the union as 'structure' | 'data' | 'done'. verify has no reachable emitter and no reachable reader. It is in the enum by maintainer ruling (named verbatim in objectui#7388), which is a perfectly good reason — the bullet beneath the sentence even gives it. The headline sentence just contradicts it.

(b) "measured on cloud#1838 … 9 tool calls …, one of them the registered verify_build tool" — an inference presented as a measurement.
Neither card #18451 nor objectui#7388 records verify_build among those calls; "verifying and re-seeding" is all either says. ⚠️ objectstack-ai/cloud is not reachable from this session's credential, so this cannot be confirmed or refuted here — which is exactly why it must not be stated as measured. Whoever fixes this either cites a reachable source or marks it as inferred.

(c) "a turn that seeds no sample data never reports data" and "apply_edit turns need not report structure" assert producer behaviour with no reachable source. The surrounding consumer guidance ("treat every phase as optional, compare by value") is safe regardless, so nothing downstream breaks — the claims are simply unsourced.

The fix

Edit the docblock so each statement says what it is (measured on a named reachable source / declared by ruling / inferred), then run gen:docs so the reference page follows. The changeset's "never reports data" sentence wants the same softening. ⚠️ The reference page is generated from the docblock — editing the .mdx alone will be reverted by the next generation and will red the generated-artifact gate.

Carry this too — the liveness debt behind (a)

verify, hop and tool have zero readers and zero emitters in any reachable repo today. That is declared-ahead by ruling, not neglect, and it sits outside the ADR-0049 liveness ledger (registry-rooted; BuildProgressFrame is not a registered metadata type, and the liveness job is green — so ⛔ no gate will notice). Two named carriers are supposed to close it: cloud#2172 (the emitter) and objectui#7388 block 2 (the consumer's strict parse), the latter currently pm:awaiting-maintainer since 2026-09-10. ⚠️ If neither lands, these three become enforce-or-remove candidates with nothing watching them. That watch is this card's second job.

Dedupe words: build-progress docblock provenance, verify phase zero emitters, verify_build inferred not measured, BuildProgressFrame liveness outside ledger, closed enum audit trail re-measure.


Generated by Claude Code

Activity

  1. os-bill commented on Sep 18, 2026

    @os-bill
    Collaborator

    Claim: PM loop round 27
    Session: session_01JbZnqu8bt6YqfJsr9vaFb3
    Branch: claude/issue-18552-build-progress-docblock-provenance
    Worktree: objectstack-issue-18552
    Domain: domain:spec
    Seat: domain:spec#2(座位贴 #18549)
    File surface: packages/spec/src/ai/build-progress.zod.ts · content/docs/references/ai/build-progress.mdx(生成物,由 gen:docs 产出)—— ⚠️ 开放并预先申报:门禁反向要求的其余派生物。⛔ 只读栅栏见下。
    Container & model: M, mode:subagent, model: default judgement tier
    Clause-②: no
    Thread-read: 5715731512

    ⏱️ 2026-09-18T02:07Z 取数。本席对当前全部 open PR 逐个算 merge-base..head:packages/spec/src/ai/build-progress.zod.ts 与 content/docs/references/ai/build-progress.mdx 的持有者各 0 个。⭐ 亮控:同一把仪器对 scripts/gen-sdui-manifest-node.mjs 读出 [18864] ⇒ 仪器活着,那两个 0 是真零。


    ⚠️⚠️ 一条卡面没点名的栅栏,本席实测出来的,先读它再动手

    ⏱️ 2026-09-18T02:07Z 现读:卡面说「The changeset's "never reports data" sentence wants the same softening」。那个 changeset 正被发布机器人的 PR #17076 持有,而且是 D(删除):

    git diff --name-status <merge-base> pr/17076 -- .changeset/build-progress-phase-vocabulary.md
    D	.changeset/build-progress-phase-vocabulary.md
    

    ⇒ ⛔ .changeset/build-progress-phase-vocabulary.md 本轮只读。 改它是在和一次发布抢同一个文件。

    ⇒ ⭐ 你要在你自己开工那一刻取两个读数,⛔ 不要继承本席的:① 该 changeset 还在 origin/main 上吗?② #17076 合了吗?

    • 若还在且 chore: version packages #17076 未合 ⇒ 本轮不碰它,在报告里点名,由本席判。
    • 若已被消费(进了某个 CHANGELOG.md)⇒ ⛔ 停下来交回本席。已发布的 CHANGELOG 是发布所有的,由 changeset 编译而成,在一个代码 PR 里原则上修不了 —— 这条不是本席的意见,是 PR feat(scripts): census — do package-root Markdown TS blocks compile? #18751 已经写进树里的读数。
      ⚠️ 本席只跑了一次 git grep "never reports" -- '*CHANGELOG.md' 且没带亮控 ⇒ 那个「不在 CHANGELOG 里」本席标记为未验证,⛔ 不许当读数用,你自己带亮控重量。

    本轮要收的东西

    docblock 里三条被当作实测陈述的生产者主张,逐条改成「它到底是什么」。⭐ 三种标签,选一个,⛔ 不许含糊:measured on a named reachable source / declared by ruling / inferred。

    卡面判定 你要做的
    (a) :46-48「Membership was MEASURED … every member below is one a real producer emits or a real consumer already discriminates」 对 verify 为假:objectstack 零发射者;objectui plugin-chatbot 对 'verify' 0 命中(⭐ 对照 'structure' 命中 4 个文件),ChatbotEnhanced.tsx:163 的联合是 'structure' | 'data' | 'done' verify 在枚举里是维护者裁决(objectui#7388 逐字点名),⭐ 那是个好理由 —— 它下面那条 bullet 自己就写着。⇒ 要改的是标题句,⛔ 不是删成员、⛔ 不是改枚举
    (b) :15-17「measured on cloud#1838:111 seconds and 9 tool calls …, one of them the registered verify_build tool」 一个推断被写成了实测。卡 #18451 与 objectui#7388 都没有把 verify_build 记进那 9 次调用 ⚠️ objectstack-ai/cloud 从本会话凭据够不到 ⇒ 这条既证不了也驳不了,而那正是它不能被写成实测的原因。⇒ 要么引一个够得到的来源,要么标为 inferred。⛔ 不许因为够不到就删掉整段
    (c) 「a turn that seeds no sample data never reports data」「apply_edit turns need not report structure」 断言生产者行为,无可达来源 标为 inferred。⭐ 卡面明说:周围那句消费者指引(treat every phase as optional, compare by value)无论如何都安全,⇒ 下游不会坏,这几句只是没出处

    ⭐ 为什么不是「注释不精确」(分诊原话,转达):该 docblock ① 随已发布的 @objectstack/spec tarball 出货(files[] 带 src/**/*.zod.ts)、② 逐字渲染进 content/docs/references/ai/build-progress.mdx。对一个闭枚举,这段出处说明就是「动数组之前先重测」那条纪律所依赖的审计线索。⇒ 下一个判断该不该加第五个成员的人,会把这几句当读数看。

    ⚠️ 生成物:顺序是硬的

    content/docs/references/ai/build-progress.mdx 由 docblock 生成。⛔ 单改 .mdx 会被下一次生成覆盖,并且红掉生成物门禁(卡面原话)。⇒ 改 docblock ⇒ 跑 gen:docs ⇒ 把两边一起提交。⚠️ 入队前若碰到 merge=os-regen 注册路径,按四步序 bash scripts/pm/os-regen-merge.sh(该名单在你开工那一刻用 grep os-regen .gitattributes 现取,⛔ 不抄)。

    ⭐ 卡面的第二件活:verify / hop / tool 的活性债

    三者在任何可达仓里零读者、零发射者。那是按裁决提前声明的、⛔ 不是疏忽,而且它落在 ADR-0049 活性账本之外(账本以 registry 为根,BuildProgressFrame 不是注册的元数据类型,活性作业是绿的)⇒ ⛔ 没有任何门禁会注意到。两个具名承接者应当关掉它:cloud#2172(发射端)与 objectui#7388 block 2(消费端的严格解析,自 2026-09-10 起 pm:awaiting-maintainer)。

    ⇒ ⭐ 本轮只做「记下这个看守」,把它写进 docblock 的出处段:这三个成员靠什么站着、谁应当关掉它、⛔ 以及没有门禁在看这件事。⛔ 不要自己去 enforce-or-remove,⛔ 不要动枚举成员。⚠️ 那两个承接者在别的仓/别的席,本轮够不到也不该够。

    ⛔ 只读栅栏

    • ⛔ .changeset/build-progress-phase-vocabulary.md —— 见上,发布机器人 PR chore: version packages #17076 持有且删除它。
    • ⛔ BUILD_PROGRESS_PHASES 的成员本身,以及 BuildProgressPhaseSchema / BuildProgressFrameSchema 的任何行为 —— 本轮是出处说明的修,⛔ 不是枚举的修。动了成员就是 Clause-② 变 yes,⇒ 停下来交回本席。
    • ⛔ packages/spec/src/ai/build-progress.test.ts 的既有断言 —— 可以加测试,⛔ 不许改既有断言来迁就新文字。
    • ⛔ objectui / cloud 两仓 —— 本轮够不到,⛔ 不要为了「补上可达来源」去改它们。

    验收

    • ⭐ 逐句可核:改完之后,docblock 里每一条生产者主张都必须能被归到三类标签之一,⛔ 没有第四类、⛔ 没有留白。在正文里做一张逐句对照表(原句 → 新句 → 标签 → 依据)。
    • ⭐ (a) 的读数你要自己重取一遍并带亮控:objectui 对 'verify' 的命中数,以及对照词 'structure' 的命中数。⛔ 一个没有亮控的 0 不作数。⚠️ 若你够不到 objectui,那就照实写「本轮未验证,读数取自卡面与 PR spec(ai): declare the closed build-progress PHASE vocabulary the agent loop emits during post-apply verification #18528 的契约复核」并点名来源,⛔ 不许把别人的读数写成自己的。
    • ⭐ DARK(必须读 0):BuildProgressPhaseSchema 的解析行为分毫不动 —— 给出改前改后对合法值与非法值的解析结果比对;packages/spec 的既有测试一条不少地绿。
    • ⭐ 生成物对账:gen:docs 之后 content/docs/references/ai/build-progress.mdx 的改动必须只是 docblock 那几句的镜像。给出该 .mdx 的 diff,并证明它没有别的动静。
    • check:generated / check:docs / check:authorable-surface / check:api-surface 全绿 —— ⚠️ 尤其 check:api-surface:本轮不应该动它,⛔ 若动了,说明你碰了导出面。

    本轮章程增量

    1. PR 正文首行 Fixes #18552;Clause-②: no 行单独占一行、写在行首,⛔ 不加反引号。
    2. ⚠️ 本席申报 no 的依据:references/lanes/spec.md:19 —— 只有「放宽接受集或扩大公开面」才是条款②;本轮既不放宽接受集(枚举与解析分毫不动),也不扩大公开面(⛔ 无新导出)。⭐ 若你量出任何导出面或接受集被动到,那是申报错了:停下来交回本席,⛔ 不要自己改成 yes。
    3. ⭐ 探针做在你保留的分支上,⛔ 不开一次性分支(容器建得出远端分支却删不掉,两道皆 403,⛔ 不重试)。
    4. 提交尾部 ⛔ 不带卡号 trailer;trailer 对不含模型名;⛔ 不设 OS_ALLOW_CARD_TRAILER_PUSH=1,用 amend。
    5. PR 正文只写一次,⛔ 不事后 PATCH;要改的在报告里点名,本席代写。
    6. 门禁清单取 node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack 逐条跑,退出码先落盘再 --ran 对账。
    7. ⚠️ 卡上已有本席贴的 Claim: 评论。⛔ 不要再贴第二条 claim。
    8. ⛔ 本令每一条读数都取自 origin/main 18cc3b1dfc,⏱️ 2026-09-18T02:07Z。若你的 base 已移动,重取,⛔ 不要继承本席的数字当成你自己的读数。

    Generated by Claude Code

  2. self-assigned this
    on Sep 18, 2026
  3. os-bill commented on Sep 18, 2026

    @os-bill
    Collaborator

    os-dev-report

    {
      "issue": 18552,
      "status": "done",
      "branch": "claude/issue-18552-build-progress-docblock-provenance",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/18870",
      "session": "session_01JbZnqu8bt6YqfJsr9vaFb3",
      "premise_still_valid": true,
      "summary": "Every producer claim in the build-progress module docblock now carries exactly one of the three labels (measured on a named reachable source / declared by ruling / inferred), and content/docs/references/ai/build-progress.mdx was regenerated from it by gen:docs. (a): the MEASURED-membership headline is retired; structure/data/done stay measured with the tree they were read against, verify is labelled declared by ruling with its zero-occurrence reading and bright control recorded beside it. (b): the cloud#1838 figure and the verify_build attribution are labelled inferred, with the reachable part (verify_build is a registered platform tool at platform-tool-names.ts:85) stated narrowly; nothing was deleted. (c): the two skipped-phase illustrations are labelled inferred and the consumer guidance around them is unchanged. A new '## Liveness watch' section records that verify/hop/tool are declared ahead, names cloud#2172 and objectui#7388 block 2 as the carriers, and states that no gate watches it because BuildProgressFrame is outside the registry-rooted ADR-0049 ledger. No enum member, schema or export moved. The dispatch's assignee field was set by the PM (os-bill) and was not written by this run. A base note: the dispatch's readings were taken at origin/main 18cc3b1dfc; this run branched from a09d79708b and re-took every reading, then merged origin/main (96fdac21ee) through os-regen-merge.sh.",
      "tests": "pnpm --filter @objectstack/spec test -> 487 files / 14058 tests PASS (every pre-existing build-progress assertion untouched; 3 tests added). pnpm --filter @objectstack/spec typecheck -> PASS (check:scripts-typecheck + check:test-typecheck, ledger unchanged at 54 files / 259 errors / 144 pinned signatures). pnpm --filter @objectstack/spec check:generated -> 'All 15 generated artifacts are up to date', including check:docs, check:api-surface, check:authorable-surface; working tree clean afterwards. pnpm lint (repo-wide eslint . --no-inline-config) -> exit 0 at head 5d12a88850; NOT narrowed, so no narrowing evidence is owed. dispatch-gates --commands --repo objectstack-ai/objectstack -> 106 commands; --ran verdict: '106 derived famil(ies) accounted for - 103 run, 3 NOT-MEASURED (3 DERIVED from a recorded exit 3)', 0 UNRUN, exit 0; 6 extra artifact-roster families whose roster sits under one of my directories were also run green. NOT MEASURED: check:dual-build-cjs-loads, check:lean-entry-closure, check:type-check-debt - each exited 3 with its own 'PREREQUISITE NOT MET ... nothing was measured' text because they read the WHOLE workspace's built output, which does not build inside this container's single foreground window; they read other packages' emitted bytes and cannot be moved by a docblock, and CI owns them. Four other gates first exited 3/1 for the same reason and were RE-RUN GREEN after building their closure (check:doc-formula-expressions, check:doc-security-posture, check:skill-examples, check:docs-transcript-drift). DARK (reads 0): a 29-line parse probe over BuildProgressPhaseSchema and BuildProgressFrameSchema (14 phase inputs + 13 frame inputs + the exported array and frame-type literals) run against the source BEFORE and AFTER the edit -> diff empty, exit 0. Covers all four legal phases parsing, invalid_value carrying the full accepted set for designing/rebuilding/VERIFY/''/3/1.5/null/undefined/{}/['verify'], the frame's too_small / invalid_type / path=['phase'] refusals, and the loose-parse survival of appLabel/items/done/total/seq. GENERATED-ARTEFACT RECONCILIATION: gen:docs writes 224 files and exactly one moved - content/docs/references/ai/build-progress.mdx (+27/-8), and its whole diff is the mirror of the two module-docblock sections plus the rewritten Producer paragraphs; the schema tables, allowed-values list and TypeScript-usage block are byte-identical. The BUILD_PROGRESS_PHASES and field docblocks are not rendered by build-docs.ts, which is why (a) and (c) produce no mdx change. os-regen verified with my own instrument: git check-attr merge answers os-regen for that mdx and unspecified for the hand-written .zod.ts beside it. (a) RE-TAKEN WITH A BRIGHT CONTROL, objectui at dda8f3815df6eb92e944a33745070e361e8d6e40: git grep -l \"'verify'\" -- packages/plugin-chatbot -> 0 files; control git grep -l \"'structure'\" same scope -> 4 files (ChatbotEnhanced.tsx, __tests__/ChatbotEnhanced.test.tsx, __tests__/buildPanelI18n-7388.test.tsx, mapMessages.ts). ChatbotEnhanced.tsx:163 types the union without verify; mapMessages.ts:743 (the docblock said 744 - corrected, and the citation now carries its tree) is the coercion default. objectstack side: 4 files mention data-build-progress and all four are this module's own declaration, its test, ai/index.ts and the contracts example (control: onProgress in 10 files) - zero emitters. No ablation was run: this change adds no guard.",
      "mcp_calls": "0 - no MCP GitHub tool was called; every GitHub read and write went through the REST proxy with curl",
      "api_writes": "3 - POST /repos/objectstack-ai/objectstack/pulls (draft PR 18870); POST /repos/objectstack-ai/objectstack/issues/18870/labels (documentation, tests, priority:p2, domain:spec - read back, nothing stripped, size/m added by the bot); POST /repos/objectstack-ai/objectstack/issues/18552/comments (this report). Plus git push on the feature branch only (empty-branch routing probe, the work commit, the merge) - no PATCH of the PR body, no POST /issues, no write to main",
      "open_questions": [],
      "out_of_scope_findings": [
        "FENCE READING, for the seat to judge: .changeset/build-progress-phase-vocabulary.md was NOT touched. Re-taken at my own start: (1) the file is still on origin/main; (2) PR #17076 'chore: version packages' is still open and unmerged and holds a deletion of it. So its 'never reports data' sentence still wants the same softening and this branch is not the place to contend for that file. The 'not yet in a CHANGELOG' half was re-measured WITH a bright control, which the dispatch had marked unverified: git grep -c 'never reports' -- '*CHANGELOG.md' -> 0 hits; whole-sentence control 'data-build-progress' -- '*CHANGELOG.md' -> 0 hits; instrument control 'changeset' -> hits across many of the 80 CHANGELOG files the same instrument sees. So the sentence has NOT been compiled into any published CHANGELOG, and the PR #18751 stop-and-return-to-the-seat condition did NOT trigger.",
        "noted, not filed: packages/spec/src/ai/build-progress.test.ts's own docblock repeats the same retired claim in its own words - 'Each member was measured against a real end of the channel'. Identical defect class, predates this branch, and its blast radius is far smaller: the tarball ships .zod.ts sources, not tests, and nothing renders it. Not fixed in-branch because the bounded-in-place-fix exemption owes a same-round supplement to the claim's declared file surface, and charter item 7 forbids posting a second claim - so the fourth condition cannot be met from here. Carrier: whoever next edits that pin, or this seat in a follow-up. Dedupe words: 'build-progress test docblock measured claim', 'verify phase zero emitters', 'closed enum audit trail re-measure'.",
        "noted, not filed: the docblock cited objectui mapMessages.ts:744 where the current tree reads 743, and cited no tree for either line number. Fixed in-branch as part of this card's own provenance scope (the citation now names objectui dda8f3815) - recorded here only so the one-line move is not read as drift."
      ]
    }

    Generated by Claude Code

  4. added a commit that references this issue on Sep 28, 2026
    0b31d90
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions