Design Questions: OpenClaw-OpenCode Bridge

Date: 2026-02-12
Status: Awaiting answers
Purpose: Clarify key architectural decisions before implementation


Context

We’re designing a multi-tier agent architecture:

DM Channel (WhatsApp/Slack)
    ↓
Personal Assistant (OpenClaw general purpose)
    ↓ (delegates workspace ops)
Orchestrator (OpenCode @ workspace-root)
    ↓ (reads/updates)
.ai/projectlist.md
    ↓ (creates/manages)
Builder Sessions (.builders/<project-id>-<name>/)
    ↓ (references detailed specs)
.ai/projects/<category>/<project-name>/

Key insight: Projects in projectlist.md ARE the sessions. Builder naming follows: .builders/<project-id>-<name>/


1. Orchestrator Workspace Structure

The orchestrator is a special OpenCode session that manages workspace-level operations.

Q1.1: Where should the orchestrator run?

Option A: Direct at workspace root (no builder workspace)

<workspace-root>/
├── .ai/
├── repos/
├── codev/
└── Taskfile.yaml
# Orchestrator runs here with `opencode acp --cwd .`

Option B: Dedicated orchestrator workspace

<workspace-root>/.orchestrator/
├── workspace-root/   (worktree → <workspace-root>)
# Orchestrator runs here

Your preference: A

Rationale: Don’t see any value in B

Q1.2: What should the orchestrator have access to?

Should it see:

  • .ai/projectlist.md - Definitely needed
  • .ai/projects/ - Needed to read project metadata
  • Taskfile.yaml - To run builder:init/cleanup tasks
  • repos/ - All repos? Or only workspace-root?
  • .builders/ - To inspect existing builders?

Your answer: Everything (in ~/src)

Q1.3: Should the orchestrator be always-running or on-demand?

Option A: Always-running daemon

  • Starts with Gateway
  • Personal Assistant sends requests via ACP
  • Fast response (already running)

Option B: On-demand spawning

  • Personal Assistant starts it when needed
  • Terminates after completing operation
  • Lower resource usage when idle

Your preference: A. We already run opencode web in a seperate pod (codev in the code-server ns) so i imagine we figure out how to get openclaw to communicate with that. It doesn’t start with the gateway, the server is expected to be running, and the orchestrator session is already there, so openclaw will probably just need to communicate with it.

2. Session-to-Project Mapping

Q2.1: How does projectlist.md map to .ai/projects/ locations?

Current examples from projectlist.md:

# Project 0012
files:
  spec: .ai/projects/ai-dev/opencode-slack-integration/prd.md
  
# Project 0014
files:
  plan: .ai/projects/tri-training/2026-02-12IMBuild/plan.md

Should we:

Option A: Add explicit metadata_path field

- id: "0014"
  title: "Ironman Training"
  metadata_path: .ai/projects/tri-training/2026-02-12IMBuild/
  files:
    plan: .ai/projects/tri-training/2026-02-12IMBuild/plan.md

Option B: Infer from spec/plan file path

  • Parse directory from existing files.spec or files.plan
  • Example: files.spec = .ai/projects/ai-dev/foo/prd.md → metadata at .ai/projects/ai-dev/foo/

Option C: Keep current approach (no automatic mapping)

  • Orchestrator doesn’t need to know .ai/projects/ location
  • User specifies repos when creating builder

Your preference: It’s implied by the files but we could use folders there instead of multiple files if easier?

Q2.2: How should the orchestrator discover which repos a project needs?

Option A: From .ai/projects//metadata.json

{
  "project_id": "0014",
  "repos": ["ai-dev", "openclaw"],
  "builder_name": "0014-ironman-training"
}

Option B: From projectlist.md

- id: "0014"
  title: "Ironman Training"
  repos: [ai-dev]  # Add new field

Option C: User specifies when creating builder

User: "Create builder for project 0014, use repos ai-dev and openclaw"
→ Orchestrator creates builder with those repos

Option D: Combination

  • metadata.json has defaults
  • User can override when creating

Your preference: I think we probably maintain it in the projectlist - use whats in the project(s) as the default but allow more to be added?

3. Personal Assistant ↔ Orchestrator Communication

Q3.1: How does Personal Assistant invoke the Orchestrator?

Option A: Direct ACP calls (orchestrator always running)

Personal Assistant → HTTP POST to http://localhost:8080/sessions/orchestrator/messages
Body: { "content": "Create builder for project 0014 with repos ai-dev" }

Option B: Via OpenClaw tool wrapper

Personal Assistant → orchestrator tool (wraps ACP calls)
orchestrator(action='create_builder', project_id='0014', repos=['ai-dev'])

