PROJECT STATUS 2026-05-30 system stable 264 commits to main ~31k LOC (19k src + 12k tests)

Nyx: 5 deadlock fixes + status pulse + reflector landed today.

Working project status as of 2026-05-30. 9 new commits merged this morning: 5 worker-deadlock root-cause fixes, GET /status/pulse (token-free SQL health broadcast every 20min), GET /reflection/digest (rule-based weekly self-improvement digest). Verifier runtime gate queued. TUI is live at apps/tui-go/nyx-tui.

670+
tests passing
~31k
LOC (19k src + 12k tests)
264
commits to main
9
new commits today

Two diagrams side by side. Mentally diff them to see what's left.

Current workflow (as of 2026-05-30)

All shipped components as of today. Five-column view: triggers on the left, oversight and persistence on the right. New today (9 commits): 5 deadlock root-cause fixes (planner 0-subtask early return + 45min fanout cap, archive() SIGTERMs subprocess, 60min worker runtime cap, autopilot 1h cooldown, watchdog tool_use idle tracking at 15min), GET /status/pulse (pure-SQL health broadcast every 20min on SSE, haiku escalation on anomaly only), GET /reflection/digest (rule-based audit-log analysis, 1 haiku call per digest, fires on daily scheduler). Verifier runtime gate queued. Go TUI live at apps/tui-go/nyx-tui. Multi-moderator and concierge-uses-planner still in flight.

