You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
console: a record:approval_decision block placed on any page other than an approval request's renders nothing — draw a visible notice instead of null #12072
packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.tsx renders the page component type record:approval_decision. Its docblock (:39–:40) says: "Outside a sys_approval_request record page there is no request to decide on, and the panel renders nothing."
Off a sys_approval_request record page, the panel draws a short, localized notice in place of null, saying it only works on approval request pages. Gate it with the same test that decides "outside" today.
On a sys_approval_request record page, behaviour is unchanged. While the request row is still loading or absent, it keeps today's null.
⛔ No new lint or save-door rule. Triage chose the loud renderer over a new gate. A lint rule comes back only if a wrong-placement producer appears.
Pins:
the block on a non-request record page renders the notice;
the block on a request page renders the panel;
the notice string is in the i18n bundle.
Clause-②: no. Dedupe: search over objectui for the approval decision panel rendering nothing off an approval request page found nothing open.
packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.tsx, ApprovalDecisionRenderer (about :126–:140). Today row is the record context's data only when ctx?.objectName === SYS_APPROVAL_REQUEST_OBJECT, and the node renders null otherwise.
Off a sys_approval_request record page (the context names another object, or none): draw a short, localized notice saying the block works only on approval request pages.
On one, with the row still loading or absent: keep today's null.
The "outside" test is the existing ctx?.objectName comparison, kept as one test with ⛔ no second copy. The module docblock's sentence (about :39–:40) follows.
packages/i18n/src/locales/*.ts: one new key for the notice, in all ten packs, with the i18n gates.
The tests beside the panel, with the card's pins:
the block on a non-request record page renders the notice;
the block on a request page renders the panel;
the notice string is in the i18n bundle;
plus: on a request page whose row is not yet loaded, still null.
One .changeset/12072-*.md.
⛔ Not on it:
any lint, save-door or schema rule (triage chose the loud renderer over a new gate);
the panel's registration, its index import, the known-types line and the zod arm (objectui#12045's page-mount step);
DeclaredActionsBar, DecisionProgressIndicator, and packages/components/src/ui/**.
Container & model: S, mode:subagent, model: opus (dispatch-gates --tier --repo objectstack-ai/objectui over these paths: no path-derived mandate; default tier). The contract review runs at the ceiling, CONTRACT_REVIEW_TIER, because of the line below.
Clause-②: yes
Why Clause-②: yes, not the card's no: the notice adds one key to the published language packs (@object-ui/i18n), which widens a published surface. This seat has read a new pack key that way before (objectui#12047's ACCEPT 6079760712). The key is the only widening, and the renderer change itself is behaviour. Changesets: @object-ui/i18nminor and @object-ui/app-shellpatch. ⛔ Never major.
Responsibility: objectui app-shell: the record:approval_decision renderer draws nothing off a sys_approval_request record page, so a block an author places elsewhere parses, validates and silently shows nothing | the platform path: the renderer's existing objectName test, now loud on the wrong page | every author who places the decision panel, now that the spec declares the type (objectstack PR #22532)
Thread-read: none
Serial constraints cleared: none blocking.
Open objectui PRs, read 2026-10-09T22:03Z: none touches approval-decision/ or the language packs.
objectui#12045 (pm:blocked, claim released) owns the panel's page-mount step. It is not in flight, and this change stays inside the renderer it will register.
In-flight claims, read 2026-10-09T22:03Z: none in this repo carries pm:dispatched (serial dispatch).
os-dev-report
{
"issue": 12072,
"status": "done",
"branch": "claude/issue-12072-decision-panel-notice",
"pr": "#12073",
"session": "session_01CGZy1BGCjdN5cXqL9cnvB8 (subagent mode: the dispatching seat's id)",
"premise_still_valid": true,
"summary": "Off a sys_approval_request record page (another object's record page, or no record context at all), ApprovalDecisionRenderer now draws a short localized notice, t('approvalsInbox.decisionPanelOffRequestPage'), in record:path's muted dashed placeholder classes, instead of null. On a request page whose row has not loaded it still draws nothing, and with its row it draws the panel unchanged. The 'outside' test is the existing ctx?.objectName comparison, kept as one comparison with an early return. One new pack key is added in all ten packs, the module docblock follows, and the changeset is .changeset/12072-decision-panel-notice.md (@object-ui/i18n minor, @object-ui/app-shell patch, with a Clause-② yes widening paragraph). There is no registration, index import, known-types line, zod arm, or lint/save-door rule. Zone 2: (1) the siblings DecisionProgressIndicator and RecordApprovalsPanel use useObjectTranslation from @object-ui/react with literal approvalsInbox.* keys and an inline defaultValue, and the notice does the same. (2) No notice component exists; the nearest sibling state is record:path's 'no stages configured' placeholder, and its class string is reused verbatim, with nothing under packages/components/src/ui. (3) No record context means useRecordContext() is null, so the notice draws, matching the card's wording; this is pinned. Draft PR #12073, head 7d10b7c, assignee os-support-ai. The worktree and its node_modules are removed.",
"tests": "All on head 7d10b7c, from the worktree root. Panel suite: pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/approval-decision/ gave Test Files 1 passed (1), Tests 11 passed (11), lock VERDICT command-exit 0. Console consumer: pnpm exec vitest run apps/console/src/services/approvalRequestsDataSource.decisionPage.test.tsx gave Tests 7 passed (7). i18n: pnpm exec vitest run packages/i18n/ gave Test Files 82 passed (82), Tests 1316 passed | 13 skipped (1329). Build: pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2 gave Tasks 28 successful, 28 total. Type-check: pnpm --filter @object-ui/app-shell type-check and pnpm --filter @object-ui/i18n type-check exit 0, both script names echoed; tsc -p tsconfig.test.json --listFilesOnly lists ApprovalDecisionPanel.test.tsx. eslint on the 12 touched code files gave 12 files, 0 errors, 0 warnings. Narrowing proof: the population is eslint.config.js files '/*.{ts,tsx}'; the count of 12 is read from the --format json output; the config has no parserOptions or projectService and no eslint-rules/ rule reads the filesystem, so the diff cannot move a verdict on any untouched file. Ablation: predictions were written before either leg ran, and both legs used objectstack's scripts/ablation-replace.mjs in wrap mode with cwd set to the objectui worktree. No dist is in the path, because vitest aliases @object-ui/i18n to src. Leg A plants 'if (ctx?.objectName !== SYS_APPROVAL_REQUEST_OBJECT) return null;' (anchor 1 to 0, blob fe48ddfb6d5c to bba2eb0d2aaa): predicted and observed 5 failed, 6 passed, the same five, namely the two notice cases, className/designer, the zh provider and the en control. Leg B deletes the zh pack key line (blob b89bcf7f113a to a846fe99c54b): predicted and observed 2 failed, 9 passed, namely 'all ten packs' and 'zh provider'. After each leg the restore was proven: blob == HEAD, and git diff HEAD is empty.",
"mcp_calls": "0 — no MCP GitHub tool was called (reads used gh api over REST; writes went through the scripts/pm relay).",
"api_writes": "3 — each relayed as one POST /repos/objectstack-ai/objectstack/dispatches executed by the fleet-write workflow: (1) pr_create POST /repos/objectstack-ai/objectui/pulls (draft #12073, read-back 8400 bytes identical); (2) label-write --assign POST /repos//issues/12073/assignees (os-support-ai, read-back MATCHES); (3) post-stamped --comment=12072 POST /repos//issues/12072/comments (this report). Not REST: two git push to the branch (empty-branch probe, then 7d10b7c). Zero label writes (path labels came from labeler.yml).",
"open_questions": [
{
"question": "objectui#12045's pending changeset (.changeset/12045-approval-decision-panel.md) says the panel 'renders nothing' outside a sys_approval_request record page. Released together with this PR, that clause is false. The file is outside this claim's surface, so it was not edited.",
"options": [
"A: the seat amends the claim and an append-only 'Superseded in part (objectui#12072)' paragraph is added to that changeset, the precedent of 12045 amendment 4 on objectui#12032's changeset",
"B: leave it; this PR's changeset already says it replaces that clause, and both entries publish into the same CHANGELOG"
],
"recommendation": "A, because the CHANGELOG then carries no false sentence. The cost is one append-only paragraph on a pending file, and it follows the precedent the seat already set."
}
],
"out_of_scope_findings": [
"carrier: the domain:ui seat (claim amendment), for the stale clause in .changeset/12045-approval-decision-panel.md ('outside a sys_approval_request record page it renders nothing'), which this change makes false. Noted, not filed: it is a pending changeset, not a released defect. Recorded in the PR's Acceptance notes and in open_questions."
],
"gates": [
{
"command": "pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/approval-decision/",
"exit": 0,
"verdict": "Test Files 1 passed (1) / Tests 11 passed (11)"
},
{
"command": "pnpm exec vitest run --maxWorkers=2 apps/console/src/services/approvalRequestsDataSource.decisionPage.test.tsx",
"exit": 0,
"verdict": "Test Files 1 passed (1) / Tests 7 passed (7)"
},
{
"command": "pnpm exec vitest run --maxWorkers=2 packages/i18n/",
"exit": 0,
"verdict": "Test Files 82 passed (82) / Tests 1316 passed | 13 skipped (1329)"
},
{
"command": "pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2",
"exit": 0,
"verdict": "Tasks: 28 successful, 28 total"
},
{
"command": "pnpm --filter @object-ui/app-shell type-check && pnpm --filter @object-ui/i18n type-check",
"exit": 0,
"verdict": "os-verify-lock: VERDICT command-exit 0 (both scripts echoed: tsc --noEmit && tsc -p tsconfig.test.json)"
},
{
"command": "pnpm exec eslint --format json (12 touched code files)",
"exit": 0,
"verdict": "files 12 errors 0 warnings 0"
},
{
"command": "pnpm check:i18n-keys",
"exit": 0,
"verdict": "Every in-scope call-site key resolves against the en pack (3314 keys), every literal inline defaultValue matches the value the pack serves, ..."
},
{
"command": "pnpm check:i18n-drift",
"exit": 0,
"verdict": "No en value changed in this range. (0 en value(s) changed (1 key(s) added, 0 removed))"
},
{
"command": "pnpm check:i18n-dead-keys",
"exit": 0,
"verdict": "report-only; approvalsInbox.decisionPanelOffRequestPage: 0 hits in the candidate list"
},
{
"command": "pnpm check:i18n-designer-parity",
"exit": 0,
"verdict": "Every en row has a zh row, and every shared row carries the same placeholders."
},
{
"command": "pnpm check:control-bytes",
"exit": 0,
"verdict": "check-control-bytes: OK (scanned 8266 tracked text file(s); skipped 85 binary)."
},
{
"command": "pnpm check:test-path-roots",
"exit": 0,
"verdict": "check-test-path-roots: OK"
},
{
"command": "pnpm check:changeset-claims",
"exit": 0,
"verdict": "No pending changeset names a file this change touches."
},
{
"command": "pnpm check:pending-changeset-literals",
"exit": 0,
"verdict": "No test source names a pending changeset."
},
{
"command": "pnpm check:new-line-citations",
"exit": 0,
"verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only, so exit 0 (arrow spelled out)"
},
{
"command": "pnpm check:vi-mock-inherit",
"exit": 0,
"verdict": "check-vi-mock-inherit: OK"
},
{
"command": "pnpm check:action-forward-parity",
"exit": 0,
"verdict": "exit 0 (action:menu / element:button payload excess-property CHECKED)"
},
{
"command": "pnpm check:installed-pin-claims",
"exit": 0,
"verdict": "OK"
},
{
"command": "node scripts/check-changeset-presence.mjs",
"exit": 0,
"verdict": "12 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s): .changeset/12072-decision-panel-notice.md."
},
{
"command": "node scripts/check-changeset-no-major.mjs",
"exit": 0,
"verdict": "No changeset declares a major bump."
},
{
"command": "node scripts/check-changeset-fixed.mjs",
"exit": 0,
"verdict": "All workspace packages are in the changeset fixed group."
},
{
"command": "node scripts/check-changeset-overwrite.mjs",
"exit": 0,
"verdict": "No pre-existing changeset was modified or deleted."
},
{
"command": "ablation leg A (renderer returns null off a request page)",
"exit": 1,
"verdict": "Tests 5 failed | 6 passed (11), as predicted; restore proven"
},
{
"command": "ablation leg B (zh pack key deleted)",
"exit": 1,
"verdict": "Tests 2 failed | 9 passed (11), as predicted; restore proven"
},
{
"command": "check:eager-closure, check:eager-locale-catalogues",
"exit": null,
"verdict": "NOT MEASURED: both need a full console build, which CI Bundle Analysis runs. Source proxy: en.ts +102 B raw / +36 B gzip -9; no catalogue added"
},
{
"command": "full app-shell suite; pnpm lint repo-wide",
"exit": null,
"verdict": "NOT MEASURED: CI's, per the dispatch"
}
],
"deviations": [
"Gates beyond the dispatch's list, derived from scripts that read the touched paths: the console decisionPage suite, check:new-line-citations, check:vi-mock-inherit, check:action-forward-parity, check:installed-pin-claims, and the changeset presence, no-major, fixed and overwrite scripts. All exit 0.",
"check:readme-exports was not run: no package export changed (the en pack and the TranslationKeys type gain one member, which the changeset states).",
"Pins beyond the claim's four, all in the claim's test file: the no-record-context case (Zone 2.3) and a check that the notice keeps the node's className and designer attributes.",
"The dispatch said 'the notice should move no first-load bytes'. That holds for the renderer code, since no entry imports the module (git grep zero hits outside tests; the control is the console test importing it). The en value, however, sits in the eager en catalogue: +36 B gzip at the source level, NOT MEASURED on a console build.",
"The 12045 pending changeset's 'renders nothing' clause was not edited, because it is outside the claim's surface. This PR's changeset states that it replaces that clause; see open_questions.",
"The commit carries objectui AGENTS.md's model-free trailer pair (Claude-Session + 'Co-authored-by: Claude'), not the harness reminder's model-named Co-Authored-By. The PR body ends with the os-dev session-URL footer, not the harness reminder's footer form.",
"objectui has no ablation-replace.mjs, so the ablations ran objectstack's copy (/home/user/objectstack/scripts/ablation-replace.mjs) with cwd in the objectui worktree. It resolves the repo from cwd.",
"No write was refused."
],
"files_changed": [
".changeset/12072-decision-panel-notice.md",
"packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.tsx",
"packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.test.tsx",
"packages/i18n/src/locales/ar.ts",
"packages/i18n/src/locales/de.ts",
"packages/i18n/src/locales/en.ts",
"packages/i18n/src/locales/es.ts",
"packages/i18n/src/locales/fr.ts",
"packages/i18n/src/locales/ja.ts",
"packages/i18n/src/locales/ko.ts",
"packages/i18n/src/locales/pt.ts",
"packages/i18n/src/locales/ru.ts",
"packages/i18n/src/locales/zh.ts"
],
"line_budget": "not applicable (no skills/ surface)"
}
Claim amendment — domain:ui seat 3, session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-09T22:26Z. It amends the claim 6090014515, on the dev's open question (report 6090270186, PR objectui#12073).
Answer: A. The surface gains an append-only paragraph on .changeset/12045-approval-decision-panel.md.
That file is objectui#12045's pending release declaration, and this seat owns it. It says the panel "renders nothing" outside a sys_approval_request record page, which this change makes false. If both changes publish in one release, the CHANGELOG would carry the false sentence beside its correction.
Shape: the precedent of objectui#12045's amendment 4 (6081923179) on objectui#12032's changeset. Append one "Superseded in part (objectui#12072)" paragraph at the end, and leave the front matter and every existing line unchanged.
check-changeset-overwrite will report the modification (it is report-only). The declared packages stay the same.
Clause-②: yes and the grades stand (@object-ui/i18nminor, @object-ui/app-shellpatch).
Draft against main, based on c0c0a0d5. git merge-tree against mainc0c0a0d5 is clean.
First line Fixes #12072, the body's only closing keyword. Clause-②: yes at line start.
The commits carry only the model-free trailer pair. Assignee os-support-ai, set with no refusal.
Scope: 14 files, +126/−9, on the claim 6090014515 as amended in 6090288136 (the append-only rider on objectui#12045's pending changeset). The governed-queue guard reads NOT GOVERNED.
What lands:
Off a sys_approval_request record page (another object's record page, or no record context at all), ApprovalDecisionRenderer draws a short localized notice, approvalsInbox.decisionPanelOffRequestPage. It uses record:path's muted dashed placeholder classes, reused verbatim, and nothing is added under packages/components/src/ui/**.
On a request page whose row has not loaded, it still draws nothing; with its row, the panel is unchanged.
The "outside" test stays the one ctx?.objectName comparison, now an early return.
Translation follows the siblings: useObjectTranslation with an inline defaultValue.
One new pack key, in all ten packs. There is no registration, index import, known-types line, zod arm, lint rule or save-door rule; the panel stays module-internal until objectui#12045's page-mount step.
The rider: objectui#12045's pending changeset gains a "Superseded in part (objectui#12072)" paragraph (2 lines added, 0 removed), so the CHANGELOG carries no false "renders nothing" sentence.
Changesets: @object-ui/i18nminor and @object-ui/app-shellpatch.
Contract review:6090649252 on the PR, rendered at CONTRACT_REVIEW_TIER by an isolated, read-only reviewer on this head, reads PASS. The seat checked the record's lines:
Served-tier: CONTRACT_REVIEW_TIER;
Head-sha equal to the head;
Local-runs: none;
Implemented-by and Reviewed-by signed;
VERDICT: PASS;
no model name.
It judged:
① the i18n surface widened by one key, the app-shell surface and the accept set unchanged, and the behaviour matching every clause of the card;
② Clause-②: yes and both grades right;
③ the open question answered by the amendment and implemented on this head.
Gates:
The panel suite passes 11 of 11, and the console's decision-page suite 7 of 7. i18n: 1,316 tests passed.
The app-shell and i18n type-checks exit 0. The four i18n gates exit 0. eslint shows 0 errors and 0 warnings.
Ablation A (null off a request page) gave 5 red, and B (the zh key deleted) gave 2 red, both as predicted, with restores proven.
CI on 043680ff: 43 runs, 40 success, 3 skipped (the expected three), 0 failure. Bundle Analysis passes at 3,168.0 of 3,204.6 KB. The en value adds about 36 B gzip to the eager catalogue.
Landed — domain:ui seat 3, session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-09T23:16Z. PR objectui#12073 merged through the queue as 20c6d351 at 2026-10-09T23:15Z; its Fixes #12072 closed this card.
The merge:
One parent, c0c0a0d5, an ancestor of origin/main.
The landed tree equals git merge-tree of that parent and the accepted head 043680ff (tree 04432472 on both).
14 files, +126/−9, all fourteen blobs equal to the accepted head's.
Content check at 20c6d351:
approvalsInbox.decisionPanelOffRequestPage appears once in each of the en and zh packs.
objectui#12045's pending changeset carries the "Superseded in part (objectui#12072)" paragraph, once.
State:pm:dispatched is removed in this act; the card is closed completed. Contract review 6090649252 PASS; ACCEPT 6090664449.
Activity
objectstack-fleet commentedon Oct 9, 2026
Claim: PM loop round 3
Session:
session_01CGZy1BGCjdN5cXqL9cnvB8Account:
os-support-aiBranch:
claude/issue-12072-decision-panel-noticeWorktree:
objectui-issue-12072Domain:
domain:uiSeat:
domain:ui#3File surface (on
mainc0c0a0d5):packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.tsx,ApprovalDecisionRenderer(about:126–:140). Todayrowis the record context's data only whenctx?.objectName === SYS_APPROVAL_REQUEST_OBJECT, and the node renders null otherwise.sys_approval_requestrecord page (the context names another object, or none): draw a short, localized notice saying the block works only on approval request pages.ctx?.objectNamecomparison, kept as one test with ⛔ no second copy. The module docblock's sentence (about:39–:40) follows.packages/i18n/src/locales/*.ts: one new key for the notice, in all ten packs, with the i18n gates..changeset/12072-*.md.⛔ Not on it:
DeclaredActionsBar,DecisionProgressIndicator, andpackages/components/src/ui/**.Container & model:
S,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier). The contract review runs at the ceiling,CONTRACT_REVIEW_TIER, because of the line below.Clause-②: yes
Why
Clause-②: yes, not the card'sno: the notice adds one key to the published language packs (@object-ui/i18n), which widens a published surface. This seat has read a new pack key that way before (objectui#12047's ACCEPT6079760712). The key is the only widening, and the renderer change itself is behaviour. Changesets:@object-ui/i18nminorand@object-ui/app-shellpatch. ⛔ Nevermajor.Responsibility:
objectui app-shell: the record:approval_decision renderer draws nothing off a sys_approval_request record page, so a block an author places elsewhere parses, validates and silently shows nothing | the platform path: the renderer's existing objectName test, now loud on the wrong page | every author who places the decision panel, now that the spec declares the type (objectstack PR #22532)Thread-read: none
Serial constraints cleared:
noneblocking.approval-decision/or the language packs.pm:blocked, claim released) owns the panel's page-mount step. It is not in flight, and this change stays inside the renderer it will register.pm:dispatched(serial dispatch).Generated by Claude Code
objectstack-fleet commentedon Oct 9, 2026
os-dev-report
{
"issue": 12072,
"status": "done",
"branch": "claude/issue-12072-decision-panel-notice",
"pr": "#12073",
"session": "session_01CGZy1BGCjdN5cXqL9cnvB8 (subagent mode: the dispatching seat's id)",
"premise_still_valid": true,
"summary": "Off a sys_approval_request record page (another object's record page, or no record context at all), ApprovalDecisionRenderer now draws a short localized notice, t('approvalsInbox.decisionPanelOffRequestPage'), in record:path's muted dashed placeholder classes, instead of null. On a request page whose row has not loaded it still draws nothing, and with its row it draws the panel unchanged. The 'outside' test is the existing ctx?.objectName comparison, kept as one comparison with an early return. One new pack key is added in all ten packs, the module docblock follows, and the changeset is .changeset/12072-decision-panel-notice.md (@object-ui/i18n minor, @object-ui/app-shell patch, with a Clause-② yes widening paragraph). There is no registration, index import, known-types line, zod arm, or lint/save-door rule. Zone 2: (1) the siblings DecisionProgressIndicator and RecordApprovalsPanel use useObjectTranslation from @object-ui/react with literal approvalsInbox.* keys and an inline defaultValue, and the notice does the same. (2) No notice component exists; the nearest sibling state is record:path's 'no stages configured' placeholder, and its class string is reused verbatim, with nothing under packages/components/src/ui. (3) No record context means useRecordContext() is null, so the notice draws, matching the card's wording; this is pinned. Draft PR #12073, head 7d10b7c, assignee os-support-ai. The worktree and its node_modules are removed.",
"tests": "All on head 7d10b7c, from the worktree root. Panel suite: pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/approval-decision/ gave Test Files 1 passed (1), Tests 11 passed (11), lock VERDICT command-exit 0. Console consumer: pnpm exec vitest run apps/console/src/services/approvalRequestsDataSource.decisionPage.test.tsx gave Tests 7 passed (7). i18n: pnpm exec vitest run packages/i18n/ gave Test Files 82 passed (82), Tests 1316 passed | 13 skipped (1329). Build: pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2 gave Tasks 28 successful, 28 total. Type-check: pnpm --filter @object-ui/app-shell type-check and pnpm --filter @object-ui/i18n type-check exit 0, both script names echoed; tsc -p tsconfig.test.json --listFilesOnly lists ApprovalDecisionPanel.test.tsx. eslint on the 12 touched code files gave 12 files, 0 errors, 0 warnings. Narrowing proof: the population is eslint.config.js files '/*.{ts,tsx}'; the count of 12 is read from the --format json output; the config has no parserOptions or projectService and no eslint-rules/ rule reads the filesystem, so the diff cannot move a verdict on any untouched file. Ablation: predictions were written before either leg ran, and both legs used objectstack's scripts/ablation-replace.mjs in wrap mode with cwd set to the objectui worktree. No dist is in the path, because vitest aliases @object-ui/i18n to src. Leg A plants 'if (ctx?.objectName !== SYS_APPROVAL_REQUEST_OBJECT) return null;' (anchor 1 to 0, blob fe48ddfb6d5c to bba2eb0d2aaa): predicted and observed 5 failed, 6 passed, the same five, namely the two notice cases, className/designer, the zh provider and the en control. Leg B deletes the zh pack key line (blob b89bcf7f113a to a846fe99c54b): predicted and observed 2 failed, 9 passed, namely 'all ten packs' and 'zh provider'. After each leg the restore was proven: blob == HEAD, and git diff HEAD is empty.",
"mcp_calls": "0 — no MCP GitHub tool was called (reads used gh api over REST; writes went through the scripts/pm relay).",
"api_writes": "3 — each relayed as one POST /repos/objectstack-ai/objectstack/dispatches executed by the fleet-write workflow: (1) pr_create POST /repos/objectstack-ai/objectui/pulls (draft #12073, read-back 8400 bytes identical); (2) label-write --assign POST /repos//issues/12073/assignees (os-support-ai, read-back MATCHES); (3) post-stamped --comment=12072 POST /repos//issues/12072/comments (this report). Not REST: two git push to the branch (empty-branch probe, then 7d10b7c). Zero label writes (path labels came from labeler.yml).",
"open_questions": [
{
"question": "objectui#12045's pending changeset (.changeset/12045-approval-decision-panel.md) says the panel 'renders nothing' outside a sys_approval_request record page. Released together with this PR, that clause is false. The file is outside this claim's surface, so it was not edited.",
"options": [
"A: the seat amends the claim and an append-only 'Superseded in part (objectui#12072)' paragraph is added to that changeset, the precedent of 12045 amendment 4 on objectui#12032's changeset",
"B: leave it; this PR's changeset already says it replaces that clause, and both entries publish into the same CHANGELOG"
],
"recommendation": "A, because the CHANGELOG then carries no false sentence. The cost is one append-only paragraph on a pending file, and it follows the precedent the seat already set."
}
],
"out_of_scope_findings": [
"carrier: the domain:ui seat (claim amendment), for the stale clause in .changeset/12045-approval-decision-panel.md ('outside a sys_approval_request record page it renders nothing'), which this change makes false. Noted, not filed: it is a pending changeset, not a released defect. Recorded in the PR's Acceptance notes and in open_questions."
],
"gates": [
{
"command": "pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/approval-decision/",
"exit": 0,
"verdict": "Test Files 1 passed (1) / Tests 11 passed (11)"
},
{
"command": "pnpm exec vitest run --maxWorkers=2 apps/console/src/services/approvalRequestsDataSource.decisionPage.test.tsx",
"exit": 0,
"verdict": "Test Files 1 passed (1) / Tests 7 passed (7)"
},
{
"command": "pnpm exec vitest run --maxWorkers=2 packages/i18n/",
"exit": 0,
"verdict": "Test Files 82 passed (82) / Tests 1316 passed | 13 skipped (1329)"
},
{
"command": "pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2",
"exit": 0,
"verdict": "Tasks: 28 successful, 28 total"
},
{
"command": "pnpm --filter @object-ui/app-shell type-check && pnpm --filter @object-ui/i18n type-check",
"exit": 0,
"verdict": "os-verify-lock: VERDICT command-exit 0 (both scripts echoed: tsc --noEmit && tsc -p tsconfig.test.json)"
},
{
"command": "pnpm exec eslint --format json (12 touched code files)",
"exit": 0,
"verdict": "files 12 errors 0 warnings 0"
},
{
"command": "pnpm check:i18n-keys",
"exit": 0,
"verdict": "Every in-scope call-site key resolves against the en pack (3314 keys), every literal inline defaultValue matches the value the pack serves, ..."
},
{
"command": "pnpm check:i18n-drift",
"exit": 0,
"verdict": "No en value changed in this range. (0 en value(s) changed (1 key(s) added, 0 removed))"
},
{
"command": "pnpm check:i18n-dead-keys",
"exit": 0,
"verdict": "report-only; approvalsInbox.decisionPanelOffRequestPage: 0 hits in the candidate list"
},
{
"command": "pnpm check:i18n-designer-parity",
"exit": 0,
"verdict": "Every en row has a zh row, and every shared row carries the same placeholders."
},
{
"command": "pnpm check:control-bytes",
"exit": 0,
"verdict": "check-control-bytes: OK (scanned 8266 tracked text file(s); skipped 85 binary)."
},
{
"command": "pnpm check:test-path-roots",
"exit": 0,
"verdict": "check-test-path-roots: OK"
},
{
"command": "pnpm check:changeset-claims",
"exit": 0,
"verdict": "No pending changeset names a file this change touches."
},
{
"command": "pnpm check:pending-changeset-literals",
"exit": 0,
"verdict": "No test source names a pending changeset."
},
{
"command": "pnpm check:new-line-citations",
"exit": 0,
"verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only, so exit 0 (arrow spelled out)"
},
{
"command": "pnpm check:vi-mock-inherit",
"exit": 0,
"verdict": "check-vi-mock-inherit: OK"
},
{
"command": "pnpm check:action-forward-parity",
"exit": 0,
"verdict": "exit 0 (action:menu / element:button payload excess-property CHECKED)"
},
{
"command": "pnpm check:installed-pin-claims",
"exit": 0,
"verdict": "OK"
},
{
"command": "node scripts/check-changeset-presence.mjs",
"exit": 0,
"verdict": "12 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s): .changeset/12072-decision-panel-notice.md."
},
{
"command": "node scripts/check-changeset-no-major.mjs",
"exit": 0,
"verdict": "No changeset declares a
majorbump."},
{
"command": "node scripts/check-changeset-fixed.mjs",
"exit": 0,
"verdict": "All workspace packages are in the changeset fixed group."
},
{
"command": "node scripts/check-changeset-overwrite.mjs",
"exit": 0,
"verdict": "No pre-existing changeset was modified or deleted."
},
{
"command": "ablation leg A (renderer returns null off a request page)",
"exit": 1,
"verdict": "Tests 5 failed | 6 passed (11), as predicted; restore proven"
},
{
"command": "ablation leg B (zh pack key deleted)",
"exit": 1,
"verdict": "Tests 2 failed | 9 passed (11), as predicted; restore proven"
},
{
"command": "check:eager-closure, check:eager-locale-catalogues",
"exit": null,
"verdict": "NOT MEASURED: both need a full console build, which CI Bundle Analysis runs. Source proxy: en.ts +102 B raw / +36 B gzip -9; no catalogue added"
},
{
"command": "full app-shell suite; pnpm lint repo-wide",
"exit": null,
"verdict": "NOT MEASURED: CI's, per the dispatch"
}
],
"deviations": [
"Gates beyond the dispatch's list, derived from scripts that read the touched paths: the console decisionPage suite, check:new-line-citations, check:vi-mock-inherit, check:action-forward-parity, check:installed-pin-claims, and the changeset presence, no-major, fixed and overwrite scripts. All exit 0.",
"check:readme-exports was not run: no package export changed (the en pack and the TranslationKeys type gain one member, which the changeset states).",
"Pins beyond the claim's four, all in the claim's test file: the no-record-context case (Zone 2.3) and a check that the notice keeps the node's className and designer attributes.",
"The dispatch said 'the notice should move no first-load bytes'. That holds for the renderer code, since no entry imports the module (git grep zero hits outside tests; the control is the console test importing it). The en value, however, sits in the eager en catalogue: +36 B gzip at the source level, NOT MEASURED on a console build.",
"The 12045 pending changeset's 'renders nothing' clause was not edited, because it is outside the claim's surface. This PR's changeset states that it replaces that clause; see open_questions.",
"The commit carries objectui AGENTS.md's model-free trailer pair (Claude-Session + 'Co-authored-by: Claude'), not the harness reminder's model-named Co-Authored-By. The PR body ends with the os-dev session-URL footer, not the harness reminder's footer form.",
"objectui has no ablation-replace.mjs, so the ablations ran objectstack's copy (/home/user/objectstack/scripts/ablation-replace.mjs) with cwd in the objectui worktree. It resolves the repo from cwd.",
"No write was refused."
],
"files_changed": [
".changeset/12072-decision-panel-notice.md",
"packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.tsx",
"packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.test.tsx",
"packages/i18n/src/locales/ar.ts",
"packages/i18n/src/locales/de.ts",
"packages/i18n/src/locales/en.ts",
"packages/i18n/src/locales/es.ts",
"packages/i18n/src/locales/fr.ts",
"packages/i18n/src/locales/ja.ts",
"packages/i18n/src/locales/ko.ts",
"packages/i18n/src/locales/pt.ts",
"packages/i18n/src/locales/ru.ts",
"packages/i18n/src/locales/zh.ts"
],
"line_budget": "not applicable (no skills/ surface)"
}
Generated by Claude Code
objectstack-fleet commentedon Oct 9, 2026
Claim amendment —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-09T22:26Z. It amends the claim6090014515, on the dev's open question (report6090270186, PR objectui#12073).Answer: A. The surface gains an append-only paragraph on
.changeset/12045-approval-decision-panel.md.sys_approval_requestrecord page, which this change makes false. If both changes publish in one release, the CHANGELOG would carry the false sentence beside its correction.6081923179) on objectui#12032's changeset. Append one "Superseded in part (objectui#12072)" paragraph at the end, and leave the front matter and every existing line unchanged.check-changeset-overwritewill report the modification (it is report-only). The declared packages stay the same.Clause-②: yesand the grades stand (@object-ui/i18nminor,@object-ui/app-shellpatch).Generated by Claude Code
objectstack-fleet commentedon Oct 9, 2026
ACCEPT —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-09T22:55Z. PR objectui#12073, head043680ff.PR shape:
main, based onc0c0a0d5.git merge-treeagainstmainc0c0a0d5is clean.Fixes #12072, the body's only closing keyword.Clause-②: yesat line start.os-support-ai, set with no refusal.Scope: 14 files, +126/−9, on the claim
6090014515as amended in6090288136(the append-only rider on objectui#12045's pending changeset). The governed-queue guard reads NOT GOVERNED.What lands:
sys_approval_requestrecord page (another object's record page, or no record context at all),ApprovalDecisionRendererdraws a short localized notice,approvalsInbox.decisionPanelOffRequestPage. It usesrecord:path's muted dashed placeholder classes, reused verbatim, and nothing is added underpackages/components/src/ui/**.ctx?.objectNamecomparison, now an early return.useObjectTranslationwith an inlinedefaultValue.@object-ui/i18nminorand@object-ui/app-shellpatch.Contract review:
6090649252on the PR, rendered atCONTRACT_REVIEW_TIERby an isolated, read-only reviewer on this head, reads PASS. The seat checked the record's lines:Served-tier: CONTRACT_REVIEW_TIER;Head-shaequal to the head;Local-runs: none;Implemented-byandReviewed-bysigned;VERDICT: PASS;It judged:
Clause-②: yesand both grades right;Gates:
043680ff: 43 runs, 40 success, 3 skipped (the expected three), 0 failure.Bundle Analysispasses at 3,168.0 of 3,204.6 KB. The en value adds about 36 B gzip to the eager catalogue.Downstream: spec(ui):
record:approval_decisionon any page other thansys_approval_request's parses and validates clean, then draws nothing (an authoring trap: placement is declared in prose, not enforced) objectstack#22538's option B (a loud renderer, not a new gate) lands here. When the page-mount step registers the type, the notice is what an author sees on a wrong page.Landing: ready + auto-merge through the queue, now. Its merge closes objectui#12072.
Generated by Claude Code
objectstack-fleet commentedon Oct 9, 2026
Landed —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-09T23:16Z. PR objectui#12073 merged through the queue as20c6d351at 2026-10-09T23:15Z; itsFixes #12072closed this card.c0c0a0d5, an ancestor oforigin/main.git merge-treeof that parent and the accepted head043680ff(tree04432472on both).20c6d351:approvalsInbox.decisionPanelOffRequestPageappears once in each of theenandzhpacks.pm:dispatchedis removed in this act; the card is closedcompleted. Contract review6090649252PASS; ACCEPT6090664449.Generated by Claude Code