Repository navigation
docs(adr): ADR-0090 D10 rule 4 — mark the run id undelivered, with its reopen condition - #19653
Merged
Merged
Conversation
…s reopen condition Rule 4 declares `performed_by` + `on_behalf_of` + run id. The first two ship; the run id has no carrier, and the ruling is to say so rather than mint one. One dated status note in the decision's own note tail, beside the 2026-09-16 note rule 4 already points at: the run id is not delivered, why (no agent-run concept on the request path, no server-constructed identifier grouping one agent task, and the two correlation ids that do travel it are caller-controlled, which the envelope refuses in writing), and the reopen condition (task-scoped agent grants land ⇒ the grant id is the run id ⇒ a successor wires `performedBy.runId`). Rule 4's own sentence is unchanged. No spec or runtime change: the `performedBy` docblock reserves the room for a sibling key, not the name, and nothing declares `runId` today. Claude-Session: https://claude.ai/code/session_01Wnstp2kTth7sGXfr8fXypc Co-authored-by: Claude <noreply@anthropic.com>
hotlong
approved these changes
Sep 22, 2026
hotlong
marked this pull request as ready for review
September 22, 2026 06:41
hotlong
deleted the
claude/issue-18374-adr-0090-d10-run-id-status-line
branch
September 22, 2026 07:26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #18374
维护者速读(草稿)
改了什么 —— ADR-0090 D10 的
agent规则 4 要求每次 agent 写入记三样:谁干的、代谁干的、哪一次运行。前两样已在产,第三样没有。本 PR 在该决策自己的注记尾部(规则 4 已经指过去的那处)加一条带日期的状态行 —— 13 行、一个文件 —— 写明「运行 id 未交付」、为什么、以及它什么时候该回来:任务级 agent 授权落地时,授权 id 就是运行 id。⛔ 规则 4 自己那句话一个字没动。为什么改 —— 执行裁决评论
5749155184(总监席 batch #195 item 2,letter C,维护者「同意」2026-09-20)。一条声明了却发不出来的契约,比一条写明「暂缓」的契约更糟;ADR-0049 的诚实状态那一档要求把它标成未交付,而不是随手铸一个「叫运行 id 的请求 id」。风险与代价(含回滚) —— 纯文档:零运行时、零 spec、零发布面。回滚 = revert 这一个提交。真正的代价是未来读者会看到一条明写「未交付」的规则 —— 这正是目的,而不是副作用。
席位意见 —— 技能席 1(
session_01Wnstp2kTth7sGXfr8fXypc)已按 GitHub 与拉取的 head495929b复核:13 行与裁决 5749155184 的五项内容逐一对应(已交付对、run id 未交付、两条 why、reopen 条件、裁决引用),规则 4 原句一字未动,注记落在规则 4 自己指向的注记尾部;check-adr-symbol-anchors、check-adr-links、check:adr-anchors在本席自己的 worktree 复跑均 exit 0,check-governed-merges --pr 19653读 GOVERNED Tier H(13 行)。两处对派发词的修正本席认可:docblock 只留位、未命名runId,注记如实写「留位不留名」;+13 行超出派发词的 ≤ +5 系派发词自相矛盾(内容清单与行数上限在 100 列换行下不可能同时成立),内容优先。建议合并;Fixes #18374合入即关卡,pm:dispatched由本席在合入时摘。你要做的(一个动作) —— 读那 13 行,认可就手工合并。
docs/adr/**是 Tier H 受管面,本 PR 保持 draft,⛔ 没有 AI 席位可以代你合、代你入队或给它挂 auto-merge。Clause-②: no
What landed
One dated status note in
docs/adr/0090-permission-model-v2-concept-convergence.md— 13 lines added, 0 removed, 1 file. It sits in the decision's own note tail, immediately after the 2026-09-16 note that rule 4's own sentence already points readers at ("see the 2026-09-16 note at the end of this decision"), so both amendments to rule 4 now live in one place, in date order. Rule 4's sentence is byte-unchanged.The note states, in the ruling's order:
performed_byandon_behalf_ofship (#18371); no run id is stamped and none is pending; why (no agent-run concept on the request path — the MCP door is explicitly stateless — so no server-constructed identifier grouping one agent task exists to carry, and the two correlation ids that do travel that path,traceIdfrom the client'straceparentandrequestIdpreferring the client'sX-Request-Id, are caller-controlled, which the envelope refuses in writing); the reopen condition (task-scoped, time-boxed agent grants land ⇒ the grant id is the run id ⇒ a successor wiresperformedBy.runId); and the ruling reference in the file's ownRuling:form.Two measured corrections to the dispatch's premises
The shipped docblock reserves the ROOM, not the NAME.
packages/spec/src/kernel/execution-context.zod.ts#performedByreads verbatim: "A one-key object rather than a bare string so the API-key door (#18335, blocked on this carrier) can name its own identifier as a sibling key if it is ruled an agent, without re-shaping a field that already shipped." It reserves a sibling-key extension point and names the API-key door as the motivating case; it never namesrunId. The status note is worded to match what is actually reserved and says so explicitly ("it reserves the room, ⛔ not the name") — writing it any other way would have put a fresh declared-but-absent key into an ADR whose whole point is that class of defect.The line budget could not hold the enumerated content. The dispatch's suggested route asked for net ≤ +5 physical lines and enumerated five required contents; at this file's 100-column wrap those two cannot both hold (the content is ~1,150 characters ≈ 12 wrapped lines). Content won, lines were minimised: 13 added lines, every one of them ≤ 100 columns, no line removed, nothing else in the tree touched.
Gates
Derived mechanically, not recalled:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands(no paths — the script took its own change set from the merge base), 19 families. All 19 run, all exit 0, reconciled with--ran:✓ dispatch-gates --ran: 19 derived famil(ies) accounted for — 19 run, 0 NOT-MEASURED (a DERIVED zero — all 19 recorded an exit code and none of them is 3).Named readings from that set:
node scripts/check-adr-symbol-anchors.mjs:: exit 0 —✅ check-adr-symbol-anchors: 2121 anchors across 140 records resolvepnpm check:doc-authoring:: exit 0pnpm check:adr-anchors:: exit 0pnpm check:pm-governed-merges:: exit 0pnpm check:nul-bytes:: exit 0 (plus a hand scan of the inserted text for control bytes: no match)One family needed a prerequisite:
pnpm --filter @objectstack/lint run check:doc-formula-expressionsfirst exited 3 — its own text says "Nothing was measured: this gate exited before running a single check", naming two unbuilt workspace packages. Afterpnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint(throughscripts/pm/os-verify-lock.sh,VERDICT command-exit 0) it re-ran at exit 0. The exit-3 reading is recorded as NOT MEASURED, ⛔ not as a failure.Repo-wide scans (
pnpm lintand the rest) are CI's run, not this PR's; the type-check lanes and the path-scheduled CI job the derivation printed as NOT MEASURED are CI's too.Reverse verification — the new citation is actually checked
The note cites
packages/spec/src/kernel/execution-context.zod.ts#performedBy, andcheck-adr-symbol-anchorsresolves that spelling. A green gate over a corpus of 2121 anchors says nothing about this one, so it was ablated:node scripts/ablation-replace.mjsswapped the symbol forablationProbeNoSuchSymbol(anchor hit 1 → 0, blob27197b6cd90d→978fa39ca89f, both verified on disk by the tool, not by an exit code), then re-ran the gate.Predicted direction: turns red naming this line. Observed:
Restore leg:
ablation-replace: ok restored: blob == HEAD (27197b6cd90d) and 'git diff HEAD' is empty. Both legs ran from the committed state; no probe file survives. (A first attempt was refused by the tool because the replacement text still contained the anchor as a substring, so the anchor count did not drop — recorded here because that attempt measured nothing.)Changeset —
skip-changeset, measureddocs/adr/**publishes nothing. Measured rather than assumed: of 83 trackedpackage.jsonfiles, 70 declarefiles[]and none of them shipsdocs/; the 13 that declare nofiles[]are allprivate: true. The singlefiles[]entry adocs|adr|**probe matched ispackages/specshippingsrc/**/*.zod.ts, which is not a docs path.Landing posture — Tier H, stays draft
docs/adr/**is Tier H (人合) on theGOVERNED_SURFACESregister inscripts/pm/check-governed-merges.mjs. This PR is opened draft and stays draft: the maintainer merges it by hand. ⛔ No AI seat merges it, queues it, arms auto-merge on it, flips it out of draft, or submits an approving review on it.Acceptance notes
claude/issue-18374-run-id-entry-carrier(564ac2f170, thedomain:specseat's write-path probe) is still on the remote. It is a stale marker, not in-flight work. Comment5753761987measured both delete channels refused (git push --deletehung up, RESTDELETE /git/refs/...answered 403), so this run did ⛔ not re-attempt the delete.#2849in the same sentence. The status note this PR adds is that follow-up's record, but the 2026-07 line was left untouched — amending it is outside this card's declared file surface, and it is not a defect, a contract violation or a metadata-authoring trap.docs/adr/0090-permission-model-v2-concept-convergence.md.origin/mainhad not moved from80ca0b1c88, so no merge was owed.Generated by Claude Code