INPUT MODERATE + GATE EXECUTE OVERSIGHT PERSIST + NOTIFY User chat ws: chat_send dashboard composer Scheduler 60s cron tick heartbeat + idle detect Self-Iterator nyx-self/* branches autonomous code edits Autopilot drains the queue dispatch with no operator Concierge haiku Q&A memory-aware replies Moderator sonnet-4-6 two-phase prompt prepend Push Gate floor + blacklist.yml + best-effort normalize Cost Guardrails billing-mode detect per-session budget cap Model Probe 24h tick, tier routing Critic/Watchdog=haiku Sleep Mode timed full autonomy floor still enforced Worker Manager cap 8 concurrent per-session isolation Worker (sonnet-4-6) default workload claude code subprocess Worker (opus-4-8) big / long tasks auto-routed by Model Probe Permission MCP stdio sidecar + research tool nyx + Codex MCP durable memory tools image + fast code Critic singleton haiku | code review gates self-iter merges Watchdog idle-v2 haiku | drift detect reinjects on stall Auto-Merge Daemon tests pass + Critic ok sweeps nyx branches Orphan sweep on boot stale session cleanup Telemetry /metrics health tokens, MTBF, success SQLite WAL events / sessions / audit spend_log / self_iter / memory full audit queryable via /audit Control Room + TUI dashboard + terminal grid streamed markdown Operator notify ntfy daemon + Discord gate prompts + digests Supervisor launchd + bash watchdog Moderator never dies send spawn review log cron self-iter reinject dispatch ws: events stream back to operator, telemetry, and SQLite ADDED 2026-05-30 (walk-away autonomy + morning fixes) Planner + Fanout + Synth POST /plan, N parallel worktrees Auto-restart on merge 30s debounce, keep-alive respawn Auto-revise loop critic revise → fixer worker (in flight) Branch janitor archive merged, quarantine exhausted Sleep auto-schedule 23:00–07:00 local, op-override wins SAFETY INVARIANT (provable by test) Tier 1 hardcoded floor cannot be overridden by any operator config, even in Sleep Mode  |  floor-cannot-be-lifted.test.ts
green = shipped and running  ·  flow lines = real data flow today  ·  2026-05-30

Full vision (all phases complete)

Target architecture when every phase ships. Green boxes are already shipped (as of 2026-05-30); blue boxes remain. What's still ahead: the multi-moderator process model with the 2-slot / 4-worker caps (in flight), concierge auto-routing big tasks through the planner (in flight), and the Verifier runtime gate + Visual Iteration items (queued). The Go TUI is live. Once the remaining items land, the operator gives intents and the system runs them across 1-2 project moderators with workers, planner, critic, auto-revise, verifier, janitor, and auto-restart all self-driving. Memory persists across all sessions; the operator becomes optional for everything except strategic conversation.

TRIGGER ROUTE MODERATE EXECUTE REVIEW PERSIST User chat Discord DM Email CI / runtime hook Cron tick Channel Router classify / dedupe Moderator clarify, decompose Memory load concierge memory Skill lookup replay if match Push Gate blacklist.yml + floor Worker (Claude) opus 4-8 Worker (Claude) sonnet 4-6 Worker (Codex) image / fast code Worker (Gemini) long context Critic Vision Critic Debugger Self-Editor Memory Keeper Skills Librarian Sync Server Notify operator ALWAYS-ON OVERSIGHT (re-injects triggers) Watchdog idle-v2  |  Scheduler  |  Self-Editor shipped: detect drift, fire crons, inject triggers Error Ingest  |  Webhook Router planned: ingest runtime hooks and external webhooks MEMORY (PERSISTENT ACROSS ALL SESSIONS) Core (frozen) Project (per repo) Session (FTS) Skill (procedural) Multi-Machine Sync WORKER TOOL SURFACE (via MCP) GitHub MCP Playwright (browser) Postgres / SQLite MCP Filesystem MCP Mem0 / Honcho
green = shipped as of 2026-05-30  ·  blue = planned  ·  final state when every phase ships

The delta is the roadmap. Blue boxes in the full vision that are not green are what the self-iteration loop will build next, in the order listed below.

7 shipped (one partial), 3 to go.

1moderator
2Abackend gate
2Bdashboard
2Ctrust
2.5errors + crons
3critic
4multi-page
5remote
6memory + watchdog
7self-edit v1

What actually works right now.

1
Minimum Viable Moderator Hono HTTP server, spawn claude as subprocess, SQLite WAL, SSE event stream, basic CLI
Phase 1
2A
Push Gate backend + multi-agent + WebSocket Permission MCP shim, per-worker config, WS hub with topic subscriptions, dev-server detection, multi-agent concurrency cap
896ade2
2B
Cursor-style dashboard Vite + React 19 + Tailwind v4 + Sonner, mac chrome, tabbed agents, collapsible chat, layout modes, settings modal, browser notifications, WS auto-reconnect
10 commits
2C
Tier-1 hardcoded floor Pure function blocking ~/.ssh, ~/.aws, .env, sudo, rm -rf, curl | sh regardless of config. Cannot be overridden.
33d0c6b
2C
blacklist.yml loader + hot-reload js-yaml parser, fs.watch hot-reload, defensive parsing of malformed configs
3002955
2C
Command normalization (best-effort) Strips ANSI escapes, null bytes, fullwidth chars; unwraps bash -c; one-level base64 decode. KNOWN_GAPS.md documents limits.
9704e88
2C
Three-layer matcher wired floor + normalize + blacklist with layer/rule reported on every decision. Invariant test proves blank config still blocks floor.
653ae52
2C
Universal audit log audit_log SQLite table, GET /audit endpoint, writes on every gate decision (subject, action, layer, rule, decided_by, ts)
4ace857
2C
Two-phase Moderator prompt moderator-system.md prepended to every spawn. Phase 1 clarifies (up to 3 questions), Phase 2 runs autonomously. sessions.phase column tracks state.
c2df7d7
2C
Dashboard approval card upgraded Shows matched rule + layer chip (red floor / amber blacklist). Operator-forbidden fields explicitly absent (no "recommended", no "confidence").
cc2a9f8
post-2C
Real-claude end-to-end pipeline 5 bug bundle (claude args reorder, --verbose, stream-json parser, tsx absolute path, MCP server name match). Worker now actually talks to Claude through Moderator. Verified live: worker read status.html and wrote a self-introduction.
50dada9
post-2C
Researcher sub-tool + permission decision schema fix New mcp__orchestrator__research tool that off-loads web lookups to a short-lived Claude sub-process. Plus fix for Claude's permission-decision schema needing updatedInput on allow. Plus pnpm dev:safe (no tsx watch) for self-iteration runs. Plus prompts/self-iteration.md guardrail template.
d17eb29
post-2C
Rebrand to Nyx + plain-English explainer + visuals Whole product renamed Nyx (Greek goddess of night, works while you sleep, pairs with Atlas). New /simple page with dashboard screenshot, terminal mockup, AI-agent definition, comparison table vs Cursor / Devin / OpenHands / Aider / Hermes.
b84d505
item 2
Audit log dashboard tab 480px right drawer with kind filter + 5s auto-refresh + expandable details JSON. Replaces curl + jq for inspecting gate decisions during the FBM trial. ScrollText icon in the titlebar.
37b8350 + 4b8048d
item 3
Numbered DB migration runner Replaces "rename moderator.db backup" with a tracked, transactional migration system. Baseline migration captures current schema verbatim. Per-migration transactions roll back cleanly on failure. Future schema changes: drop a numbered file in db/migrations/, ship.
b79a0de
item 4
Error webhook (POST /events/error) External systems (CI, runtime crash reporters, other crons) POST here and Nyx auto-spawns an investigation agent. Writes a trigger_received entry to the audit log. Investigation-only by default; no commits, no deploys without operator approval.
aff751b
item 4
Repo priming (auto-load CLAUDE.md) When a worker enters a repo, root CLAUDE.md and .claude/CLAUDE.md are auto-loaded and prepended to the prompt under a PROJECT MEMORY header. 8000-char cap with truncation note. Interop with existing Claude Code memory convention; no new config needed.
f519b85
item 4
Cron scheduler Schedules table + in-process tick loop (60s). Supports @every 5m/1h/1d, @hourly, @daily HH:MM. REST endpoints to CRUD. Cron fires write trigger_received audit entries with schedule context. Unlocks "every morning check FBM CI status" type automations.
f42602d
item 5
Memory Keeper core (Hermes frozen-snapshot) ~/.orchestrator/memory/MEMORY.md (2200 char cap) + USER.md (1375 char cap). Loaded once per worker spawn, immutable mid-session. Prefix-cache friendly. Capacity warnings at 80%. Injected into prompt as GLOBAL MEMORY section before any per-task content.
phase 6 slice 1
item 6
Per-repo PROJECT.md memory <repo>/.orchestrator/PROJECT.md (4400 char cap) loaded when worker enters that repo. Distinct namespace from operator-managed CLAUDE.md. Workers can propose updates; operator approves (write flow in a later slice). Solves Hermes' multi-project budget overflow.
phase 6 slice 2
item 7
Skills Librarian + skill MCP tool ~/.orchestrator/skills/<name>.md. Workers see all available skill names + descriptions in their prompt prefix, and can call mcp__orchestrator__skill (action=get) to read the full body when one is relevant. /internal/skill backend route. Safe name validation prevents path traversal.
phase 6 slice 3
item 8
Discord bot (apps/discord-bot) DM the bot anything, message forwards to Nyx, worker reply DMs back. One persistent agent per Discord user (clear with /reset). discord.js + bot-logic.ts (pure, unit-tested via mock ModeratorApi). Long replies chunked at 1900 chars for Discord's 2000-char limit.
phase 5
item 8
Cloudflare Tunnel script scripts/tunnel.sh runs cloudflared against localhost:5173 (the dashboard). Free *.trycloudflare.com URL per session. Setup notes in the script comments for upgrading to a named tunnel + custom domain.
phase 5
item 9
Critic (Phase 3a) POST /sessions/:id/review spawns a short-lived claude with the session's text events + a strict reviewer prompt. Verdict: approve / revise / abstain + critique up to 300 words. 90s timeout. Manual-trigger first; auto-trigger on session.succeeded gated behind a config flag still being designed.
phase 3a
item 11
Watchdog (Phase 6 slice 4) Always-on in-process monitor. Default 5-minute scan interval. Flags any session "running" longer than 15 minutes as stuck, logs a warning, writes a kind="watchdog" entry to audit_log. First slice; drift detection and external health checks come later.
phase 6 slice 4
DEMO
Yaga.co.za scraper (built autonomously by Nyx) Operator gave Nyx a one-sentence brief; Nyx self-dispatched a discovery worker (Puppeteer one-shot), found the public JSON endpoint, wrote lib/yaga-client.js + lib/yaga-sniper.js + scripts/smoke-yaga.mjs. Returns real listings from yaga.co.za through the existing FBM Sniper Pro pipeline. Zero human code edits.
ec21188 (FBM repo)
DEMO
Yaga UI integration (also autonomously by Nyx) Nyx wired the new yaga scraper into the FBM Sniper Pro desktop app (server.cjs, shared seller-trust, ui/index.html, ui/app.js across 31 state maps, 6 UI modules, onboarding step, regression tests). 13 files, 111 insertions, 18 deletions in 12 minutes. Self-corrected when its own post-commit scan caught a forbidden arrow character in the commit message and amended. Desktop build launched first-try.
0006259 (FBM repo)
item 14
Self-Iterator v1 (Phase 7, narrow scope) Auto-dispatches a fix worker scoped to the orchestrator repo when (a) a worker terminates with status=failed or (b) the watchdog finds a stuck session. Safety rails: loop prevention (label check), mutex (one self-iter at a time), cooldown (3 attempts per signal-key per hour), branch isolation (always nyx-self/<ts>-<reason>, never main, never auto-push), protected files (push-gate/floor.ts and self-iterator.ts itself), kill switch (NYX_SELF_ITER_DISABLED env). 8 dedicated tests + full suite 196/196.
aa1d457 + c082378
item 14
First autonomous self-modification (history) On its first boot, the Self-Iterator fired against a real watchdog signal (a stuck session from before the PC crash earlier). The fix worker correctly created the nyx-self/2026-05-28T15-54-37-stuck branch, diagnosed the root cause as "(c) worker making slow but real progress" rather than a code bug, and per its prompt wrote a 104-line tuning note with two ranked recommendations (raise threshold; switch to idle-based detection) instead of changing code. Stayed on the branch, no push, no merge. Diagnosis was 80% right; safety pattern was 100% right.
ef37468 on nyx-self/...
item 14
Orphan-on-boot sweep (fix surfaced by self-iter) The self-iter's first dispatch was triggered by a false-positive: a session marked status=running whose worker process had died with the previous moderator. markOrphanRunningAsFailed() now sweeps every running session to failed at moderator boot, before Watchdog or SelfIterator start. The class of false positives is now eliminated. Regression test added.
c082378
tooling
watch-agent.mjs live event tail Pretty-printer that tails the events table for any session via sqlite polling. Colored tool_use / tool_result / assistant text / system events, exits on terminal status. Built so the operator could monitor the yaga integration run from a separate terminal without the React dashboard. Reused for every Nyx run since.
aa1d457

14 items the loop will work through, in order.

Ordered smallest-and-safest first so the self-iteration loop validates itself on easy wins before touching anything load-bearing. The total is roughly 30-35 hours of subagent execution to ship every box in the "full vision" diagram above.

Self-iteration is now live (v1). The three guardrails are shipped: (a) pnpm dev:safe runs the moderator without tsx watch so worker edits don't trigger mid-task restarts, (b) the self-iter prompt explicitly tells the worker "STOP and report if the diagnosis is unclear, do not guess", (c) every dispatch writes a kind=self_iter audit row plus a self_iter_attempts row, and every code change lands on a fresh nyx-self/<ts> branch with its own commit so it's rollbackable. Items 15-26 above are the next-iteration backlog that Nyx itself can work through.

How to use it today.

1

Start the full stack

One command, moderator on :3000 + dashboard on :5173, concurrently labeled.

cd ~/projects/agent-orchestrator
pnpm dev
2

Open the dashboard

Visit http://localhost:5173. You should see the mac-window chrome and a green "live" indicator in the titlebar.

3

Create an agent

Click the + button in the tab bar. A new agent tab appears. It is empty (no worker spawned yet).

4

Send your first message

Type in the right-side chat panel. cmd+enter sends. This spawns a worker with your message as the prompt. The Moderator prompt template prepended automatically asks for clarification if needed, otherwise goes straight to work.

5

Watch what happens

Worker output streams into the chat panel. If it spins up a localhost dev server, the middle pane iframes it (live, interactive). If it tries something gated (git push, edit ~/.env, etc.), the bottom bar lights up amber with the matched rule and layer chip.

6

Approve or deny gated actions

Click approve or deny on the bottom bar. Decision is logged to audit_log and broadcast back to the worker via WS so it can continue (or handle the denial).

7

Customize what gets gated

Click the gear icon. Edit the blacklist tab. Add patterns. Save. The loader hot-reloads, the matcher uses new patterns on the next decision.

# ~/.orchestrator/blacklist.yml
bash:
  - "git push *"
  - "fly deploy *"
paths:
  - "**/.env*"
  - "~/personal-notes/**"
