Skip to content

feat(proxy): support terminal-on-success managed tools - #34

Merged
mostlydev merged 2 commits into
masterfrom
issue-30-terminal-on-success
Aug 3, 2026
Merged

feat(proxy): support terminal-on-success managed tools#34
mostlydev merged 2 commits into
masterfrom
issue-30-terminal-on-success

Conversation

@mostlydev

Copy link
Copy Markdown
Owner

Summary

  • adds the opt-in x-claw.terminalOnSuccess annotation for authoritative managed actions
  • emits protocol-valid empty terminals for OpenAI-compatible and Anthropic buffered and streaming responses
  • retains the complete tool trace and hidden receipt continuity without requesting a contradictory model-authored terminal round
  • documents the manifest contract

Safety contract

  • termination requires a 2xx tool response and normalized top-level ok: true
  • a terminal-on-success call must be final in the original tool-call order; invalid order is rejected before any tool executes
  • failed annotated calls keep the recovery loop
  • unannotated tools remain unchanged
  • duplicate replay of an authoritative success terminates; duplicate rejection remains an error and nonterminal

Review and verification

Codex implemented this RED-first after a design debate with Claude. Claude then performed an adversarial counter-review, independently reran the test matrix, and approved the semantics. The only follow-up was a comment-placement cleanup in 6fcf779.

  • go test ./...
  • go vet ./...
  • go test -race ./...
  • go test ./internal/proxy -run TerminalOnSuccess -count=10
  • gofmt and git diff checks

Closes #30

@mostlydev

Copy link
Copy Markdown
Owner Author

Two-agent review trail for this PR (design debate → implementation → adversarial counter-review).

Design (debated to convergence before any code): Codex proposed a six-point contract; Claude's adversarial pass accepted five points with refinements and overturned one — the original design excluded the executed tool round from hidden continuity, but the duplicate tracker is per-turn, so a model that cannot see the receipt on its next turn could re-execute a non-idempotent action. The converged contract retains the assistant call + authoritative receipt in continuity and anchors ObserveTerminalAssistant to the synthetic empty terminal, so no model-authored text can contradict the receipt.

Jointly resolved semantics, each with tests:

  • Ordering: a terminal-annotated call must be final in the original call order (native suffix included); violations are rejected preflight with zero tools executed, via an internal retry round mirroring the existing unsafe-mixed mechanism — not a 502.
  • Trigger: termination requires HTTP 2xx and top-level ok: true in the service envelope. Timeouts, schema rejections, non-2xx, ok: false all keep the recovery loop.
  • Prior error + later terminal success: terminates — the annotation contract is per-tool authoritative success; the earlier error survives in tool_trace, and the empty terminal means no false narration either way.
  • Duplicates: replay of a cached authoritative success terminates (refusing would reopen the incident on round 2); reject-policy duplicates yield an error envelope and stay nonterminal.
  • Invalid annotation values: warn via a distinct intervention and stay disabled — silent disable would recreate the incident silently; manifest rejection would brick the agent over a typo.

Counter-review of the implementation (f5349df): challenged preflight coverage across managed/native orderings, the envelope target of the ok check, the hoisted continuity append against all three loop-exit paths, and the anthropicMessageTextBlocks change's effect on non-terminal synthesis — all confirmed correct under independent verification (go test -race ./..., TerminalOnSuccess ×3 and ×10, go vet, gofmt). Only finding: stranded comments after the hoist, fixed in 6fcf779.

Left unmerged for operator decision.

@mostlydev
mostlydev merged commit 43f1b7b into master Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support annotation-driven terminal-on-success managed tools

1 participant