CommunityCoding & Developmentgithub.com

zheref/en

Drive one open pull request to verified readiness under a mandatory acting-cycle cap. Use when $mukai hands over its PR, or when the maintainer invokes $en on <CODE>#<N> for an open PR. Pending CI or review keeps the run active; quiet polls spend no cycle. At Ready, merge only a recorded Futon-owned stacked delivery through Nen's bounded guard; hand every other PR to the maintainer. Never cast a review vote. After this run completes, the caller offers the wrap-up — $cleanup, required, with $third-hand optional beside it — En does not own it.

What is en?

en is a Claude Code agent skill that drive one open pull request to verified readiness under a mandatory acting-cycle cap. Use when $mukai hands over its PR, or when the maintainer invokes $en on <CODE>#<N> for an open PR. Pending CI or review keeps the run active; quiet polls spend no cycle. At Ready, merge only a recorded Futon-owned stacked delivery through Nen's bounded guard; hand every other PR to the maintainer. Never cast a review vote. After this run completes, the caller offers the wrap-up — $cleanup, required, with $third-hand optional beside it — En does not own it.

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

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.

En — the circle held around one PR until it is Ready

Nature: Manipulator. Everything en does is board-facing — driving, reporting, ringing, watching. Kurapika says so when he runs it. When a cycle sends him back into the change itself — a reviewer's finding that needs code — the mode for that fix is the change's own (Enhancer, Conjurer, Transmuter), named out loud for that cycle and handed back afterwards.

Stay with this PR: report it, observe every current-head check and review, drive it to verified Ready, ring once at its human gate — and stop after at most N acting cycles.

En is the last composite of the local plane and the only one that may need to hold attention past the moment the PR was opened. $mukai ends by offering this handoff — starting it itself only under nen/workflow.json → mukai.autoEn (ruling 2026-09-28); from there the PR belongs to En — and the still-active user turn only on the autoEn path, a typed start from the offer being its own turn — until Sharingan proves it Ready, or a concrete blocker/cap/terminal state/cancellation ends En's run. The merge is the maintainer's later act except for § 5's recorded Futon delivery exception. This run does not harvest and does not clean. When En has completed, the caller offers the wrap-up through the picker (cleanup § 2, row wrap-up; ruling 2026-10-13) — only under cleanup § 2's two prerequisites (HR-366); a Ready PR at § 5's prompt meets neither: $cleanup, required, with $third-hand optional beside it — separate skills, started after this file's protocol has returned, never as a step of En.

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.

What is genuinely en's own is the cap, the watch's shape, and the boundary at the end of the session. Those three are § 2, § 6 and § 7, and they are the only places this file asserts anything. Third-Hand is not in that boundary.


1. Invocation

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

$en [on <CODE>#<N>]

Started by $mukai with no clause under mukai.autoEn — the PR is the one step 8 just opened — by $getsuga § 3 for the release proposal it just opened (there en runs steps 1–5 and returns its quoted verdict to getsuga; step 6's bell is not rung, because getsuga § 3a is that PR's merge), by futon's per-issue chain for the PR its effort opened, or for its integration→main PR (futon § 5 opens no PR into its integration branch; it merges there locally), or by the maintainer, naming a PR that is already open (mukai's offer line). The rule that every PR a session opens or causes to be opened reaches the maintainer through this run or with the verdict quoted is docs/PROCESS.md § Reporting a phase's (zheref/hatsu#103), cited, not restated:

nen parse en --grammar "on [<ref>]" --line "<the invocation, minus the $en prefix>"

Verified live at v0.3.0 (docs/ab/en.md § 2.1): on HA#41 → ref: HA#41 at exit 0, and a bare on parses with the clause absent, also exit 0. The clause is anchored behind a literal for the reason $spiritual-message § 1 records — a lone bracketed slot is refused at the template.

The empty line is refused, and that is why a composite does not parse at all. Verified live: --line "" exits 2 with "the line must open with the literal 'on' — it is what introduces <ref>". An anchored optional clause requires its anchor; "no clause" and "empty line" are different inputs, and only the first parses. So mukai, under autoEn, hands the PR over directly and calls nen parse en not at all — echoing a parse of a line nobody typed would be theatre, and feeding it "" would produce a refusal that means nothing. The parse runs when, and only when, the maintainer typed a clause.

A missing argument or configuration item is asked for and set up inline (missing-argument, missing-configuration; WORKFLOW.md § 4 Ask, set up, continue): a maintainer's line that exits 2, or names no PR where the session holds none, is the trigger to offer the session's open PRs in the picker and resume on the answer, never the end of the run.

Resolve the code once, up front, and keep the slug for every later call — never re-derive it a second way (claude/agents/kurapika.md § How you work):

nen repo resolve <CODE> --repo <path to the target repo's own checkout>
nen ref format --code <CODE> --kind PR --number <N>

A closed or merged PR ends the run immediately with what happened to it. There is nothing to land.

An open PR whose head is already published stays in En on every continuation. When its branch falls behind the PR base, or a review fix needs publication, run En's current-tree evidence steps and $murasaki's guarded fast-forward push (§ 3 and murasaki § 6). Do not send the published branch through $aka's squash. First publication follows the authorization already carried by its invoking workflow, whether a direct Aka call or a composite such as Futon. En still stops at § 5's separate human merge gate. For example, PR #274 was already published at b5fddea when #273 advanced main; its catch-up merge preserved that published ancestry and Murasaki pushed the verified descendant 5de39c5.

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.

2. The cap — grammar, not a default

En acts. Steps 2 and 4 drive; a cycle that finds a new review finding goes back into the change and pushes a fix. That makes en the mutating half of the loop pair, and $izanagi's whole discipline binds: a loop that writes needs a bound a loop that reads does not, and making the bound part of the grammar means it can never be defaulted, inherited, or forgotten.

