Skip to content

feat: v1.5 release — serve-based orchestration, observability, dynamic plans, permissions#78

Merged
nigel-dev merged 17 commits intomainfrom
release/v1.5
Feb 15, 2026
Merged

feat: v1.5 release — serve-based orchestration, observability, dynamic plans, permissions#78
nigel-dev merged 17 commits intomainfrom
release/v1.5

Conversation

@nigel-dev
Copy link
Owner

@nigel-dev nigel-dev commented Feb 15, 2026

Summary

Major release implementing serve-based orchestration as the new default execution mode, with rich observability, dynamic plan orchestration, configurable permission policies, and improved UX.

Issues closed: Closes #74, closes #65, closes #66, closes #68, closes #69, closes #75

Follow-up issues created:

Changes

Fix #74: Session-aware notification routing

  • Notifications now route to the session that launched the job (launchSessionID), not whichever session happens to be active
  • Schema migrated from v2 to v3 with backward-compatible migration

Feat #65: Serve-based orchestration (5 components)

  • Port allocator (src/lib/port-allocator.ts): File-locked port allocation in configurable range (14100-14199)
  • SDK client (src/lib/sdk-client.ts): Typed client wrapper with health check polling and exponential backoff
  • Serve-based launch: Jobs launch via opencode serve --port N instead of TUI mode (configurable, default ON)
  • SDK monitoring (src/lib/monitor.ts): SSE event subscription for deterministic state detection, replacing tmux output hashing for serve-mode jobs. Dual-mode: SSE for serve, tmux for TUI.
  • Question relay (src/lib/question-relay.ts): Permission requests routed to launching session with job context. Auto-approval for worktree-scoped operations.
  • Enhanced mc_attach: Auto-opens tmux window with opencode attach for serve-mode jobs

Feat #66: Rich job observability

  • mc_status enriched with current tool, files edited, activity log for serve-mode jobs
  • mc_overview shows real-time activity indicators (streaming/tool_call/blocked/idle)
  • mc_capture supports structured event capture with filter parameter

Feat #68: Dynamic plan orchestration (4 sub-features)

  • Dynamic replanning: Skip, add, or reorder jobs mid-plan with audit log
  • Inter-job communication: Orchestrator relays findings between jobs via SDK
  • Session forking: New jobs can fork existing sessions to inherit context
  • Fix-before-rollback: Serve-mode agents get a chance to fix test failures before merge rollback

Feat #69: Permission policy engine

  • Configurable per-job/per-plan permission policies in JSON
  • Policy cascade: job-level > plan-level > global config > built-in default
  • Default: auto-approve inside worktree, deny outside (safe defaults)
  • All policy decisions logged for audit

Feat #75: Session title annotations

  • Session titles annotated when jobs need attention ("job-name done", "job-name failed", "N jobs need attention")
  • Titles reset when user re-enters the session

Fix: cancelPlan race condition

  • Moved unsubscribeFromMonitorEvents() and activePlanId = null before job killing in cancelPlan() to prevent async completion handlers from racing with plan cleanup ("No active plan exists" console error)

Fix: Model not forwarded in serve mode

  • The serve-mode launch path called createSessionAndPrompt() without passing the model, so spawned agents used the server's default model instead of inheriting the orchestrator's model
  • Now calls getCurrentModelInfo(context?.sessionID) and passes it through to the SDK sendPrompt() call, matching how the TUI path already forwards the model via the -m flag

Testing

Automated

  • bun run build passes
  • bun test passes — 801 tests across 47 files (up from 614)
  • All new features have dedicated test coverage
  • Schema v2→v3 migration tested
  • TUI-mode backward compatibility preserved in all dual-mode features

Manual E2E (427-test plan)

Full execution of the comprehensive manual test plan (MANUAL_TEST_PLAN.md) covering all 17 MCP tools, all 12 job states, and all 8 plan states.

Phase Description Tests Result Notes
0 Nuclear cleanup & snapshot 6 ✅ 6/6
1 Single job lifecycle 22 ✅ 22/22
2 Error handling & edge cases 28 ✅ 28/28
3 Multiple jobs 14 ✅ 14/14
4 Git workflow (sync & merge) 18 ✅ 16/18 2 blocked: mc_merge requires main branch
5 Plan orchestration 81 ✅ 30+ pass 5G (TouchSet) deferred to unit tests
6 Realistic multi-job 49 ⛔ Blocked Requires mc_merge (main branch)
7 Model verification 12 ✅ 8/12 4 adapted for serve mode (no -m flag or prompt file)
8 mc_report flow 54 ⚠️ 11/54 See known issue below
9 mc_overview dashboard 16 ✅ 16/16
10 OMO plan mode 10 ✅ 10/10
11 Hooks (observational) 5 ✅ 3/5 2 not testable (crash detection, compaction)
12 Final cleanup 8 ✅ 8/8
13 Serve mode launch & port 24 ✅ 24/24 Port allocation, uniqueness, release, TUI fallback
14 Enhanced mc_attach 13 ✅ 13/13 Serve: tmux window, TUI: attach command
15 Serve mode observability 21 ✅ 21/21 JSON capture, telemetry, filters, TUI fallback
16 Session-aware notifications 13 ✅ 13/13 launchSessionID captured, routing verified
17 Permission policy engine 17 ✅ 17/17 Default, permissive, restrictive, schema
18 Dynamic orchestration 16 ✅ 16/16 Audit log, relay patterns, session IDs

Blocked tests (~51): Phase 6 and Phase 4 merge tests require main branch. Testing was done on release/v1.5 where mc_merge correctly refuses to merge (validates main worktree is on default branch).

Known issue found during manual testing

checkAgentReport() skipped for serve-mode jobs — The monitor's poll() routes serve-mode jobs to subscribeToSSE() and skips checkAgentReport(). This means mc_report(status: "blocked") and mc_report(status: "needs_review") write to the filesystem (visible in mc_status) but do NOT trigger alerts in mc_overview or notifications. The monitor report pipeline is TUI-mode only. Filing as follow-up.

Other discoveries during manual testing

  1. Dual-plugin loading: The global opencode.json config had "opencode-mission-control" in the plugin list, loading the npm-cached v1.4.2 alongside the local dev build. The cached version couldn't parse v3 state files, causing "Invalid job state" errors. Fix: removed from global plugin list.
  2. Serve mode speed: Agents complete in 1-10s via serve mode (vs 30s+ in TUI mode), making time-sensitive injection tests impractical without pre-staging.

Notes

@nigel-dev nigel-dev merged commit 2f0a1f2 into main Feb 15, 2026
5 checks passed
@nigel-dev nigel-dev deleted the release/v1.5 branch February 15, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment