Director runtime
Each of the 5 departments has a director agent that operates the department harness. Directors run via spawned claude -p processes. They read live state, decide what to do, and emit structured ACTIONS that the backend executes.
This is the layer above the per-project coding harness. A director’s job is coordination (sending Decisions, Priorities, BuildRequests, etc.); the actual code-writing happens inside specific projects, each running their own coding harness with the role graph documented elsewhere in these docs.
Prompt resolution
Section titled “Prompt resolution”Director prompts are resolved by inheritance:
base/<role>.md+ department/<role>.md+ department/departments/<dept>/<role>.md (if exists)+ ceo override (if business + worker + ceo mode)+ live state (charter + notes + decision log + memory + inbox + outbox)+ "your task right now" (closer asking for ACTIONS)Roles: orchestrator, worker, validator, documenter, summarizer. The CEO is a worker variant for Business when handling Directive kind.
The resolved prompt is available via GET /api/org/:dept/prompt?role=&mode=&context=1.
Memory injection (round 31)
Section titled “Memory injection (round 31)”Each prompt’s live-state block includes a synthesized ## Recent decisions (your own memory, newest first) section drawn from the dept’s last 12 director-run records. Each line is <ts> [<decisionKeyword>] → <first action> (final:<outcome>). This lets a director notice patterns like “I keep deferring this” or “last 3 NEXT_WORKER_CEO_MODE went to the same message.”
Synthesis happens in synthesizeRecentMemory(harnessSlug, limit) and is also exposed at GET /api/org/:dept/memory?limit=N for the Memory tab in the Department Harness Dashboard (table view + collapsible “Raw text injected into prompt” inspector).
The autonomous loop
Section titled “The autonomous loop”POST /api/org/:dept/run-loop runs:
- Orchestrator — reads inbox + state, outputs one decision keyword:
DONE— nothing left to doNEXT_WORKER <id>— assign a worker to handle inbox messageNEXT_WORKER_CEO_MODE <id>— Business-only: assign CEO mode for a DirectiveNEXT_VALIDATOR <id>— validator should crosscheck a recently emitted outbox messageESCALATE <id> <reason>— exceeds authority
- Worker / CEO / Validator — runs with the chosen message in context. Outputs reasoning + ACTIONS block.
- Backend executes the ACTIONS sequentially. Charter validation runs server-side; a violating action errors out and aborts the iteration.
- Loop back to step 1 with updated state. Stops on DONE / ESCALATE / max-iterations / cancellation / per-step error.
Every loop’s full trace persists to ~/org-{dept}/.harness/director-runs/<ts>_loop.md. Each worker’s full output appends to ~/org-{dept}/.harness/worker-log.md.
Server-side scheduler
Section titled “Server-side scheduler”Each department has a .harness/director-config.json with {autoLoop, autoIntervalSeconds}. When autoLoop: true, the server registers a scheduled loop that fires every autoIntervalSeconds (30-3600).
- Schedulers are server-side, not browser-side. Closing every browser doesn’t stop them.
- They survive Hot Module Reload via
globalThis.__papercupSchedulers. - Skip iterations when an active run is in flight (no overlap).
- Re-read config on each tick so toggle/interval changes take effect immediately.
- Scheduled run records use the
_scheduler.mdsuffix (vs_loop.mdfor manual).
GET /api/org/schedulers lists all active server-side schedulers with secondsRemaining until next fire.
In-flight control
Section titled “In-flight control”GET /api/org/active-runs— list current claude processes across all depts (pid, kind, elapsed)POST /api/org/:dept/stop-loop— SIGTERM the active claude process for that dept (then SIGKILL after 2s grace)POST /api/org/admin/stop-all— emergency stop: cancels all active runs + clears all schedulers + persistsautoLoop: falseto every dept
These controls live in each dept’s Director Agent tab (in /harness/org-{slug}). The earlier per-tile cockpit on /papercup/organization and the standalone /papercup/health page were removed; their code is preserved at libs/papercup-shared/src/_discarded/HarnessOpsCockpit.tsx.
Streaming director output
Section titled “Streaming director output”GET /api/org/:dept/run-director-stream?role=&mode= is an SSE endpoint that streams claude’s stdout chunk-by-chunk:
event: start— run kicked offevent: chunk— partial stdoutevent: stderr— partial stderrevent: done— process closed; final decision keyword
The Department Harness Dashboard’s Director Agent tab uses this to stream output live into a terminal-style pane during a run.
Director run records
Section titled “Director run records”Every claude invocation produces a ~/org-{dept}/.harness/director-runs/<ts>_<kind>.md file with the prompt summary, decision keyword, and full stdout. Surfaced as a “Recent runs” disclosure in the Director Agent tab; click to expand any run inline.
GET /api/org/:dept/director-stats parses these records to compute KPIs: total runs, breakdown by outcome (DONE/NEXT_WORKER/cancelled/etc), breakdown by kind (orchestrator/loop/scheduler).
Director config
Section titled “Director config”Per-dept config at ~/org-{dept}/.harness/director-config.json:
{ "autoLoop": false, "autoIntervalSeconds": 60}Editable via PUT /api/org/:dept/director-config (auto-emits an audit entry). The Department Harness Dashboard’s Director Agent tab persists changes immediately. The server-side scheduler reschedules on every config write.