zheref

kotoamatsukami

Own impacted project-wide unit, UI and integration tests at mukai — run only the declared suites the change can affect, and handle UI evidence. Aka never runs this. Coverage capture and measurement are byakugan's. Gyo is linting. A skipped suite needs a named proof; an accepted snapshot invalidates the run.

zheref 0 Updated 3w ago
GitHub

Install

npx skillscat add zheref/hatsu/surfaces-antigravity-skills-kotoamatsukami

Install via the SkillsCat registry.

SKILL.md

Shared policy location: docs/DISCOVERY.md, docs/WORKFLOW.md,
docs/LAUNCH-MIGRATION.md, docs/STANDALONE-ENTRY.md, docs/PROCESS.md and docs/SURFACES.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.

Kotoamatsukami — the tests that this change can actually move

The gate on a declaration change is the REPOSITORY's role, not the file's kind. Maintainer's
ruling, 2026-09-18 (`docs/ROSTER.md` § Rulings of 2026-09-18 — G4 is
the repository's role, not the file's kind
): G4 (CON-7) in a canon repository —
the repositories nen repo classify reports as role: canon (nen/repos.json → maintained_tools), whose product is the process — and G2
(CON-5) in a consumer repository
, where a nen/contract.json, nen/workflow.json or
nen/gates.json is that repository's own configuration and governs nothing else. This skill runs
against consumer checkouts by design
, so every declaration-gate instruction below names both
halves explicitly rather than asking you to reinterpret a bare "G4". The merge is en § 5's
either way — the ruling moves the gate, never the owner.

Nature: Transmuter carries every run: kotoamatsukami executes declared machinery and reports
what it did. Fixing what the suite found is the surrounding phase's work in that phase's own
nature — and where the "fix" would be to re-record a golden, § 8 is the rule that decides
whether that is a fix at all.

On the tree mukai is about to put up, run every declared unit, UI and integration suite this
change can affect, tell me exactly what it said, skip the rest with proof, and show me every
scene a UI suite re-recorded.

Kotoamatsukami is `/mukai`'s test owner, taken after review
mutations are checkpointed and before `/byakugan` captures and
measures coverage. It is the sole project-wide test run on the PR-bound tree — unit, UI,
integration. It does not capture coverage and it does not gate the ladder. `/aka`
never calls it: aka runs `/gyo` (lint), squashes, catches up and pushes.
`/gyo` is linting, on every Ren turn. `/tsukuyomi`
never calls it: tsukuyomi is the focused lane on every ren turn.

It is also invocable alone as a diagnostic, where it runs the same selection and carries no
publication proof. Mukai's later evidence step consumes the artifacts this run already produced
and does not execute the suites again.

Where the two overlap with tsukuyomi — the dry run, the exit-code table, fix the code and never
the test
, never state a count nobody printed — the rule is authored in
`/tsukuyomi` and read there. What is authored here is the half
tsukuyomi does not have: choosing which declared suites the change can affect, and handling the
images a UI suite produces. Coverage capture and extract are byakugan's.


0. Standalone entry — when no composite is holding the run

Kotoamatsukami is normally mukai's impacted-test step, and this section is what it does when it is
typed alone.
The contract is `docs/STANDALONE-ENTRY.md`.
Reached from ANY composite, skip this section entirely — the composite established P1–P4, and re-deriving them is how two answers to one question appear. Say which composite is holding the run. mukai and en both reach it, and each established the branch, the base and the change
set before it reached this step.

The state class kotoamatsukami inherits is S1 — the change set. § 4's impact selection runs
"only what this change can move", and cold there is no this change until the base is named.

P3 · The base defaults to the fetched origin/<branch.base> — the remote trunk, never the local
ref.

git fetch origin
git diff --name-only origin/<branch.base>...HEAD   # committed since the base
git status --porcelain                             # staged, unstaged, untracked

