Send a build to a declared NON-PRODUCTION destination by running the repository's own `deploy` row through `nen shu deploy --target <name> --run`, behind a freshness gate — and, ONLY when the latest archive is not a build of the trunk's tip, run /susanoo first in a clean worktree at origin/<branch.base> with the maintainer's own gitignored files copied from core. Use ONLY when the maintainer invokes /kagutsuchi [<target>] or asks in their own words to upload this. The target is typed, or nen/workflow.json → deploy.defaultTarget; neither is asked as free text. The plan is printed always; sending happens only on that call — typed, or a futon `then` step on the advance go — never proposed. Production and the stores are /mugetsu at G3.
Install
npx skillscat add zheref/hatsu/surfaces-antigravity-skills-kagutsuchi Install via the SkillsCat registry.
Kagutsuchi — one build, one named destination, on your word
Nature: Emitter, Transmuter for § 3b's worktree. A build leaving this machine is a release act.
Show me exactly what would be sent and where, prove it is the build of this tip — build me one
if it is not. Then, because I called for it, send it — once.
A human call, per target. Plugin root and the declaration gate by role:
PROCESS.md § Authority every phase shares.
0. Standalone entry
Reached from a composite, skipped, and the composite says it holds it
(`docs/STANDALONE-ENTRY.md` § 4). Cold: P1; P2 inside
§ 3's plan; S2, the target typed or deploy.defaultTarget, its source said (§ 1); the artifact's
commit is § 3a's gate.
1. Invocation — and who is allowed to say it
P1 — this run opens with /ten kagutsuchi (`ten` § 6 catches up this phase's
missing prerequisites under its own name; the phases this run calls skip theirs).
/kagutsuchi [<target>]<target> is a key of nen/contract.json → project.targets, and the call is the
authorization. Two sources, and the report says which (§ 5). Typed: the maintainer's word,
never a near-match; not a declared key → refused, naming the declaration PR, the keys listed. Omitted: nen/workflow.json → deploy.defaultTarget (`WORKFLOW.md`
§ 2 → deploy; ruling 2026-09-29, HA#146), read in the checkout the send runs from (§ 3b), one
row per state — null/absent → asked as free text (missing-maintainer-choice), the keys
listed, none starred; a declared key whose why reads non-production (§ 2) → the target; one whosewhy does not → refused, never asked; no declared key → refused, naming the declaration PR;
not a string → missing-configuration by pointer. --target is always passed to nen shu deploy
explicitly. A call is the stop — no confirmation, no options: the plan (§ 3), the gate (§ 3a),
a build only if owed (§ 3b), the report (§ 5).
- No agent prompts for it, no composite calls it on its own authority — a
`futon`thenstep reaches it only on the advance go
`mugetsu` § 3 defines — a recorded delegation is NOT the call and a
subagent never self-authorises: without the call it prints the plan, says it has none, and
stops. One call, one target, one send, quoted verbatim. - It calls nothing but the verb, its gate and, only under § 3b, `susanoo`;
never `mugetsu`.
2. The parameters, and where they come from
| Value | File → key |
|---|---|
| The destinations: what they append, require, and why | nen/contract.json → project.targets.<name> → args, requiresEnv (names, § 5), why, unsupported |
What deploy runs, and in which lane |
project.verbs.<lane>.deploy; project.defaultLane or --lane |
| Whether this host may, and what must be true first | project.hosts; project.preconditions.<lane> (asserted, never performed) |
| Whether to tag what was sent, and with what name | nen/workflow.json → tags.deploy.<target>, tags.identity.nameFrom (§ 4a) |
| The target when none is typed; the archive's commit | deploy.defaultTarget (§ 1); nameFrom line 2 (§ 3a) |
| § 3b's trunk and copies | branch.base; project.fromCore[] (WORKFLOW § 3) — read from core; the rest from the worktree |
Non-production is the why's PROSE, not a typed field (§ Residue), read failing closed: a why
that implies the destination reaches end users is `mugetsu`'s at G3
(row release-go); no why, or one not clearly non-production, is refused.
3. The plan — printed always, before anything
nen shu deploy --repo <path> [--lane <lane>] --target <name> --dry-runThe target: line, the host row and every precondition
(PROCESS.md § Running a declared verb). Write--dry-run though the bare form is read-only; what is sent is what was shown.
3a. The freshness gate — before --run, every time
What reaches testers matches a known commit at the trunk's tip (HA#146: a 95-commit-stale
archive was one green --run from TestFlight). After the plan:
"$hatsu_root/scripts/send_freshness_check.sh" --repo <path> # [--base <branch>]; default branch.baseExit 0 — fresh — prints § 5's four lines; § 4 sends from here. Exit 3 (notags.identity): tree clean, § 4 sends from here, § 5 reads unverified. Exit 2 naming a dirty tree, no archive, a build SHA not HEAD or notorigin/<base>'s tip (both SHAs named) is row stale-send: § 3b rebuilds,
never a send from here, never a question; exit 2 on a malformed nameFrom (a symlink,
out-of-tree, a bad SHA) is a declaration defect — stop.
3b. The fresh build — susanoo, in a clean worktree at the trunk's tip, ONLY when owed
Ruling 2026-09-29 (HA#146): "kagutsuchi by default runs susanoo for a fresh build ONLY when
latest build is not up to date with target branch" — in one idempotent worktree, the maintainer's
own files copied from core (the two rulings before it).
Core is nen wc worktrees --repo <path> --json's core; an active nen wc swap refuses
(`amenotejikara`). Then, plan first:
"$hatsu_root/scripts/kagutsuchi_worktree.sh" --repo <path> [--base <branch.base>] [--dry-run]Its header is the contract: fetch; one detached worktree at <core>/.nen/worktrees/kagutsuchi
at origin/<base> — created | reused (idempotent) | moved; dirty → exit 2, never
discarded; every project.fromCore path copied from core only, proven untracked, gitignored
and regular in core and at the tip, nothing synthesised; copied: and core-ignore: lines. Then `susanoo` --repo <worktree> (## 0. skipped,
held here); § 3a again, in the worktree, still run; § 4 from the worktree — rebuilding in<worktree>, said. Never nen shu archive or deploy in a checkout § 3a refused.
4. The send — only on the call, only that target
nen shu deploy --repo <path> [--lane <lane>] --target <name> --run--run is a second, independent flag — no single-flag path to acting. Run it once; on a
failure read § 5, fix the named fact and re-run under the same call.
4a. The distribution tag — OPT-IN, and only after the send succeeded
A repository may ask for what was sent to be tagged by declaring tags.identity.nameFrom (the identity, then the build SHA; `susanoo`
§ 5a) and tags.deploy.<target> (whether, and whether pushed). Every check and the cut live in
`scripts/dist_tag.sh` — its header is the contract — run only
after a green --run, the target in a file (PROCESS.md § Escaping the
maintainer's words):
"$hatsu_root/scripts/dist_tag.sh" --repo <path> --target-file "$target_file" [--dry-run]Exit 0 cut; 3 not declared; 2 refused; 1 nen tag cut refused — its reason
stands. A rejected --push: delete the local tag, verified absent from origin,
re-cut. A tag refusal never unsends anything.
5. The refusals, credentials, and the report
Codes per claude/agents/kurapika.md § The shu verbs; a seat beats a typo.
| Exit | Fact | Reaction |
|---|---|---|
1 |
the deploy tool ran and failed | relay its output and the destination's state — or that you do not know it |
2 |
--target naming no declared destination |
refused (§ 1), the declaration PR named, the keys shown — never a near-match |
2 |
--run with --dry-run; an unsatisfied precondition or requiresEnv variable |
fix the wiring; the plan still prints, the failing rows FAIL |
3 |
unsupported host | G5. Name the hosts the declaration allows and stop — never retry |
4 |
a seat, or the target declares unsupported |
quote it verbatim and stop |
5 |
the program could not be started | nen shu tools --repo <path>; relay the remedy |
Credentials are asserted, never handled: nen checks each requiresEnv variable is set without
reading it; this skill never reads, prints or asks for one. An unset one is exit 2 with
its name.
Then one block, stop: the target, its source (typed | workflow.json → deploy.defaultTarget; the typed answer where § 1 asked) and its why, the lane, the argv from the--dry-run report, § 3a's four lines (built SHA, HEAD, origin/<base>'s tip, fresh |unverified), § 3b's block where it ran (core, tip, worktree state, copied: lines, susanoo's
artifacts) or no rebuild owed, whether --run was passed, each exit
code, the maintainer's call quoted verbatim, and one tag line (cut, refused with nen's reason,
or not declared). Re-render the turn
report, the upload in 01 Accomplished, and say nothing about what is next.
Residue
Nothing marks a target as production (§ 2 reads the why), exit 1 says nothing about the far end, nothing records the authorisation (no
per-run log, zheref/nen#91), and § 3a, § 3b and the default target are Hatsu's — two scripts, and
a key nen neither validates nor reads; nen has no worktree verb; a per-stack default is nen's to add
(PROCESS.md § Residue and owned dependencies). kamui
is reserved — not this skill, not a composite.
Authority and hard limits
- Permitted, only on the maintainer's own call: the plan for any declared target; § 3a's gate;
§ 3b's worktree, copies andsusanoowhen § 3a says the archive is not the tip's;nen shu deploy --target <that target> --runonce, to a non-production destination; § 4a's tag after
a green--run. - Not permitted:
--runfor production or a store (mugetsuat G3);nen shu release; a
GitHub Release; a merge, PR, label, commit or push; an edit to a declaration to make a line work;
any push or tag other than § 4a's; a rebuild when § 3a readfresh;susanooor the send in a
checkout § 3a refused; a--discard, or a copy from any checkout but core. - The call is one send wide, ends with the run, and is never authority for another target.
nen shu deploy's exit3is the one G5 it raises (§ 3a's3is unverified, not a stop). - Never runs unasked, prompts for itself, runs from a composite on its authority, or treats a
delegation as the call; never picks a target (§ 1's rows, nothing else). - Never sends past § 3a — a stale archive is rebuilt (§ 3b) or refused, never sent and tagged
later. Never sends to production or a store, or what it did not show; never reads, prints, exports or asks for a credential; never
retries exit3, routes around a seat, sends twice, or claims a send it did not read. - Never tags an undeclared target, composes a tag name, tags after a plan-only run or a failed
send, re-tags, or routes around a tag refusal; a green send is not a cut tag, and G3 still
needs its own recorded go.