Your preference: I think this needs more research by you to make a recommendation, definitely prefer api calls to cli if possible

Q3.2: What operations should the orchestrator handle vs Personal Assistant?

Orchestrator handles:

  • [✓ ] Create builder session
  • [✓ ] Terminate builder session
  • List all sessions (with git status per builder)
  • Update projectlist.md status
  • Link session to .ai/projects/ entry
  • [✓ ] Sync builder workspace state back to repos
  • [✓ ] Run Taskfile commands (builder:init, builder:cleanup)

Personal Assistant handles directly (no orchestrator):

  • [✓ ] Show session status (query stored metadata)
  • Route messages to existing builder sessions
  • [✓ ] General conversation, questions, web searches
  • Query projectlist.md (read-only)
  • [✓ ] Non-workspace operations

Any others?

  • [✓ ] Update projectlist.md status

4. Event Filtering and Chat Output

Q4.1: Which OpenCode events should be forwarded to chat?

Problem: Streaming all events (file_opened, file_changed, command_run, etc.) would be noisy and expensive.

Proposed filter (hardcoded, no AI processing):

Always forward:

  • agent.complete - “Done! Added rate limiting.”
  • agent.question - “Should I write tests?”
  • agent.error - “Build failed: missing dependency”
  • agent.waiting_approval - “Need permission to run npm install”

Never forward:

  • agent.file_opened
  • agent.file_read
  • agent.thinking

Conditional (only if critical):

  • agent.command_run - Only if exit_code !== 0
  • agent.test_run - Only if tests failed

Your preferences:


Q4.2: Should we send a “started working” message?

User: "Add rate limiting"
OpenCode: "🔨 Working on it..." (immediate feedback)
[... silence while working ...]
OpenCode: "✅ Done! Added rate limiting." (completion)

Your answer: Sure

Q4.3: Where should session event history be stored?

For on-demand queries like “What did you change?”, we need full event history.

Option A: In-memory (Gateway)

  • Fast, simple
  • Lost on Gateway restart
  • Suitable for short-lived sessions

Option B: Redis/Database

  • Persistent across restarts
  • Queryable, searchable
  • More complex setup

Option C: File-based in builder workspace

.builders/0014-ironman-training/
├── workspace-root/
├── ai-dev/
└── .session-history.json  # All events stored here

Option D: Don’t store (always query OpenCode session history API)

  • Assumes ACP has session history endpoint
  • No duplicate storage
  • Depends on ACP capabilities

Your preference:


Q4.4: Should the orchestrator also use filtered events?

The orchestrator session itself will emit events when creating/managing builders.

Should orchestrator events be:

  • Forwarded to DM channel (admin sees everything)?
  • Logged only (silent background operations)?
  • Filtered same as builder sessions?

Your answer: Should be the same as builders

5. Project Status Transitions

Q5.1: Should the orchestrator auto-update projectlist.md status?

Scenario: Personal Assistant asks orchestrator to create builder for project 0014.

Should orchestrator:

Option A: Auto-update status

Before: status: planned
Orchestrator creates builder
After: status: implementing

Option B: Manual only

  • Orchestrator never modifies projectlist.md
  • Human updates status explicitly
  • Follows current workflow (human approval gates)

Option C: Suggest status change

Orchestrator: "Builder created. Suggest updating project 0014 status: planned → implementing. Approve?"
Personal Assistant relays to user via DM
User approves → orchestrator updates

Your preference: I think the update to projectlist happens first… So with human change to projectlist is agreed, then passed to orchestrator to reconcile

Q5.2: Which status transitions should require human approval?

From projectlist.md lifecycle:

conceived → specified → planned → implementing → implemented → committed → integrated
     ↑                                                                         ↑
Human approves                                                           Human approves

Current gates:

  • conceivedspecified: Human must approve spec
  • committedintegrated: Human validates production

Should orchestrator be allowed to transition:

  • plannedimplementing (when builder created)
  • implementingimplemented (when PR created)
  • implementedcommitted (when PR merged)

Your answer: I think the personal assistant with human input does this.

  • plannedimplementing personal assistant changes before handing to opencode
  • implementingimplemented personal assistant changes when pr is raised by opencode
  • implementedcommitted personal assistant changes after merge & input from human

6. Multiple Builders Per Project

Q6.1: How to handle projects with multiple builders?

Example from projectlist.md:

- id: "0012"
  notes: "Two builders: 0012-slack-gateway, 0012-bridge-plugin"

Current structure:

.builders/
├── 0012-slack-gateway/
└── 0012-bridge-plugin/

Questions:

  1. How should user create multiple builders for one project?
  2. Should they share the same session_id (0012)?
  3. Or have separate IDs (0012a, 0012b)?
  4. How to track in projectlist.md?

