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 }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
console: the approvals Recall button reads "Override Recall" and says the recall finalises the step and is recorded as an admin override — the server records neither, and a submitter-admin recalling their own request is told it is an override #13225
Filing gate ① a user-visible defect with a named site and a named real producer. Derived from objectui#13164 (the same notice, its reassign lever), whose dev measured this while fixing that card. Filed by objectui domain:ui seat 1 (seat post objectui#5560, session_014MXhk1yjWh37d634hLy3p7). ⛔ Not a claim.
Reader (who acts): the objectui domain:ui execution seat. Seat 1 dispatches it once objectui#13222 (which holds DeclaredActionsBar.tsx and the ten language packs) has landed.
The defect
On a pending approval request, the Recall button can read "Override Recall", and its dialog says: "Continuing uses your admin override: it finalises the step immediately and bypasses the approvers who have not acted — {who}. The decision is recorded as an admin override."
Two of those claims are false for a recall, and the framing itself is wrong for one viewer:
"recorded as an admin override" is false.ApprovalService.recall (objectstack packages/plugins/plugin-approvals/src/approval-service.ts, at objectui's pin f4755a68a) writes its sys_approval_action row with action: 'recall' and no via_override. The request goes to recalled, and its pending approvers are cleared. No decision is recorded.
A submitter who is also an admin is told their own recall is an override. With can_act: false, is_submitter: true and can_override: true, the button still reads "Override Recall", with the bypass sentence. The submitter recalling their own request is the ordinary path, not an override.
reach
Named real producer: objectstack's shipped approval_recall (sys-approval-request.object.ts, at the pin). Its visible has carried the admin-override arm since objectstack#12716, "spelled byte-identically to the three core decision levers".
On the objectui side, actionAdmittedByOverride (packages/app-shell/src/utils/approvalOverride.ts) admits it, so isOverrideDecision relabels it, and the bar gives it the decision notice.
Measured: a unit probe rendered DeclaredActionsBar with the shipped recall declaration, for an override-only admin and for a submitter-admin. Both read "Override Recall" with the decision sentence (objectui#13164's dev report, 6288370239, out-of-scope finding 1).
Expected
A submitter, admin or not, recalling their own request sees the plain Recall, with no override framing.
An admin who holds no slot and is not the submitter, recalling through the override, is told what a recall does: the request is withdrawn, its approvers can no longer act, and the record is unlocked. It must not say "finalises the step" or "recorded as an admin override", because the server records neither.
Stale beside it
The header of utils/approvalOverride.ts says "approval_recall / approval_resubmit gate on is_submitter and never match". That describes the declaration as it was before objectstack#12716.
The approval_recall fixture in DeclaredActionsBar.overrideAffordance.test.tsx declares it submitter-only.
Dedupe
Method: semantic search_issues on objectstack-ai/objectui, open and closed.
"approval Override Recall notice says finalises the step admin override recall can_override": 1 hit, objectui#13164 itself (the parent; its reassign half only).
Claim: PM loop round 3 (priority:p3, bug)
Session: session_014MXhk1yjWh37d634hLy3p7
Account: huangyiirene (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-13225-override-recall
Worktree: objectui-issue-13225
Domain: domain:ui
Seat: domain:ui#1
File surface, read at objectui main58798ec (which carries objectui#13164's PR #13222):
packages/app-shell/src/utils/approvalOverride.ts. actionAdmittedByOverride and isOverrideDecision admit approval_recall through its can_override arm, the submitter's own recall included, and the header's "approval_recall / approval_resubmit gate on is_submitter and never match" is stale since objectstack#12716;
packages/app-shell/src/views/DeclaredActionsBar.tsx, the overrideNotice composition. approvalRouteVerb reads approve, reject and reassign, and a recall falls to the decision sentence;
the approvalsInbox.* override entries in packages/i18n/src/locales/*.ts, all ten packs, only if a recall sentence needs its own key;
tests beside them (the approval_recall fixture in DeclaredActionsBar.overrideAffordance.test.tsx);
one changeset (@object-ui/app-shell, plus @object-ui/i18n if a key is added; patch).
Not the server's recall or override path, and not the approve, reject or reassign sentences objectui#13164 just landed. Stop on breach; explain in the report.
Container & model: S, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui over this surface reads no path-derived mandate)
Clause-②: yes
Responsibility: the risk is produced by objectui's own approvals action bar, which labels a recall "Override Recall" and tells the admin it finalises the step and is recorded as an admin override (the server records neither), and frames a submitter-admin's own recall as an override; the platform path that covers it: none (the dialog is the only statement of the consequence); who reaches it: every admin who recalls a pending request, their own included.
Thread-read: none
The card had no comment at this claim. It was filed by this seat from objectui#13164's dev report (6288370239), and objectui#13164 has landed (6288801287).
Serial constraints cleared:
No open objectui PR touches DeclaredActionsBar.tsx or approvalOverride.ts.
Open objectui#13227 (another seat's objectui#13146) adds settingsView.fieldErrorsToast* to all ten packs, about 2,500 lines from approvalsInbox. Any key here stays in approvalsInbox, and the dev merges main before pr_create if objectui#13227 has landed.
Why Clause-②: yes: the claim cannot yet say whether the recall can be described with existing copy. A new approvalsInbox.* key would widen @object-ui/i18n's exported TranslationKeys (precedent: objectui#13164). 「拿不准 ⇒ 按 yes」. The dev reports which it was.
{
"issue": 13225,
"status": "done",
"branch": "claude/issue-13225-override-recall",
"pr": "https://github.com/objectstack-ai/objectui/pull/13240",
"session": "session_014MXhk1yjWh37d634hLy3p7 (subagent run: the parent's harness-stamped id, as on the Claude-Session trailer of 1cf5d98b6)",
"premise_still_valid": true,
"summary": "H1 confirmed at the pin f4755a68a. approval_recall's visible is the submitter arm OR the can_override arm (objectstack#12716), so actionAdmittedByOverride admitted it and isOverrideDecision relabelled it for any viewer with can_act false and can_override true. Measured on the bar at BASE 58798eca8 with the corrected fixture: the submitter-admin (can_act false, is_submitter true, can_override true) got data-override-decision true and 'Override Recall', and the override-only admin got the decision sentence. H2 confirmed in ApprovalService.recall. It writes one sys_approval_action row with action 'recall' and no via_override (only the decision and reassign writers set that column), sets status recalled, clears pending_approvers, empties the approver index, mirrors recalled into the approval-status field when one is configured, and resumes the run with decision 'recall'. attachViewers serves is_submitter as a plain boolean. H3 implemented. (a) isOverrideDecision reads the served is_submitter flag for any lever whose declared gate names it; only an explicit false leaves the override as the only door, so the fail-safe direction is unchanged. Approve, reject and reassign name no submitter arm and are judged exactly as before. (b) approvalRouteVerb reads /recall, and an override recall gets its own notice, named and unnamed: the request is withdrawn, the record is unlocked, and the approvers who have not acted can no longer act on it. It keeps the 'Override Recall' framing, and does not say 'finalises' or 'recorded as an admin override'. (c) The stale header line and the submitter-only recall fixtures (both test files) now describe the shipped declaration. All ten packs gain approvalsInbox.overrideRecallNotice and overrideRecallNoticeWho as real translations. One changeset covers app-shell and i18n (patch). Clause-② turned out yes (two keys), and the PR body carries that line. main was merged into the branch (f0300beff) before pr_create, because objectui#13227 had landed.",
"tests": "Final head c32944a0b (fix commit 1cf5d98b6 plus a merge of main f0300beff); every exit code was captured on its own line before any pipe. (1) The premise run at BASE source used the corrected fixture and the new pins: 'Tests 4 failed | 27 passed (31)'. The Received values were data-override-decision 'true', 'Override Recall', and the decision sentence in named and unnamed form. (2) Targeted at 1cf5d98b6: the four DeclaredActionsBar suites, approvalOverride.test.ts and useConsoleActionRuntime.overrideNotice.test.tsx gave 'Test Files 6 passed (6)', 'Tests 116 passed (116)'. (3) Blast radius at c32944a0b: 68 files from git grep (approvalOverride, the three predicates, overrideNotice, DeclaredActionsBar, approvalsInbox, approval_recall, product-neutral) across app-shell, apps/console, components, core, react, plugin-detail, plugin-grid and scripts gave 'Test Files 68 passed (68)', 'Tests 968 passed (968)', blast exit=0. (4) i18n package at c32944a0b: 'pnpm exec vitest run packages/i18n/' gave 'Test Files 84 passed (84)', 'Tests 1319 passed | 13 skipped (1332)', exit 0. (5) Ablation after the fix commit (1cf5d98b6): DeclaredActionsBar.tsx and approvalOverride.ts were set to their BASE blobs while the packs and tests stayed at HEAD. The on-disk hashes equalled BASE (86de7b3e8, 7b83f4400), and grep -c went mayHoldAsSubmitter 2 to 0 and overrideRecallNotice 2 to 0. The run gave 'Tests 6 failed | 50 passed (56)': exactly the six recall pins, and their Received values are the card's Actual. The approve-still-finalises, reassign and plain-submitter controls stayed green under ablation, as controls should. The restore was git checkout HEAD -- under a trap (absolute paths). The on-disk hashes then equalled the HEAD blobs (f27b4ab0e, 37ac56dd8), git diff HEAD was 0 bytes, and the marker counts were back at 2. No dist step: both suites reach the bar and the helper by relative import, and the pack through the vitest source alias. No permanent ablation file was kept.",
"gates": "Hand-derived from objectui's package.json for this diff (dispatch-gates.mjs refuses objectui, so no --ran reconciliation applies). At c32944a0b, locked under os-verify-lock (slot os-dev-13225), each part's exit was captured separately; the lock's batch-last-exit is NOT quoted as a verdict. pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' --filter '@object-ui/i18n^...' build: exit 0. pnpm --filter @object-ui/app-shell type-check: exit 0, and tsc --listFilesOnly on its tsconfig.test.json lists both changed test files. pnpm --filter @object-ui/i18n type-check: exit 0. pnpm --filter @object-ui/app-shell lint: exit 0, 0 errors; its warnings on touched files are pre-existing except one '(p: any)' in a new test, the same shape as its siblings in that file; no warning ratchet exists. Unlocked check:* at c32944a0b, exit 0 each: check:i18n-keys; check:i18n-drift ('0 en value(s) changed (2 key(s) added, 0 removed'); check:i18n-dead-keys (neither new key listed); check:new-line-citations ('VERDICT new-cross-file-line-citations: 0 new citation(s)'); check:control-bytes; check:test-path-roots; check:vi-mock-specifiers; check:vi-mock-inherit; check:vi-mock-override-shape; check:changeset-claims; check:pending-changeset-literals; node scripts/check-changeset-presence.mjs; node scripts/check-changeset-no-major.mjs. node scripts/check-governed-queue-guard.mjs --test over the 15 changed paths: NOT GOVERNED. NOT MEASURED: check:eager-locale-catalogues, reason: PREREQUISITE NOT MET (it reads a built console bundle), left to CI. PR #13240 check-runs at report time (total_count 35, 35 listed): success for Changeset Bump Policy, Changeset Fixed Group Check and label; skipped for Test (coverage), Test (coverage shard 8-way) and dependabot; queued for Bundle Analysis; in_progress for Test shards 1-16/16, Test (dist pins), Type Check, Lint, Build & E2E, Build Docs, Repo Gates, Governed Surface Queue Guard, Live E2E (informational), Changeset Claim Re-read, Changeset Declaration, Changeset Overwrite Report and Line Citation Gate. Left to CI: the full app-shell suite, and the repo-wide lint and test.",
"mcp_calls": "0",
"api_writes": "2 relay strokes through scripts/pm/fleet-write/dispatch.mjs and scripts/pm/post-stamped.mjs, each a POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot], each preceded by a write-pace --status read, all prefixed OS_PM_WRITE_HOURLY_MAX=60 per the PM's mid-run note. (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/13240/assignees [huangyiirene]. The relay read it back as 10492 bytes sent and 10492 stored, identical, assignee huangyiirene. (2) comment = POST /repos/objectstack-ai/objectui/issues/13225/comments (this report). Labels: none written; the PR's labels (tests, package: app-shell, package: i18n) were applied by the repo's labeler. git push x3 to the branch (the empty-branch probe, the fix commit, the merge commit); these are not REST. REST reads only through gh api: the card and its comments, the parent report, PR #13227's state, PR #13240 and its check-runs.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed (in PR #13240's Acceptance notes): an admin who holds a slot on the request but did not submit it reaches approval_recall only through the override arm, since the recall gate has no can_act arm, yet still sees the plain Recall. isOverrideOnlyViewer requires can_act false, and this change keeps that precondition, so the only viewer relabelled is the one the card's Expected names. This is the module's tolerated fail-safe direction, and nothing in that dialog is false: the declared description still says what a recall does.",
"carrier: none · noted, not filed (in PR #13240's Acceptance notes): two sibling fixtures outside the claim still declare the recall submitter-only, its pre-objectstack#12716 shape: RecordDetailView.approvalDeclaredActions.test.tsx (app-shell) and approvalRequestsDataSource.decisionPage.test.tsx (apps/console). Neither renders an override-capable viewer against the recall, so neither hides a defect today."
],
"deviations": "(1) The harness attribution reminder asked for a model-named Co-Authored-By trailer. The commits carry the model-free pair (Claude-Session + Co-authored-by: Claude) per objectui AGENTS.md, and the PR body uses os-dev's session-URL footer, not the harness's form. (2) The full @object-ui/app-shell suite was not run locally and is left to CI; the targeted files and a 68-file blast-radius set ran instead. (3) check:eager-locale-catalogues is NOT MEASURED locally (it needs a built console). (4) Per the PM's mid-run note, both relay writes and the pace reads before them carried OS_PM_WRITE_HOURLY_MAX=60; nothing else changed. (5) No environment variable value was printed; the relay session was passed explicitly with --session."
}
#13240 merged through the merge queue at 2026-10-20T11:33Z. The squash commit 06be396 has one parent (24001c1), and git merge-base --is-ancestor places it on origin/main878a4af (exit 0)
queue
no gh-readonly-queue/main/pr-13240-* branch remains
landed content
on origin/main, approvalOverride.ts holds function mayHoldAsSubmitter (1), and DeclaredActionsBar.tsx's route reading includes recall (1). The packs carry overrideRecallNotice* (en 2, zh 2). Positive control: objectui#13164's approvalsInbox.overrideReassignNotice* reads are kept (2)
records
claim 6288830273, dev report 6289496950 on this card, ACCEPT 6289530529 and ## Contract review6289537361 (TIER_DEFAULT, the declaration face, PASS) on PR #13240
closing
closed completed at 2026-10-20T11:33Z through the PR's Fixes #13225; pm:dispatched is removed in this act. The note is late because the seat's session hit its usage limit between 11:25Z and 12:10Z
A submitter's own recall is the plain Recall. An admin recalling someone else's request sees "Override Recall" with a notice saying what a recall does: the request is withdrawn, the record is unlocked, and the remaining approvers can no longer act. The notice says nothing about a finalised step or an override record, because the server records neither.
Activity
objectstack-fleet commentedon Oct 20, 2026
Claim: PM loop round 3 (
priority:p3,bug)Session:
session_014MXhk1yjWh37d634hLy3p7Account:
huangyiirene(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-13225-override-recallWorktree:
objectui-issue-13225Domain:
domain:uiSeat:
domain:ui#1File surface, read at objectui
main58798ec(which carries objectui#13164's PR #13222):packages/app-shell/src/utils/approvalOverride.ts.actionAdmittedByOverrideandisOverrideDecisionadmitapproval_recallthrough itscan_overridearm, the submitter's own recall included, and the header's "approval_recall/approval_resubmitgate onis_submitterand never match" is stale since objectstack#12716;packages/app-shell/src/views/DeclaredActionsBar.tsx, theoverrideNoticecomposition.approvalRouteVerbreadsapprove,rejectandreassign, and a recall falls to the decision sentence;approvalsInbox.*override entries inpackages/i18n/src/locales/*.ts, all ten packs, only if a recall sentence needs its own key;approval_recallfixture inDeclaredActionsBar.overrideAffordance.test.tsx);@object-ui/app-shell, plus@object-ui/i18nif a key is added;patch).Not the server's recall or override path, and not the approve, reject or reassign sentences objectui#13164 just landed. Stop on breach; explain in the report.
Container & model:
S,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuiover this surface reads no path-derived mandate)Clause-②: yes
Responsibility: the risk is produced by objectui's own approvals action bar, which labels a recall "Override Recall" and tells the admin it finalises the step and is recorded as an admin override (the server records neither), and frames a submitter-admin's own recall as an override; the platform path that covers it: none (the dialog is the only statement of the consequence); who reaches it: every admin who recalls a pending request, their own included.
Thread-read: none
The card had no comment at this claim. It was filed by this seat from objectui#13164's dev report (
6288370239), and objectui#13164 has landed (6288801287).Serial constraints cleared:
DeclaredActionsBar.tsxorapprovalOverride.ts.settingsView.fieldErrorsToast*to all ten packs, about 2,500 lines fromapprovalsInbox. Any key here stays inapprovalsInbox, and the dev mergesmainbeforepr_createif objectui#13227 has landed.ObjectListViewInspector.tsxandmetadata-admin/i18n.ts.Why
Clause-②: yes: the claim cannot yet say whether the recall can be described with existing copy. A newapprovalsInbox.*key would widen@object-ui/i18n's exportedTranslationKeys(precedent: objectui#13164). 「拿不准 ⇒ 按yes」. The dev reports which it was.Claimed at: 2026-10-20T10:26Z
objectstack-fleet commentedon Oct 20, 2026
os-dev-report
{ "issue": 13225, "status": "done", "branch": "claude/issue-13225-override-recall", "pr": "https://github.com/objectstack-ai/objectui/pull/13240", "session": "session_014MXhk1yjWh37d634hLy3p7 (subagent run: the parent's harness-stamped id, as on the Claude-Session trailer of 1cf5d98b6)", "premise_still_valid": true, "summary": "H1 confirmed at the pin f4755a68a. approval_recall's visible is the submitter arm OR the can_override arm (objectstack#12716), so actionAdmittedByOverride admitted it and isOverrideDecision relabelled it for any viewer with can_act false and can_override true. Measured on the bar at BASE 58798eca8 with the corrected fixture: the submitter-admin (can_act false, is_submitter true, can_override true) got data-override-decision true and 'Override Recall', and the override-only admin got the decision sentence. H2 confirmed in ApprovalService.recall. It writes one sys_approval_action row with action 'recall' and no via_override (only the decision and reassign writers set that column), sets status recalled, clears pending_approvers, empties the approver index, mirrors recalled into the approval-status field when one is configured, and resumes the run with decision 'recall'. attachViewers serves is_submitter as a plain boolean. H3 implemented. (a) isOverrideDecision reads the served is_submitter flag for any lever whose declared gate names it; only an explicit false leaves the override as the only door, so the fail-safe direction is unchanged. Approve, reject and reassign name no submitter arm and are judged exactly as before. (b) approvalRouteVerb reads /recall, and an override recall gets its own notice, named and unnamed: the request is withdrawn, the record is unlocked, and the approvers who have not acted can no longer act on it. It keeps the 'Override Recall' framing, and does not say 'finalises' or 'recorded as an admin override'. (c) The stale header line and the submitter-only recall fixtures (both test files) now describe the shipped declaration. All ten packs gain approvalsInbox.overrideRecallNotice and overrideRecallNoticeWho as real translations. One changeset covers app-shell and i18n (patch). Clause-② turned out yes (two keys), and the PR body carries that line. main was merged into the branch (f0300beff) before pr_create, because objectui#13227 had landed.", "tests": "Final head c32944a0b (fix commit 1cf5d98b6 plus a merge of main f0300beff); every exit code was captured on its own line before any pipe. (1) The premise run at BASE source used the corrected fixture and the new pins: 'Tests 4 failed | 27 passed (31)'. The Received values were data-override-decision 'true', 'Override Recall', and the decision sentence in named and unnamed form. (2) Targeted at 1cf5d98b6: the four DeclaredActionsBar suites, approvalOverride.test.ts and useConsoleActionRuntime.overrideNotice.test.tsx gave 'Test Files 6 passed (6)', 'Tests 116 passed (116)'. (3) Blast radius at c32944a0b: 68 files from git grep (approvalOverride, the three predicates, overrideNotice, DeclaredActionsBar, approvalsInbox, approval_recall, product-neutral) across app-shell, apps/console, components, core, react, plugin-detail, plugin-grid and scripts gave 'Test Files 68 passed (68)', 'Tests 968 passed (968)', blast exit=0. (4) i18n package at c32944a0b: 'pnpm exec vitest run packages/i18n/' gave 'Test Files 84 passed (84)', 'Tests 1319 passed | 13 skipped (1332)', exit 0. (5) Ablation after the fix commit (1cf5d98b6): DeclaredActionsBar.tsx and approvalOverride.ts were set to their BASE blobs while the packs and tests stayed at HEAD. The on-disk hashes equalled BASE (86de7b3e8, 7b83f4400), and grep -c went mayHoldAsSubmitter 2 to 0 and overrideRecallNotice 2 to 0. The run gave 'Tests 6 failed | 50 passed (56)': exactly the six recall pins, and their Received values are the card's Actual. The approve-still-finalises, reassign and plain-submitter controls stayed green under ablation, as controls should. The restore was git checkout HEAD -- under a trap (absolute paths). The on-disk hashes then equalled the HEAD blobs (f27b4ab0e, 37ac56dd8), git diff HEAD was 0 bytes, and the marker counts were back at 2. No dist step: both suites reach the bar and the helper by relative import, and the pack through the vitest source alias. No permanent ablation file was kept.", "gates": "Hand-derived from objectui's package.json for this diff (dispatch-gates.mjs refuses objectui, so no --ran reconciliation applies). At c32944a0b, locked under os-verify-lock (slot os-dev-13225), each part's exit was captured separately; the lock's batch-last-exit is NOT quoted as a verdict. pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' --filter '@object-ui/i18n^...' build: exit 0. pnpm --filter @object-ui/app-shell type-check: exit 0, and tsc --listFilesOnly on its tsconfig.test.json lists both changed test files. pnpm --filter @object-ui/i18n type-check: exit 0. pnpm --filter @object-ui/app-shell lint: exit 0, 0 errors; its warnings on touched files are pre-existing except one '(p: any)' in a new test, the same shape as its siblings in that file; no warning ratchet exists. Unlocked check:* at c32944a0b, exit 0 each: check:i18n-keys; check:i18n-drift ('0 en value(s) changed (2 key(s) added, 0 removed'); check:i18n-dead-keys (neither new key listed); check:new-line-citations ('VERDICT new-cross-file-line-citations: 0 new citation(s)'); check:control-bytes; check:test-path-roots; check:vi-mock-specifiers; check:vi-mock-inherit; check:vi-mock-override-shape; check:changeset-claims; check:pending-changeset-literals; node scripts/check-changeset-presence.mjs; node scripts/check-changeset-no-major.mjs. node scripts/check-governed-queue-guard.mjs --test over the 15 changed paths: NOT GOVERNED. NOT MEASURED: check:eager-locale-catalogues, reason: PREREQUISITE NOT MET (it reads a built console bundle), left to CI. PR #13240 check-runs at report time (total_count 35, 35 listed): success for Changeset Bump Policy, Changeset Fixed Group Check and label; skipped for Test (coverage), Test (coverage shard 8-way) and dependabot; queued for Bundle Analysis; in_progress for Test shards 1-16/16, Test (dist pins), Type Check, Lint, Build & E2E, Build Docs, Repo Gates, Governed Surface Queue Guard, Live E2E (informational), Changeset Claim Re-read, Changeset Declaration, Changeset Overwrite Report and Line Citation Gate. Left to CI: the full app-shell suite, and the repo-wide lint and test.", "mcp_calls": "0", "api_writes": "2 relay strokes through scripts/pm/fleet-write/dispatch.mjs and scripts/pm/post-stamped.mjs, each a POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot], each preceded by a write-pace --status read, all prefixed OS_PM_WRITE_HOURLY_MAX=60 per the PM's mid-run note. (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/13240/assignees [huangyiirene]. The relay read it back as 10492 bytes sent and 10492 stored, identical, assignee huangyiirene. (2) comment = POST /repos/objectstack-ai/objectui/issues/13225/comments (this report). Labels: none written; the PR's labels (tests, package: app-shell, package: i18n) were applied by the repo's labeler. git push x3 to the branch (the empty-branch probe, the fix commit, the merge commit); these are not REST. REST reads only through gh api: the card and its comments, the parent report, PR #13227's state, PR #13240 and its check-runs.", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed (in PR #13240's Acceptance notes): an admin who holds a slot on the request but did not submit it reaches approval_recall only through the override arm, since the recall gate has no can_act arm, yet still sees the plain Recall. isOverrideOnlyViewer requires can_act false, and this change keeps that precondition, so the only viewer relabelled is the one the card's Expected names. This is the module's tolerated fail-safe direction, and nothing in that dialog is false: the declared description still says what a recall does.", "carrier: none · noted, not filed (in PR #13240's Acceptance notes): two sibling fixtures outside the claim still declare the recall submitter-only, its pre-objectstack#12716 shape: RecordDetailView.approvalDeclaredActions.test.tsx (app-shell) and approvalRequestsDataSource.decisionPage.test.tsx (apps/console). Neither renders an override-capable viewer against the recall, so neither hides a defect today." ], "deviations": "(1) The harness attribution reminder asked for a model-named Co-Authored-By trailer. The commits carry the model-free pair (Claude-Session + Co-authored-by: Claude) per objectui AGENTS.md, and the PR body uses os-dev's session-URL footer, not the harness's form. (2) The full @object-ui/app-shell suite was not run locally and is left to CI; the targeted files and a 68-file blast-radius set ran instead. (3) check:eager-locale-catalogues is NOT MEASURED locally (it needs a built console). (4) Per the PM's mid-run note, both relay writes and the pace reads before them carried OS_PM_WRITE_HOURLY_MAX=60; nothing else changed. (5) No environment variable value was printed; the relay session was passed explicitly with --session." }Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
LANDED ·
domain:uiseat 1 ·session_014MXhk1yjWh37d634hLy3p7· 2026-10-20T12:13Z ·pm:dispatchedcleared06be396has one parent (24001c1), andgit merge-base --is-ancestorplaces it onorigin/main878a4af(exit 0)gh-readonly-queue/main/pr-13240-*branch remainsorigin/main,approvalOverride.tsholdsfunction mayHoldAsSubmitter(1), andDeclaredActionsBar.tsx's route reading includesrecall(1). The packs carryoverrideRecallNotice*(en 2, zh 2). Positive control: objectui#13164'sapprovalsInbox.overrideReassignNotice*reads are kept (2)6288830273, dev report6289496950on this card, ACCEPT6289530529and## Contract review6289537361(TIER_DEFAULT, the declaration face, PASS) on PR #13240completedat 2026-10-20T11:33Z through the PR'sFixes #13225;pm:dispatchedis removed in this act. The note is late because the seat's session hit its usage limit between 11:25Z and 12:10ZA submitter's own recall is the plain Recall. An admin recalling someone else's request sees "Override Recall" with a notice saying what a recall does: the request is withdrawn, the record is unlocked, and the remaining approvers can no longer act. The notice says nothing about a finalised step or an override record, because the server records neither.
fix(app-shell,i18n): a submitter's own recall is not an override, and…