8

Inspect the audit log

API-only for now. UI tab coming.

curl http://localhost:3000/audit | jq
curl http://localhost:3000/audit?kind=gate_decision&limit=20 | jq

Honest list. None are blockers, all are scoped.

med
No real DB migration story.
Schema additions (e.g., the audit_log table, sessions.phase column) work for fresh DBs and use try/catch ALTER for upgrades. Older DBs from before a column existed can fail. Workaround: rename apps/moderator/data/moderator.db to backup and let it recreate.
med
tsx watch restarts moderator on every save.
When the moderator restarts, in-flight WS connections drop. Dashboard auto-reconnects within ~500ms. Active claude subprocesses are orphaned but continue writing to the DB.
minor
Audit log is API-only; no dashboard UI yet.
Inspect with curl until the UI tab ships (planned soon, low effort).
minor
Memory layers not built.
Workers spawn fresh each time and only see what Claude Code reads from CLAUDE.md natively. The Hermes-inspired 5-layer stack (core + project + session + skill + sync) is Phase 6.
minor
Approval card is functional but minimal.
Shows matched rule + layer + command. Does NOT yet show diff summary, files changed, test status, or recent worker actions (operator spec for the full evidence card). Add as needed during the FBM trial.
minor
No critic, no vision review.
Worker output is not reviewed before being marked done. UI work cannot be auto-iterated against a screenshot yet. Both are Phase 3.
minor
No remote access.
Dashboard is localhost:5173 only. Cloud Tunnel for phone access is Phase 5.
minor
Self-iteration is janky-possible only.
You can point the orchestrator at its own repo and have a worker improve it. Restart is manual; rollback on test failure is not automatic. Phase 7 (Self-Editor) is deferred per the Self-Editor risk note in the trust spec.

