Render one turn of work as a rich report (HTML page or native surface artifact), never a chat summary — the desk above the fold, the last turn, what landed and what did not, the delta graph, evidence, spend, launch, decisions. Use when the maintainer invokes hatsu:spiritual-message [as turn|landing], asks to see the report, or when hatsu:ren, hatsu:mukai or hatsu:en reaches its reporting step. Which blocks a variant renders is configuration; the dated final report is hatsu:backlog-board's.
Install
npx skillscat add zheref/hatsu/spiritual-message Install via the SkillsCat registry.
Shared policy: `PROCESS.md` § Standalone entry.
Spiritual Message — the turn, seen
Nature: Manipulator. The nature of the work reported is stated in the page, never adopted.
What does this turn need from me, and what did the last request actually do?
`ren`'s fifth step, `mukai`'s handover artifact and
`en`'s first. The desk comes first, under the tally: the one thing only the
maintainer can do is never read ninth.
0. Standalone entry
From a composite, skip this; bare, the contract is
`docs/STANDALONE-ENTRY.md` (S1, S3). Every block is
evidence-sourced or marked unavailable; no recoverable turn boundary reads this last turn: not recoverable.
1. Invocation
hatsu:spiritual-message [as <turn | landing>] [against <base>]nen parse spiritual-message --grammar "as [<variant:turn|landing>] against [<base>]". Default turn. No against
clause: origin/<branch.base> after git fetch origin, named on the page with its short SHA. A
local branch name is never the base: a stale local main hands over somebody else's delta. A
missing argument or configuration item is asked for and set up inline (missing-argument,missing-configuration; `WORKFLOW.md` § 4 Ask, set up, continue).
2. The variants
turn at ren step 5, every turn. turn-fast there under the fast profile — desk and
last turn only. landing at mukai step 9 (after the PR opened) and en's
first step — the turn blocks + the PR body, the verdict quoted inside the ask. Each publishesreports.sections.<variant>.blocks, never a remembered list.
No final here. The dated final report is a one-effort Rikugan with a cleared desk,
`backlog-board` § 3's variant final into<reports.dir>/<YYYY-MM-DD>-<effort>.html (ruling 2026-09-19). Hand over.
After `hatsu:aka` (pushed, no PR) re-render turn at the same address, the push
in Landed.
3. The parameters
From the target's nen/workflow.json, read as `PROCESS.md`
§ Invocation and parsing says.
| Key | Used for | Default |
|---|---|---|
reports.dir / .template / .captures |
kept-report dir, template, capture dir | Reports / spiritual-message / <dir>/captures |
reports.sections.<variant>.blocks |
the blocks this variant renders | none declared → every block |
coverage.minimum / .recommended / .ideal |
the coverage band | 80 / 85 / 90 |
branch.base |
the delta's base | main |
reports.timeZone |
the page's clock | the host's zone |
Reporting does not schedule verification. Use what the owning phase produced (coverage: not due until mukai); coverage.* configures presentation, never permits running it. Evidence of another
source-tree identity is stale.
4. Assemble the data
nen report data --repo <path> --base origin/<branch.base> [--tiers <json>] [--target <owner/name> --prs <n,...>] --jsonOne nen.report.data/v0.1 document: commits[], files[], evidence[], coverage, proof,lastStop, phases[], usage[], the header fields, plus objects[] where a target was named. It
never writes; every absence is null with the reason on stderr, quoted not replaced; an
unresolvable base is exit 2. Three companions fill what git cannot know:nen shu evidence --base <ref> (rows gaining a data: URI src), nen shu test-report --from-artifacts, the saved nen shu coverage --touched with nen's band.
The merge shape — base document ∪ extension, every row key spelled because the template iterates
them, keys and values per `PROCESS.md` § Escaping and validation of
report data:
<base data> ∪ { variant, title, gate, footerNote, generatedAtLocal,
turnLabel, effortStage, stageClass, worktree,
tallyNeedsYou, tallyBlockers, tallyLanded, tallyGaps, deskCleared,
ask: null | { kind: DECIDE|DO|MERGE, gate, question, whyNow, objects[{label,url}],
options[{letter,label,command,consequence,star,starredClass}],
blocker: null | {rule,step,executedAfter,why,nextAction,findings[{text}]} },
readiness[{verdict,reason,gate}], lastTurnRequest, lastTurnRequestFull,
lastTurnHighlights[{text,outcome,outcomeClass,why}], mukaiLastTurn,
lastTurnCorrections[{what,who,whyAsked,howHandled}],
lastTurnCheckIssues[{check,issue,howHandled}], lastTurnStops[{why,autonomy,policy}],
accomplished[{text,why}], challenges[{text,why}], notDelivered[{text,why}],
decisions[{text,why}], architectureCaption, graphJson, graphMermaid,
graphNodes[], graphEdges[], captures[{role,alt,src}], evidenceUnavailable,
tests[{suite,name,status}], touchedCoverage[{file,percent,band}],
spendPhases[{lane,percent,amount,steps}], hasSpendPhases, noSpendPhases, actionsMinutes, spendNote, launch, prBody[{markdown}],
spendUsage[{surface,model,input,output,cacheRead,cacheWrite,minutes,source,notReported,reported}] }spendPhases, never phases: the verb answers phases[] (each with durationMs, note andsteps[{verb,durationMs,…}]) and usage[]. Per phase: percent = durationMs / max durationMs × 100 (the
bar regex), amount as 12.3 s / 4 m 05 s, steps as build 41.2 s · lint 3.1 s or ""; hasSpendPhases /noSpendPhases are the inverse pair for an empty ledger.spendUsage: one row per surface+model, counters and minutes summed; a --not-reported entry
sets notReported: true, reported: false. actionsMinutes sums--minutes entries, not read with none; spendNote is "" or one muted line. tests[] andtouchedCoverage[] are likewise re-mapped from shu test-report and the saved shu coverage --touched, never passed through. generatedAtLocal: "$hatsu_root/scripts/report_time.sh"; repo, gate, turnLabel,effortStage, stageClass, worktree: derived per WORKFLOW.md § Where the effort is.
Record usage before rendering (`WORKFLOW.md` § The effort's ledgers), from the surface's readout: nen usage record --effort <branch> --surface <s> [--model <alias>] --input/--output/--cache-read/--cache-write <n> --source <text> — Claude Code's /cost line, Codex's session-log usage, Cursor and
Antigravity --not-reported (nothing exposed); Actions minutes for the runs en observed fromgh api repos/{o}/{r}/actions/runs/{id}/timing, recorded --minutes <n> --source "gh actions timing".
--variant injects sections.<block> and sectionList.
The ask is the desk. At most one per turn, opening DECIDE, DO or MERGE, with the Crazy
Slots options, one star, and the nen pr ready verdict quoted verbatim. A turn owing nothing
sets ask: null and writes deskCleared. A G5 puts its evidence inside the ask — ask.blocker,
in the wrapper #g5-blocker `jutaisho` verifies before handing over the
link (hatsu#56).
5. The graph document
The delta is conceptual and session-wide, never a file list. Author nen.report.graph/v0.1 — { contract, caption, nodes[{id,label,kind,change}], edges[{from,to,rel,change}] }, worked example.
change is added | changed | removed | unchanged on nodes and edges; every edge endpoint names a
declared node. nen report render --graph <file> validates it, injecting graphJson,graphMermaid, graphNodes[], graphEdges[]; <details> carries the text fallback.
6. Fill the template
nen report render --variant <turn|turn-fast|landing> --graph <graph file> \
--template "$hatsu_root/templates/spiritual-message.html" --data <§ 4 doc> --out <reports.dir>/current.html --repo <path>Template language, exit codes and --dry-run: `docs/WORKFLOW.md` § 2
→ reports; prove with --dry-run before shipping. Escaping and validations:
`PROCESS.md` § Escaping and validation of report data.
Template path: $hatsu_root is resolved per `ten` § 0 (hatsu_root="${HATSU_PLUGIN_ROOT:-}"; [ -n "$hatsu_root" ] || hatsu_root='<the absolute path ten § 0 printed>');"$hatsu_root/templates/spiritual-message.html" resolves deterministically across checkouts.
PR body diagram: nen report mermaid --graph <file>, pasted by `shibari` § 3.
7. Publish it
- On Claude Code an Artifact, ONE URL per branch (`PROCESS.md`
§ Publishing a report). Headline title ≤ 60 chars, stable across turns
(`WORKFLOW.md` § Report titles). - On Antigravity a native Markdown artifact in
<appDataDir>/brain/<conversation-id>/spiritual-message.md
viawrite_to_filewithArtifactMetadata({ Summary: "<Variant> report for <effort>", UserFacing: true, RequestFeedback: false }).
The bridge renders declared variant blocks (reports.sections.<variant>.blocks, includingprBody,decisions,readiness, Desk/Ask with quotednen pr readyverdict, Last turn, Tally, deltagraphMermaid,
Evidence, coverage, Spend, Launch), G5 blocker in<div id="g5-blocker">, via GFM tables, alerts (> [!NOTE]), Generative UI. - Elsewhere
<reports.dir>/current.html(from § 6), overwritten every render, transient.
Say one line in chat and stop — variant, branch, link or path.
8. Not a gate event
Rendering, its one line and its gaps follow `PROCESS.md` § Reporting a
phase; a chat summary or markdown dump in chat is never the fallback. The bell is `jutaisho`'s, runs after this skill in ren's order and takes this
page's link.
Permitted: read working copy, history, nen/*.json; publish/republish this branch's
report Artifact (including Antigravity's <appDataDir>/brain/<conversation-id>/); write under<reports.dir>. Not permitted: anything else on disk, any GitHub write, label, merge or push,
or a delegation (`PROCESS.md` § Authority every phase shares).
Hard limits
- Never lets a chat summary stand in for the report, or dumps a raw chat markdown recap in place of publishing the artifact or HTML page. (Markdown is permitted strictly as the native artifact document on artifact-capable surfaces such as Antigravity).
- Never writes outside
<reports.dir>(except when publishing the native artifact in the surface's declared conversation artifact directory on Antigravity), gives aturnorlandingrender a kept file, or
renders the dated final report — `backlog-board` § 3's. - Never claims readiness by eye — the verdict is
nen pr ready's, quoted, or absent — never
omits the desk, oraskfrom the data (nullor the § 4 object). - Never fills the session blocks from only the last request, puts earlier-turn work into this
last turn, or drops a gap from Not delivered to read better. - Never renders the delta as a file list, or
landingbefore the PR exists (F6: its extras are
shibari's, an empty verdict readsnot-ready) or while a review round is owed. - Never fires the
nen stopbanner, efforts table or push notification (§ 8), links a capture
unresolvable off this machine, writes an unescaped value, or uses the raw form beyond the
validated graph document (§ 6).
History: this effort's history file; dated live verifications: docs/ab/spiritual-message.md.