Repository navigation
Take operator approve off the MCP server - #38
Conversation
|
@romamo Decision needed: with They existed only to be passed to
Checks pass locally (396 tests); CI was still running when this was posted. Reply here with a number or your own answer; shipmill takes this up on the tick after your reply. |
|
Decision by @romamo, given in chat; posted by Claude on his behalf. 1. Remove the |
An agent over MCP could call operator_approve and run and verify its own proposal. operator approve is now mcp=False like decisions approve, and out of PROJECT_COMMANDS; the mcp serve gateway flags only that tool used are removed. Docs and the server instructions say a person approves from a shell. Part of #35 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a9022a7 to
f668590
Compare
operator approve ran a proposal's playbook and its verify step on any shell call, so an agent with a shell could approve its own proposal. It now follows decisions approve (#37): requires_person=True, and ctx.attest asks the person to type the proposal id before anything runs. No flag answers it, --yes and a raw payload's "yes" included; off a terminal it exits 4 with PERSON_REQUIRED, a mistyped id with ATTESTATION_MISMATCH, and the proposal stays proposed. operator show is the preview. A person's approval on the receipt records approval.via (terminal; a human approval written before reads as unknown; a policy's has none), reusing ApprovalChannel from the decision record. The field is optional in operator-proposal.schema.json. requires_person implies mcp=False, so on its own this breaks `mcp serve --project`: its bound gateway_url no longer names a served tool (MCP_BIND_UNKNOWN). It lands after #38, which takes the gateway flags off mcp serve. Part of #35 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
On a project,
cloudfall mcp serveservedoperator approveas theoperator_approvetool, so an agent could run and verify its own proposal with no person in the loop.operator approvegetsmcp=Falsewith the same comment asdecisions approve("A person approves; no agent tool stands in for it"); the CLI command itself is unchanged"operator.approve"is removed fromPROJECT_COMMANDS;operator_listandoperator_showstay tools--gateway-url,--gateway-ca,--gateway-certand--gateway-keyflags ofcloudfall mcp serveare removed. Onlyoperator_approvetook them, and treaty refuses to start a server that binds a field no served tool has (MCP_BIND_UNKNOWN)docs/operator-guide.md("The record", "Through an agent") andsdk/README.mdnow say a person approves from a shell withcloudfall operator approve### Securityentry under UnreleasedTests
test_a_project_call_cannot_approve_its_own_proposal: callingoperator_approveon a project server returnsUNKNOWN_TOOL--list-toolstest:operator_listandoperator_showare listed,operator_approveis notoperator_approvefrom the expected tools to the never-tools setgateway_urlbinding assertion is gone from the secrets/URL test, since the tool no longer existsuv sync,uv run ruff check .,uv run mypy,uv run pytest(396 passed),uv run cloudfall config validate --project config/examplesanduv lock --checkall passPart of #35
🤖 Generated with Claude Code