CommunityCoding & Developmentgithub.com

zheref/ren

Run each request in an independent effort worktree by default, rechecking isolation on continuations. Warm up, author, verify and commit locally, handle launch, report and ring the bell, then wait. Use on $ren <request> or ordinary work in a repository using the turn loop. Ren composes six skills; it never pushes or opens a PR and ends only on the maintainer's $aka or $tensho call.

What is ren?

ren is a Claude Code agent skill that run each request in an independent effort worktree by default, rechecking isolation on continuations. Warm up, author, verify and commit locally, handle launch, report and ring the bell, then wait. Use on $ren <request> or ordinary work in a repository using the turn loop. Ren composes six skills; it never pushes or opens a PR and ends only on the maintainer's $aka or $tensho call.

Works with✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/zheref/hatsu/tree/HEAD/surfaces/codex/ren

Installed? Explore more Coding & Development skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Shared policy location: docs/DISCOVERY.md, docs/WORKFLOW.md, docs/LAUNCH-MIGRATION.md, docs/STANDALONE-ENTRY.md, docs/PROCESS.md, docs/using/README.md and docs/using/mirrors.md belong to the resolved Hatsu plugin root, not the consuming repository. On an installed surface, use the absolute root printed by ten to read those files (re-resolve through that skill if unavailable). Relative links below identify source locations; a missing consumer docs/ copy is not a missing policy and must not trigger a duplicate filing. Never copy or invent a second policy in the target repository.

Ren — one request, one turn, every time

No fixed mode. Ren is a composed run: the mode is whichever the request is — Enhancer for product code, Conjurer for canon, Transmuter for machinery — held for the turn and named in the reply, with Manipulator named alongside it while the turn's reporting steps run. Name the mode in play, say when it switches and why, and never blend two under one header (claude/agents/kurapika.md).

Take the request. Warm up if this is the first one, write it, prove and commit it, handle launch, show me the report, ring once. Then wait.

Ren is the shape of ordinary work in the local plane. It is not a batch runner and not a watcher: one invocation is one request, and one request is one turn. The loop is that the next request starts the next turn, with the warm-up step already spent.

This file composes. It does not re-specify. Every step below is another skill's, named and linked, and its procedure, its exit-code reactions, its refusals and its residue live there. If you find a rule here that is really that skill's, it is in the wrong file — go read it where it is authored, because a rule restated in two places drifts in one of them.


1. Invocation

P1 — this run opens with $ten ren (ten § 6 catches up this phase's missing prerequisites under its own name; the phases this run calls skip theirs).

$ren <request> [--profile fast|standard|thorough]
nen parse ren --grammar "<request> [--profile <profile:fast|standard|thorough>]" \
  --line "<the request, minus the $ren prefix>"

profile: (clause absent) means profile.default (§ 2a); the words "fast turn" or "thorough turn" inside the request are read as the same override.

Verified live at v0.3.0 (docs/ab/ren.md § 2.1): a request line parses to request: <the whole line> at exit 0, and an empty line refuses at exit 2 — " is required and the line does not supply it" — with the corrected line printed. A turn with no request is never inferred from what the session was last doing — it is asked for as free text: the request is the maintainer's word (row missing-maintainer-choice, recorded through nen stop answer, docs/WORKFLOW.md § 4 The maintainer's word is never derived), so any readings the session suggests are listed for reference, none starred and none a picker option, and the turn runs on what the maintainer types.

Ren is also the default shape, not only an explicit call. In a repository whose nen/workflow.json describes this loop, an ordinary request from the maintainer is a ren turn; say so on the first one, so nobody is surprised by the report and the bell at the end of it.

2. The turn, in order

