Two spend-safety fixes from the gap audit (#4814):
- Client.Do refused a 402 only on the budget check, but parsed
maxAmountRequired with a swallowed error, so a non-decimal, overflowing
or negative amount became 0 and passed the cap trivially while Payer.Pay
still signed against the string. Now reject any amount that is not a
positive integer before signing.
- Require settled only when the facilitator implemented Settler; a
verify-only facilitator served the resource while no funds moved. Add
Config.RequireSettlement to fail closed in that case.
Tests cover invalid/negative/overflow amounts and the verify-only
fail-closed path.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
Closes#4813. The stdio transport is the path an external MCP host (Claude
Desktop) uses, and it emitted broken output:
- tool results were `fmt.Sprintf("%v", decodedJSON)` → Go map-syntax
(`map[id:1 name:bob]`), not JSON. Now returned as JSON text.
- tool-execution failures were returned as JSON-RPC protocol errors; per the
MCP spec they must be a result with `isError:true` so the agent can read the
failure. Now they are (span/audit still record the error).
Both fixes are shared between stdio and websocket via a new `mcpToolResult`/
`mcpToolError` (dedupes the two transports). Added the missing stdio round-trip
tests (the package had zero) proving JSON output and the isError contract, using
an injected fake client; updated the websocket auth tests that asserted the old
protocol-error-on-tool-failure behavior.
Also fixes a pre-existing golangci-lint failure on master (unnecessary
`string(...)` conversion in grpcreflect.go from #4821) so the mcp package lints
clean — another one the required-checks gap let through.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
The last-100-commit assessment found the loop producing busy-work — but the root
cause was the roadmap: every forward item was hardening/conformance/docs-polish,
no net-new capability. The loop was faithfully executing a maintenance backlog.
Restock the roadmap with real capability bets and demote maintenance to explicit
background:
- Now: agents that pay (wire the existing x402 buyer into the agent runtime);
AP2 mandate foundation over A2A+x402 (#3552).
- Next: gRPC-reflection MCP; Kubernetes operator + CRDs.
- Later: the runtime-fitness loop (live Mu + operator/canary); HTTP/3; A2A
reconnection; memory/RAG.
- Ongoing: hardening/conformance/DX, capped so it never crowds out capability.
Repoint .github/loop/PRIORITIES.md to rank the capability bets at the top, with
the flagship decomposed into buildable issues (#4786 buyer wiring, #4787 spend
observability, #4788 example), so the loop pulls real work instead of grooming
itself.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
An assessment of the last 100 commits found ~45% were pure "refresh planner
priorities" bookkeeping and much of the rest was thrashing on one weak provider
(AtlasCloud text-tool-call repair) and guarding docs the loop already wrote —
motion, not progress. Two prompt-policy fixes:
PLANNER (planner.md):
- Default to NOT committing. Post the assessment and close the issue; open a
PRIORITIES.md PR ONLY when the change is MATERIAL (top item changes, an item
is added/removed, or a top item's issue closed). No PRs for reorders below
the top, reword, or "keep it current" — that churn was the loop's #1 waste.
- Add a diminishing-returns guard: don't queue the Nth doc-guard or the Nth
robustness workaround for an already-tolerated class; mark exhausted areas
needs-human and rank real-headroom capability instead.
TRIAGE (triage.md):
- Cap the AtlasCloud/plan-delegate tail-chase: another instance of a class the
agent already tolerates is NOT filed as a routine patch — comment "recurred —
capped" and, if worth more, needs-human. Real regressions (lint/tests/
govulncheck on master) and genuinely new defects still get filed.
Prompt-only; reversible. Steers the loop toward outcomes over busy-work.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>