Skip to content

Files

The load-bearing files and runtime artifacts in a nexus-code checkout, grouped by role. "Tracked?" means the file is committed to the code repo; state artifacts under monitor/.state/ and per-project trees under work/ are runtime-only and gitignored.

This is a curated inventory, not an exhaustive one. monitor/ alone holds 153 tracked files at depth 1 at a3177ef6, of which this page names 73; the tables below cover the entry points, the shared libraries other code sources, and the artifacts an operator has to reason about. git ls-files -- ':(glob)monitor/*' is the ground truth, and the :(glob) prefix is not optional — git's pathspec * crosses /, so the bare form answers about the whole subtree.

For the architectural framing see Architecture. For per-key config documentation see Config.

Repo root

Path Purpose Tracked?
CLAUDE.md Cross-cutting agent rules loaded into every Claude Code session in this workspace yes
README.md Repo landing — points at this docs site yes
LICENSE License (MIT) yes
CHANGELOG.md Reverse-chronological changes yes
CONTRIBUTING.md Thin pointer into docs/contributing/ yes
SECURITY.md Vulnerability disclosure flow (thin pointer; full prose in docs/admin/security.md) yes
watcher Symlink to monitor/watcher/entry.sh — the user-invoked entry point yes
nexus Symlink to monitor/watcher/entry.sh — equivalent alias for watcher yes
package.json Project-local Claude Code npm manifest; the @anthropic-ai/claude-code version is a maintainer-managed vetted floor for fresh installs, not a per-release pin yes
package-lock.json npm lockfile recording the resolved Claude Code version for reproducible npm ci yes
mkdocs.yml Docs site config yes
docs/ Docs site sources (you are here) yes
config/ Config template + loader (see below) yes
monitor/ Watcher + bot + helper scripts (see below) yes
skills/ Agent-facing skills (see Skills) yes
experiments/ Scratch / exploratory material yes
work/ Per-project checkouts (gitignored) no
reports/ Append-only agent reports (gitignored) no
assets/ Local clone of the asset+issue repo, maintained by ng upload (gitignored) no

watcher at the repo root is the canonical user-invoked entry point (nexus is an equivalent alias): agent-sandbox tmux new-session ./watcher [--continue] boots the whole stack inside an inner-tmux session — headless watcher + registered services via monitor/svc.sh up, the orchestrator spawned by the watcher, and the invoking window left running the services cockpit.

config/

Path Purpose Tracked?
config/nexus.example.yml Template documenting every key, default value, and env-var override yes
config/nexus.yml Per-operator config — gitignored, chmod 600. Copy nexus.example.yml, edit every value no
config/load.sh Tiny Python/pyyaml wrapper. load.sh <dotted.key> [default] prints the resolved value yes

The loader walks the precedence order: script-local env var → config/nexus.yml → config/nexus.example.yml template → hardcoded fallback inside the script. See Config for every key.

monitor/

The core scripts. Three tiers: the watcher loop (watcher/), agent-facing tooling (ng, mint-token.sh, etc.), and operator notifications (notify.sh).

Path Purpose Tracked?
monitor/README.md The original architecture + ops doc; superseded by this docs site but still useful as the source-of-truth for the watcher implementation yes
monitor/agent-prompt.md Launch prompt for the monitor agent (orchestrator) yes
monitor/BOT_SETUP.md First-time GitHub App setup walkthrough yes
monitor/BOT_ADMIN_GUIDE.md Day-2 admin: rotation, troubleshooting, common errors yes
monitor/infra-resolved.md Closed-issue log — themes that have shipped fixes, consulted by nexus.infra-review yes
monitor/ng Compact GitHub / watcher helper CLI (every ng <verb>) yes
monitor/mint-token.sh Mints / caches the bot's installation access token (also --jwt-only for App-level JWT) yes
monitor/upload-asset.sh Commits a local file into the asset repo's main branch under assets/...; prints a SHA-pinned URL. ng upload is a thin shim over this yes
monitor/notify.sh Tiered Pushover / ntfy / SMTP fan-out for events GitHub can't surface yes
monitor/spawn-worker.sh Worker launcher — creates the tmux window, prepends the worker floor, execs claude --dangerously-skip-permissions yes
monitor/pane-state.sh Robust pane-state classifier. monitor/pane-state.sh --states is the vocabulary — do not hand-maintain a copy of it here; at a3177ef6 it prints twelve tokens: idle, busy, user-typing, autosuggest-only, empty, blocked, absent, over-limit, working-background, working-self-paced, idle-orphan-async, unknown. working-background and working-self-paced mean the worker is ACTIVE, and unknown means could not look at all — a caller matching a shorter list retires a live worker. The helper to call instead of eyeballing tmux capture-pane yes
monitor/_tmux_socket.sh The tmux SOCKET-PATH ceiling in one place: tmux_socket_path/len/verdict compose ${TMUX_TMPDIR:-/tmp}/tmux-<uid>/<name> and compare against TMUX_SUN_PATH_MAX=107 — sun_path is 108 bytes and 107 is the most a NUL-terminating caller can bind, so a guard written to the widely-quoted "108" is off by one and passes the boundary path that fails. 108 IS bindable by the kernel with a full-struct addrlen; the limit is the calling convention, not the kernel (#991) yes
monitor/tmux-socket-fits.sh CLI over the above: --socket NAME [--tmpdir DIR] -> exit 0 fits / 3 REFUSED with the measured length, the composed path and the remedy; --suggest prints a TMUX_TMPDIR that cannot blow the ceiling. Separates "the address could not be formed" from "the code under test is broken", which used to present as the same FAIL yes
monitor/mutation-gate.sh Safe single-mutant harness (#1032). Refuses any line that is not a complete logical line (--list shows the eligible ones), PROVES the edit applied, runs every mutant under timeout + ulimit -f + a free-space floor, and classifies killed-by-assertion / survived / killed-unattributable rather than reporting a bare KILL. --run-bounded <script> exercises the bound alone yes
monitor/svc.sh Service cockpit (read-only dashboard) + unified service CLI: status, up, start/stop/restart <name>, logs <name> yes
monitor/bootstrap-recover.sh Idempotent whole-stack recovery — relaunches an unhealthy watcher via launcher.sh and every unhealthy, unsupervised registry service (headless). svc.sh up delegates here yes
monitor/services.registry.example Annotated template for the operator-local services.registry (one TAB-separated service per line: name, workdir, launch, healthcheck, optional logfile) yes
monitor/services.registry The operator's actual service registry no
monitor/claude-loop.sh The orchestrator loop wrapper — execs claude with the resolved $CLAUDE_BIN, --dangerously-skip-permissions, --settings, and --continue, suppressing the resume dialog via CLAUDE_CODE_RESUME_* env vars yes
monitor/watcher/spawn-fresh-orchestrator.sh Cold-spawn an orchestrator window (no resume), used when the session pin is stale/absent. (Lives under watcher/; listed again in that table) yes
monitor/retire-preflight.sh The MANDATORY synchronous pre-kill gate — reads live pane state and returns safe=<0\|1> before any worker tmux kill-window; blocks while a skeptic-pending marker is live (test-retire-preflight.sh covers it) yes
monitor/skeptic-channel.sh The worker↔skeptic comms channel + await park used by nexus.skeptic (await-hang marker under .state/skeptic/pending/) yes
monitor/worker-heartbeat.sh Worker liveness writer invoked from worker-settings.json hooks; parses the hook payload (.tool_name, .session_id, .notification_type) into heartbeat/<window>.json yes
monitor/declare-wait.sh / monitor/declare-no-wait.sh Worker self-declarations of an external-wait (e.g. a long Slurm job) vs. no-wait, written keyed on $NEXUS_WORKER_WINDOW so the idle classifier refines idle-orphan-async yes
monitor/async-run.sh Status-preserving background launcher (/nexus-code#1071). setsid-detaches a command, retains its exit status in a per-token state dir, and registers a RESOLVABLE asyncrun:<token> wait. --status <token> answers running / terminal rc=N / died (killed before it could report) — the three-way a bare nohup … & fuses into "absent". Use instead of nohup … &. yes
monitor/_pane-live.sh _tmux_pane_is_dead — refuse to paste-buffer into a dead pane; a paste into one kills the tmux SERVER (#745) yes
monitor/paste-followup.sh Deliver a follow-up message into a running worker/orchestrator window (VI-mode-hardened load-buffer/paste-buffer pattern) yes
monitor/user-pat.sh Resolves the user's gh auth token PAT for surfaces the bot's installation token can't reach (ng fetch-asset, private-package installs) yes
monitor/_claude-bin.sh Shared $CLAUDE_BIN resolver sourced by every spawn surface: env override → node_modules/.bin/claude → system claude yes
monitor/install-claude-local.sh Project-local Claude Code install/upgrade via npm ci/npm install; idempotent fast-path skips when the installed --version matches the pin yes
monitor/install-hpc-skills.sh / monitor/install-labsh.sh / monitor/_install-lib.sh / monitor/install-prompt.md Operator-setup installers ( skill pack, labsh) and shared install helpers yes
monitor/bootstrap-install.sh First-run bootstrap launcher — execs claude --dangerously-skip-permissions against the install prompt to set the stack up from a fresh clone yes
monitor/jupyter-up.sh / monitor/jupyter-kernel-crawl.sh / monitor/jupyter-health.sh JupyterLab-as-a-service activation, work-root kernel discovery, and healthcheck (see nexus.jupyter) yes
monitor/labsh-root.sh / monitor/labsh-supervised.sh / monitor/_lab-context.sh labsh project-agent access, supervised-revival wrapper, and shared lab-context resolver yes
monitor/_cc-version.sh / monitor/cc-auto-update-apply.sh / monitor/cc-auto-update-prompt.md / monitor/cc-auto-update-watchdog-prompt.md / monitor/cc-restart-watchdog-loop.sh The gated Claude-Code self-update machinery (version resolution, apply, watchdog prompts/loop); see skills/nexus.cc-update/GUIDE.md yes
monitor/watcher-supervise-tick.sh / monitor/revive-watcher.sh / monitor/boot-recover.sh / monitor/boot-recover.session-start-hook.json Watcher supervision tick, manual watcher revival, and boot-time stack recovery (SessionStart hook) yes
monitor/calibrate-pressure-thresholds.sh One-shot calibration of context-pressure thresholds yes
monitor/git-https-setup Helper to wire git HTTPS credential flow for the bot yes
monitor/repo-root.sh Shared three-valued predicate: is a directory the ROOT of its own git repository? (git -C <non-repo> walks UP and answers about the enclosing repo at rc 0 — /nexus-code#1196, #1080) yes
monitor/boot-recover-hook-check.sh Reports whether the cold-boot SessionStart hook is actually ARMED — i.e. actually runs boot-recover.sh, not merely that some hook is executable. A hook whose command does not exist is silent on every channel anyone looks at (stdout, stderr, rc identical to no hooks; it IS recorded in the session transcript, stream-json and --debug-file, none on by default — measured, #1174), so a check outside the session is the practical signal yes
monitor/async-launch-patterns.conf Regex patterns hooks/async-launch-detect.sh matches to spot background spawns yes
monitor/test-interactive-sessions.sh / monitor/test-retire-preflight.sh Top-level monitor/ unit tests (interactive-session detection; retire-preflight gate) yes
monitor/proc-kill-authorized "May I kill this pid?" as an ALLOWLIST with a default-DENY arm (#851) — session ownership, never name matching. --filter passes only authorised pids, names every refusal on stderr, exits 1 when it dropped any yes
monitor/proc-exists-authorized The waiting-side sibling (#1073): "is the job I am waiting on still running?", keyed on session ownership and pid identity rather than argv, and it OWNS the loop so the polarity cannot be inverted. Five exit codes; 3 means REFUSED — neither present nor absent yes
monitor/_bookkeeping.sh The bookkeeping-contract guard primitives, including bk_pane_kill_authorized — the pane-state kill allowlist with a default-deny arm yes
monitor/_tmux-window.sh One window-key vocabulary (@id-resolved, index / session:window / NAME) shared by pane-state.sh and paste-followup.sh; refuses an ambiguous key rather than guessing (#323, #905) yes
monitor/shell-files.sh shf_is_shell — one DERIVED definition of "which files here are shell files", for guards whose population must not be a filename glob (#792) yes
monitor/guards-for-diff.sh "Which registered guards read the files I just changed?" (#803) — --run executes exactly those. Backs ng guards-for-diff yes
monitor/send.sh ng send — the harness-neutral agent-delivery contract (per-agent transport + receipt, one common ledger); see skills/nexus.agent-delivery yes
monitor/request-channel.sh The watcher-mediated request inbox and request/reply protocol (agent-channel RFC parts B + D); the inbox lives under .state/requests/ and rides the watcher's existing emit yes
monitor/lit.sh Backs ng lit — content-relevance literature discovery across S2, ASTA and OpenAlex, deduped against the reference library (see Literature) yes
monitor/locals-env.sh SOURCE-only: joins the nexus-wide project-local toolchain (locals/bin on PATH, uv state pinned out of $HOME). Sourced by every spawn launcher; also the BASH_ENV this nexus exports yes
monitor/remote-up.sh / monitor/remote-*.sh / monitor/_remote_lib.sh The off-by-default confined remote agent channel — enable/status/down helper, forced command, enrollment, sshd supervision, health (see skills/nexus.remote-access) yes
monitor/obligations.sh / monitor/_obligations.sh The obligation ledger backing ng obligation pairs / ng obligation settle — who is waiting on whom, discharged on the record yes
monitor/reports-roll.sh Time-partitions the flat reports/ dir into MONTHLY archive subdirs behind a ≥1-month buffer, so recency-oriented -maxdepth 1 consumers keep working (#444) yes

monitor/hooks/

Claude Code hook handlers wired from orchestrator-settings.json / worker-settings.json; each reads the hook-event JSON payload on stdin.

Path Purpose Tracked?
monitor/hooks/orchestrator-session-pin.sh UserPromptSubmit hook — pins the orchestrator session-id to .state/orchestrator-session-id for --resume; gated on NEXUS_IS_ORCHESTRATOR=1 yes
monitor/hooks/block-askuserquestion.sh PreToolUse hook — blocks AskUserQuestion calls so the orchestrator never strands itself on a dialog yes
monitor/hooks/async-launch-detect.sh PostToolUse hook — spots background spawns (ScheduleWakeup, async bash) from .tool_input.command yes
monitor/hooks/decision-emit.sh / monitor/hooks/decision-mark-unresolved.sh Emit / un-resolve structured worker-decision rows (fingerprint + dedup) for the orchestrator yes
monitor/hooks/over-limit-emit.sh StopFailure hook — writes a per-window over-limit stamp when .error_type == "rate_limit", probing plausible reset_at field paths yes
monitor/hooks/turn-failure-emit.sh StopFailure hook — emits turn-failure info even when the session crashed yes
monitor/hooks/_cause_classify.sh Shared helper that classifies a turn-end/failure cause from the payload yes

monitor/docs/

Path Purpose Tracked?
monitor/docs/agent-state-machine.md The worker/orchestrator state-machine reference (pane states, transitions) yes
monitor/docs/orchestrator-guide.md Long-form orchestrator operating guide yes

monitor/cc-harness/

The Claude-Code-update gate harness — exercises the spawn/respawn surfaces against a mock backend before a version bump is promoted.

Path Purpose Tracked?
monitor/cc-harness/gate.sh The gate entry point — runs the harness and returns a pass/fail verdict for a candidate Claude Code release yes
monitor/cc-harness/demo.sh Demonstration / smoke driver for the harness yes
monitor/cc-harness/mock-backend.py Mock Claude backend the harness drives so spawns run offline/deterministically yes
monitor/cc-harness/lint-no-mass-kill.sh Lint guard asserting no spawn path can mass-kill windows yes
monitor/cc-harness/lint-no-tmux-server-kill.sh Lint guard on the tmux-SOCKET axis: kill-server/kill-session must be provably socket-scoped (-L/-S), and a TMUX_TMPDIR isolation without unset TMUX is a no-op because $TMUX outranks it (#644). --selftest is the negative control + pragma manifest yes
monitor/cc-harness/_lib.sh Shared harness helpers yes
monitor/cc-harness/README.md Harness rationale + usage yes

monitor/watcher/

The watcher and its tests. The protocol is documented at Watcher protocol; this table is the file inventory.

Path Purpose Tracked?
monitor/watcher/entry.sh User-invoked entry. Reconciles --continue onto the session-id pin, brings up the stack via svc.sh up, renames the current window to services and execs the svc.sh cockpit yes
monitor/watcher/main.sh The continuous watcher loop — snapshot, classify, paste, archive, heartbeat, prune yes
monitor/watcher/launcher.sh Watcher (re)spawn. Launches main.sh headless (setsid-detached, WATCHER_WINDOW=headless, log monitor/.state/watcher.log), verifies the pidfile publish, sweeps a legacy watcher window yes
monitor/watcher/_hosting_migration.sh Legacy-hosting detection (WATCHER_WINDOW != headless) + the one-shot migration-notice body the startup sweep emits yes
monitor/watcher/bootstrap.sh Agent-side on-wake check. Verifies the watcher is alive (heartbeat + pid + tmux window), respawns via launcher.sh if stale, prints archived diffs newer than last-ack.txt, advances last-ack.txt yes
monitor/watcher/_lib.sh Shared helpers: heartbeat / lock parsers, _watcher_alive, _classify_diff, _target_window_present, _respawn_loop_check yes
monitor/watcher/_github.sh snapshot_github + helpers — three GraphQL surfaces (issues, PR conversation, PR review threads, new issues), _graphql_polling_gate, _graphql_backoff_active, _watcher_handle_graphql_failure yes
monitor/watcher/_deliveries.sh snapshot_deliveries — polls /app/hook/deliveries on the App-JWT bucket; surfaces cross-repo bot-relevant events yes
monitor/watcher/_mentions.sh snapshot_mentions — cross-repo mentions search for repos where the App is NOT installed yes
monitor/watcher/_unstick.sh Auto-unstick library: case A (permission Enter), case B (rate-limit cascade + Anthropic API probe + orchestrator ack); case C (the API-error Enter-nudge) retired in #1670 yes
monitor/watcher/_idle_probe.sh Idle-worker classifier: enumerates worker windows, classifies into wrapped/wrapped-but-stub/no-wrap-up/idle-too-long/pane-absent/retained, dedupes transitions yes
monitor/watcher/_respawn.sh / _respawn_async.sh / _respawn_prompts.sh Orchestrator respawn library: resume-mode choice (--resume <pin> vs cold fresh spawn), launcher composition, duplicate-orchestrator adjudication, and the respawn prompt bodies yes
monitor/watcher/_config.sh Watcher config-knob resolution (thresholds, cadences) yes
monitor/watcher/_emit_dedup.sh / _emit_filters.sh Emit signal-vs-noise dedup and the filters that suppress noise-only sections yes
monitor/watcher/_compose_nudge.sh Composes the unstick/follow-up nudge text delivered into a stuck pane yes
monitor/watcher/_functional_check.sh Post-emit functional check — reaction scan over the eligible-comments section yes
monitor/watcher/_orchestrator_liveness.sh Orchestrator liveness machine (heartbeat / paste-received / jsonl-mtime fallback) yes
monitor/watcher/_over_limit.sh Rate-limit / over-limit detection + re-wake scheduling yes
monitor/watcher/_orphan_async.sh idle-orphan-async wake loop (/nexus-code#1071): resolves each declared wait per-kind (sacct for Slurm, async-run.sh --status for asyncrun, unresolvable for a syn- token), and wakes the stalled worker ONLY when nothing is still running, nothing is queued in its pane, and it still reads the class. Never clears a wait. yes
monitor/watcher/_service_health.sh Registered-service healthcheck runner → the --- service health --- emit (nexus.service-recovery) yes
monitor/watcher/_scheduler.sh Cadence scheduler for the watcher's periodic surfaces yes
monitor/watcher/_target_absent.sh Detect-and-recover when the target (orchestrator) window is absent yes
monitor/watcher/_cc_update.sh / _cc_auto_update.sh DETECT → INFORM half of the gated Claude-Code self-update loop (emits --- claude code update available ---) yes
monitor/watcher/_version_restart.sh Version-aware self-restart — detects watcher source-set drift after a pull and re-execs (issue #186) yes
monitor/watcher/_test_helpers.sh Shared helpers for the watcher test suite yes
monitor/watcher/spawn-fresh-orchestrator.sh Cold-spawn an orchestrator with no resume (safe degradation when the pin is stale/absent) yes
monitor/watcher/run-tests.sh Runs the whole monitor/watcher/test-*.sh suite yes
monitor/watcher/fixtures/ Stub gh / tmux / mint-token binaries + .ansi pane fixtures used by the test scripts yes
monitor/watcher/test-*.sh Mock-tmux / mock-gh unit tests, one per behavioural surface; run all via run-tests.sh or any one with bash <file> yes

The suite is large, and this page deliberately carries no test-file count — a count is a property of a tree and of a moment, and a number here rots silently. Derive it, with its ref:

git ls-tree -r --name-only <ref> | grep -cE '(^|/)test-[^/]*\.sh$'

Measured at a3177ef6: 469 files named test-*.sh tree-wide, of which 452 are in the fast band CI discovers (monitor/ and monitor/watcher/, depth 1 each) — 431 under monitor/watcher/ and 21 at the monitor/ top level — plus 16 under monitor/watcher/test-integration/ and 1 under monitor/cc-harness/. Note the anchor: a bare grep -c 'test-.*\.sh$' matches on the whole PATH and so counts test-integration/_harness.sh and test-integration/stub-claude.sh, which are not tests; it answers 471.

The table below is a curated sample of the load-bearing ones, not the full list; run the whole suite with monitor/watcher/run-tests.sh.

Test file Covers
test-paste-dead-pane-guard.sh _tmux_pane_is_dead + the paste-buffer call-site manifest + end-to-end "server survives a corpse" (#745); SLOW_TESTS=1
test-lib.sh _lib.sh standalone classifiers (_target_window_present, _classify_diff, …)
test-target-window-live.sh _target_window_present against a real tmux remain-on-exit corpse + session-scope check (#741); SLOW_TESTS=1
test-unstick.sh _unstick.sh cases A / B / C
test-emit-gate.sh Compose-report / signal-vs-noise / resurface
test-graphql-gate.sh _graphql_polling_gate cadence + bucket-floor
test-snapshot-github.sh snapshot_github happy path
test-snapshot-github-failure.sh Detect-and-react on GraphQL rate limit + other failures
test-snapshot-deliveries.sh _deliveries.sh end-to-end (curl mock)
test-snapshot-mentions.sh _mentions.sh cross-repo mention search
test-idle-probe.sh _idle_probe.sh six-class transitions + dedup
test-tmux-socket-ceiling.sh The 107/108 boundary against a real AF_UNIX bind AND real tmux, tmux's socket composition, the three outcomes of th_require_tmux_socket, run-tests.sh's pre-flight refusal, and a ratchet that every helper-sourcing real-tmux suite carries the precondition
test-mutation-gate-bounds.sh monitor/mutation-gate.sh's two properties: the predicate (including the &&/\|/heredoc shapes that promote a line with no backslash anywhere, which bash -n calls valid) and the bound (the real yes yes contained at 64 KB, rc 153, inherited by a grandchild; the pipe hole closed by the wall clock)
test-public-mirror-build-entry-guard.sh public-mirror/build.sh's entry conditions: a flagless invocation is a dry run (exit 6) and a dirty tree is refused (exit 7), each paired with a WHOLE-TREE CHECKSUM proving nothing was touched; --yes / --allow-dirty / NEXUS_MIRROR_BUILD_OK=1 still build
test-pane-state.sh monitor/pane-state.sh classifier across fixtures
test-entry.sh entry.sh self-checks, pin reconciliation (--continue), svc.sh up delegation, cockpit hand-off
test-hosting-migration.sh _hosting_migration.sh legacy-hosting detection + one-shot migration notice
test-respawn-loop-guard.sh / test-respawn-loop-integration.sh _respawn_loop_check rate limit and end-to-end respawn behaviour
test-ng-*.sh Each ng verb's edge cases (state-dir resolution, report init/check, fetch-asset, reply --repo, wrap-up)

monitor/.state/ (runtime; not tracked)

Everything under .state/ is local runtime state — never committed, never shared across operators. The directory is created on first watcher launch.

Path Purpose Retention
watcher-heartbeat pid + ISO ts + target; liveness only — beaten by a constant-cadence background ticker (monitor.watcher.heartbeat_tick_seconds, default 20 s), not by the poll loop overwritten each tick
watcher.pid Self-published watcher PID — the headless-hosting liveness anchor (launcher.sh and svc.sh validate the owner's identity, not just kill -0) watcher lifetime
watcher.lock PID-based lock; prevents two watchers on the same state dir watcher lifetime
watcher-target Current target window (written at startup) watcher lifetime
services/<name>.pid Per-registry-service headless-supervisor pidfile (bootstrap-recover.sh / svc.sh) service lifetime
orchestrator-session-id The orchestrator session-id pin — written at spawn and on every orchestrator turn; the watcher's --resume target. ./watcher (no --continue) archives it to *.archived.<epoch> until archived
watcher.log Append-only watcher log (startup, emits, paste failures, respawns) manual rotation
diffs/<ts>_<shortid>.md Archived emit bodies — one per signal cycle pruned at monitor.diff_retention_days (default 7)
last-ack.txt ISO timestamp of the newest archived diff the orchestrator has read advances on bootstrap
last-snapshot.txt Persistent baseline for local-state diffing (carries across watcher restarts) overwritten on absorb
last-change.txt Cache of the most recent emit body overwritten each emit
action-log.jsonl Append-only JSONL trace of meaningful actions ({ts,agent,event,...}) manual rotation
dashboard.md Cache of the dashboard middle (between NEXUS_DASHBOARD_START/END markers) overwritten on ng dashboard get/put
dashboard-updated.ts ISO timestamp of the last successful ng dashboard put overwritten each push
processed-comments.txt Local cache of comment:<id> / issue:<n> entries already reacted on (propagation-lag guard) append-only
watcher-unstick.log Auto-unstick action log — one line per detection / send-Enter / backoff / cascade / heads-up / ack manual rotation
unstick/<window>.<case>.{fp,tries,epoch,audit} Per-(window, case) fingerprint + retry counter + pre-action pane capture overwrites in place
unstick/ratelimit.{reset,cascade,last-wait}.epoch Case-B session state (probed reset, last cascade, last waiting-log) cleared on cascade or expiry
watcher-alerts.log [iso] WARN <surface> <classification> ... lines from _watcher_handle_graphql_failure append-only
graphql-backoff-<surface> Per-surface GraphQL reset-epoch; per-surface short-circuit while present + 30 s grace self-clears after reset
graphql-alert-emitted-<surface>-<epoch> Flag: rate-limit sentinel + log already emitted for this (surface, reset) pair self-clears with backoff file
graphql-other-last-log-<surface> Marker for the once-per-10-min throttle on non-rate-limit GraphQL failures self-overwrites
graphql-gate-last-log-<kind> Throttle marker for _graphql_polling_gate alert lines (probe_failed, probe_malformed, below_floor) self-overwrites
last-delivery-cursor.txt Newest delivery GUID seen by snapshot_deliveries overwrites each poll
last-mention-cursor.txt Max databaseId seen by snapshot_mentions overwrites each poll
bot-installed-repos.txt owner/repo cache for snapshot_mentions repo-skip filter refreshed at most once per 24 h
idle-state.tsv (window, class) set from the previous idle-probe cycle; drives transition dedup overwrites each cycle
respawn-history.txt Sliding window of epoch tag lines for _respawn_loop_check append + auto-prune
respawn-guard-tripped Flag file written once on the ok→tripped transition; cleared on next successful paste manual or auto-clear

reports/ (runtime; not tracked)

The append-only project log. One file per significant state change, named <project>_<YYYY-MM-DD>_<HHMMSS>_<slug>.md. The directory is gitignored — any cross-repo embed must go through ng upload first.

See skills/nexus.report for the schema and docs/operating/reports.md for the operator workflow.

work/ (runtime; not tracked)

Per-project clones. Each work/<project>/ is its own git repo. The watcher snapshots HEAD and clean|dirty for each in its --- git --- section; that section is suppressed as noise unless paired with a real change (reports, tmux windows, bells).

The convention: never create a CLAUDE.md under work/<project>/ — it would leak nexus-specific rules into a foreign repo. Project agents read the workspace CLAUDE.md instead.

skills/

The agent-facing skill library. 14 skills today, one directory each. All but one hold a SKILL.md with YAML frontmatter and a body; nexus.cc-update ships a path-referenced GUIDE.md instead so it is never auto-loaded into a worker's skill index.

Path Body
skills/nexus.tmux-spawn/SKILL.md Delegating work via the prompt-file + launcher pattern
skills/nexus.window-cleanup/SKILL.md Closing idle worker windows
skills/nexus.worker-defaults/SKILL.md The injected worker safety floor
skills/nexus.bot/SKILL.md Bot identity for GitHub writes
skills/nexus.report/SKILL.md Report schema + Infrastructure Issues feedback loop
skills/nexus.infra-review/SKILL.md Periodic infrastructure meta-review
skills/nexus.self-fix/SKILL.md Editing the nexus itself
skills/nexus.dashboard/SKILL.md Overview-issue identity block + dashboard schema
skills/nexus.skeptic/SKILL.md Independent adversarial validation of a worker's result
skills/nexus.service-recovery/SKILL.md Response protocol for a service-health emit
skills/nexus.jupyter/SKILL.md JupyterLab-as-a-service for nexus projects
skills/nexus.private-package-install/SKILL.md Installing private GitHub packages via the user's PAT
skills/nexus.cron-state-tsv/SKILL.md Durable session-state for recurring CronCreate agents
skills/nexus.cc-update/GUIDE.md Evaluating a Claude Code release before bumping the pin (path-referenced, not auto-loaded)

See the Skills catalog for trigger conditions and audience per skill.

assets/ (runtime; not tracked)

Local clone of the asset+issue repo (github.asset_repo). Maintained by monitor/upload-asset.sh: copies the source file into assets/<repo-path>, commits as the bot, pushes to main. The printed URL is SHA-pinned to the post-push commit.

The assets/ tree on the remote follows this convention:

  • assets/<issue-number>/<basename> — when --issue N is passed.
  • assets/reports/<basename> — for sources whose path contains reports/.
  • assets/general/<basename> — everything else without --issue.

URLs use blob/<sha>/ for .md / .ipynb (renders as a page); everything else gets raw/<sha>/ (302 to a same-domain signed CDN URL that renders for any logged-in github.com viewer). See monitor/README.md "Embedding files" for the rationale and the full failure matrix.

Tracked files at a glance

If you want to know what the code repo ships, this is the canonical list — git ls-files after a fresh clone. Everything else is runtime, per-operator, or pulled in on demand.

.github/workflows/         CI (docs build, etc.)
config/                    nexus.example.yml + load.sh
docs/                      this docs site (mkdocs sources)
experiments/               scratch / exploratory material
mkdocs.yml                 docs site config
monitor/                   watcher + bot + helpers + agent prompt
  README.md  agent-prompt.md  BOT_SETUP.md  BOT_ADMIN_GUIDE.md
  ng  mint-token.sh  notify.sh  upload-asset.sh  spawn-worker.sh  pane-state.sh
  claude-loop.sh  retire-preflight.sh  skeptic-channel.sh  worker-heartbeat.sh
  install-*.sh  jupyter-*.sh  labsh-*.sh  _cc-version.sh  cc-auto-update-*
  hooks/                   Claude Code hook handlers (session-pin, decision-emit, …)
  docs/                    agent-state-machine.md  orchestrator-guide.md
  cc-harness/              gate.sh + mock-backend.py — cc-update gate
  watcher/                 entry, main, launcher, bootstrap, _*.sh helpers, the test-*.sh suite
  infra-resolved.md
skills/                    one dir per nexus.* skill (see reference/skills.md)
watcher  nexus            symlinks → monitor/watcher/entry.sh
package.json  package-lock.json     project-local Claude Code npm pin
CLAUDE.md  README.md  LICENSE  CHANGELOG.md
CONTRIBUTING.md  SECURITY.md