Structured report
One self-contained HTML file (no network) that lets a busy reader
- see the whole work as a map of tasks, with what is waiting on them inside each task,
- open any task — and any stage inside it — and audit how it was done and why each claim is believed,
- answer the agent's questions right there, and see which of their prompts produced what.
Structure vs. content
- Structure belongs to the template (
assets/template.html): layout, section names (Problem, Task, Context, Conclusions, Assumptions, Result, Not checked, Workflow, Needs approval, Your actions), their order, statuses, every icon and every UI label. Fixed, always English. Icons mark structure only, never what the content is about. - Content is yours: the JSON, in the user's language.
scripts/build.pyvalidates it and fills the template's placeholders. You never write HTML and never invent sections.
Workflow
- Collect the material: messages, tool results, files, commands, links, tests, measurements, decisions. Report only what actually happened.
- Cut it into tasks (1–12): one task = one goal with its own outcome. Connect them with
links:depends,blocks,related. - Fill every task following the rules below and
references/schema.md. - Write the JSON — default
reports/<YYYY-MM-DD>-<slug>.jsonin the working directory. - Build:
python3 <skill>/scripts/build.py <file>.json→<file>.html. Fix everyerror:; read everywarning:and fix it unless it is genuinely true. - Open it locally (
open/xdg-open/start) and give the path. Never upload it. - In chat: 2–4 lines — the headline result and what waits on the reader.
Living report: track the session, take answers back
When the user wants the report kept up to date through the session (or asks for a tracked / living report), bind the session once:
python3 <skill>/scripts/track.py start reports/<file>.json # creates <file>.journal.json
From then on the UserPromptSubmit hook (install once: track.py install-hook, which also adds
the Stop hook) logs every user
prompt to the journal and reminds you of the prompt number. After each prompt that changes the
work, update the JSON and rebuild — build.py fingerprints every block (each node × section)
and stamps new or changed blocks with the current prompt. Never write stamps yourself. The report
shows a Prompts rail; picking a prompt highlights what appeared (green) or changed (blue) there.
Questions for the reader. Put decisions in approvals. Each is a question with options —
exclusive by default (one answer) or "multi": true (any that apply) — your recommend (a
list for multi), why and due. The reader always has "your own answer" as an extra option; a
question without options is answered in free text. In the report the open questions of a
Needs approval section form a series, one question at a time: an exclusive option answers
and moves on, a multi-choice or own answer is confirmed with Next, the series ends on a review of
all answers, and Submit answers sends them to you — there is no other way to send, and
actions (steps the reader takes) have no inputs. The answers go to a local answer service (127.0.0.1:47319, started and
kept up to date by the build) even when the report is opened as a plain file, and are stored in
the journal as the next prompt. While the report has open questions, keep a waiter running as a
background command:
python3 <skill>/scripts/track.py wait reports/<file>.json
When the reader sends, wait prints the answers and exits — that output comes back to you:
treat it exactly as the user's prompt and continue; start wait again if questions remain.
If no waiter is running, the Stop hook hands queued answers over before your turn ends, and the
UserPromptSubmit hook attaches them to the user's next message — answers are never lost. Answered
questions show as answered after the next build. --static builds a report without the answer
channel (for sharing outside this machine): questions are shown read-only, with no inputs.
Link under the input. scripts/statusline.py prints one status-line row for the session's
report — its title as a clickable link that opens the HTML in the browser, and how many questions
still wait. Use it as the status line or append its output to an existing one; it prints nothing
for sessions without a report.
Every block of the report has a copy as Markdown button (the whole report, a task card, a report, a section, a single item, a step, a prompt) — point the reader to it when they want to paste something elsewhere.
The rules that make the report trustworthy
Separate how you know each thing; never blur it.
- context — sources you actually looked at:
id(C1…), shorttitle, a realurl, and anotewith the exact fact taken. Never invent URLs. Prefer repo / web URLs:file://links do not open on the reader's machine (build warns; a missing local file is an error). - inferences — conclusions, each with
basis(context ids) andconfidence. No basis → it is an assumption. - assumptions — taken as true without checking:
why, how toverify,riskif wrong. - unchecked — what you did not check or do, with
whynot. Readers rely on this more than on anything else; say it plainly. A finished task withoutuncheckedgets a warning ([]means "checked everything" — only if true). - result — what exists now, as typed items. Every
verifieditem needshow: the command, test or link that proves it — the build fails without it. - stages — the steps you actually took, 2–8 per level. A stage is the same kind of node as a
task:
id+titlerequired, any task field allowed, its ownstages+flow, to any depth. On the card it showsdetail(what you did),outcome(what came out),status,when,uses. Clicking a stage opens its report in the same structure, so give real content to stages that were real work. Dead ends are stages too (failed/skipped). - next steps are planned stages — anything still to do is a stage with
status: "planned", adetail(what will be done) andwhen(the condition or time: "after your approval", "Monday"). An unfinished task with no planned or in-progress stage gets a warning. - approvals — decisions only the reader can make: the question,
whyit is theirs,options(exclusive, ormulti: true), yourrecommend(one of the options; a list for multi),due. Several related questions in one node become a series — order them as the reader should answer them. Never ask approval for something already done. - actions — things only the reader can do, with the exact
commandandduewhen relevant. - secrets — the report gets forwarded. The build fails on anything that looks like a key, token, private key, JWT, password assignment or credentials in a URL (gitleaks is used too when installed). Remove it from the content; never "mask" it by hand. Secrets in logged prompts are masked automatically.
Write structure, not prose
Every text field renders structure, so give it structure:
- item→ bullets;1. item→ numbered (real sequences only); two or moreKey: valuelines → an aligned table; a JSON array of strings → bullets.**bold**the one or two things per line the reader must not miss;==text==highlights;`code`for identifiers, paths, commands.- No paragraph longer than two sentences; no subtitles or intro lines.
Field guidance: brief — 1–3 Key: value lines for the map card. problem — key/value facts.
goal — bullets of what done means. result.summary — key/value or bullets.
Language
Content in the user's language, meta.lang set to its code. Structure labels stay English.
Files
assets/template.html— the structure: markup with placeholders, styles, icons, and a script for layout, navigation, search, the prompts rail and answering.scripts/build.py— validates the content (checks above, secrets), stamps the journal, renders the template.--checkvalidates only;--templateuses another template.scripts/track.py—start,wait,hook,stop-hook,daemon,status,install-hook(see its docstring).scripts/statusline.py— the report link for the Claude Code status line.references/schema.md— every field.examples/— English and Russian examples; the Russian one carries a 5-prompt journal.