Skip to content

MCP: four tools still honor-system, dead gate code, ungated publish_version #83

Description

@abbyfluoroethane

Successor to #28, which is closed: b981aec blocked the six pure-judgment sign-offs at the MCP dispatcher, but three things it did not cover are still open. Splitting them out because #28's title ("baseline gate") no longer describes what's left.

1. Four tools still take any active user_id on trust

_require_human_user (src/opal/mcp/server.py:3982) is unchanged — it only checks that the supplied id matches an active User row. These four are not in _HUMAN_ONLY_SIGNOFFS, so they still reach it and an agent can pass any discoverable id:

  • join_execution
  • focus_step
  • complete_step
  • bind_issue_hold

complete_step is the sharp one: it attributes procedure work to a named person in the execution record. Worth deciding per tool against the principle b981aec established — objective/blocker-gated acts may be delegated by admin opt-in, pure-judgment sign-offs may not. Completing a step is plausibly the former (an operator working through a procedure with agent assistance), but "any id passes" is not what opt-in means either.

2. The old gate is now dead code in the blocked handlers

All six blocked tools are refused before dispatch, so the _require_human_user calls inside _sign_disposition, _accept_risk, _stamp_risk_review, _baseline_batch and _reaffirm_requirement never execute (each handler has exactly two references: its definition and the unreachable dispatch line).

_baseline_requirement is worse than dead — it carries an inlined copy of the gate (server.py:3948-3960) rather than calling the helper. If anyone hardens _require_human_user to fix item 1, that path silently would not get it. One fact, one home: delete the inlined copy and the unreachable calls, or make the helper the single gate and drive the block from it.

3. publish_version has no human gate

Dispatched at server.py:2233 with no check at all. It publishes immutable procedure versions — an authoritative act by the same reasoning that made baselining human-only. b981aec flagged this itself as out of scope and noted it on risk #76:

publish_version publishes immutable procedure versions with no human gate today — related but out of this scope; noted on risk #76 for follow-up.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions