Send a build to a declared NON-PRODUCTION destination — the internal channel, the testers' track, the preview environment — by running the repository's own `deploy` row through `nen shu deploy --target <name> --run`. Use ONLY when the maintainer invokes hatsu:kagutsuchi <target> or asks in their own words to upload this to a named destination. The plan is printed always, sending happens only on that call naming that target — typed by name, or as a futon `then` step on the advance go mugetsu § 3 defines — no composite calls it on its own authority and no agent proposes it. Production and the stores are hatsu:mugetsu at G3, never this skill.
Install
npx skillscat add zheref/hatsu/kagutsuchi Install via the SkillsCat registry.
Kagutsuchi — one build, one named destination, on your word
Nature: Emitter. A build leaving this machine is a release act.
Show me exactly what would be sent and where. Then, because I said this target by name, send it —
once.
A human call, per target (the maintainer's kagutsushi is still an invocation).
Plugin root and the declaration gate by role are PROCESS.md § Authority
every phase shares.
0. Standalone entry
`docs/STANDALONE-ENTRY.md`, narrowest form (no wired entry):
P1, and P2's block plus the tag or commit the artifact will carry, inside § 3's plan —
orientation, not a gate; nothing is asked but a missing target.
1. Invocation — and who is allowed to say it
P1 — this run opens with hatsu:ten kagutsuchi (`ten` § 6 catches up this phase's
missing prerequisites under its own name; the phases this run calls skip theirs).
hatsu:kagutsuchi <target><target> is required grammar, never a default — not even where exactly one destination is
declared — a key of nen/contract.json → project.targets, because naming it is the
authorization. It is the maintainer's word, typed, never picked (missing-maintainer-choice;
`WORKFLOW.md` § 4): a missing one is asked as free text, the declared
keys listed for reference, none starred and none a picker option; an undeclared one is refused,
naming the declaration PR that would add it; other gaps are missing-configuration. A named call is the stop — no confirmation, no
lettered options — so the plan prints first (§ 3) and the report says what was sent (§ 5).
- No agent prompts for it (the
stagingtarget is declared, never shall I upload it?), no
composite calls it on its own authority — a `futon`thenstep reaches it
only on the advance go `mugetsu` § 3 defines, not restated here; the
step's@<target>is this target, still required (the 2026-09-28 default is mugetsu's alone),
still non-production only — a recorded delegation is NOT the call (a DRAFT,OPEN-2) and a subagent never self-authorises: without the maintainer's own call it
prints the plan, says it has none, and stops. One call, one target, one send — ayesforstagingis no authority an hour later — quoted verbatim, never paraphrased or inferred. - It calls nothing but the verb — never `susanoo` (the maintainer builds
the package first) nor `mugetsu` (an upload is no step toward publication).
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 only, § 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) |
Targets are project-level, deploy rows per-lane, and nen never checks the pairing: read thetarget: line and the composed would run: every time.
Non-production is the why's PROSE, not a typed field (§ Residue), read failing closed: a why
that says or implies the destination reaches end users is `mugetsu`'s at
G3 (row release-go); no why, or one that does not clearly say non-production, is refused —
an unstated claim is one nobody made. An untrue why is a declaration defect beyond any reading.
3. The plan — printed always, before anything
nen shu deploy --repo <path> [--lane <lane>] --target <name> --dry-runBeyond PROCESS.md § Running a declared verb, it carries the target:
line with what it appends and requires, the host row and every precondition asserted. Write--dry-run though the bare form is read-only — the spelling no reader misreads. Paste the plan
before sending, every time; what is sent must be what was shown.
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 — the same authorization only for the same target and
call.
4a. The distribution tag — OPT-IN, and only after the send succeeded
A repository may ask for what was sent to be tagged (ruling 2026-09-18, corrected 09-19) by
declaring tags.identity.nameFrom (line one the identity, line two the build SHA, shared with
`susanoo` § 5a so announced and cut cannot differ) and tags.deploy.<target>
(that this target is tagged at all, and whether pushed; no entry, no tag). This is the one tag,
cut where a build lands; the default is not to tag.
Every check, refusal and the cut live in `scripts/dist_tag.sh`,
run only after a green --run, the target passed as PROCESS.md
§ Escaping the maintainer's words says:
"$hatsu_root/scripts/dist_tag.sh" --repo <path> --target-file "$target_file" [--dry-run]It reads the opt-in first, composes dist/<target>/<identity> from variables so the prefix cannot
disagree with the target, refuses a nameFrom that is not a regular file inside the repository (a
symlink included), a build SHA that is not a raw 40-character commit (never tagging HEAD instead),
a dirty tree and an illegal ref name, then runs nen tag cut … [--push]. Exit 0 cut (or all
checks passed under --dry-run); 3 not declared, nothing cut, not an error; 2 refused,
reason on stderr; 1 nen tag cut refused — its reason stands, never routed around (--at
must be an ancestor of origin/<trunk>).
--push is not atomic: a rejected push leaves the name local and absent on origin, refused
forever after; the one remedy is deleting that local tag at that SHA, verified absent fromorigin, and re-cutting. A tag refusal never unsends anything: § 5
reports the send and the tag on separate lines.
5. The refusals, credentials, and the report
Codes per claude/agents/kurapika.md § The shu verbs; order matters, and a seat deliberately
beats a mistyped target.
| Exit | Fact | Reaction |
|---|---|---|
1 |
the deploy tool ran and failed | relay its output, name the failing step, and say what state the destination is in — or that you do not know |
2 |
--target absent, or naming no declared destination |
the trigger to ask (§ 1), the declared list verbatim as the options — never pick one, never a near-match, never add the target to the declaration |
2 |
--run with --dry-run; an unsatisfied precondition or requiresEnv variable |
fix the wiring; a precondition still prints the plan with the failing rows FAIL, relayed whole |
3 |
unsupported host | G5. Name the hosts the declaration allows and stop — never retry, never re-route |
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, and this skill never reads, prints, exports, writes or asks for one. An unset one is exit2 with its name — a secret, never asked for — and the run ends there, naming it for the
maintainer to set in their own shell.
Then one block, and stop: the target and its why quoted, the lane, the argv copied out of the--dry-run report, whether --run was passed, each step's exit code and nen's, and the
maintainer's call quoted verbatim (with the pick where § 1 asked; a delegation is context, never
its place). One tag line: cut and pushed, cut locally, refused with nen's reason, or not
declared for the target — a malformed declaration is read-and-rejected, not absent. Re-render the turn report, the upload in 01 Accomplished
(PROCESS.md § Reporting a phase), and say nothing about what is next.
Residue
Nothing marks a target as production (§ 2 reads the why), nothing checks a target belongs to
its lane (the guard is reading the plan), exit 1 says nothing about the far end ("I do not
know what state the destination is in" is honest), and nothing records the authorisation (the
call is quoted by hand; no per-run log yet, zheref/nen#91).
Authority and hard limits
- Permitted, only on the maintainer's own call naming the target: print the plan for any declared
target; runnen shu deploy --target <that target> --runonce, to a destination whosewhy
says non-production; and, only wheretags.deploy.<target>is declared, cut that one tag throughscripts/dist_tag.shafter a green--run. - Not permitted:
--runfor production or a store (that ismugetsuat G3);nen shu release; a GitHub Release; a merge, PR or label; an edit toproject.targetsto make a
line work; any push or tag other than § 4a's (atags.deployblock added to get one is itself a
declaration change at its gate). - The call is one send wide, ends with the run, and is never authority for another target. Not a
gate event of its own; exit3is the one G5 it raises. - Never runs unasked, prompts for itself, runs from a composite on its authority (a futon
then
step on the advance go, mugetsu § 3, is the maintainer's), or treats a delegation as the call; never chooses or defaults a target, sends to a near-match, or adds one to the declaration. - Never sends to production or a store, or what it did not show; never reads, prints, exports
or asks for a credential. - Never retries an exit
3, routes around an exit4seat, sends twice on one call, or claims
a send succeeded on a plan or an exit code it did not read. - Never tags an undeclared target, composes a tag name of its own, tags after a plan-only run or a
failed send, re-tags, or routes around a tag refusal — not by tagging another commit, not by
pushing a branch to make--atan ancestor, not by dropping--push. - Never lets a tag refusal read as a failed send, or a green send read as a cut tag: G3 still
needs its own recorded go.