#StepThe skill that owns itWhy it is here
1warm up$breathbind/re-verify isolation on every entry under WORKFLOW § Where worktrees live before Ten catch-up or mutation; warm and prove a fresh branch once per new effort in that checkout — the session's own harness worktree on an observed hook refusal (HR-374). Explicit continuations reuse only the verified effort-owned worktree. A red base is a G5 before authoring; so is a conflicting clause in its constitution check (breath § 4a), recorded on this step's ledger entry
2author the change$rasenganwrite what the maintainer asked for, on the stack this repository declares: the edits, the tests beside them, the docs and changelog its conventions owe — with the declared iteration.checks run as the author's own feedback while the work is in front of them
3verify and commit$kokusenevery inexpensive iteration.checks verb and the declared focused tests over the finished tree, red refused; then triage, an ask on what is flagged, one shaped commit — local only
4launch$amaterasuan isolated effort reports the dry-run command and records core launch deferred; explicit maintainer call required, then continues without asking, even when serial. No target → no launch target declared; skipped. A core launch never moves authoring or delivery out of its bound worktree
5report$spiritual-message as turnthe page: accomplished, challenges, not delivered, architecture, screenshots, the exact launch command, decisions
6bell$jutaisho (§ 1 decides whether the page's ask makes it a stop)the rungs the workflow declares — and a stop only if one is genuinely due

Step 2 is the change itself, and it stopped being half-numbered on 2026-09-10. This table used to carry a step 1.5 — "the work", owned by no skill — beside a step 2 called build, which read rasengan as run the build command rather than build the thing. The maintainer's ruling (docs/ROSTER.md HR-55) settles it: rasengan IS the authoring phase, so the work has a skill, the six whole numbers are six skills again, and the compile-before-commit sits with the phase that stages the tree.

The order is load-bearing in five places, and those five are the only ones ren asserts:

  • 1 before 2 — no authoring on an unverified base. Breath cuts the branch from origin/<branch.base>'s freshly fetched tip and proves the declared checks on it, so the first line of the change lands on a tree already known to build and the first red anybody sees is one this effort caused. A red base tip is a G5 stop there, before a line is written; it is never repaired inside this effort. The same holds for breath § 4a's constitution check, whose gate breath § 6 states (WORKFLOW.md § The constitution check).
  • 2 before 3 — nothing is committed that was not authored in this turn and verified in it. Rasengan writes the change and keeps its own inner loop honest; kokusen then runs the declared checks over the finished tree and refuses to commit on red. The two runs are not a duplication: the tree moves with every line written after the author's last check, so the only run a commit can rest on is the one taken by the phase holding the index. Where a turn iterates (write, check, write again), it is step 2 iterating with itself, and step 3 is entered once.
  • 3 before 4. Launch handling follows the committed result; isolation does not authorize a core launch. A deferred command is not a demonstration of this effort's tree.
  • 4 before 5. The report distinguishes a deferred dry-run command from argv actually run.
  • 5 before 6. The bell carries the report's link. A bell that rings before the page exists sends the maintainer to nothing.

The phases this composite calls SKIP their own ## 0. Standalone entry sections. docs/STANDALONE-ENTRY.md is the contract for a phase typed by hand into an arbitrary checkout; a phase reached from here inherits P1–P4 from this run — the warm-up, the orientation, the change set and every derived argument — and re-deriving them would produce a second answer to a question this composite already settled. Each phase says which composite is holding it instead.

Inside step 1, once per classified effort, $direct runs — for an effort that names an issue (<CODE>#<N> in the request) or a text classify already labelled — with this session's --surface, --model and --effort (unread where the harness hides one), exactly as build § 2b does; its § 6 owns the compare and the one ask, and the typed $ren is already the decision to work here, so it never blocks. Its answer B ends this turn, not the loop: steps 5 and 6 still run and the report names the restart line. An effort with no job/ label is undirectable, one line, and the turn goes on. It is not a seventh step and asserts no order of its own: it reads inside the warm-up, asks at most once, authors nothing — and its § 7 publish step does not run here: Ren cannot leave the machine (§ 3), so the verdict stays in the report and the local ledger, and direct.publish acts only under build, file (once filed) or standalone.

Warmup runs once per effort; checkout selection is checked on EVERY entry. Later turns and PR phases re-verify the bound absolute effort path under $hatsu_root/docs/WORKFLOW.md § Where worktrees live before step 2 or any catch-up. Report the path, original-prompt waiver status and whether Breath warmed or only re-verified. Continuation never bypasses isolation.

A new request is a new effort unless the caller explicitly continues the current one. Sitting on a clean feature branch from a previous effort is not a continuation (zheref/hatsu#60; $breath § 2a). Breath still runs, still fetches the configured base, and still cuts a newly rendered branch. Reuse is only for an explicit "continue" / "same effort" / "on this branch", or for turn 2+ of a loop whose step 1 already cut this branch in this session.

When a later turn of this effort, or $mukai, re-enters $hanten, it reuses the same cycle ledger — .nen/hanten/<branch-slug>.cycle.json. Remediation does not reset reviewer counts. Breath cutting a new branch is the only new cycle (zheref/hatsu#63; hanten § 2a).

2a. Profiles, and the phase ledger

profile.default in nen/workflow.json shapes the turn (standard when absent); § 1's --profile overrides it, a value outside profile.allowed is asked for again with the allowed list as the picker's options, and the turn's first line names the profile in play.

ProfileWhat changes in § 2
faststep 1 verifies the binding; warmup still runs once; steps 2 and 3 as declared; step 4 skipped, launch line deferred by profile fast; isolation still requires an explicit maintainer core-launch call; step 5 renders --variant turn-fast
standardtoday's turn, as the table above states it
thoroughstandard, and after step 3 kotoamatsukami's impacted suites run, on every turn

A profile decides which steps run and which variant step 5 renders, never what happens inside a step. Steps 2 and 3 run as their skills say under every profile. Under fast the impacted suites are not run (they are mukai's, step 4 there); under thorough kotoamatsukami's impacted suites run after step 3, ren being that skill's third caller. The launch is skipped, not moved: mukai has no launch step, and amaterasu § 1a says how a skipped launch is taken. Coverage is captured by no ren profile; that is byakugan's, at mukai.

A landing (mukai) always runs thorough, whatever the turns before it named.

Every step is one ledger entry (WORKFLOW.md § The effort's ledgers owns the mechanism; what is ren's is which steps and when). Before a step, nen phase begin --effort <branch> --phase <step-name> --surface <s> [--model <reported-model>] --dial <level>; if the model is a harness-reported served ID, add --note "model-kind=served; registry alias <alias>" (WORKFLOW § The effort's ledgers); at the first phase record nen session record with the harness's title/id when exposed, once per session; after a step, nen phase end --effort <branch> --phase <step-name> --exit <code>, so .nen/phases/<effort>.json carries one timed entry per phase, a refused step included. Step 1's end carries breath § 4a's record as its --note, composed with the note step 1 began with, because end --note replaces it (the script's --begin-note; WORKFLOW § The constitution check, steps 3, 5 and 6, owns the forms). The check is not an entry of its own, so the six steps stay six entries (HR-58). The usage entry is recorded at step 5: nen usage record --effort <branch> --surface <s> [--model] --dial <level> [--input] [--output] [--cache-read] [--cache-write] [--minutes] from the surface's own cost readout, --not-reported on a surface that exposes none.

A resumed effort reads before it writes (zheref/hatsu#444, zheref/hatsu#445; nen 0.28, the pin). An effort whose branch already has a phase ledger, or a PR, is a resume: first, where a PR exists — the open one: a successor's number, never the PR a base deletion closed (en § 6) — nen pr ledger read --target <owner/name> --pr <n> --effort <branch> --repo <checkout> --json, adding --restore only where nen phase show finds no local ledger; then nen phase show --effort <branch> --json. WORKFLOW § The effort's ledgers, The durable slice, owns the verdicts and the one skip-line form; a skipped breath entry's note is read before step 2 (WORKFLOW § The constitution check, step 7). Per phase, in order: ended at exit 0 → skipped and named; open → continued with nen phase begin --resume (one entry, resumedAt appended); ended non-zero → the resume stops there and refuses by name (refused <phase>: ended at exit <n>), writing nothing, because that step's own stop is answered first — never begun a second time; none of these → begun as above. A begin --resume refused at exit 2 (another phase open) is a finding to report, never a skip. A step that publishes reads its object first and never publishes twice: nen pr open answers existing for the same base and head, nen pr ledger post unchanged for the same bytes. The proof is node scripts/resume_proof.mts (lane resume-proof, docs/ab/ren.md).

A step that refuses ends the turn where it refused. Kokusen asking about a flagged file or refusing a red tree, amaterasu finding the declared device disconnected — each is that skill's own handling, and ren neither retries past it nor smooths it over. What ren adds is that steps 5 and 6 still run: a turn that stopped at step 3 is still a turn, and the report names the stop in Not delivered.

3. What each turn produces, and what it never produces

Produces: local commits on the effort's branch, a launch result or explicit deferral under Amaterasu § 3, one report at the branch's report address, and at most one bell.

Never produces: a push, a pull request, a tag, a label, a comment (direct's opt-in model/ label and comment included: under Ren, direct is report-only), a release, a deploy. Ren is the phase that cannot leave the machine, and that is what makes it safe to run on every request without asking. The moment work needs to leave, a human says so.

Isolated efforts never automatically launch from core, serial or parallel. Amaterasu § 3 owns the deferral; Ren does not request approval, switch to core or invoke a swap to complete it.

4. The loop, and what ends it

One request, one pass through § 2. Then wait. There is no timer, no poll, no background pass, and no self-continuation: the next request is the next turn.

Ren ends only on $aka or $tensho — the two places the effort leaves the machine. Nothing else closes it:

  • a turn that stopped at a step is a turn that stopped, not the end of the loop;
  • a G5 stop inside a step ends that turn, and the answer resumes the loop;
  • the maintainer moving to a different effort starts a new loop, with its own step 1;
  • the session ending ends the loop the way it ends everything else. A ren loop is session-scoped, never a standing arrangement, and never promises persistence it does not have.

Ren never proposes its own ending. In particular it never suggests $aka — that skill's § 1 forbids being prompted for, and a composite that ends every turn with "ready to push?" is the exact inversion the local plane's push discipline exists to prevent. The report says the branch is ready; the maintainer says the rest.

No nen verb can drive this loop, and that is verified rather than assumed (docs/ab/ren.md § 2.2). nen ships two loop primitives and neither fits. nen watch until spawns one program, directly, with no shell, and classifies it against izanami's read-only table before the first run: nen watch until --command "nen shu build" --max-iterations 1 is refused at exit 2 — "'nen shu build' classifies as mutating … izanami watches only" — and nen parse izanami "nen shu build until it is green" reports [mutating] at exit 1. A turn is six skills and many programs, most of them mutating, so it has no single --command and would be refused if it had one. nen loop slots is a concurrency budget across efforts (--efforts <path.json> --local-cap <n>), which is a different question entirely — how many efforts may be in flight, not how one effort takes its next turn. So the loop lives in the session, under $izanami's borrowed discipline: one line per turn, no line when nothing happened, no background timer, no deferral primitive, and a visible way to end it. This is a boundary, not a missing verb to file — a turn loop is a conversation's shape, and nen deliberately owns operations rather than conversations.

Turn completion and discoveries

A completed turn means authored work, focused tests and inexpensive iteration checks verified by kokusen, a local checkpoint, and the actual launch/report outcome. rasengan may run focused tests for feedback; kokusen owns their mandatory finished-tree execution. A repository with no applicable executable tests says so explicitly. The shared iteration.checks list remains shared with breath; a focused lane is an explicit supported declaration, not a new checkpoint-only policy key.

Impacted project-wide tests and coverage measurement/gating are due in mukai / $kotoamatsukami (the declared unit, UI and integration suites the change can affect) and $byakugan (coverage). Linting is $gyo, on every Ren turn. Neither those tests nor coverage is triggered by the words “turn complete,” by a local commit, or by collecting a report. No nested skill or declared coverage command may hide a full-suite run outside its owner.

Every phase, subagent, composite and resumed run follows the common discovery protocol. Concrete out-of-scope gaps are reconciled and captured under standing filing authority; unchanged findings produce no write. Report created/updated/unchanged/pending and continue this request where possible. Capture never authorizes an unrelated build, a stage label, closure, merge or release.

5. The parameters — read by the steps, named here

Ren reads one nen/workflow.json key for itself, profile (§ 2a). For the rest it names which step owns which, so a maintainer tuning the file knows where the effect lands:

KeyThe step it configures
profile.default, profile.allowedevery step, § 2a: which of them run, which is skipped, and which report variant step 5 renders
branch.template, branch.basestep 1 — $breath
iteration.checks, iteration.lanethree steps read the same pair, for three different questions — step 1 $breath (was the base sound), step 2 $rasengan (does what I just wrote work), step 3 $kokusen (is the tree I am about to record green)
commits.allowedAttributionTrailers, commits.forbiddenTrailersstep 3 — $kokusen
launch.default, launch.fallbackstep 4 — $amaterasu
reports.dir, .template, .retain, .captures, coverage.*step 5 — $spiritual-message
notifications.rungs, notifications.soundstep 6 — $jutaisho

Each step states its own default when a key is absent. Ren neither supplies a default nor overrides one — a composite that quietly substituted a value would make the file a lie for the step that owns it. A key a step needs and cannot default is asked for and set up inline by that step (row missing-configuration, docs/WORKFLOW.md § 4 Ask, set up, continue).

6. Reporting the turn in chat

One line, then the report link, led by where the effort is — the same values the page's status line carries (docs/WORKFLOW.md § Where the effort is):

Turn 4 · authoring · gate: none — local · worktree quirky-chatterjee-88d5f6 · <branch>

Then whether step 1 ran, which steps ran and which refused, and where the page is. Every turn says it, a turn that stopped included — the maintainer never has to scroll or open the page to learn the stage and the gate. Not a prose recap of the page — that is exactly what step 5 exists to replace, and duplicating it is how the page stops being read.

Residue

One entry, and it is a boundary rather than a gap:

  1. The composition itself has no verb, and is not expected to get one. nen owns operations, not conversations (§ 4, verified live). Ren's ordering is prose because it is a sequence of other skills, each of which is verb-backed where a verb exists. Every deterministic step inside a turn is a verb or a named residue in the skill that owns it — nen shu <check> and nen shu tools (step 2's inner loop; the authoring itself is that skill's own named boundary), nen shu <check> again over the finished tree plus nen commit check --require-proof, nen stage triage and nen commit format --repo (step 3), nen shu dev --target (step 4), nen report data and nen report render (step 5), nen stop and the osascript/afplay fallback (step 6, named there). Ren adds no residue of its own, and if a step in this file ever grows a bare shell command, it belongs in that step's own skill as named residue instead.

    RETIRED at nen 0.5. Step 5 used to be named here as "the missing nen report data / nen report render". Both are in the pinned binary and both were exercised against this repository at the pin — data exit 0, render exit 0 writing a 38 283-byte page — so the by-hand assembly and the scratch renderer are gone rather than deferred ($spiritual-message §§ 3–4).

Authority

  • Permitted: everything the six composed skills are each permitted, under their own authority, one at a time, in § 2's order.
  • Not permitted: anything none of them may do — and specifically no push, no PR, no tag, no label, no comment, no deploy, whatever the request says. A request to "push this when it builds" is answered by doing the turn and saying that $aka is the maintainer's call.
  • Ren grants no delegation of its own. Composing a skill does not widen what that skill may do; each step runs under exactly the authority its own file gives it, and a run-scoped delegation granted inside a step expires with that step, not with the loop.

Hard limits

  • Never pushes, never opens a pull request — no matter how many turns have passed or how ready the branch looks.
  • Never proposes $aka or any other human call as a next step it is waiting on (§ 4).
  • Never restates another skill's protocol. If ren and a composed skill disagree, the composed skill is right and this file is the bug.
  • Never skips step 5 or step 6 because a turn ended early — a stopped turn still reports and still rings, and Not delivered names the stop.
  • Never re-runs step 1 on a later turn of the same effort, and never skips it on the first.
  • Never runs unattended — no timer, no background pass, no self-continuation (§ 4).
  • Never carries a loop past the session it started in, or promises persistence it was not given.
  • Never overrides a nen/workflow.json value on a step's behalf (§ 5).

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Related Skills