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 ""exits2with "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. Somukai, underautoEn, hands the PR over directly and callsnen parse ennot 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.
| Key | File | Used for | Default when the key (or the file) is absent |
|---|---|---|---|
monitor.maxCycles | nen/workflow.json | the cap — the count of acting cycles (§ 6) | 20 |
monitor.pollSeconds | nen/workflow.json | the interval between observations, as --interval-ms | 300 (→ --interval-ms 300000) |
branch.base | nen/workflow.json | the 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 on | main |
reports.dir / .sections / .retain | nen/workflow.json | step 7's file — backlog-board § 3's keys | Reports / required, no default (WORKFLOW § 2 → reports) / final-only |
notifications.rungs / .sound | nen/workflow.json | step 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 handEvery 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
0printsiteration <n>/<cap>and how many remain — the verb's own word is iteration, and en's cycle is what it is claiming; exit1IS the cap and ends the run at § 6's cap-out row, with the invocation named in nen's own refusal. The--lineis the same stringnen parse izanagiechoed above, restated on every claim, somonitor.maxCyclescannot be quietly raised mid-run: a claim carrying a differentNis exit2naming both lines (verified live against exactly this shape —up to 3running,up to 20claimed —docs/ab/izanagi.md§ Retired at nen 0.7).The
--idis the PULL REQUEST, not the session, and that is a decision with a consequence worth stating: the ledger is.nen/loop/en-<CODE>-<N>.jsonunder 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$enon 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 withnen 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
$hantensettles, never before. - Arrivals are remediated, and an owed round is re-requested without asking only inside sharingan
§ 6's two bounds (
round_policy.maxRoundsrequests,round_policy.minRoundsresolved; rowcap-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> --runredrives a swallowed run once (action_requiredorstartup_failurethat never executed); anaction_requiredrun 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
| # | Step | The skill that owns it | When |
|---|---|---|---|
| 1 | landing report | $spiritual-message as landing | once, 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 |
| 2 | drive | $sharingan | first blocking condition, threads, checks, the confirmation pass |
| 3 | catch up | $murasaki | only 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) |
| 4 | drive again | $sharingan | after step 3 moved the tree underneath it |
| 5 | observe | this file, § 6 | while 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 |
| 6 | resolve the gate | this file, § 5; the human handoff rings through $jutaisho's four parts | after 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 |
| 7 | the dated final report | $rikugan (§ 8), which composes backlog-board § 3's --variant final | after 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 readysaysreadyANDnen pr body-checksays every requirement is satisfied ANDnen pr converge(nen pr converge --target <owner/name> --pr <N> --catalogue "$hatsu_root/contracts/issue-sections.json", HR-11) exits0, all deterministic, none re-derived by eye: converge's exit1is not ready, whatever it blocks on. Ruled (HR-357, record R-2026-10-24-01, zheref/hatsu#450): its--jsonclosingSourcenone-on-non-default-base, while the Development guard's--bodyform exits0(so the Associated issues table holds no closing row, as a stacked delivers part PR does), is not applicable — reported as such with thatclosingSourcequoted, 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, whateverbranch.basedeclares — the guard verifies fully and its0is required (a--basenaming another branch only adds an informational note); (2) the PR's base is not the default branch andbranch.baseis — its quotedretarget-pendingline stands beside them, neither a pass nor a veto; (3) neitherbranch.basenor the PR's base is the default branch — its quotednot-applicableline 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 whatevernen pr readysays 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). Everynen pr edit-bodythis 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:
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."$hatsu_root/scripts/gh_token_env.sh" nen pr ready <N> --gh-repo <owner/name> --require-head <SHA> --explainexits0and says Ready. The reviewer sixth stop and exhausted bot limits do not qualify.nen pr body-checksucceeds against the live body and the currentcontracts/pr-body.requirements.jsonfrom this plugin root, andnen pr converge --target <owner/name> --pr <N> --catalogue "$hatsu_root/contracts/issue-sections.json"exits0beside it, or is not applicable as § 4 reads it (HR-357, record R-2026-10-24-01; quote converge'sclosingSourcein the register row). Otherwise converge's exit1is not ready, whatever it blocks on (HR-11). En still settles every finding and thread under § 4 before this gate.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--runonly after those gates pass; then read GitHub'smergedAtand base back. Its exit7means 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:
- On
branch.base— the base read back (gh pr view <N> --json baseRefName); a stacked PR whose delivery just merged is retargeted throughnen pr retargetfirst (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. - The verdict —
nen pr ready --explainsaysready; 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 calledready, and one Hatsu line carrying the recorded head and each exit-9call's--jsonverbatim, written into the body's completion checklist throughnen pr edit-bodybefore the prompt — the durable record that hanten's rounds were the review. Under an effectiveaiReviewers: optional | offthe 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; areadythat 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. - The body —
nen pr body-checksatisfied against the live body. - The Development links — the guard's
0quoted against the live PR, re-run after anyedit-body;retarget-pendingis check 1 failing (case (2)),not-applicableis case (3), quoted in the0's place and still the prompt, and any other line is a finding to fix, never a prompt. - The head pinned — the commit
nen pr readyjudged 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-iterationsis still not the cap. Its own--helpsays so — "a SAFETY bound, not izanagi's mandatory cap" — and it bounds watch observations, not the count of acting cycles. The cap isnen 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:
| Observed | What 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 retargeted | outside 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 thread | inspect 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 dirty | claim 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 above | not 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 handoff | end 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 one | a 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 unmerged | the run ends, saying so — there is nothing to land, and reopening is the maintainer's call |
| nothing changed | one 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 fromv0.5.0he has a definition to be raised as. The roster's ruling of 2026-09-09 partially closesOPEN-1— "Illumi is provisioned foren's long watch, and only when one is needed" — andclaude/agents/illumi.mdlanded 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 titleden · illumi · <model alias>, on the fast tier at effortmedium, holding the samemonitorpolicy 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_agenton Codex;invoke_subagentwithWorkspaceinheriton Antigravity). En may hand this watch toen · illumithere the same way. The hand-off buys in-session attention, never background persistence: the watch remains bound to the active session, paced bynen watch until(§ 6). The second-processcodex execworktree 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 untilnen pr readyexits 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, notfuton, notsenkei; that half ofOPEN-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
- 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 absentnen report data/nen report render(step 1 and the readiness report, named inspiritual-message),nen pr ready/nen pr body-check/nen pr stalenessand the two verbssharinganrefuses to call for a verdict (steps 2 and 4),nen pr cascade-mainand its missing--no-push(step 3, named inao),nen stopplus theosascript/afplayfallback and the stop marker (step 6, named injutaisho). - RETIRED at nen
0.7: counting cycles against the cap.nen loop iterateclaims each acting cycle and refuses past the cap (§ 2).nen parse izanagistill refuses a missingNonce at parse time andnen watch until --max-iterationsstill 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. - RETIRED at nen
0.5:nen/workflow.jsonis validated.nen schema check --repo <path>carries anok nen/workflow.jsonrow at the pinned build (verified live,docs/ab/en.md§ Retired at nen 0.5), and a malformedmonitorblock is a FAIL by pointer. § 2's keys are still read here; reading a file is not residue. - 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.mdlanded atv0.5.0and step 5 hands toen · 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. Inzheref/hatsuonly, one half of it is now supplied from OUTSIDE the plane:.github/workflows/pr-readiness.ymlre-runsnen pr readyon every event that can change the answer and publishes the verdict as thereadinesscheck 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 alwayssuccess, 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) staysOPEN-1and unreachable from here. - 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 classifyanswers 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_changesabove 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 intomainends 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 onnen pr staleness's ownmergePermittedfield, 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
sharinganescalation (§ 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.