zheref

kagutsuchi

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.

zheref 0 Updated 3w ago
GitHub

Install

npx skillscat add zheref/hatsu/kagutsuchi

Install via the SkillsCat registry.

SKILL.md

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 staging target is declared, never shall I upload it?), no
    composite calls it on its own authority
    — a `futon` then step 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 — a yes for
    staging is 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 the
target: 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-run

Beyond 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 from
origin
, 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 exit
2 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; run nen shu deploy --target <that target> --run once, to a destination whose why
    says non-production; and, only where tags.deploy.<target> is declared, cut that one tag through
    scripts/dist_tag.sh after a green --run.
  • Not permitted: --run for production or a store (that is mugetsu at G3);
    nen shu release; a GitHub Release; a merge, PR or label; an edit to project.targets to make a
    line work; any push or tag other than § 4a's (a tags.deploy block 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; exit 3 is 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 exit 4 seat, 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 --at an 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.