The impacted set is computed from the union of both, and against <base> overrides the base
(§ 1, where it sits beside on <lane> in one grammar). Name the resolved base, the two counts and the selected suites out loud before the first suite
runs — selection is the claim this skill is trusted for, and a selection nobody can audit is not one.

A stale local main is the specific failure this defaults away from: it widens the delta with
work the branch did not do, which widens selection, which turns an impacted run into a slow
approximation of the full suite and reports it under the impacted run's name.

P4 · Nothing to ask, where the declaration is complete. The suites come from
nen/workflow.json → tests.required and the selection from the delta; neither is a question. § 6's
empty-declaration case is unchanged and still says so rather than inventing a runner, and § 3's
"an empty configured set, and an empty selected set, are not green" binds a cold run exactly as it
binds a wired one. An empty delta is reported as an empty delta, never as a pass.

What does not change. UI evidence handling, the re-recorded-snapshot invalidation (§ 8), the
named proof a skipped suite owes, the scenes becoming the evidence table. It still does not measure
coverage
— that is `/byakugan`'s, and a cold entry does not merge the two.

Hand-back. Next in the wired run: /byakugan — capture and measure touched-file coverage.
It does not rerun these suites; it reads what this run produced.


1. Invocation

/kotoamatsukami [on <lane>] [against <base>]
nen parse kotoamatsukami --grammar "on [<lane>] against [<base>]" --line "<the invocation, minus the /kotoamatsukami prefix>"

Two optional anchored clauses in one grammar, verified live at nen 0.10.0: on shell against origin/main → lane: shell, base: origin/main; against origin/main alone → the lane absent and
the base set; an empty line → both absent. Every one exit 0.

against <base> names the base every delta in this skill is read from. With no clause the base
is the latest state of nen/workflow.json → branch.base — git fetch origin first, then
origin/<branch.base>; the local ref is used only where that fetch proves it already equal, and a
fetch that cannot run is a stop rather than a silent fall-back
(`docs/STANDALONE-ENTRY.md` § 3 · P3). The resolved base is
named out loud either way.

Verified live at v0.3.0 (docs/ab/kotoamatsukami.md § 2.1): on shell → lane: shell, exit 0.
The clause is anchored behind a literal for the reason `/spiritual-message` § 1
records; with no clause the starting lane is nen/workflow.json → iteration.lane, defaulting to
the declaration's own project.defaultLane. A bare invocation is not parsed — there is nothing
in it to parse — and the resolved starting lane is named out loud either way. Selection may then
add or skip other declared lanes; the starting lane is not a licence to run every suite.

2. The parameters, and where they come from

Value File → key Default when absent
The suites that must be considered nen/workflow.json → tests.required ["test"]
Suites considered alongside them, not independently gating nen/workflow.json → tests.extra []
Which lane a suite runs in when selection has not named another nen/workflow.json → iteration.lane project.defaultLane
What each suite actually runs nen/contract.json → project.verbs.<lane>.<verb> (test, ui-test, …) none — an absent row is exit 2, the trigger to set it up (§ 6); a seat is exit 4
Where it runs, with what, producing what project.lanes.<lane>.cwd, the row's env (names only) and artifacts —
Whether this host may project.hosts a declaration with no hosts block constrains nothing
What must be true first project.preconditions.<lane> []
Which files count as visual evidence project.evidence.globs none — § 9's table is then empty and says so
How a path becomes a suite and a scene project.evidence.scene {suite}-{scene}
How the images reach a PR body project.evidence.mechanism —

When nen/workflow.json is absent, say so in the turn's report, in these words — "no
workflow.json: using the built-in defaults from docs/WORKFLOW.md"
— and use the defaults
above.

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
missing lane or verb row is set up through nen scaffold init (§ 6).

project.evidence is NEN's block at the pinned build, and nen shu evidence reads it. The
loader parses it rather than preserving it, and from this release the block key itself is guarded
against a near-miss
: evidences, Evidence or evidenc would have been preserved, read by
nobody, and nen shu evidence would then have refused at exit 2 saying the repository declares no
evidence block — about a file that plainly declares one. Now it is refused by pointer. Verified live
(docs/ab/kotoamatsukami.md § Retired at nen 0.5): a declaration carrying evidence and launch
reports ok nen/contract.json project (…) under nen schema check, and nen shu evidence --base main groups the changed artifacts suite → scene at exit 0.

A required suite the declaration seats is a disagreement, not a pass. Where tests.required
names test and project.verbs.<lane>.test is {"unsupported": "…"}, nen shu test answers exit
4 with the declaration's own reason — quote it, and do not convert the seat into a skip-with-proof
that pretends the suite ran.

3. When this run is due

Mukai calls this skill after review mutations are checkpointed and before byakugan. That is the
first project-wide test run of the effort: aka did not run one. Three callers reach this skill:
mukai at its step 4; En, when a catch-up on the open PR invalidates the run; and
`/ren` under the thorough profile, after its step 3 on every turn of that
profile (ren § 2a). Under fast and standard, ren never calls it.

Re-run it, and invalidate the previous run, when any of these moves the tree: a review fix, a
snapshot acceptance, a test byakugan added to reach the coverage bar, an execution-configuration
edit, a conflict resolution, a metadata edit, or a catch-up that changed any path.
`/murasaki` does not run this skill itself; it reports the
invalidation and returns to mukai (or En) so this phase runs on the new tree before any update
push.

A red required suite that was selected to run is mukai's G5, raised at the moment a pull
request was about to open. Kotoamatsukami reports red; the phase that was about to publish decides
what that costs. The turn (or landing) page carries spiritual-message's blocker payload — step,
rule, expected versus actual, this-run visual evidence or an explicit unavailable reason —
before `/jutaisho` links it
(zheref/hatsu#56; `/spiritual-message` § 5a).

4. Impact selection — run only what this change can move

Construct one ordered unique candidate list: every entry of tests.required first, followed by
entries from tests.extra that are not already named. Then, for each candidate, decide run or
skip against the changed set:

git -C <path> fetch origin <base>
git -C <path> diff --name-only origin/<base>...HEAD

The range is origin/<base>...HEAD after that fetch — never the bare branch name. Local main is
never fast-forwarded after breath cut the branch from it.

Skip a candidate only with a named proof that the change cannot affect that suite's assertions
and cannot contribute coverage of any touched measurable file.
Two reasons to run, and either
one is enough:

  1. Assertions. A changed source, test, fixture, snapshot, golden, or execution-configuration
    file this suite reads could make a test fail or pass for a new reason.
  2. Coverage. A touched non-test source file in a language this suite instruments would otherwise
    have no chance to appear in `/byakugan`'s table.

Fail closed. If the mapping is ambiguous, if a lane's cwd overlaps the change, if a
dependency between packages is possible but not disproved, if execution configuration changed
(nen/contract.json, nen/workflow.json tests.* / coverage.*, runner config, coverage
config), or if Nen has no selector for a finer grain — run the declared row. A silent skip is
worse than a slow run: it is an unperformed check rendered as a clean one.

The grain this skill may select at the pinned build is the declared row — a lane × a verb,
whose argv the repository already wrote. It does not invent --grep, --only-changed, or a
runner flag the declaration does not contain. Per-test selection inside a declared row is
Nen #207; until that verb exists, name the residue
and keep the grain at the row. A row whose declared argv is already scoped (Hatsu's
plugin-bump-guard fixture) is selected or skipped as a whole, which is the point of declaring
it as its own lane.

Applicable projects. In a multi-lane or multi-package repository, a candidate whose cwd and
source tree share no path with the changed set, whose tests cannot import the changed packages,
and whose instrumentation cannot cover any touched measurable file, is skippable with that proof.
A single-lane repository whose one test row covers the whole tree runs that row whenever any
executable or measurable file changed, and skips it when the change is prose-only, data-only, or
otherwise outside what the suite can see — Hatsu's own Markdown-only skill edits are this skip.

Print the selection table every time: suite · lane · verb · run|skip · proof. A skip without a
proof is a bug in the run, not a performance win.

An empty configured set, and an empty selected set, are not green

tests.required empty and tests.extra empty is a legitimate declaration — and nothing ran, so
nothing passed.
Report it in these words:

not applicable — no tests configured, naming nen/workflow.json → tests.required as the
empty list, and tests.extra with it.

Every candidate skipped with proof is also not green:

not applicable — no impacted suites, with the skip table.

Never green, never passed, never a tick. Green is a claim about a run; there was no run.
Mukai treats either phrase as nothing to prove and says so — it does not convert it into a
pass, and it does not stop for it. Hatsu's own nen/workflow.json is the empty-configured case,
and says so in its own $comment.

This is not § 6's case. An empty tests.required is a repository that declared no suites; § 6
is a repository that declared nothing at all, and answers exit 2.

5. The dry run, once

For each selected row, once per repository per session:

nen shu test    --repo <path> [--lane <lane>] --dry-run
nen shu ui-test --repo <path> [--lane <lane>] --dry-run

The exact argv, cwd, env names and declared artifacts, spawning nothing. A UI suite is the
slow one and the one most likely to be wired to a simulator, a device or a browser you did not
expect — reading the argv costs seconds and reading it wrong costs the run.

The dry run is 0 only when there is something to dry-run, and § 7's table applies to it in
full.
It is not a probe that always succeeds — it resolves the declaration first, and a
declaration that has nothing to resolve refuses at the same code the real run would. A seat
answers 4 on the dry run and 4 on the run, byte for byte. Quote it and do not pretend a
real run remains.

6. A repository that declares nothing

nen shu test / nen shu ui-test exits 2 naming the missing nen/contract.json (or its missing
project block). That exit is the trigger to set the declaration up, not the end of the run
(missing-configuration): offer it in the picker, write it through nen scaffold init with the
repository's own documented command as the row, validate with nen schema check, and resume — the
file rides this effort's branch or its own declaration PR at the declaration gate (G4 in a canon
repository, G2 in a consumer one). Where the maintainer picks run once without it, run the
documented command and say plainly that no declaration exists yet. Read that fact off
test/build/lint and never off nen shu detect.

