Skip to content

fix(opencode): keep invalid repair sink under DFIR deny-all - #16

Merged
TimothyVang merged 1 commit into
mainfrom
agent/m25-seal-reliability
Jul 9, 2026
Merged

fix(opencode): keep invalid repair sink under DFIR deny-all#16
TimothyVang merged 1 commit into
mainfrom
agent/m25-seal-reliability

Conversation

@TimothyVang

Copy link
Copy Markdown
Owner

Summary

FORCE_AGENT seal reliability gap on the live SessionPrompt path (post-#15 tool_choice: required):

  1. Root cause (code, not model): DFIR locked profile uses "*": "deny" with only findevil-mcp_* / findevil-agent-mcp_* allowed. That stripped the internal invalid tool from prepared.tools.
  2. experimental_repairToolCall remapped unknown/garbled names to invalid, then AI SDK failed with Model tried to call unavailable tool 'invalid' (m24 seal-smoke evidence).
  3. Fix: always keep the invalid repair sink executable under deny-all (still hidden via activeTools), and remap common underscore/hyphen MCP name drift (e.g. findevil-agent_mcp_*findevil-agent-mcp_*) before falling back to the sink.

Does not invent used_fallback=0. Residual model prose/incomplete seal loops can still force caseforge fallback; this only fixes the broken self-correction path for invalid tool names.

Binary

  • Installed: $HOME/.local/bin/verdict
  • Version: 0.0.0-agent-m25-seal-reliability-202607092026
  • Commit: bd75e8435ce5418e5065927f87c4b3e53f8c1af5

Test plan

  • bun test test/session/tool-repair.test.ts (9 pass) in packages/opencode
  • bun typecheck in packages/opencode
  • Pre-push monorepo typecheck green
  • caseforge FORCE_AGENT re-smoke (feeds=caseforge) — may still be model residual

SessionPrompt tool_choice=required still failed FORCE_AGENT when models
invented MCP names: experimental_repairToolCall remapped to `invalid`,
but DFIR `"*": deny` stripped that sink so AI SDK reported
"unavailable tool 'invalid'". Keep the sink executable (hidden via
activeTools), remap underscore/hyphen drift onto real tools, and cover
with unit tests.
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@TimothyVang
TimothyVang merged commit 1be8410 into main Jul 9, 2026
8 of 9 checks passed
@TimothyVang
TimothyVang deleted the agent/m25-seal-reliability branch July 9, 2026 20:30

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bd75e8435c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// "unavailable tool 'invalid'".
return Record.filter(
input.tools,
(_, k) => k === "invalid" || (input.user.tools?.[k] !== false && !disabled.has(k)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep invalid out of native tool definitions

In OPENCODE_EXPERIMENTAL_NATIVE_LLM sessions with DFIR-style "*": "deny" permissions, this now leaves the internal invalid tool in prepared.tools; the native branch passes all of prepared.tools into nativeTools(...)/toDefinitions(...) and has no activeTools filter like the AI SDK branch. That means the repair sink is advertised to the provider rather than only kept executable, so the model can select invalid directly and loop on repair hints. Filter the sink from native tool definitions while keeping it available for repair execution.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant