Repository navigation
feat(run-token): investigate REST calls use the run token in enforce - #788
Conversation
In run-token enforce mode the investigate pod still called mctl-api's work-item routes (and, in discovery mode, the capability gateway's MCP connection) with the static MCTL_TOKEN, so MCTL_TOKEN could not leave the investigate template. mctl-api 4.119.0 already admits everything the DevLoop path needs under the investigate scope: reads of the run's own work item and sealing its own execution's snapshot. - run_token.mctl_api_bearer(): the run token in enforce mode, "" (no credential, never the static token) when enforce has none, otherwise MCTL_TOKEN. - WorkItemClient resolves its bearer per request through it, so a client built before setup() still uses the run token. - The capability gateway uses run_token.mcp_auth() like mctl_mcp_config(). - The investigator resolves --issue-url from the work item after run_token.setup(), not before. Self-attaching runs (no we_ execution) and action approvals are refused by the scope until their own slices land; investigate's work context is at observe, where a refused attach proceeds without a snapshot. Refs #717
|
Claude finished @mashkovd's task in 15s —— View job Review completeApproved at 072a444: no P1/P2 findings, 1 P3.
|
|
|
||
| run_token.setup(shadow_scope="investigate") | ||
|
|
||
| # After run_token.setup(): in enforce mode this read uses the run token, |
There was a problem hiding this comment.
P3 — With --dry-run, run_token.setup() is skipped, so under MCTL_RUN_TOKEN_MODE=enforce this --issue-url resolution gets no credential and fails with WORK_ITEM_UNKNOWN (before, it used MCTL_TOKEN). Probably fine since enforce pods shouldn't hold MCTL_TOKEN, but worth a note if dry-run is used with work-item-only invocations.
Antigravity (agy) reviewModel: gemini-3.8-flash-high · commit Finding 1:
|
agy P2 on #788: under enforce, a --dry-run with only --work-item-id skipped run_token.setup() and so resolved the issue url with no credential. setup() needs no Claude credential, so it now runs in dry-run as well. An explicit WorkItemClient token no longer overrides the run token in enforce mode, and the gateway's observe shadow header is tested. Refs #717
|
Addressed in 896e5d8:
Full suite: 6734 passed, 21 skipped. |
|
Claude finished @mashkovd's task in 16s —— View job Review completeApproved at 896e5d8 with no P1/P2 findings.
This was a static review. I didn't run the tests. |
There was a problem hiding this comment.
No P1/P2 findings (0 P3). Good to merge. At 896e5d8 the dry-run gap is closed (setup() now runs before the work-item read), and WorkItemClient._bearer passes an explicit token through mctl_api_bearer, so enforce never uses a static token.
Antigravity (agy) reviewModel: gemini-3.8-flash-high · commit No significant issues found. |
Why
Option (c) on #717 (owner decision 2026-10-24): move each run's REST calls off the static
MCTL_TOKENonto its scoped run token, then removeMCTL_TOKENfrom the CWFT. This is slice 2 of the plan posted on #717, for investigate.Slice 1 (mctlhq/mctl-api#779, 4.119.0) already admits everything the DevLoop path needs under the
investigatescope, so this slice needs no mctl-api change:we_execution)GET /api/v1/work-items/{own}/...BindWorkItemGET routePOST /api/v1/work-items/{own}/executions/{own}/snapshotBindWorkItem+BindExecution(#779)DevLoop work items are created with
visibility: tenant, and the scope'sReadAllTenantspassescanSeeWorkItem.What
run_token.mctl_api_bearer(): the run token in enforce mode;""(no credential) when enforce has no run token, never the static token; otherwiseMCTL_TOKEN.WorkItemClientresolves its bearer per request through it, so a client built beforesetup()still uses the run token. An explicittoken=argument still wins (Temporal workers are unchanged: their mode isoff).capability_gateway._default_remote_headers()usesrun_token.mcp_auth()likemctl_mcp_config(). Before this, discovery mode would have connected with the static token in an enforce run.run_issue_investigator.main()resolves--issue-urlfrom the work item afterrun_token.setup().Not in this PR (later slices on #717)
we_execution):POST .../executionsis outside the scope, so the attach is refused. Investigate's work context is atobserve, where a refused attach proceeds without work context (no snapshot). Design pending owner decision.ActionApprovalClientstays onMCTL_TOKEN. Under the investigate scope only read tools pass mctl-api anyway, so a granted approval could not be used by investigate today.Tests
tests/test_run_token.py, each mutation-verified (reverting the change turns it red):setup()(red with the oldMCTL_TOKENread)WORK_ITEM_UNKNOWN(red with a static fallback)setup()(red with the old header code)main()callssetup()before the issue-url read (red with the old order)Full suite: 6731 passed, 21 skipped.
Refs #717
🤖 Generated with Claude Code