7. The run, and the exit codes

Run each selected row exactly once, through its own verb, in candidate order:

nen shu test    --repo <path> [--lane <lane>]
nen shu ui-test --repo <path> [--lane <lane>]

Never the runner's own command line typed from memory. Under --json the report is one document,
where steps[].exitCode is the runner's own code and the top-level exitCode is nen's.

Reactions, by exit code (claude/agents/kurapika.md § The shu verbs is the authority):

Exit Fact Reaction
0 the suite ran and passed next selected row; when a non-empty selected list is exhausted, for UI, § 8–9
1 red — it ran and failed; the runner's own code is in steps[].exitCode read what failed, decide whether it is the code or (UI only) the golden, fix the code, re-run. Unfixable red is mukai's G5
2 usage: no declaration, no project block, unknown lane, unsatisfied precondition a missing declaration or lane is set up (§ 6), an unknown lane asked for, never the end of the run. An unmet precondition is nen's to assert and never to perform — satisfy it and name it
3 the declaration excludes this host G5 naming the host that can, where it blocks delivery. Never a retry, and never "the unit tests passed so it is green"
4 a seat — this lane declares no such suite quote the reason verbatim. A seat on a required name is the two-file disagreement; it is not a skip-with-proof
5 the runner is not on PATH nen shu tools --repo <path>, relay the per-tool remedy

Verified live at this pin (docs/ab/kotoamatsukami.md § 2.3, § 2.2): a red UI run relays the
runner's own stdout, prints ran: … -- exit 1, and puts 1 in both steps[0].exitCode and nen's
exitCode; a seat prints its sentence on stderr and, under --json, no document at all.

A test is never patched to pass — `/tsukuyomi` § 6's rule, binding
here because this is the slow suite and the temptation is larger.

8. A re-recorded snapshot is a change to an assertion