KeyFileUsed forDefault when the key (or the file) is absent
monitor.maxCyclesnen/workflow.jsonthe cap — the count of acting cycles (§ 6)20
monitor.pollSecondsnen/workflow.jsonthe interval between observations, as --interval-ms300 (→ --interval-ms 300000)
branch.basenen/workflow.jsonthe base § 5 prompts on. Step 3 catches up from, and "behind" is measured against, the PR's own baseRefName (gh pr view <N> --json baseRefName), which is branch.base for every PR en prompts onmain
reports.dir / .sections / .retainnen/workflow.jsonstep 7's file — backlog-board § 3's keysReports / required, no default (WORKFLOW § 2 → reports) / final-only
notifications.rungs / .soundnen/workflow.jsonstep 6's rungs — $jutaisho's keys["push","os","sound"] / Glass

Before cycle 1, the cap is spelled out through the verb that refuses a missing one:

nen parse izanagi "take <CODE>-PR-#<N> to its human gate until it is Ready up to <monitor.maxCycles>"

Verified live at v0.3.0 (docs/ab/en.md § 2.2), both ways:

$ nen parse izanagi "take HA-PR-#41 to its human gate until it is Ready up to 20"
task: take HA-PR-#41 to its human gate
until: it is Ready
cap: 20
exit=0

$ nen parse izanagi "take HA-PR-#41 to its human gate until it is Ready"
nen: no 'up to <N>'. Izanagi is the MUTATING half of the loop pair and the cap is required grammar,
never defaulted or inferred -- an invocation without it is refused rather than run once 'to see'.
  try: take HA-PR-#41 to its human gate until it is Ready up to <N>
exit=2

The value comes from monitor.maxCycles; the requirement comes from the grammar. Those are two different things and the distinction is the point: the file supplies a number, and the verb refuses to run without one. A repository whose monitor block is missing gets 20, stated out loud — it does not get an unbounded watch, because "the file said nothing" is exactly the case an inherited-and-forgotten default is dangerous in.

RETIRED at nen 0.7: counting the acting cycles by hand

Every acting cycle is CLAIMED before it acts, and the cap is enforced by the claim being refused — izanagi § 3's retirement, inherited whole:

git rev-parse --path-format=absolute --git-common-dir   # <common>, in the effort worktree
nen loop iterate --id en-<CODE>-<N> \
  --line "take <CODE>-PR-#<N> to its human gate until it is Ready up to <monitor.maxCycles>" \
  --repo <common>

Exit 0 prints iteration <n>/<cap> and how many remain — the verb's own word is iteration, and en's cycle is what it is claiming; exit 1 IS the cap and ends the run at § 6's cap-out row, with the invocation named in nen's own refusal. The --line is the same string nen parse izanagi echoed above, restated on every claim, so monitor.maxCycles cannot be quietly raised mid-run: a claim carrying a different N is exit 2 naming both lines (verified live against exactly this shape — up to 3 running, up to 20 claimed — docs/ab/izanagi.md § Retired at nen 0.7).

The --id is the PULL REQUEST, not the session, and that is a decision with a consequence worth stating: the ledger is .nen/loop/en-<CODE>-<N>.json under the git common directory, so it outlives the session (§ 7) and the effort worktree, which cleanup removes (docs/ab/en.md § The cap outlives the worktree), so a re-invoked $en on the same PR resumes the same cap rather than starting again at cycle 1. That is the honest reading of "twenty acting cycles to ready this PR" — a cap a session boundary reset would be a cap nobody has. When the readiness drive genuinely ends — Ready, closed, or handed to the maintainer at a gate — close the ledger with nen loop iterate --id en-<CODE>-<N> --line "<same line>" --release "<why>" --repo <common>; a loop at its cap can always still be released, and a fresh cap after that is a new --id, chosen deliberately and said out loud, never a re-typed line.

The cap is a ceiling, not a target. Reaching it is a failure to reach Ready and is reported as one: what is still not true, and what the next cycle would have done. izanagi § 4's rule, unchanged. The reviewer-round policy is $sharingan § 6's, stated there once and cited here, never restated:

  • One Copilot round is requested after $hanten settles, never before.
  • Arrivals are remediated, and an owed round is re-requested without asking only inside sharingan § 6's two bounds (round_policy.maxRounds requests, round_policy.minRounds resolved; row cap-reached), then en keeps watching; either bound reached is § 6's fifth stop.
  • Before any re-request, nen wake verify --repo-slug <owner/name> --now <ISO> --author-pattern <the maintainer login> --run redrives a swallowed run once (action_required or startup_failure that never executed); an action_required run by the Copilot bot cannot be retried and is reported as such. Then the no-op sync guard: count commits ahead of the last reviewed head (git rev-list --count <reviewed-head>..HEAD, read-only) and the diff stat; zero reviewable change means no request.
  • Copilot auto-reviews every push, so the cap governs requests, not arrivals; an arrival past the cap is still remediated and its threads settled.

Past the maximum the run ends at not-ready with the board. Neither is a G5. nen/workflow.json → monitor.maxCycles is en's acting-cycle cap, a different number.

3. The run, in order

#StepThe skill that owns itWhen
1landing report$spiritual-message as landingonce, at the start — 00–07 plus 08 PR body and 09 Readiness. If this En was started by mukai (autoEn) or typed from its offer in the same sitting with no newer human request, 00 still answers that mukai request
2drive$sharinganfirst blocking condition, threads, checks, the confirmation pass
3catch up$murasakionly when the branch is behind its PR's base (baseRefName, § 2); a typed composite's handoff passes through (aka § 0, second carve-out; HR-20)
4drive again$sharinganafter step 3 moved the tree underneath it
5observethis file, § 6while CI or a reviewer round is pending; each poll runs nen wake verify in dry-run (no --run), and --run only when a swallowed run is found; rebuild the current-head snapshot on every change, returning to steps 2–4 when action is needed
6resolve the gatethis file, § 5; the human handoff rings through $jutaisho's four partsafter verified Ready or § 6's sixth stop: a PR on branch.base gets the human merge bell; every off-base PR first checks Futon ownership, then either takes the bounded Ready delivery merge or reports the refusal and current base to the maintainer, with no merge bell; under getsuga § 3, return the verdict to getsuga
7the dated final report$rikugan (§ 8), which composes backlog-board § 3's --variant finalafter a confirmed bounded merge or the human bell; this is En's successful terminus

Four orderings are en's own assertions:

  • 3 before 4. Driving a branch that is behind its base produces a readiness verdict against a tree that is about to change. Catch up first, then re-decide.
  • 4 before 6. The gate action carries a verdict. Acting before the second drive would act on a reading the catch-up already invalidated.
  • 5 before 6. Pending is not Ready. Required CI and every reviewer round owed at the current head must settle, and every incoming finding must be disposed, before the gate action or handoff exists — the one round that settles without arriving is a met round quorum's unavailable member's (nen decides it, zheref/nen#361), and the stop on a round no quorum member can post is § 6's sixth.
  • 6 before 7. The dated final report records the gate event; rendering it first would preserve a readiness handoff that had not happened yet.

Step 3 is conditional and stays conditional. A branch level with its base does not get a catch-up "to be safe": murasaki would re-run the declared iteration checks for nothing, and on a published branch it would push a commit that changes no content.

En's equivalent of mukai steps 3–5 runs whenever the tree this watch is about to treat as current has changed, not only when step 3's catch-up moved a path. That includes a review fix authored in steps 2/4 while the branch is still level with branch.base (step 3 then stays skipped), a catch-up that returns without pushing, and a later murasaki that was meant to publish but itself changed a path. Claim an acting cycle, then run $kokusen, $kotoamatsukami and $byakugan, then call murasaki again. It may push only when that catch-up is a no-op; if it changed any path, this paragraph repeats rather than handing a stale tree to readiness. That is the same owner map $sharingan § 5 already names when Kurapika authored the PR; En does not invent a fourth suite.

4. Readiness is never en's claim

A PR that introduces gate configuration absent from the actual trusted workflow/validator revision selected by its readiness event is a bootstrap PR. Record the event and exact checkout ref before classifying it: Hatsu's readiness workflow explicitly checks out github.event.pull_request.base.sha on both of its events, while another frozen validator may use the default branch's head. A stacked PR base carrying the configuration is therefore not, by itself, proof that the validator trusts it; the checked-out revision is. Follow docs/GATE-CONFIGURATION.md, The two-step landing: land the bootstrap step into the branch that supplies that trusted revision, then judge a follow-up after the event resolves to the landed copy. The bootstrap PR's self-supplied gate is a forecast, never its verdict; unevaluated or a failed trusted-revision run is not Ready. Only the follow-up's trusted-revision verdict may enter the ordinary readiness conjunction.

That bootstrap result is an explicit not-Ready terminal handoff, not an observation hold and not § 5's Ready merge prompt. Quote the actual unevaluated or failed trusted-revision verdict, point the maintainer to the first landing under the repository's existing G2/G4 ownership, and require the later trusted-revision follow-up before readiness can be claimed. En never merges or calls the bootstrap Ready; the human owns that first landing and the ordinary trusted-revision path resumes only on the follow-up.

Steps 2 and 4 are $sharingan's whole engine, not a substitute for it, and this file restates none of its protocol — the first-blocking-condition order, the channel decided by who authored the PR, the escalation ladder, the round_policy.maxRounds request cap and the completed-round prerequisite, the thread hygiene run through nen pr threads, the one-directional confirmation pass that may only veto. Read it there.

Two things en relies on and does not re-derive:

  • A PR is Ready iff nen pr ready says ready AND nen pr body-check says every requirement is satisfied AND nen pr converge (nen pr converge --target <owner/name> --pr <N> --catalogue "$hatsu_root/contracts/issue-sections.json", HR-11) exits 0, all deterministic, none re-derived by eye: converge's exit 1 is not ready, whatever it blocks on. Ruled (HR-357, record R-2026-10-24-01, zheref/hatsu#450): its --json closingSource none-on-non-default-base, while the Development guard's --body form exits 0 (so the Associated issues table holds no closing row, as a stacked delivers part PR does), is not applicable — reported as such with that closingSource quoted, never as a pass, and readiness proceeds on the other conjuncts — and the Development guard ("$hatsu_root/scripts/pr_development_link_check.sh" --pr <owner/name#N> --base <branch.base>, zheref/hatsu#203) in exactly one of three cases, decided by the PR's own base first: (1) the PR's base is the default branch, whatever branch.base declares — the guard verifies fully and its 0 is required (a --base naming another branch only adds an informational note); (2) the PR's base is not the default branch and branch.base is — its quoted retarget-pending line stands beside them, neither a pass nor a veto; (3) neither branch.base nor the PR's base is the default branch — its quoted not-applicable line stands beside them, neither a pass nor a veto. docs/WORKFLOW.md § Build accountability and issue associations states the rule once. sharingan § 4's rule, and $pr-state's before it: a readiness claim is that verdict, quoted, or it is not made.
  • A parity PR (its closing issue a port issue of a family with a spec repository) adds one more conjunct: the convergence table, computed and read as docs/config/spec-repo.md § The convergence table at readiness says and quoted beside the verdict in the landing report, the register row and § 5's prompt; which rows — and which could not read table — make the PR not ready whatever nen pr ready says is that section's, stated once there (zheref/hatsu#447).
  • A body this run rewrites — new or re-recorded screenshots after a review — re-renders the whole Evidence table and passes "$hatsu_root/scripts/pr_body_evidence_check.sh" --body <file> before it is written (docs/WORKFLOW.md § The UZF-26 evidence shape, The table, exactly). Every nen pr edit-body this run makes is followed by the Development guard, its line quoted.
  • sharingan's escalation is a G5 and it ends this run's cycle, not just its step. A PR that will not reach Ready is one of the plane's genuine stops (docs/WORKFLOW.md § 4), and en does not spend the rest of its cap re-driving past it.

En never casts a review vote. Kurapika runs on the maintainer's credentials, so GitHub would record the vote as theirs — a governance vote on a PR they have not read. That holds even when the finding is real and even when it is the only path visible. sharingan § 5's rule, binding here because a long watch is where the temptation compounds.

5. The merge prompt and recorded Futon delivery exception

Not under getsuga § 3. For a release proposal getsuga started en on, this step and § 8 do not run: en hands the quoted nen pr ready, body-check, criteria and Development-guard verdicts, its judged head: and, under an effective aiReviewers: optional | off, Hatsu's two-ref Hatsu line (PROCESS, AI reviewers per consumer; any disagreement with nen's printed value said) back to getsuga, because § 3a is that PR's merge (ROSTER ruling 4 of 2026-09-26, kept by the exception of 2026-10-01); a waiver-backed ready there carries no hanten condition (PROCESS, AI reviewers per consumer). Where § 3a falls back to the declaration gate, getsuga § 3a owns that stop and presents this section's prompt for the proposal.

Narrow exception, only for a Futon-owned stacked delivery PR (ruling 2026-10-19; issue #154). Every PR off branch.base enters the ownership check; a missing record is a refusal and a handoff at its current base, without guessing whether the PR was intended as Futon delivery. En may merge a PR whose live base is non-main only when all of these hold at the same current full head SHA:

  1. node "$hatsu_root/scripts/futon_effort_record.mts" verify --repo <effort-worktree> --pr <N> succeeds. The Git-common-dir record binds the typed Futon invocation, selected issue, PR, non-main base and current head. A missing, mismatched or stale record is a failed ownership claim; title, branch name and session memory cannot replace it.
  2. "$hatsu_root/scripts/gh_token_env.sh" nen pr ready <N> --gh-repo <owner/name> --require-head <SHA> --explain exits 0 and says Ready. The reviewer sixth stop and exhausted bot limits do not qualify.
  3. nen pr body-check succeeds against the live body and the current contracts/pr-body.requirements.json from this plugin root, and nen pr converge --target <owner/name> --pr <N> --catalogue "$hatsu_root/contracts/issue-sections.json" exits 0 beside it, or is not applicable as § 4 reads it (HR-357, record R-2026-10-24-01; quote converge's closingSource in the register row). Otherwise converge's exit 1 is not ready, whatever it blocks on (HR-11). En still settles every finding and thread under § 4 before this gate.
  4. nen pr merge <N> --delivery --requirements-from <absolute plugin-root contracts/pr-body.requirements.json> --repo <effort-worktree> --require-head <SHA> returns a passing plan. Nen independently checks the non-main, unprotected base, Ready, body, current head and author. Run the same command with --run only after those gates pass; then read GitHub's mergedAt and base back. Its exit 7 means authority was unconfirmed after merge and is an urgent G5 report, never success. A confirmed merge is reported as merged; § 5's human merge prompt and its G2/G4 bell are skipped.

If any gate fails or is unknown, or the bounded command is denied, quote the exact refused command and verdict, preserve any effort record, and hand this PR to the maintainer at its current base. This is a handoff with the failed gate, not an automatic merge or a claim of Ready. Quote retarget-pending or not-applicable where the Development guard printed it; neither line authorizes a merge. Never substitute gh pr merge, --admin, --auto, another base, or an unpinned head. A PR targeting branch.base or the default branch takes the maintainer path even if metadata exists. This exception does not grant Futon itself a PR merge or change getsuga's release-unit path.

An off-base PR with failed ownership or another failed gate gets no merge prompt. It reports the refusal, current base and Development guard line, then stops at the maintainer handoff. A PR on branch.base in case (3) — neither branch.base nor the PR's base is the default branch — gets the prompt: the guard's quoted not-applicable line stands in place of its 0 at check 4, because the merge is the maintainer's either way. It is the G2/G4 merge stop, never a G5 (ROSTER § Rulings of 2026-09-30 — En never merges, row Closing keywords act only on the default branch). Futon opens no PR into its integration branch (futon § 5 merges there locally), so this is never futon's path.

The default is the maintainer's merge (docs/ROSTER.md § Rulings of 2026-09-30 — En never merges, narrowed by § Ruling of 2026-10-19 — recorded Futon delivery merges); futon § 5, kurapika.md, the gate tables (ROSTER, README, WORKFLOW) and nen/decisions.json row own-pr-merge cite it. It supersedes ruling 3 of 2026-09-29. En's work is the drive: every finding fixed, every thread answered and resolved. Every other PR ends at the merge prompt, after five checks in order, every verdict line printed:

  1. On branch.base — the base read back (gh pr view <N> --json baseRefName); a stacked PR whose delivery just merged is retargeted through nen pr retarget first (getsuga § 3's mechanism, jujisho's), and the guard re-run after that read-back — **a PR off the trunk is given no main-bound merge prompt (ruling 2026-09-29 (2)); its non-main ownership outcome is the separate path above.
  2. The verdict — nen pr ready --explain says ready; or § 6's sixth stop holds — its five conditions, (a)–(e), are PROCESS.md § Reviewer rounds and review threads, The sixth stop, stated once there (the maintainer's ruling of 2026-10-11): the not-ready verdict quoted verbatim, never called ready, and one Hatsu line carrying the recorded head and each exit-9 call's --json verbatim, written into the body's completion checklist through nen pr edit-body before the prompt — the durable record that hanten's rounds were the review. Under an effective aiReviewers: optional | off the sixth stop is instead the hanten prompt, its conditions, the value's source refs and the Hatsu line (aiReviewers: optional (base <sha>, default <sha>)) all PROCESS.md § Reviewer rounds and review threads, AI reviewers per consumer, stated once there; a ready that rests on nen's waiver of a declared bot's round is Ready only with hanten settled and Hatsu's own read not stricter (HR-333; PROCESS, the disagreement sentence). A CI reviewer lane — its round, why it is never requested, its place in the quorum and when it is unavailable — is PROCESS.md § Reviewer rounds and review threads, Event-driven reviewer lanes, stated once there.
  3. The body — nen pr body-check satisfied against the live body.
  4. The Development links — the guard's 0 quoted against the live PR, re-run after any edit-body; retarget-pending is check 1 failing (case (2)), not-applicable is case (3), quoted in the 0's place and still the prompt, and any other line is a finding to fix, never a prompt.
  5. The head pinned — the commit nen pr ready judged is GitHub's head, and the prompt's line names it.

The prompt presents the PR's link and one line the maintainer may run, offered and never run by en — in the chat message as a bash block (WORKFLOW § 4's hand-over rule), the picker carrying one short question and short starred options (jutaisho § 4's shape). Its picker never carries the merge act; the maintainer merges outside the session (jutaisho § 4). So it never offers the act, which is what no agent may do for the merge phase (ROSTER § Rulings of 2026-09-30 — En never merges):

gh pr merge <N> --repo <owner/name> --merge --match-head-commit <judged head>   # the maintainer's; never --admin, never --auto

--match-head-commit makes GitHub refuse the line if the head moved after the verdict. The maintainer merges from the GitHub UI or from that line; en reads the state back only if asked. The merge is not a review: the review is the reviewers' rounds (§ 4) and hanten's before them; en never votes and never self-reviews.

Step 6 is $jutaisho at <G2|G4>, with the gate shibari derived and sharingan confirmed. It owes all four of that skill's parts — the nen stop banner, the report link, lettered options with a ⭐ on the recommended decision — the report linked, never an option (Crazy Slots), and the question through the surface's own native option picker, its answer recorded through nen stop answer before the run acts (WORKFLOW.md § 4 Every picker answer is recorded).

nen stop --template emits the blank five-column shape the efforts table is filled into — verified live at v0.3.0, exit 0 (docs/ab/en.md § 2.4):

| Effort  | Open issues & PRs | Status (gate)   | Thought flow | Session / lane |
| ------- | ----------------- | --------------- | ------------ | -------------- |
| <title> | <link>            | <status (gate)> | <one line>   | <session>      |

The merge prompt is the stop's MERGE ask, for the run's own PR and another's alike: the PR's link, the gate it stands at, whose review it carries, the verdict quoted and the line above.

It prompts exactly once for this run — at Ready, or at § 6's sixth stop — and at no other time, and rings once, with the prompt. A quiet observation rings nothing — a bell that rings every poll of a four-hour wait is a bell nobody hears.

6. The observation hold — nen watch until on nen pr ready, and what a cycle is

The condition is polled by the same read-only observation engine $izanami uses. The verb owns the wait between observations; a caller does not repeatedly invoke a one-iteration command and pretend --interval-ms paced those invocations. Each refresh window has exactly two observations: the first establishes the window and the verb waits monitor.pollSeconds before the second. The window then returns to Sharingan's full snapshot, because nen pr ready alone cannot expose new review activity that leaves its verdict unchanged:

"$hatsu_root/scripts/gh_token_env.sh" nen watch until --pr <CODE>#<N> --until ready --repo <path> <identity flags> \
  --max-iterations 2 --interval-ms <monitor.pollSeconds × 1000>   # one paced refresh window; no exclusion flag

--pr is nen pr ready's own in-process read (zheref/nen#264), so the watched verdict and the quoted one never disagree, and no command string is handed over (shapes (3) and (b) of WORKFLOW.md § Writing a skill block, #218). The wrapper puts the token in the verb's environment and nowhere else; --interval-ms is at least 30000 under --pr.

<identity flags> is selected by sharingan § 4 for the target: omit it when the target ships nen/gates.json; use --gates "$hatsu_root/contracts/reference.gates.json" only for <reference-repo>; otherwise pass the target's hand-supplied --reviewers and explicit --approvers. Never point one repository's gates file at another repository. No exclusion flag rides the call, and none is needed (pr-state § 2): a declared ruling lives in the target's nen/gates.json → checks.excluded, which nen pr ready reads itself at the pull request's base, so the watched verdict and the one that counts are the same verdict, every honoured exclusion named in it. A ruling with no entry is missing-configuration, and a check nobody ruled out keeps the PR not-ready — the verb's verdict quoted verbatim — never ready.

nen pr ready classifies [read-only] — verified live at v0.3.0 (docs/ab/en.md § 2.3): nen parse izanami "nen pr ready HA#41 --repo /path --gates /abs/gates.json until it is ready" → [read-only], exit 0. So does the merge-state read, gh pr view <n> --repo <owner/name> --json state -q .state. And the merge itself does not: nen watch until --command "gh pr merge 41" is refused before the first observation, exit 2 — "'gh pr merge 41' classifies as mutating … izanami watches only". The verb that polls this loop structurally cannot merge. Section 5's bounded Futon delivery exception is an explicit acting step, never an observation inside this watch.

--max-iterations is still not the cap. Its own --help says so — "a SAFETY bound, not izanagi's mandatory cap" — and it bounds watch observations, not the count of acting cycles. The cap is nen loop iterate's (§ 2). Two verbs, two bounds; neither substitutes for the other.

What counts as a cycle — and it is what en CLAIMS, not what the watch observes. A cycle is spent when en acts: goes back to step 2, pushes a fix, re-requests a review. An observation that finds nothing changed is not a cycle and is never claimed, and neither is the pre-check before the first act (izanagi's iteration 0). Otherwise a four-hour poll at five-minute intervals would exhaust a cap of 20 in under two hours without a single thing having happened — and since nen 0.7 that is a mistake with a ledger behind it rather than a miscount nobody can see: claim only where en acts, and the <n>/<cap> the verb prints is the number the report carries.

What the observation hold reacts to:

ObservedWhat en does
a requested reviewer round not yet posted at the current head — Copilot minutes after a request or a push, nen pr ready row 4 (CON-32(b): review requested, not yet posted)pending, not Ready (sharingan § 5's rule, the verb's row 4 its evidence) and no cycle is spent: observe until it posts — unless nen waives that round under an effective `aiReviewers: optional
a required check turned red at the current head — except a CI reviewer lane's own CANCELLED or FAILURE, a lane fault the hold ends on, not-ready, its state quoted (PROCESS.md § Reviewer rounds and review threads, Event-driven reviewer lanes)claim an acting cycle and return to step 2 (§ 3's step-5 cell): the failing run is read, the fix authored, verified through the phase owners and pushed — a new epoch
the PR converted to draft, or its base retargetedoutside the hold's vocabulary: name it, end the watch, and hand back — a draft is not driven, and a retarget re-derives the gate (WORKFLOW § Gate derivation)
a new review, comment or threadinspect and classify it first. If it requires remediation or a reviewer re-request, claim an acting cycle, then return to step 2; an approval or informational event that needs only a read spends no cycle. $sharingan addresses every inline and summary finding through its own channel, and decides whether a further round may be requested (§ 6 there; owed at head after en's own request or push is not a reason)
the branch fell behind, or the PR went dirtyclaim an acting cycle, then step 3 and step 4 — catch up, then re-decide. A conflicted PR gets no checks at all, which reads as "clean" rather than "broken" (sharingan § 5)
the PR becomes Ready (§ 4's three cases, the PR's own base first: (1) a PR into the default branch, with the Development guard's 0; (2) with its retarget-pending line quoted; (3) with its not-applicable line quoted — neither line a veto)step 6: on branch.base, ring the human merge gate; every off-base PR checks § 5's Futon record first and either takes the bounded Ready merge or reports the exact ownership/gate refusal at its current base, without an automatic merge
checks-green failing only on a CI reviewer lane's check still in flight at head (a red check at the same head is the red-check row) (PROCESS.md § Reviewer rounds and review threads, Event-driven reviewer lanes)pending, not Ready — a wait: the push already re-ran the lane, so nothing is requested of it and no cycle is spent; observe until the check concludes, then re-decide. Past PROCESS's lane stall bound (same paragraph) it is a named impossible condition — the hold ends not-ready, the check's state quoted
a round owed at head to a member of a met round_quorum that cannot post it — exhausted credits, no run at head, a run that completed without a round (PROCESS.md § Reviewer rounds and review threads, One bot reviewer suffices); except a CI reviewer lane whose check is still in flight, which is the row abovenot a pending state — nen fulfils it (zheref/nen#361) and the verdict reads it so; nothing is requested of that member and no cycle is spent
an unmet round_quorum member with no round-check run at the judged head, the round row the only failing row, its window not yet passed (PROCESS.md, The sixth stop, (c)'s third observation; HR-373, zheref/hatsu#543)pending, a wait — no cycle spent: run the two paced refresh windows (§ 6's block) at that head, quoting each with its head; a push restarts them. Still no run after both, it is that member's (c) observation and the row below decides
every round_quorum member unavailable at the judged head, the round row the only failing row (PROCESS.md § Reviewer rounds and review threads, The sixth stop, (a)–(e))not a pending state — no round will arrive. End the hold and go to step 6, the sixth stop, with the not-ready verdict quoted verbatim and the Hatsu line beside it; no cycle is spent
an effective aiReviewers: optional | off (PROCESS), its hanten prompt's conditions met (PROCESS.md § Reviewer rounds and review threads, AI reviewers per consumer, stated once there)not a pending state — the round is not expected. End the hold and go to step 6, the sixth stop, the not-ready verdict quoted verbatim with PROCESS's Hatsu line; no cycle is spent. Under an effective off en never requests a bot
the PR merged before the gate handoffend as a terminal external state, naming that readiness was not the run's observed terminus
the PR closed by its base's deletion — a closed event whose preceding event is base_ref_deleted, no reopened after it (the raw timeline, every page: gh api --paginate repos/<owner>/<name>/issues/<N>/timeline; nen 0.28 has no timeline verb), its head branch still on origin, and the deleted base already merged (its PR merged, or its last head an ancestor of origin/<branch.base>: git merge-base --is-ancestor) — WORKFLOW § Stacked pull requests rule 5; GitHub reopens no PR whose base is gone, and nen pr retarget refuses a closed onea successor, not an end (zheref/hatsu#495): claim an acting cycle, still on this run's loop id (en-<CODE>-<N> of the original PR) until the run ends — the successor gets no fresh cap, though its hanten ledger is a new effort's (hanten § 2b); catch the branch up onto branch.base (step 3, murasaki); open a successor PR through mukai's shibari, its body naming the PR it replaces and why, with its own Closes/Part of lines and Development links; post a fresh durable slice on it (mukai step 8a); in a futon run, nen run append it (WORKFLOW § Recorded Futon delivery ownership); comment once on the closed PR naming the successor and calling its slice historical; then drive the successor from step 2. An unmerged deleted base or a deleted head is the row below
the PR closed unmerged any other way, or by base deletion with its head branch gone or its base unmergedthe run ends, saying so — there is nothing to land, and reopening is the maintainer's call
nothing changedone line, or no line. Not a status screenful; nen watch until already prints one line per observation

Six stops apply here: the condition true (verified Ready); the cap reached, reported with what is still not true; a human gate, which is never retried past; an impossible condition, named rather than waited on — a closed PR will not become Ready (a base-deletion close is § 6's successor row, not a stop); and the round ceiling (zheref/hatsu#102): round_policy.maxRounds requested, or round_policy.minRounds resolved with the verdict still not-ready — a round owed at head that no bound lets en request is a named impossible condition for the watch, not a state to poll — reported not-ready with nen pr ready --explain quoted and the board, never a raised number, never a G5; and every quorum member unavailable — PROCESS's The sixth stop, (a)–(e), or under an effective aiReviewers: optional | off its AI reviewers per consumer hanten prompt — the hold ends at step 6 on the not-ready verdict, the sixth stop, which outranks the round ceiling (the maintainer's ruling of 2026-10-11; nen/decisions.json row reviewer-exhausted). izanagi's generic three-no-op stop does not apply to En: quiet observations claim no cycle, and three unchanged pending reads cannot terminate the current-head readiness promise. Three consecutive observation errors still stop nen watch until as an unread capability failure, exactly as the verb documents; that is not a pending-state success.

7. The session boundary — and the Illumi hand-off

A watch lives in the session that started it. nen watch until is a foreground process, the observations are this conversation's, and there is no timer, no background pass, no deferral primitive and no self-continuation anywhere in this plane — the same boundary $ren § 4 records for its own loop and docs/ab/ren.md § 2.2 proves live.

A model choosing to finish a response is not a session boundary and not a run outcome. While the task is alive, pending CI/review remains under observation. If the host or maintainer actually interrupts the session, say the acting-cycle count reached, the last verdict, and that the run was interrupted; it is resumable by re-invocation — $en on <CODE>#<N> re-fetches everything and re-decides from live evidence (sharingan § 9's rule). Notes worth keeping go in the run's transcript, never trusted over a fetch.

Under a Futon-based batch (futon, kazaana, dowsing-chain's wave), this run's terminus is that delivery's state in WORKFLOW.md § Batch delivery rule 2: ready, the verdict quoted at the current head; merged; or held-<cause>, parked in the run's manifest with its three facts — the exact human-only prerequisite or bound, the last nen pr ready verdict and its judged head, and the resume line. Each of this file's not-ready stops maps to one cause there: the sixth stop and hanten prompt to held-gate, the cap and round ceiling to held-cap, § 6's hand-backs and § 5's refusals to held-handback. The batch counts nothing else as delivered, and asks no wrap-up while this run is still driving (zheref/hatsu#488).

One thing does survive the session, deliberately: the cap. <common>/.nen/loop/en-<CODE>-<N>.json is a file under the git common directory (§ 2), so a re-invocation on the same PR resumes the same count (§ 2) — the watch is per session, the cap is per readiness drive. Say the resumed <n>/<cap> out loud on the first claim of a resumed run, so the maintainer sees a budget being continued rather than one silently restarting.

A pre-Ready observation hold measured in hours is Illumi's, and from v0.5.0 he has a definition to be raised as. The roster's ruling of 2026-09-09 partially closes OPEN-1 — "Illumi is provisioned for en's long watch, and only when one is needed" — and claude/agents/illumi.md landed in this same wave, because a provision that cannot be executed is a provision in name only (docs/ROSTER.md § Rulings, 5). On a surface with in-session subagents, step 5 is handed over, not abandoned: a subagent titled en · illumi · <model alias>, on the fast tier at effort medium, holding the same monitor policy this file reads. He never claims or spends En's acting-cycle cap: each quiet poll is an observation, not an Izanagi iteration. He records the five facts per observation, compares them, and wakes Kurapika — naming what changed and the act it needs. He performs none of it, and the readiness hand-off stays G2/G4.

What the hand-off buys is attention, not persistence, and the difference is stated rather than blurred. A delegate is still raised from a session: the paragraph above still holds — no timer, no background pass, no deferral primitive, no self-continuation. What Illumi gives is a watcher whose entire job is the watch, at a tier that can afford to hold it for the hours an overnight CI queue or a reviewer in another timezone takes. An observation hold that needs to survive the maintainer closing the session still has no mechanism anywhere in this plane — that is named, reported as an interruption, and never simulated.

Codex and Antigravity have in-session subagents (spawn_agent on Codex; invoke_subagent with Workspace inherit on Antigravity). En may hand this watch to en · illumi there the same way. The hand-off buys in-session attention, never background persistence: the watch remains bound to the active session, paced by nen watch until (§ 6). The second-process codex exec worktree remains Hanten's isolation for a reviewer who must not share the author's tree; it is not this watch and is not a persistence mechanism. If the session is interrupted, the resumable ledger is reported exactly as above. A model choosing to stop calling tools while CI checks, reviewer rounds, or review comments are pending is voluntarily abandoning the watch, which is not an outcome and must never report G2/G4 readiness: the observation hold remains active in-session until nen pr ready exits 0, the acting-cycle cap is reached, or the session is actually interrupted.

And the hand-off widens nothing. Illumi is provisioned for this watch and no other loop — not backlog-loop, not futon, not senkei; that half of OPEN-1, and the whole of Killua's row, stay OPEN and stay the maintainer's G4-class ruling to make. What must never happen is en running unattended to fill a gap: an unbounded, unwatched acting loop is precisely the shape the cap exists to make impossible, and improvising one would close a maintainer's OPEN question by attrition rather than by ruling.

8. The dated final report

Not under getsuga § 3 (§ 5): the proposal's report is getsuga's own.

After the deterministic Ready verdict and step 6's human bell or confirmed bounded delivery merge, render the final variant — a one-effort Rikugan with a cleared desk, this effort's register, spend and legend — by naming $rikugan over this PR and the issues it closes (its § 2 row for en; ruling 2026-09-30), which composes backlog-board § 3, the render path (maintainer's ruling, 2026-09-19). There is no spiritual-message as final any more; hand over and say so.

<reports.dir>/<YYYY-MM-DD>-<effort>.html

That path is backlog-board § 3's and reports.retain: final-only's, not en's invention: turn and landing renders live at their Artifact address (or the transient current.html on a surface with none), and only this one gets a dated file. <reports.dir> is git-ignored, and neither skill writes anywhere else in the tree.

Then the run ends. For a confirmed bounded Futon delivery merge, report the PR notation, head SHA, quoted Ready verdict, verified merged state and base, acting-cycle count and final report path; there is no human merge line. For a main-bound PR at the human gate, report the same evidence and § 5's merge line; the human merge or vote remains outside the run. If the PR merged externally before handoff, report that terminal state without rewriting it as an observed Ready success.

Do not start $cleanup or $third-hand from this file. When this run has completed, the caller offers the wrap-up picker (cleanup § 2) after En has returned, and only once cleanup § 2's two prerequisites hold — cleanup required, third-hand optional. Cleaning and harvesting are those phases', not En's.

Residue

  1. The composition itself has no verb, and is not expected to get one. nen owns operations, not conversations (docs/ab/ren.md § 2.2, verified live). En adds no residue of its own — every deterministic step inside a cycle is a verb or a named residue in the skill that owns it: the absent nen report data / nen report render (step 1 and the readiness report, named in spiritual-message), nen pr ready / nen pr body-check / nen pr staleness and the two verbs sharingan refuses to call for a verdict (steps 2 and 4), nen pr cascade-main and its missing --no-push (step 3, named in ao), nen stop plus the osascript/afplay fallback and the stop marker (step 6, named in jutaisho).
  2. RETIRED at nen 0.7: counting cycles against the cap. nen loop iterate claims each acting cycle and refuses past the cap (§ 2). nen parse izanagi still refuses a missing N once at parse time and nen watch until --max-iterations still bounds one observation — three different jobs, and only the middle one used to be this skill's. What stays en's is DECIDING which cycles to claim (§ 6: en acts, so en claims; an observation that changed nothing does not), and that is judgment rather than residue.
  3. RETIRED at nen 0.5: nen/workflow.json is validated. nen schema check --repo <path> carries an ok nen/workflow.json row at the pinned build (verified live, docs/ab/en.md § Retired at nen 0.5), and a malformed monitor block is a FAIL by pointer. § 2's keys are still read here; reading a file is not residue.
  4. A watch that survives the session has no mechanism at all (§ 7) — not a missing verb: no timer, no background pass, no deferral primitive anywhere in this plane. The long watch itself is no longer a gap — illumi.md landed at v0.5.0 and step 5 hands to en · illumi, which buys attention for hours; **persistence past the session is what remains unavailable in this plane, and it is named rather than improvised around. In zheref/hatsu only, one half of it is now supplied from OUTSIDE the plane: .github/workflows/pr-readiness.yml re-runs nen pr ready on every event that can change the answer and publishes the verdict as the readiness check run (that file's header is the authority; no consumer repository carries it). It is not a watch and grants En nothing — it never merges, votes, comments or wakes, and En still claims and caps its own cycles exactly as above. Be precise about which half it supplies: the verdict now PERSISTS on the pull request and can be read without a session. Nobody is NOTIFIED — the check is always success, so nothing is pushed to the maintainer. Persistence was the half a session could never supply; being told is still unsupplied, and stays named here rather than claimed. The rest of Illumi's row (backlog-loop, futon, senkei) stays OPEN-1 and unreachable from here.
  5. The commits-ahead count against an arbitrary reviewed head has no verb. The no-op sync guard's git rev-list --count <reviewed-head>..HEAD (§ 6) is read-only and named here as residue, not improvisation: nen wc classify answers only against the base, and a nen request for a count against a named head is owed.

Authority

  • Permitted: everything the composed skills are each permitted, under their own authority, one at a time, in § 3's order — and per cycle, resolved fresh. izanagi § 2's rule: authority never accumulates across iterations, and a run-scoped delegation granted inside a step expires with that step.
  • Not permitted: any merge outside § 5's recorded Futon delivery path; any gate label; any review vote — request_changes above all; any force-push; any --no-verify; any tag, release or deploy. A landing that would need one of those is reported and the run stops.
  • En grants no delegation of its own, and its own long run does not become standing authority for the acts inside it. Anything a composed skill would have asked for on its own, it still asks for.
  • Log every mutating action — object, action, cycle number, time — and report the whole log when the run ends (izanagi § 2). An unlogged write inside a loop is the one thing nobody can reconstruct afterwards.

Hard limits

  • Never merges outside § 5's recorded Futon delivery exception (rulings 2026-09-30 and 2026-10-19, docs/ROSTER.md). Every PR into main ends at § 5's merge prompt, save getsuga § 3a's own release proposal, which getsuga merges. En never runs the line it offers: not at Ready, not at the cap, not on nen pr staleness's own mergePermitted field, not because the PR has been Ready for hours. This is the skill standing closest to that gate for the longest, which is exactly why the limit is first.
  • Never casts a review vote, never self-reviews, never impersonates an automated reviewer (§ 4).
  • Never runs without a cap — the value from monitor.maxCycles, the requirement from the grammar (§ 2). Never raises its own cap mid-run and never restarts itself to get more cycles.
  • Never runs unattended, and never promises persistence it was not given (§ 7). A watch measured in hours is handed to en · illumi; if the session is actually interrupted, report the interruption and resumable live state. Do not misname interruption as success or cap exhaustion.
  • Never counts an observation that found nothing as a cycle, and never fabricates one to manufacture a cap-out (§ 6).
  • Never requests a reviewer round outside sharingan § 6's rule — the verb only, inside both bounds, never a number raised in-session (§ 2; zheref/hatsu#102).
  • Never rings or prompts outside a terminus — verified Ready, or § 6's sixth stop (§ 5) — and never rings twice for the same transition.
  • Never claims readiness by eye — nen pr ready + nen pr body-check, quoted, or it is not claimed (§ 4). Never declares a PR G2/G4 ready while checks, reviewer rounds, or review threads are pending.
  • Never renders the final report while required CI or the owed current-head review round is pending, and never gives a turn render a kept file (§ 8).
  • Never starts cleanup or Third-Hand from inside this run. The caller offers the wrap-up after En has completed, only once cleanup § 2's two prerequisites hold.
  • Never retries past a human gate, and never spends the rest of the cap re-driving past a sharingan escalation (§ 4).
  • Never restates another skill's protocol. If en and a composed skill disagree, the composed skill is right and this file is the bug.

Individual skills in this repo

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

Related Skills