Reports¶
reports/ is the durable, append-only log of what every agent did and what it learned. The watcher snapshots filenames and mtimes; the orchestrator surfaces new reports in Recent landings; ng wrap-up uploads them to the asset repo and posts link comments on the tracking issue. This page covers the operator-visible contract; the per-section semantics live in skills/nexus.report/SKILL.md.
Filename convention¶
<reports-dir>is the absolute path injected into every worker's spawn prompt bymonitor/spawn-worker.sh. Workers in a secondary clone (worktree or fresh clone) write to the primary clone'sreports/, not their own.<project>is thework/<subdir>the worker is editing (e.g.kompot,labsh), ornexusfor workspace-level work that spans projects.<YYYY-MM-DD>_<HHMMSS>is ISO date plus 24-hour time. UTC or local — be consistent across a session.<slug>is short kebab-case:fig2-revision,bench-eligibility,pr14-validate. When the work is issue-driven, embed the issue number:*_issue53_*.mdsols reports/*issue53* 2>/dev/nullretrieves the chain.
Example: reports/kompot_2026-04-14_153200_fig2-revision.md.
The five required sections¶
---
project: <slug> # enforced
date: <YYYY-MM-DD> # enforced
session-id: <uuid> # enforced (never the literal "unknown")
window: <tmux-window> # conventional
trigger: <issue#> [comment-id] # conventional
status: completed | partial | blocked # enforced — exactly one of these three
disposition: no-further-pass | second-pass # skeptic reports only; report-init
# seeds `TODO`, an ordinary worker deletes it
---
# <Title>
## Summary
- One or two sentences. `ng wrap-up` quotes this into the link comment.
## What Was Done
- Concise list of actions taken and files changed.
## Current State
- State of the work right now, files created/modified, running jobs.
## What Remains
- Specific next steps, blockers, decisions needed.
## How to Resume
- Exact commands or instructions to pick up where this left off.
## Infrastructure Issues
- Anything that made the work harder than it needed to be.
- Omit the section entirely when nothing came up. No placeholders.
Summary, What Was Done, Current State, What Remains, How to Resume are mandatory. Infrastructure Issues is conditional — present and substantive when something hurt, absent otherwise.
Why reports exist¶
Three reasons, in order of frequency.
Resumption surface. If a session crashes, the orchestrator restarts, or a sibling worker needs to pick up where you left off, the report is what survives. How to Resume is load-bearing: it tells the next worker which branch to check out, which Slurm job ID to poll, which kernel still holds the loaded dataset.
Dashboard input. The watcher's report-snapshot diff feeds the orchestrator's wake; the orchestrator's In-flight and Recent landings sections are computed from the filename list. A new reports/*.md is the visible signal that work has progressed.
Source for the periodic infra-review. ## Infrastructure Issues sections aggregate across sessions into a ranked backlog of tooling fixes. See the feedback loop below.
Append-only, not overwritten¶
Reports are never edited or overwritten in place. If state changes significantly mid-session, write a new file with a fresh timestamp:
reports/kompot_2026-04-14_103000_fig2-start.md ← start of session
reports/kompot_2026-04-14_153200_fig2-done.md ← end of session
The trail of progressive reports preserves history; an overwritten file loses it. CI guards (check-no-reports-leaked.yml) refuse PRs that add files under reports/ — they're meant to be uploaded to the asset repo via ng wrap-up, not committed to the code repo.
The three ng verbs¶
# 1. Start the report — frontmatter'd skeleton, captures session id + tmux window.
monitor/ng report-init <slug> [--project <name>] [--issue <#>] [--comment-id <id>] [--reports-dir <path>]
# 2. Validate the report against the schema.
monitor/ng report-check <path> [--allow-todo] [--skeptic-gate-settling]
# 3. Wrap up — upload + link comment + rocket + retain + log-action, all atomic.
monitor/ng wrap-up <issue> <report-path> \
[--trigger-comment <id>] [--repo <owner>/<repo>] [--trigger-repo <owner>/<repo>] \
[--comment-body-file <path> | --no-comment] [--retain <reason> | --no-retain] [--allow-stub]
ng report-init¶
Writes a correctly-frontmatter'd skeleton at the canonical <reports-dir>/<project>_<YYYY-MM-DD>_<HHMMSS>_<slug>.md path. Reads the session id from the running Claude Code session, captures the current tmux window, and fills in the issue / comment refs from the flags. The agent then opens the file and fills in the five content sections.
<project> is cwd-derived — the first segment after the last /work/ in $PWD, falling back to the window name only when it ran outside a work/ tree — so it need not equal the frontmatter window:. Don't index reports by a filename glob on a window name; use monitor/ng reports-for-window <window>, which keys on the frontmatter and keeps found / looked-and-found-none / could not look apart as rc 0 / 1 / 2.
The skeleton is written into the primary clone's reports/ regardless of which worktree you are in; report-init rejects --repo outright for that reason. It ships full of placeholders (_(fill in)_, disposition: TODO), so a freshly-initialised report fails report-check by design until you fill it in.
ng report-check¶
Validates a report against the schema: frontmatter fields, the five required sections (Infrastructure Issues conditional), body length ≥ monitor.report_min_chars (default 500), and absence of placeholder text (TODO, FIXME, <...>, _(fill in)_, _(later)_).
Exits 0 complete, 1 incomplete (specifics on stderr), 2 file missing or unreadable. Of the frontmatter, only project, date, session-id and status are enforced — window: and trigger: are conventional, written by report-init but not failed on. status must be exactly one of completed | partial | blocked. Two further fields are validated only when present: disposition: (must parse as no-further-pass or second-pass — nothing else does, merge included) and fanout: (must read <N> spawned / <M> returned, with M <= N).
ng wrap-up runs report-check as a pre-flight and refuses to ship a stub asset URL. If you're intentionally checkpointing mid-flight (e.g. a context-pressure save) and the body legitimately contains placeholders, pass --allow-stub to wrap-up, which forwards --allow-todo to the check.
ng wrap-up¶
The end-of-task hand-off, folded into one verb:
- Run
ng report-checkas a pre-flight. If the report fails schema validation (missing sections, body belowmonitor.report_min_chars, or placeholder text), the verb refuses with a non-zero exit before any side-effects. Pass--allow-stub(forwards--allow-todoto the check) to bypass for intentional mid-flight checkpoints. - Upload the report to the asset repo's
mainbranch underassets/<issue>/<basename>viamonitor/upload-asset.sh. The comment lands on<issue>in--repo; pass--trigger-repo <owner>/<repo>when the trigger comment lives in a different repo than the issue (defaults to--repo). - Post a templated comment on
<issue>:## <Title>\n\n<Summary>\n\nFull report: <URL>. Pass--comment-body-file <path>for a bespoke body (the{{REPORT_URL}}token is substituted), or--no-commentto skip the comment entirely (the two are mutually exclusive). - Rocket-react the trigger comment if
--trigger-comment <id>is supplied. - Retain the worker's tmux window.
wrap-upauto-retains by default — it logs awindow-retainevent so the orchestrator's window-cleanup loop keeps the window alive (defaultmonitor.retain_ttl_seconds, 24 h) under the tagwrap-up-<YYYY-MM-DD>, giving you a resume surface. Pass--retain <reason>for a custom tag, or--no-retainto close-immediately (--no-retainand--retainare mutually exclusive). The retain is logged only when the verb runs inside the tmux window it's retaining. - Append a
wrap-upevent tomonitor/.state/action-log.jsonl.
Exit codes — and 3 is the one that is not a failure.
| Exit | Meaning | What to do |
|---|---|---|
0 |
every attempted step succeeded | nothing |
1 |
a step failed | the stderr block names which steps were ok / failed; retry just those |
3 |
NOTHING FAILED, AND NOTHING PUBLISHED — the composed link comment carried no claim the author wrote | an unchanged retry cannot clear it — it reproduces the outcome exactly. Two causes, both projections losing your content: the teaser composed to a fragment or to nothing (#1114), or the report changed while the composed body did not, so only the asset link moved (#862). Edit the opening of ## Summary — its first sentence, within the first 200 chars — so the correction is in the composed body, then re-run; or pass --comment-body-file. Re-running is not free: no step failed, so every step that already succeeded runs again, including the skeptic step (Step 0b), which arms a round keyed on the report sha — and the edit this remedy asks for moves that sha (#1230). To re-read the diagnostic without re-running the verb, use ng wrap-up --last, which replays the record read-only and arms nothing. |
The guarantee behind 3: wrap-up publishes a composed link comment only when that comment carries a claim the author wrote; when the composition cannot carry one it publishes nothing, exits 3, and names the cause. It is stated over the mechanism, not over a list of steps, so a lossy stage nobody has enumerated yet is still covered. Full treatment in skills/nexus.report/SKILL.md under "## Summary IS the comment".
Why reports/ is gitignored¶
reports/ is workspace-scoped and ephemeral. Most reports cite paths, commit shas, and configuration values specific to a single operator's environment; committing them to the public code repo would conflate workspace state with shippable code, and growing the log over time would bloat git log and clone size.
Instead, ng wrap-up pushes each report to the asset repo's main branch and prints a SHA-pinned URL. The link comment on the tracking issue is what readers on github.com see. The asset repo (github.asset_repo — typically a private repo per operator) is the durable surface; the code repo stays clean.
Linking to a bare reports/<file>.md path in the code repo doesn't work — github.com 404s, because the file isn't on any branch. Always upload via ng wrap-up first.
The Infrastructure Issues feedback loop¶
When the work hits something rough — a command that was hard to discover or had surprising behaviour, broken / flaky tooling, sandbox or Slurm surprises, a GitHub-interface rough edge, agent-to-agent communication friction — record it in a ## Infrastructure Issues section with concrete reproduction detail.
These sections are the source material for the periodic infrastructure meta-review. The 2026-04-28 review triaged 173 reports — 93 of them carrying ## Infrastructure Issues content — and clustered the cross-cutting themes into a ranked backlog of fixes. Themes that surfaced ≥ 6 times each got a PR:
monitor/ng reactexited silently on success — 11 cites.- The bot's GitHub App was installed on a subset of internal repos, blocking cross-repo writes — 16 cites.
ng pr create/ng issue createwere repo-locked to the nexus with no--repoflag — 8 cites.mint-token.shreturned empty silently from a non-nexus-root cwd — 1 cite, but the highest-severity finding (security boundary bypassed by falling through to userghauth).
None of those would have been spotted without agents writing them down. The monitor/infra-resolved.md table lists every retired theme alongside the fix commit/PR so future meta-reviews don't re-discover them.
The skill that drives the periodic review is nexus.infra-review. Operators don't run it manually — the orchestrator runs it on a schedule and spawns the resulting fix-workers.
One rule for agents writing reports: don't write placeholders ("nothing to report"). Omit the section.
Cadence — when an agent writes a report¶
- Task completion. Final report summarises what was done;
status: completed. - Before going idle. Partial work, waiting on input or a decision; report captures the partial state,
status: partialorblocked. The orchestrator or any successor agent can resume from it. - Context pressure. Context window filling up; write the report before it's lost. A crashed session with no report is wasted compute.
- Handoff. Spawning a follow-up worker that needs to pick up the in-progress work; the report is the brief.
For the deep dive — section semantics, the issue-driven slug, share-on-GitHub patterns — read skills/nexus.report/SKILL.md. Operators rarely need it; orchestrator and worker prompts pull it in by absolute path.