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
mcp: list_actions marks no action unavailable for an AI service account, though run_action refuses its confirmation-gated actions whatever it sends #33067
Filing gate: ① a named-site behaviour gap, class b, carried out of #32936 (its acceptance is "No runtime change"; scope addition 6839924935 asked for both a text and a listing change, and PR #33057 delivers the text only). Priority and lane are triage's.
What is true on main (read at 64c426ab, contract review 6846560754 on PR #33057)
listActions in packages/runtime/src/domains/mcp.ts sets a row's unavailable from apiForwardCredentialRefusal alone (lines 1127 and 1148). It never reads the caller's kind.
A row's requiresConfirmation is actionLooksDestructive (the declared ai.requiresConfirmation, else mode: 'delete' or variant: 'danger').
run_action, REST /actions, resume_run and a host's dispatchAction refuse an AI service account (isAiServiceAccountCaller: principalKind === 'agent', no onBehalfOf) 428 ACTION_CONFIRMATION_REQUIRED on an action declaring ai.requiresConfirmation: true, whatever the call sends (ADR-0151 D3 rule 3; actionConfirmationRefusal).
The exported JSDoc on McpActionSummary.unavailable says it is "Present when run_action would refuse this action for THIS caller's credential before running it" — which this case meets and the listing does not answer.
Business reason
An AI client on a service-account key lists actions, sees a gated action with no unavailable marker, calls it and is refused every time. After #33057 the skill and tool descriptions tell it so, but the listing is the one machine-readable answer a client plans from, and it says the action is available. reach: every headless agent on an AI service account key that plans from list_actions.
Acceptance
For a caller isAiServiceAccountCaller is true of, a row whose action declares ai.requiresConfirmation: true carries unavailable (reason naming the account rule, the same sentence family as the runtime's "a person runs this action"); computed from the declared flag, not from actionLooksDestructive.
A person, a delegated agent (onBehalfOf set) and the system context see the listing unchanged.
Pins on both arms (account → marker; delegated agent → no marker) with code/shape asserted; changeset on the touched package.
Dedupe: list_actions unavailable service account, listActions unavailable requiresConfirmation → only #32936 (the text half). New.
⛔ Not a claim. MCP list_actions shows an AI service account confirmation-gated actions as available, and run_action then refuses them 428. That refusal is loud and names the remedy (a person runs it), so it is not a wrong answer and the MCP focus raise does not apply (rule 8): p2. It is linked under the MCP epic #32897.
Claim: PM loop round 5, card thread · 2026-11-13T17:57Z · MCP p2 under the maintainer's 「mcp 相关 p2 任务也可以派发处理」 (2026-11-13T15:50:52Z)
Session: session_01L9qibxBYPPczsnXa8gB52y
Account: os-tesla
Branch: claude/project-thread-bsdrd4
Worktree: objectstack-issue-33067
Domain: domain:server
Seat: domain:server#7
File surface: packages/runtime/src/domains/mcp.ts (listActions), packages/runtime/src/action-execution.ts / action-dispatch.ts (only to export an existing predicate), the stdio twin if it serves the listing, the list_actions description and served skill text (packages/mcp/src/skill-md.ts + console mirror) only if they state when unavailable appears, their tests, one root changeset. Stop on breach.
Container & model: S, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate; PM default), effort: medium
Clause-②: yes (widening) — the listing answers unavailable on rows it left bare for an AI service account; no input is newly refused
Metadata-protocol: none
Responsibility: the bare row is produced by listActions in packages/runtime (objectstack) | actionConfirmationRefusal / isAiServiceAccountCaller already decide the refusal at run_action and the other doors | every headless agent on an AI service-account key planning from list_actions reaches it today
Thread-read: 6847240864
Premise: re-measure — read at 64c426ab (review 6846560754); the dev reproduces at origin/main first
Serial constraints cleared: packages/runtime/src/domains/mcp.ts is shared with this seat's #32872 (PR #33134): edits stay in listActions; land serially, merge main after a sibling lands
{
"issue": 33067,
"status": "done",
"branch": "claude/project-thread-bsdrd4",
"pr": "https://github.com/objectstack-ai/objectstack/pull/33144",
"session": "session_01L9qibxBYPPczsnXa8gB52y",
"premise_still_valid": true,
"summary": "listActions (packages/runtime/src/domains/mcp.ts) now marks a row unavailable with actionConfirmationRefusal's own code (ACTION_CONFIRMATION_REQUIRED) and sentence when isAiServiceAccountCaller(ec) and the action declares ai.requiresConfirmation: true; the confirmation mark wins over the forward-credential mark, matching run_action's order (admission gate before forwardApiAction). A person, a delegated agent and the system context are not asked, so their listing is unchanged. The McpActionSummary.unavailable JSDoc in packages/mcp named only the endpoint case and UNAUTHENTICATED and now names the account case (surface note: read as the order's description row). The stdio twin has no own listActions (same registerActionTools), and neither the list_actions tool description (still true) nor the served skill needed a change, so no Skills-docs line.",
"tests": "Measured at origin/main dd4ce50b (test commit f6f2fa19): 2 failed / 16 passed: gated row had no unavailable; combined case listed UNAUTHENTICATED while run_action answered ACTION_CONFIRMATION_REQUIRED. After fix: action-confirmation-gate.test.ts 18/18. Ablations via ablation-replace.mjs, each anchor 1->0 and restored to HEAD blob 00b5770f: A (no confirmation mark) 2 failed; B (gate asked for every caller) 2 failed (person/delegated CONTROL); C (forward first) 1 failed. At head 06c6cc6c: runtime vitest 600/600 files, 11936 passed 19 skipped; mcp vitest 63/63 files, 1104 passed; runtime+mcp typecheck exit 0; pnpm lint exit 0.",
"gates": "dispatch-gates --commands at 06c6cc6c: 66 families run with </dev/null, exit codes captured; 63 exit 0; exit 3 PREREQUISITE NOT MET: check-plugin-teardown-shape --self-test (pinned commit unreachable), check:dual-build-cjs-loads (no full dist); check:dts-closure exit 1 because the closure was built OS_SKIP_DTS=1 (39 packages without .d.ts, no export changed). --ran: 66 derived, 64 run, 2 NOT-MEASURED, 0 UNRUN. Record: /mnt/project-files/server-seat-7/r2026-11-13/out/33067/gates-ran-06c6cc6c.list. CI check-runs: in_progress at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "3 — reads only: issue_read get x1, issue_read get_comments x2; 0 writes",
"api_writes": "1 relay write — pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST /issues/33144/assignees), run 43485642149; plus this os-dev-report comment via post-stamped",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted in PR Acceptance notes: row requiresConfirmation stays actionLooksDestructive, so a heuristic-only row says requiresConfirmation: true with no marker for an account, and it runs (pinned)"
]
}
Activity
objectstack-fleet commentedon Nov 13, 2026
triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH
Path: none
Triage: first touch →
domain:server· p2 ·pm:queue· 2026-11-13T07:46Z⛔ Not a claim. MCP
list_actionsshows an AI service account confirmation-gated actions as available, andrun_actionthen refuses them428. That refusal is loud and names the remedy (a person runs it), so it is not a wrong answer and the MCP focus raise does not apply (rule 8): p2. It is linked under the MCP epic #32897.Generated by Claude Code
objectstack-fleet commentedon Nov 13, 2026
domain:server#7 · os-tesla · session_01L9qibzuZJBQY4wUQFJbkfx
Claim: PM loop round 5, card thread · 2026-11-13T17:57Z · MCP p2 under the maintainer's 「mcp 相关 p2 任务也可以派发处理」 (2026-11-13T15:50:52Z)
Session:
session_01L9qibxBYPPczsnXa8gB52yAccount:
os-teslaBranch:
claude/project-thread-bsdrd4Worktree:
objectstack-issue-33067Domain:
domain:serverSeat:
domain:server#7File surface:
packages/runtime/src/domains/mcp.ts(listActions),packages/runtime/src/action-execution.ts/action-dispatch.ts(only to export an existing predicate), the stdio twin if it serves the listing, thelist_actionsdescription and served skill text (packages/mcp/src/skill-md.ts+ console mirror) only if they state whenunavailableappears, their tests, one root changeset. Stop on breach.Container & model:
S,mode:thread,model: default (dispatch-gates --tier: no path-derived mandate; PM default),effort: mediumClause-②: yes (widening) — the listing answers
unavailableon rows it left bare for an AI service account; no input is newly refusedMetadata-protocol: none
Responsibility: the bare row is produced by
listActionsinpackages/runtime(objectstack) |actionConfirmationRefusal/isAiServiceAccountCalleralready decide the refusal atrun_actionand the other doors | every headless agent on an AI service-account key planning fromlist_actionsreaches it todayThread-read: 6847240864
Premise: re-measure — read at
64c426ab(review 6846560754); the dev reproduces atorigin/mainfirstSerial constraints cleared:
packages/runtime/src/domains/mcp.tsis shared with this seat's #32872 (PR #33134): edits stay inlistActions; land serially, merge main after a sibling landsobjectstack-fleet commentedon Nov 13, 2026
domain:server#7 · os-tesla · session_01L9qibxBYPPczsnXa8gB52y
os-dev-report
{ "issue": 33067, "status": "done", "branch": "claude/project-thread-bsdrd4", "pr": "https://github.com/objectstack-ai/objectstack/pull/33144", "session": "session_01L9qibxBYPPczsnXa8gB52y", "premise_still_valid": true, "summary": "listActions (packages/runtime/src/domains/mcp.ts) now marks a row unavailable with actionConfirmationRefusal's own code (ACTION_CONFIRMATION_REQUIRED) and sentence when isAiServiceAccountCaller(ec) and the action declares ai.requiresConfirmation: true; the confirmation mark wins over the forward-credential mark, matching run_action's order (admission gate before forwardApiAction). A person, a delegated agent and the system context are not asked, so their listing is unchanged. The McpActionSummary.unavailable JSDoc in packages/mcp named only the endpoint case and UNAUTHENTICATED and now names the account case (surface note: read as the order's description row). The stdio twin has no own listActions (same registerActionTools), and neither the list_actions tool description (still true) nor the served skill needed a change, so no Skills-docs line.", "tests": "Measured at origin/main dd4ce50b (test commit f6f2fa19): 2 failed / 16 passed: gated row had no unavailable; combined case listed UNAUTHENTICATED while run_action answered ACTION_CONFIRMATION_REQUIRED. After fix: action-confirmation-gate.test.ts 18/18. Ablations via ablation-replace.mjs, each anchor 1->0 and restored to HEAD blob 00b5770f: A (no confirmation mark) 2 failed; B (gate asked for every caller) 2 failed (person/delegated CONTROL); C (forward first) 1 failed. At head 06c6cc6c: runtime vitest 600/600 files, 11936 passed 19 skipped; mcp vitest 63/63 files, 1104 passed; runtime+mcp typecheck exit 0; pnpm lint exit 0.", "gates": "dispatch-gates --commands at 06c6cc6c: 66 families run with </dev/null, exit codes captured; 63 exit 0; exit 3 PREREQUISITE NOT MET: check-plugin-teardown-shape --self-test (pinned commit unreachable), check:dual-build-cjs-loads (no full dist); check:dts-closure exit 1 because the closure was built OS_SKIP_DTS=1 (39 packages without .d.ts, no export changed). --ran: 66 derived, 64 run, 2 NOT-MEASURED, 0 UNRUN. Record: /mnt/project-files/server-seat-7/r2026-11-13/out/33067/gates-ran-06c6cc6c.list. CI check-runs: in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "3 — reads only: issue_read get x1, issue_read get_comments x2; 0 writes", "api_writes": "1 relay write — pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST /issues/33144/assignees), run 43485642149; plus this os-dev-report comment via post-stamped", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted in PR Acceptance notes: row requiresConfirmation stays actionLooksDestructive, so a heuristic-only row says requiresConfirmation: true with no marker for an account, and it runs (pinned)" ] }