Your answer: I think multiple builders for the same project, like the above, is fine. If there is more than one simultaneous builder in a category then a new group should be created for the subsequent one(s).

Q6.2: Should builders be linkable/aware of siblings?

If project 0012 has two builders, should they:

  • Run independently (no awareness of each other)?
  • Share context somehow (coordinated by orchestrator)?
  • Have access to each other’s workspaces?

Your answer: Independent, before being spawned the integration rules should be agreed (e.g. an api contract)

7. Chat Binding Configuration

Q7.1: Where should chat bindings be stored?

Chat bindings link sessions to chat surfaces:

session_id: "0014"
platform: whatsapp
channel_id: "120363xxx@g.us"
trigger: all_messages

Option A: Gateway config file

# ~/.openclaw/config/bindings.yaml
bindings:
  - session_id: "0014"
    platform: whatsapp
    channel_id: "120363xxx@g.us"

Option B: In .builders/ workspace

.builders/0014-ironman-training/.binding.yaml

Option C: In projectlist.md

- id: "0014"
  title: "Ironman Training"
  chat_binding:
    platform: whatsapp
    channel_id: "120363xxx@g.us"

Option D: Database/Redis

Your preference: I think we can store the info in projectlist (we might not need channel_id?) but ~/.openclaw needs to be correct


Q7.2: Should one project support multiple chat bindings?

Example: Project 0014 bound to BOTH:

  • WhatsApp group (team collaboration)
  • Slack thread (status updates)

Should this be allowed? Not in scope for now, but yaml should support multiple

If yes, how?


8. Builder Naming and Lifecycle

Q8.1: Confirm builder naming convention

Current pattern from projectlist.md:

.builders/<project-id>-<kebab-case-name>/

Examples:

  • .builders/0012-slack-gateway/
  • .builders/0013-market-maker-mvp/
  • .builders/0014-ironman-training/

Is this the standard we should follow? Yes

If no, what should it be?


Q8.2: When should builders be cleaned up?

Trigger options:

  • When project status → committed (PR merged)
  • When project status → integrated (deployed)
  • When project status → abandoned
  • [x ] Manual cleanup only (never automatic)
  • After X days of inactivity
  • When user explicitly requests termination

Your preferences: Manual for now, leave space in the spec to revisit automation later

Q8.3: Should cleanup preserve anything?

When cleaning up .builders/0014-ironman-training/:

Should we preserve:

  • Session history/logs (move to .ai/projects/.../session-history.json?)
  • Git commits (assume pushed to remote already)
  • Local changes (fail cleanup if uncommitted changes?)
  • Nothing (delete everything)

Your answer: Sounds good, needs to ensure there aren’t any uncommitted changes

9. Integration with Existing Projects

Q9.1: Backward compatibility with current .builders/

You mentioned:

Project 0013: "Built in .builders/0013-market-maker-mvp"
Project 0012: "Two builders: 0012-slack-gateway, 0012-bridge-plugin"

Are these builders:

  • Already using the OpenCode session pattern?
  • Created manually (not via orchestrator)?
  • Something else?

Your answer: They are created manually, at the moment, but do loosely follow the pattern.


Q9.2: Migration path for existing projects

For projects already implementing with existing builders:

Should orchestrator:

  • Detect and adopt existing builders?
  • Require rebuild/recreation?
  • Support both old and new patterns?

Your answer:


10. OpenCode ACP Discovery

Q10.1: Dependencies on Phase 0 discovery

Many design decisions depend on what OpenCode’s ACP actually supports.

Critical questions for Phase 0:

  1. Does ACP have a session history API?
  2. Can we specify event filtering mode when creating session?
  3. Does ACP support session metadata (tags, custom fields)?
  4. Can multiple clients attach to same session?
  5. Does ACP persist sessions across server restarts?

Should we:

  • Answer architecture questions now (with assumptions)?
  • Block on Phase 0 discovery first?
  • Design generically to adapt later?

Your preference:


11. Additional Questions

Q11.1: Any other architectural concerns?


Q11.2: Priority order for implementation?

Once we have answers, what order should we implement?


Summary

Please annotate this document with your answers. Use HTML comments or add text directly.

When complete, this will form the foundation for:

  1. Updated opencode-session-pattern.md (with orchestrator)
  2. New orchestrator-pattern.md document
  3. Implementation specifications for the OpenClaw tool
  4. Gateway configuration schemas

Next Steps After This:

  1. You annotate with answers
  2. I review and create updated/new documentation
  3. We align on the architecture
  4. Phase 0: ACP protocol discovery (if not blocking)
  5. Implementation begins