This is the UI-specific rule, and it has no equivalent in tsukuyomi because a unit test has no
golden to overwrite.

A snapshot suite has two ways to go green, and only one of them is a fix:

  1. the code was wrong, the code changed, the rendering now matches the recorded image — a fix;
  2. the recorded image was overwritten with what the code renders now — an accepted change to what
    the suite asserts
    , which is green for exactly the same reason a deleted test is green.

So a re-record is never the reaction to a red run. The reaction to red is § 7's: read what
failed, decide what is wrong, change the code. A re-record happens because the change intended to
alter that surface — and then it is expected, it is enumerated, and each altered scene is looked at
before it is committed.

  • Look at every re-recorded image. Not the count, not the filenames — the pixels. A golden nobody
    opened is an assertion nobody made.
  • Say which scenes changed and why the change was intended, in the turn report and in the PR
    body. UZF-26's evidence table is the place that lands (§ 9).
  • A scene that changed and was not meant to is a finding, reported as one, even when the suite is
    green — especially then.
  • Never --update-snapshots, -u, RECORD=all or the equivalent as a way past a red run, and
    never a mass re-record that sweeps up scenes the change had no business touching. Where the
    declared row itself is the re-recording form, run it deliberately, name it, and enumerate what it
    wrote.
  • Never hand-edit a golden. An image edited by a person asserts a rendering no code produces.

Loosening a comparison tolerance, widening a mask, adding a retry loop and skipping a flaky scene
are the same move in different clothes.

An accepted image changes the tree, so prior regression, coverage, and evidence claims are
stale. Kokusen checkpoints the assertion change and this skill reruns selection-plus-execution
before `/byakugan` captures coverage from the replacement artifacts.

9. The scenes become the evidence table

The images the suite re-recorded are the evidence: UZF-26's rule is that the recorded test
images are the screenshots, never separately-staged captures, so the evidence cannot drift from what
the tests assert (claude/agents/hisoka.md § The evidence set). Kotoamatsukami's last act on a
selected UI row is to hand that set on:

  • to `/spiritual-message` § 4's {{#each screenshots}} — one table per screen, the
    states as columns, PNGs embedded as data URIs before a PR exists;
  • to `/shibari`, which puts the same table in the PR body through the
    mechanism project.evidence.mechanism names.

Mukai's evidence step consumes these artifacts. It does not execute ui-test again. If no matching
artifact exists for this tree, return here rather than quietly running the suite inside the
evidence step.

RETIRED at nen 0.5: enumerating the changed artifacts is a verb.

git -C <path> fetch origin <base>
nen shu evidence --repo <path> --base origin/<base> [--json]

It matches git diff --name-status <base>...HEAD — through the seam, spawning no invocation the
repository declared, only git diff itself — against project.evidence, derives each surviving
file's suite and scene, and reports them grouped suite → scene. Verified live at v0.5.0,
exit 0:

evidence: 1 changed file across 1 suite (public-mirror), against main...HEAD

suite: __Snapshots__
  added    Settings                 src/__Snapshots__/test_snapshot_Settings.png

--json publishes nen.shu.evidence/v0.1. A repository with no project.evidence block is exit
2 naming it
— the one usage refusal this verb has — and no changed file matching a glob is exit
0 with an empty row set
, never an error. Read those two apart: the first is a declaration to
write, the second is a truthful "this change re-recorded nothing".

origin/<base>, after that fetch — never the bare branch name. Against a stale local ref the
enumeration carries every golden anybody re-recorded on the trunk this week as though this branch
had. nen shu evidence --base takes a ref, so pass origin/<base> and the whole class goes
away.

Never pass a declared glob to git as a bare pathspec. A project.evidence.globs entry is
written in shell-glob terms; a git pathspec is not that. Passed bare to git diff,
'**/__Snapshots__/**/*.png' matched zero of three changed snapshots, exit 0, no warning
(verified live, docs/ab/kotoamatsukami.md § 2.4). An empty evidence table read as "this change
re-recorded nothing" is the worst failure mode this skill has.
nen shu evidence carries its
own matcher.

