Skip to content

feat(opencode): bridge OpenCode to CAS specialised agents - #9

Merged
Alter-Igor merged 2 commits into
devfrom
cas-opencode-bridge
Aug 1, 2026
Merged

Alter-Igor merged 2 commits into
devfrom
cas-opencode-bridge

Conversation

@Alter-Igor

@Alter-Igor Alter-Igor commented Aug 1, 2026 •

Copy link
Copy Markdown
Owner

Issue for this PR

Closes #8

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Bridges the OpenCode fork to the Central Agent Service (CAS) at agent.alterspective.com.au so specialised business agents can be used from the coding shell without moving worktree ownership off the machine.

Hardened after adversarial review (claude-fable-5 + openai/gpt-5.6-sol via Synapse):

  1. MCP alterspective-agent → /api/v1/mcp with CAS_MCP_TOKEN (missing env → empty bearer → 401 fail-closed)
  2. Permission denials for cas_resolve_tool_call and cas_admin_*
  3. Safe tools cas-safe-*: agent allowlist, size caps, secret/source heuristics, untrusted output fencing
  4. Façade subagents: cas-delegate, cas-drafter, cas-matter-audit
  5. Plugin routing / degraded system prompt
  6. Plan + review artifacts under docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/

How did you verify your code works?

  • bun test test/plugin/cas-bridge/cas-bridge-routing.test.ts from packages/opencode: 11 pass / 0 fail (observed)
  • Live CAS MCP smoke with a real CAS_MCP_TOKEN: not run (token absent on this machine)
  • Adversarial plan review recorded in FEAT docs

Screenshots / recordings

N/A — config/plugin/tools only; no UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

No user-doc impact: developer/fork integration only.

Summary by CodeRabbit

  • New Features

    • Added a secure bridge for delegating eligible business tasks to specialized remote agents.
    • Added tools to list agents, start delegated runs, check status, and cancel runs.
    • Added dedicated drafting and matter-audit workflows.
    • Added safeguards against forwarding source code, secrets, oversized content, or untrusted output.
    • Added degraded behavior when authentication is unavailable.
  • Documentation

    • Added setup guidance, implementation plans, security reviews, and integration status documentation.
  • Tests

    • Added coverage for routing, validation, security safeguards, and degraded mode.

Wire agent.alterspective.com.au into the fork via .opencode/: MCP entry,
permission denials for resolve/admin tools, cas_safe_* tools with agent
allowlist and payload guards, façade subagents, and routing/degraded
system-prompt injection. Includes unit tests and FEAT-CAS-OPENCODE-BRIDGE docs.

Closes #8

No user-doc impact: developer/fork integration only.
@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8ec0ef22-407d-4e64-9c8e-cc44b7ebd57c

📥 Commits

Reviewing files that changed from the base of the PR and between 5c2e2e6 and e875a21.

📒 Files selected for processing (5)
  • .opencode/tool/cas-bridge-lib.ts
  • .opencode/tool/cas-safe-list-agents.ts
  • docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/adversarial-review-gpt56.md
  • docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/status.md
  • packages/opencode/test/plugin/cas-bridge/cas-bridge-routing.test.ts

📝 Walkthrough

Walkthrough

Added a token-gated MCP bridge between OpenCode and CAS. The bridge provides restricted tools, façade agents, routing prompts, payload validation, untrusted-output fencing, run controls, tests, and implementation documentation.

Changes

CAS OpenCode Bridge

