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
Extend contract-gating to every late-bound tool surface with a single, compaction-safe gate. #4995 gates per-action Composio tools; this adds the surfaces it does not cover — the generic composio_execute dispatcher, the MCP-registry bridge (mcp_registry_tool_call), and workflows (run_workflow) — and makes per-action gating resilient to context compaction.
Problem
Agents compose late-bound tool calls before the tool's full contract (input JSON schema + description) is in context, so they guess argument formats and slugs — e.g. a Composio Gmail search sent without the quotes the query syntax needs, or an invented GMAIL_LIST_MESSAGES in place of the real GMAIL_FETCH_EMAILS. #4995 (for #4853) fixed this for per-action Composio tools, but:
The generic composio_execute dispatcher, the MCP-registry bridge, and workflows have the same thin-schema problem and are not gated.
fix(composio): gate per-action tools on their full contract (#4853) #4995's per-action gate tracks "already surfaced" as an in-memory seen set per tool instance, which — as its own docs note — does not reset when the surfaced schema drops out of context via summarization / microcompact / trim. The model then acts on a schema it can no longer see.
Solution
A single ContractGateMiddleware in the agent harness (assemble_turn_harness) gating all four surfaces:
Presence is derived from the transcript, not per-tool-instance state: a [contract-gate:<digest>:<key>] marker leads a delivered contract message; before each model call the gate rescans tool-role messages and rebuilds the in-context set. A contract folded away by the summarizer / blanked by microcompact / dropped by trim is no longer present, so it is re-delivered (fail-safe) — closing fix(composio): gate per-action tools on their full contract (#4853) #4995's compaction gap.
The marker embeds an XXH3-64 digest of the exact contract bytes, so a summarized/rewritten contract fails the digest match and is re-delivered.
Full-schema discovery tools (describe_workflow, mcp_registry_list_tools, composio_list_tools) pre-credit the contracts they fully render, so there is no redundant re-delivery.
composio_execute / MCP / workflows gated — the first call each turn to each surface, with its contract not in the transcript, is short-circuited with the full contract; the retry runs.
Compaction-safe presence — a contract dropped from context (summarize / microcompact / trim) is re-delivered; presence is transcript-derived and per-run.
Contract integrity — a rewritten/summarized contract body fails the payload digest and is re-delivered.
Risk: transcript-derived markers could interfere with prompt formatting if models echo them back. Mitigation: markers are tool-role messages, not user/assistant turns, so models do not see them as instructions.
Open question: whether the composio::contract_gate module should be deleted outright rather than left in place.
Acceptance Criteria
As listed in the issue body (six acceptance checkboxes).
Summary
Extend contract-gating to every late-bound tool surface with a single, compaction-safe gate. #4995 gates per-action Composio tools; this adds the surfaces it does not cover — the generic
composio_executedispatcher, the MCP-registry bridge (mcp_registry_tool_call), and workflows (run_workflow) — and makes per-action gating resilient to context compaction.Problem
Agents compose late-bound tool calls before the tool's full contract (input JSON schema + description) is in context, so they guess argument formats and slugs — e.g. a Composio Gmail search sent without the quotes the query syntax needs, or an invented
GMAIL_LIST_MESSAGESin place of the realGMAIL_FETCH_EMAILS. #4995 (for #4853) fixed this for per-action Composio tools, but:composio_executedispatcher, the MCP-registry bridge, and workflows have the same thin-schema problem and are not gated.seenset per tool instance, which — as its own docs note — does not reset when the surfaced schema drops out of context via summarization / microcompact / trim. The model then acts on a schema it can no longer see.Solution
A single
ContractGateMiddlewarein the agent harness (assemble_turn_harness) gating all four surfaces:[contract-gate:<digest>:<key>]marker leads a delivered contract message; before each model call the gate rescans tool-role messages and rebuilds the in-context set. A contract folded away by the summarizer / blanked by microcompact / dropped by trim is no longer present, so it is re-delivered (fail-safe) — closing fix(composio): gate per-action tools on their full contract (#4853) #4995's compaction gap.describe_workflow,mcp_registry_list_tools,composio_list_tools) pre-credit the contracts they fully render, so there is no redundant re-delivery.composio::contract_gatehookup is removed to avoid double-gating (the module is left in place, tracked for removal).Scope: core (Rust). Kill switch
OPENHUMAN_CONTRACT_GATE=0.Acceptance criteria
composio_execute/ MCP / workflows gated — the first call each turn to each surface, with its contract not in the transcript, is short-circuited with the full contract; the retry runs.flows/skills/mcpoff (the gate degrades to pass-through)..github/workflows/ci-lite.yml).Related
Implementation Plan
Triage Assessment
composio_execute, MCP-registry bridge, workflows) and making presence transcript-derived for compaction safety. PR Extend the contract gate to composio_execute, MCP registry, and workflows #4861 is already open and tracks implementation. Not a duplicate — Unified late-bound tool contract gate with compaction-safe transcript presence #5038 is the spec/plan issue that Extend the contract gate to composio_execute, MCP registry, and workflows #4861 implements.Proposed Scope
assemble_turn_harnessinsrc/openhuman/agent/.ContractGateMiddleware— a single harness middleware replacing per-surface gating.[contract-gate:<digest>:<key>]markers with XXH3-64 payload digest.contract_gatehookup (module retained, tracked for removal).OPENHUMAN_CONTRACT_GATE=0.Implementation Steps
ContractGateMiddlewareinsrc/openhuman/agent/harness/— evaluate presence from transcript markers before each model call.assemble_turn_harness— gatecomposio_execute,mcp_registry_tool_call, andrun_workflow.describe_workflow,mcp_registry_list_tools,composio_list_tools).composio::contract_gatehookup.flows/skills/mcpoff → gate degrades to pass-through.Verification
tests/json_rpc_e2e.rsand composio/contract gate tests.cargo-llvm-covdiff coverage >= 80%.Risks and Open Questions
composio::contract_gatemodule should be deleted outright rather than left in place.Acceptance Criteria