Where the declaration carries no project.evidence block, say so — "no evidence globs declared;
no scene table"
— and do not invent a glob. A repository that records no images is entitled to say
so, and UZF-26's two sanctioned incompletenesses are checked by `hisoka`,
not manufactured here.

A seat for ui-test is quoted and the evidence table is empty for the same reason: there was no
suite to re-record. That is the logic-only case UZF-26 exempts, stated in the body.

What three consumer repositories declare today — recorded from the fold-in report's survey of
2026-09-09, and not authority. The lane's own ui-test row is the authority, read at run time:

Repository What its ui-test row says today
<product-repo-A> a seat, until its UI-test targets actually run. Exit 4, the sentence quoted, the unit suite unaffected
kro-pwa a real row — the Playwright pair its lane declares. Read the row; it is two steps and both are the suite
<product-repo-B> a real row — the Paparazzi verify task its lane declares, which is the snapshot suite and the source of this section's images

No toolchain name in that table lives in nen. Where a copy disagrees with the file, the file wins
and this table is the bug
.

10. Report

One line, then the tables: the selection (suite · lane · verb · run|skip · proof), each selected
verb's exit code and what it meant, the runner's own summary quoted, and — where a UI row
ran — the scene rows by suite with their statuses. Where the configured or selected set was
empty, the not applicable sentence instead of green. Where a required name was a seat, the
seat's sentence.

Never a pass/fail count nen did not print and the runner did not say. Coverage capture path
and bands are `/byakugan`'s report, not this one.

Residue

  1. Impact selection at declared-row grain (§ 4). No nen verb answers "which of these declared
    rows can this diff move". Per-test selection inside a row remains
    Nen #207.
  2. RETIRED at nen 0.5: nen shu evidence --base <ref> (§ 9).
  3. RETIRED at nen 0.5: nen shu test-report (tsukuyomi § 6).
  4. Parsing a declared UI-test artifact that test-report does not read is still residue.
  5. Looking at an image has no verb. Where the surface cannot show one, say that the goldens
    were not looked at
    .
  6. RETIRED at nen 0.5: nen/workflow.json is validated.

Coverage capture (.nen/regression/<lane>.json) is byakugan's residue, not this skill's.

Authority

  • Permitted: select among declared test / ui-test rows; run the selected rows; probe the
    host through nen shu tools; read the working copy and its git history; report every code and
    quote the runner.
  • Not permitted: push, commit, PR, label, merge, deploy, or edit a declaration on the fly.
    Also not permitted: weakening the suite to make it pass, inventing a runner filter,
    running unselected rows "to be sure" after a proved skip, capturing coverage, or
    running nen shu coverage.
  • The G5 on a red required suite is `/mukai`'s. The G5 on a
    touched file under coverage.minimum
    is `/byakugan`'s.

Hard limits

  • Never runs as part of aka. Lint (that is `/gyo`), squash, ao and
    push do not include this phase.
  • Never captures or gates coverage. That is byakugan's.
  • Never skips a suite without a named proof, and never treats an ambiguous mapping as a skip.
  • Never invents a runner filter the declaration did not write.
  • Never re-records a golden to get past a red run (§ 8).
  • Never commits a re-recorded image nobody looked at, and never hand-edits one.
  • Never mass re-records beyond the scenes the change intended to alter.
  • Never patches, skips, .only-narrows, retry-loops, masks or loosens a comparison to reach
    green — `/tsukuyomi` § 9's rule.
  • Never treats exit 4 as red, or works around a seat.
  • Never treats exit 5 as a failing suite.
  • Never runs a test or UI-test command from memory in a repository that declares one.
  • Never states a pass/fail count nen did not print and the runner did not say (§ 10).
  • Never passes a declared glob to git as a bare pathspec (§ 9).
  • Never reports green from an earlier run, and never reports green for an empty configured or
    empty selected set.
  • Never presents by-hand enumeration as a verb's output.