Layer / File(s) Summary
Bridge architecture and routing
docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/plan.md, .opencode/opencode.jsonc, .opencode/plugin/cas-bridge-routing.ts, .opencode/agent/*, AGENTS.md
Configured the CAS MCP server and denied raw or administrative CAS tools. Added token-aware routing and degraded-mode prompts. Added three CAS façade agents.
Validation and MCP client
.opencode/tool/cas-bridge-lib.ts
Added token detection, agent allowlisting, payload limits, source and secret detection, untrusted-output fencing, authenticated JSON-RPC MCP calls, and JSON/SSE response parsing.
Safe CAS tool façades
.opencode/tool/cas-safe-*.ts
Added safe tools for delegation, agent listing, run retrieval, and run cancellation. The tools validate credentials and inputs and sanitize results and errors.
Verification and implementation records
packages/opencode/test/plugin/cas-bridge/cas-bridge-routing.test.ts, docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/*, AGENTS.md
Added tests for routing, degraded mode, validation, sensitive-content detection, and output fencing. Added implementation status and adversarial review records.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OpenCode
  participant cas_bridge_routing
  participant cas_safe_delegate
  participant cas_bridge_lib
  participant alterspective_agent
  OpenCode->>cas_bridge_routing: transform system prompt
  cas_bridge_routing-->>OpenCode: routing or degraded-mode guidance
  OpenCode->>cas_safe_delegate: delegate agentId, task, context
  cas_safe_delegate->>cas_bridge_lib: validate delegate input
  cas_bridge_lib->>alterspective_agent: initialize MCP session
  cas_bridge_lib->>alterspective_agent: call cas_delegate
  alterspective_agent-->>cas_bridge_lib: CAS result
  cas_bridge_lib-->>cas_safe_delegate: bounded untrusted result
  cas_safe_delegate-->>OpenCode: fenced delegation output
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary change: bridging OpenCode to CAS specialised agents.
Description check ✅ Passed The description follows the template and covers the issue, change type, implementation, verification, screenshots, and checklist.
Linked Issues check ✅ Passed The PR satisfies issue #8 by adding the MCP configuration, denied tools, safe tools, façades, routing, tests, and implementation documentation.
Out of Scope Changes check ✅ Passed The changes are related to the CAS bridge objectives, including implementation, tests, security reviews, status, and supporting documentation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cas-opencode-bridge

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 9

🧹 Nitpick comments (1)
packages/opencode/test/plugin/cas-bridge/cas-bridge-routing.test.ts (1)

11-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Type the plugin fixture and hook values.

mockInput, hooks, and the three localHooks values use any. This can hide a changed plugin input contract or a missing hook. Use the actual plugin input type, Awaited<ReturnType<typeof plugin>> for hooks, and inferred types for each localHooks value.

Suggested type changes
-let hooks: any
+let hooks: Awaited<ReturnType<typeof plugin>>

-    const localHooks: any = await plugin(mockInput)
+    const localHooks = await plugin(mockInput)

Construct mockInput as the minimal valid value for Parameters<typeof plugin>[0] instead of casting it to any.

As per coding guidelines, avoid the any type in TypeScript tests.

Also applies to: 19-19, 45-45, 55-55, 65-65

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/opencode/test/plugin/cas-bridge/cas-bridge-routing.test.ts` at line
11, Replace the any-based casts in the cas-bridge routing test: construct
mockInput as a minimal valid Parameters<typeof plugin>[0] value, type hooks as
Awaited<ReturnType<typeof plugin>>, and let each of the three localHooks values
use inferred types. Remove all any usage while preserving the existing fixture
behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.opencode/tool/cas-bridge-lib.ts:
- Around line 45-50: Update looksLikeSecret so Bearer-token detection is not
gated by the overall text.length; remove the 500-character condition or limit
evaluation to the matched local token context, while preserving the existing
Bearer pattern and other secret checks.

In @.opencode/tool/cas-safe-list-agents.ts:
- Around line 8-14: Update execute in the cas-safe-list-agents tool to wrap
callCasMcpTool in try/catch, matching cas-safe-delegate.ts, cas-safe-get-run.ts,
and cas-safe-cancel-run.ts. Return a safe error message from the catch path
after redacting any Bearer token pattern (Bearer\s+\S+) from the error text,
while preserving the existing token check and successful wrapUntrusted flow.

In
`@docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/adversarial-review-gpt56.md`:
- Line 245: Remove the standalone `|` row from the Markdown table in the
reviewed document, leaving the surrounding two-column table rows unchanged.

In
`@docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/adversarial-synthesis.md`:
- Line 29: Update both records in
docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/adversarial-synthesis.md:29-29
and docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/status.md:38-38 to make
denying raw cas_delegate and other CAS MCP tools to the primary agent an
explicit release-gated requirement, or document and enforce a user-only path
with permission tests. Ensure the primary agent cannot bypass the safe façade
through model-callable raw tools; both records must reflect the same
requirement.
- Line 23: Harden the CAS-output path around wrapUntrusted by escaping or
stripping hostile delimiters, system-prompt markers, and tool-call text before
producing model-facing output, or replace the boundary with structured output.
Ensure raw CAS-result tools cannot bypass wrapUntrusted, and add regression
coverage for marker payloads and truncation behavior.
- Line 21: Update the raw CAS tool authorization flow described in the “Auth not
verified” row to disable or deny tools such as cas_delegate whenever
CAS_MCP_TOKEN is missing or empty, rather than allowing an empty Bearer
credential to reach the raw MCP transport. Route unauthenticated calls through
the safe bridge if that is the established path, and add a test that verifies no
network request occurs without a token.

In `@docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/status.md`:
- Around line 21-24: Update the validation command documentation in status.md to
specify packages/opencode as the working directory and place the command in a
shell-formatted code fence. Preserve the existing test command while making its
execution context explicit and reproducible.

In `@packages/opencode/test/plugin/cas-bridge/cas-bridge-routing.test.ts`:
- Around line 114-119: Strengthen the wrapUntrusted test to validate the
complete untrusted-output contract: assert that the output includes the
untrusted-output instruction or warning text, and exercise a body exceeding the
configured response limit to verify truncation behavior. Keep the existing
delimiter and body assertions while using the relevant limit configuration
symbol.
- Around line 21-37: Update the test setup around beforeAll and afterEach to
reset CAS_BRIDGE_ROUTING_ENABLED, CAS_BRIDGE_ROUTING_DISABLED, and
CAS_AGENT_ALLOWLIST to known values before every test, using beforeEach rather
than one-time initialization. Preserve afterEach restoration of the original
environment values so each test remains isolated.

---

Nitpick comments:
In `@packages/opencode/test/plugin/cas-bridge/cas-bridge-routing.test.ts`:
- Line 11: Replace the any-based casts in the cas-bridge routing test: construct
mockInput as a minimal valid Parameters<typeof plugin>[0] value, type hooks as
Awaited<ReturnType<typeof plugin>>, and let each of the three localHooks values
use inferred types. Remove all any usage while preserving the existing fixture
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a272c18f-a649-47ea-b46d-9c012cf9775e

📥 Commits

Reviewing files that changed from the base of the PR and between 3f66835 and 5c2e2e6.

📒 Files selected for processing (17)
  • .opencode/agent/cas-delegate.md
  • .opencode/agent/cas-drafter.md
  • .opencode/agent/cas-matter-audit.md
  • .opencode/opencode.jsonc
  • .opencode/plugin/cas-bridge-routing.ts
  • .opencode/tool/cas-bridge-lib.ts
  • .opencode/tool/cas-safe-cancel-run.ts
  • .opencode/tool/cas-safe-delegate.ts
  • .opencode/tool/cas-safe-get-run.ts
  • .opencode/tool/cas-safe-list-agents.ts
  • AGENTS.md
  • docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/adversarial-review-fable.md
  • docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/adversarial-review-gpt56.md
  • docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/adversarial-synthesis.md
  • docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/plan.md
  • docs/implementation/current/FEAT-CAS-OPENCODE-BRIDGE/status.md
  • packages/opencode/test/plugin/cas-bridge/cas-bridge-routing.test.ts

Comment thread .opencode/tool/cas-bridge-lib.ts Resolved
Comment thread .opencode/tool/cas-safe-list-agents.ts Resolved
Remove Bearer length gate, redact list-agents errors, harden tests and
docs formatting from PR #9 review.
@Alter-Igor

Copy link
Copy Markdown
Owner Author

PR-loop disposition (cycle 1)

Head: e875a211f4c2a9a1ccf6f5de8bb253036a10f678

CodeRabbit

  • Fixed: Bearer secret check length gate; cas-safe-list-agents try/catch+redaction; test beforeEach isolation; wrapUntrusted truncation asserts; markdown table + status.md shell fence.
  • Threads resolved with replies pointing at fix commit.

Compliance / standards

CI gap

Merging with documented CI-queue residual; no unresolved threads.

@Alter-Igor
Alter-Igor merged commit 2625dd3 into dev Aug 1, 2026
12 of 19 checks passed
@Alter-Igor
Alter-Igor deleted the cas-opencode-bridge branch August 1, 2026 09:53
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.

feat: bridge OpenCode to CAS specialised agents

1 participant