Where to find things.

apps/moderator/src/ Backend: Hono server, DB, worker spawn, push gate
apps/moderator/src/push-gate/ floor.ts (Tier 1), blacklist-loader.ts (Tier 2), normalize.ts (best-effort), matcher.ts (orchestrator)
apps/moderator/src/routes/ agents, sessions, gate, dev-servers, internal, config, audit
apps/moderator/src/prompts/ moderator-system.md (clarify-then-run prompt)
apps/moderator/test/ 28 test files, 130 passing
apps/dashboard/src/ Frontend: React 19 + Tailwind v4 + Zustand store + ws client
apps/dashboard/src/components/ LayoutShell, Titlebar, TabBar, Workspace, AgentsSidebar, PreviewPane, ChatPanel, PushGateBar, SettingsModal, Toaster
docs/overview.html Architectural overview / pitch document (this file's sibling)
docs/status.html This file. Working project status.
docs/superpowers/specs/ Design docs: orchestrator, push gate / dashboard, trust corrections, KNOWN_GAPS
docs/superpowers/plans/ Implementation plans: Phase 1, 2A, 2B, 2C
~/.orchestrator/blacklist.yml Operator-owned push gate Tier 2 patterns (paths + bash + mcp)
~/.orchestrator/roles.json Per-role model configuration (moderator, worker, critic, watchdog)
apps/moderator/data/moderator.db SQLite WAL database (sessions, events, agents, messages, gate queue, audit log)

Why this order, not "build everything."

The trust trial gates the rest.

Phases 1-2C give you a tool you can actually point at FBM Sniper for 30 nights. That data tells us which Phase 6 memory features matter and which Part B safety features are needed first. Building Phase 6 before the trial is guessing.

Depth on a few things beats breadth on twenty.

The win isn't the longest feature list. It's being the only tool where you genuinely close the laptop and trust it. Earned by Push Gate + audit log + Pending Learnings reliability, not by shipping every roadmap item.

Self-Editor stays scoped.

An orchestrator modifying its own gate logic is the single feature most likely to break the trust pitch catastrophically. Phase 7 stays planned but only for non-safety code, and is not part of the public release.

Part B is intentionally deferred.

Pending Learnings, skill provenance, token budgets, and the circuit breaker are all great features. They are also all more value to a tool that has lived through real incidents than to a tool that hasn't. Ship the trial, learn, then build them with that data.