⌂ Home ☷ Board

MC-3718: Orchestrator Flow — Design Proposal

Date: 2026-05-19 · Ticket: MC-3718 · Status: APPROVED by orchestrator — decomposed into phase tickets. Key constraint: The 2026-04-20 tmux/worktree/xterm.js rearchitecture was REJECTED. This proposal is orthogonal — orchestrator routing, not browser display. No xterm.js, no per-ticket tmux, no new systemd service, no wholesale rebuild.

1. Current state — where the orchestrator IS and IS NOT

1.1 Human path (Elmar → MC composer → work)

The composer (templates/partials/session_composer.html) has three modes — Quick Ticket, Luci do it now, Chat with Luci — all hitting POST /api/v1/session_start.

1.2 Scheduled path (cron → task → outcome)

cron → scheduler.py tick → load_tasks() → run_task() → subprocess / direct-API / background. On success: silent. On failure: _task_notify() → Telegram direct. On 3× fail: create_mc_ticket(). The orchestrator never sees outcomes. Complete bypass.

1.3 What already exists and is close

luci-persistent tmux session + full API (persistent_luci.pysend(), harvest(), start/stop/switch; app.py:8336 endpoints) — the intended orchestrator, fully functional, but unwired as a front door. The infrastructure exists; the WIRING is missing.

2. Target architecture

luci-persistent becomes the single coordination layer. Both inbound paths route through it.

Human path (target): composer → POST /api/v1/persistent_luci/send → persistent session reasons (decompose/clarify/do/ticket/delegate) → response inline in composer, with cross-message continuity.

Scheduled path (target): scheduler.py task completes → outcome written to a new orchestrator_inbox table → mc_pickup.py drain cycle reads pending items → consolidated digest → persistent_luci.send() → orchestrator triages (routine=silent, repeated failure=ticket, auth=immediate Telegram preserved, actionable=Telegram+ticket).

Design options

Decision: Option B for Phase 1 (composer), Option A for Phases 2-3 (scheduler).

orchestrator_inbox schema:

CREATE TABLE orchestrator_inbox (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  source_type TEXT NOT NULL,      -- 'scheduler','pickup','api','self_heal'
  source_id TEXT,
  message TEXT NOT NULL,
  priority TEXT DEFAULT 'normal',  -- 'critical','normal','low'
  status TEXT DEFAULT 'pending',   -- 'pending','claimed','processed','ignored'
  created_at TEXT DEFAULT (datetime('now')),
  processed_at TEXT,
  claim_expires_at TEXT
);
CREATE INDEX idx_orchestrator_inbox ON orchestrator_inbox(status, priority, created_at);

3. Phased plan (each independently shippable)

Phase 1 — wire composer "Chat with Luci" to the persistent session

Phase 2 — scheduler posts outcomes to the orchestrator inbox

Phase 3 — mc_pickup.py drains the inbox through the orchestrator

Phase 4 — orchestrator-initiated intent decomposition (OPTIONAL, deferrable)

Elmar states high-level intent; orchestrator decomposes into tickets/delegation. Start as advisor (responds, Elmar clicks to act), add autonomous action once trusted. quick_ticket/implement_now remain as bypass shortcuts.

4. Risks & constraints

Summary

Recommended: Option B (P1 composer) + Option A (P2-3 scheduler). 3 required phases + 1 optional. ~5 days total, each phase independently shippable. Files: session_composer.html, app.py, scheduler.py, mc_pickup.py, models.py (schema), persistent-session context.