Bring an already-published branch up to date with its base, rerun the shared iteration checks, and before pushing any source/test change return to the caller so kotoamatsukami can refresh impacted tests and byakugan can recapture coverage. Murasaki composes ao; it never independently owns tests, coverage, squashes, force-pushes, first-publishes, or opens a PR.
Install
npx skillscat add zheref/hatsu/surfaces-antigravity-skills-murasaki Install via the SkillsCat registry.
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 byten 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.
Murasaki — the branch, current and still true
Nature: Manipulator. The last step touches the remote, and an operation that moves shared state is
GitHub-side operation whichever nature authored the diff — the same reading
`/aka` and `/ao` make of themselves.
Put the base underneath me, prove the declared iteration checks still pass, and — only if this
branch is already out there — put the update on the remote.
Murasaki is `/mukai`'s first step and the step
`/en` runs when a PR falls behind its base. It is also invocable alone. It is
the maintenance half of publishing, where `/aka` is the decision
half: aka is the human call that first sends a branch out, and murasaki keeps a branch that has
already gone out honest afterwards.
This file composes. It does not re-specify. Each of the three steps is another skill's, named and
linked, and its procedure, its exit-code reactions, its refusals and its residue live there. A rule
in this file that is really ao's, kotoamatsukami's or byakugan's is in the wrong file — go read it where it is
authored, because a rule restated in two places drifts in one of them.
0. Standalone entry — catch this branch up with the remote base
Typed alone, murasaki has one job and it finishes it: bring this branch up to date with the base,
resolving what can be resolved. That is the catch-up half of § 3, and it is complete work in its
own right — the maintainer standing on a branch that has fallen behind main wants it current, not a
referral. The contract is `docs/STANDALONE-ENTRY.md`.
Reached from any composite, skip this section — `/mukai` and
`/en` are the two that reach it; /aka composes
`/ao` directly, not this skill — — § 3's three steps run in full, and § 5's
return-to-caller governs instead of anything here.
The base is origin/<branch.base> — remote main by default, fetched first.
git fetch originfrom <base> overrides it (§ 1), and the resolved base is named out loud either way. The remote
ref is the default for the reason it is the default everywhere in this contract: catching up onto a
stale local main produces a branch that is current with nothing, and the next catch-up does the work
again over a wider delta.
P2 · Orient, and refuse the one state that cannot be caught up. State the branch, clean-or-dirty
with every path, commits ahead, and whether the branch is published:
| What P2 read | What murasaki does |
|---|---|
| A feature branch, behind the fetched base | Run. This is the case the section exists for |
| A feature branch already current with the base | Say so with the sha, run nothing, and stop. A merge commit that merges nothing is noise in the history |
| Dirty working copy | Ask before touching git state, showing every uncommitted path — a catch-up over uncommitted work is how it gets lost in a conflict resolution. Never stash unasked, never discard |
| On the trunk | Stop. There is no branch here to catch up |
The run — § 3 step 1, in full, and it is `/ao`'s.
Murasaki composes ao and restates none of its protocol: ao reads the checkout, decides rebase or
merge by whether anything has been published, classifies every conflicted path before touching
one, and resolves the mechanical ones. Graceful means exactly that classification — a mechanical
conflict is resolved, a semantic one is never guessed at.
A semantic conflict is a G5 stop with both sides shown (ao § 6), unchanged and non-negotiable.
Picking the side that lets the run finish is the failure the classification exists to prevent, and a
cold entry — where no caller is waiting on the result — is where the temptation is strongest.
Then the shared iteration checks over the caught-up tree (§ 3 step 2), so the maintainer learns
here, not three phases later, that the base brought something red with it. A red check is reported
with the failing check quoted; it is not repaired inside a catch-up.
Where it stops: § 5's invalidation point — and a standalone run does not push at all.
The predicate is § 5's own and it is any tracked path, not just source and tests:
`docs/WORKFLOW.md` § Phase ownership binds a capture to the exact tree
hash, "including sources, tests, snapshots and execution configuration", and § 5 says "if any
path changed, all earlier impacted test and coverage evidence is invalid." Report which paths the
catch-up moved and name `/kotoamatsukami` and
`/byakugan` as what owes a refresh.
Then stop, whether or not the catch-up was a no-op. § 6's push sits after the caller's steps 3–5
in the wired run — WORKFLOW.md § 5 step 6 admits it "only when this catch-up is a no-op", and even
then on a tree those steps proved. A standalone run has no steps 3–5 behind it: the commits it would
publish were never through kokusen → kotoamatsukami → byakugan in this run at all. Pushing them
would be `docs/STANDALONE-ENTRY.md` § 2 Rule 2's absorbing a
later phase, and the phase it absorbs is the one that leaves the machine.
This is not murasaki absorbing a phase (`docs/STANDALONE-ENTRY.md`
§ 2, Rule 2): the catch-up was always its own step 1. What a standalone run declines to do is
everything that was never its — it still owns no tests, no coverage, no squash, no force-push, no
first-publish, and opens no PR.
Hand-back, and § 7 makes it a short one. Next in the wired run: /kotoamatsukami and/byakugan where evidence was invalidated; otherwise the branch is current and nothing was
pushed. It names no phase beyond those two — § 7 forbids proposing /aka or /mukai
as a next step this run is waiting on, and `docs/STANDALONE-ENTRY.md`
§ 6 defers to that stricter rule rather than overriding it.
1. Invocation
P1 — this run opens with /ten murasaki (`ten` § 6 catches up this phase's
missing prerequisites under its own name; the phases this run calls skip theirs).
/murasaki [from <base>]nen parse murasaki --grammar "from [<base>]" --line "<the invocation, minus the /murasaki prefix>"Verified live at v0.3.0 (docs/ab/murasaki.md § 2.1): from release/1.4 → base: release/1.4,
exit 0. The clause is anchored behind a literal for the reason
`/spiritual-message` § 1 records, and the shape is deliberately ao's, because the
clause means the same thing in both.
A bare invocation is not parsed, and that is the verb's own answer rather than an omission.
Verified live:--line ""against this grammar refuses at exit2— "the line must open with the
literal 'from' — it is what introduces<base>". There is nothing to parse in/murasaki
with no clause, so the parse runs only when the maintainer typed one; with no clause the base
isnen/workflow.json→branch.base, defaultmain. Name the base out loud either way.
2. The parameters — nen/workflow.json, with the defaults stated
| Key | Used for | Default when the key (or the file) is absent |
|---|---|---|
branch.base |
what § 4 puts underneath the branch | main |
iteration.checks |
the declared verbs § 5 re-proves the merge with | ["build"] |
iteration.lane |
the lane those verbs run in | project.defaultLane |
nen schema check --repo <path> VALIDATES this file at the pinned build — verified live, the row
reads ok nen/workflow.json coverage 80/85/90 (touched), branch '{model}/{persona}/{descriptor}' off 'main', checks: lint. A malformed key is a FAIL by pointer, so this skill no longer checks
the shape by eye; it reads the values, and states the defaults whenever they are what applied.
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
typed clause that exits 2 is the trigger to ask for the base, not the end.
3. The three steps, in order
| # | Step | The skill that owns it | Why it is here |
|---|---|---|---|
| 1 | pull | `/ao` | fetch the base, rebase what is unpublished / merge what is published, classify every conflict, resolve the mechanical ones |
| 2 | checkpoint and invalidate | this file, § 5 | run the shared iteration.checks (lint is `/gyo`); if catch-up changed any tree path, earlier kotoamatsukami and byakugan evidence is stale and the caller must refresh it before this skill pushes |
| 3 | publish the update | this file, § 6 | nen wc publish, never --set-upstream — only if the branch was already on the remote |
The order is load-bearing in three places:
- 1 before 2. The point of the declared iteration checks here is to prove the merge, not the
branch. Running them first would prove the tree nobody is about to push. - the checks before any caller-owned regression refresh inside step 2. A red iteration check
makes a later test result meaningless: the merge is not proven, so the suite would run against a
tree nobody is about to publish. On this repository the declared check is lint
(`/gyo`); a red lint is not a failed compile. Prove the declared checks
first, always. - 2 before 3. Nothing goes to the remote that has not just been proven on the tree that is
going. A push that re-runs the checks afterwards is a push that already happened.
A step that refuses ends the run where it refused, and nothing is pushed. Ao stopping on a
semantic conflict (§ 4), a check coming back red (§ 5), kotoamatsukami finding a red suite — each is
handled where it is owned. Murasaki adds nothing to it except the guarantee that step 3 does not
run.
4. Step 1 — `/ao`, and the conflict that ends the run
Ao's whole engine, unchanged: the published/unpublished test, rebase-or-merge, the conflict table,
the mechanical resolutions, the re-proved build. This skill restates none of it.
A semantic conflict is ao's G5, not murasaki's, and murasaki neither retries past it nor
re-renders it. Ao leaves the tree conflicted, shows both sides verbatim, prints the abort line and
stops; this run ends there, having pushed nothing, and says so in one line. The answer resumes it.
Ao never pushes — its own hard limit — and being called from inside murasaki does not lend it
one. § 6's push is murasaki's, made after ao has returned and said what it did.
5. Step 2 — checks, invalidation, and the caller-owned regression phase
nen shu <check> --repo <path> --lane <iteration.lane> # every iteration.checks entry, in orderThis half is murasaki's own step, and deliberately not a call to
`/rasengan`. Rasengan is the AUTHORING phase (the maintainer's ruling
of 2026-09-10, `docs/ROSTER.md`); what step 2 wants is a verdict on a tree
nobody has authored on — the merge ao just made. So murasaki runs the declared checks itself, reads
them off `/rasengan` § 6's exit table, and hands a red one to rasengan
to author the fix, after which step 2 runs again over the repaired tree.
Compare the caught-up tree with the pre-catch-up tree. If any path changed, all earlier impacted
test and coverage evidence is invalid. Do not run kotoamatsukami or byakugan here. Return
to the caller — mukai steps 3–5, or En's equivalent named in
`/en` § 3: `/kokusen` checkpoints the caught-up
tree, `/kotoamatsukami` refreshes impacted tests and
`/byakugan` recaptures coverage, then this skill is called again and
may push only when that later catch-up is a no-op. Murasaki
grants itself no test and no capture authority. Only a complete no-op catch-up may reuse earlier
evidence; report that fact and do not rerun the suite here. The exit-code tables — 1 red, 2 declaration, 3 host, 4 a
seat quoted verbatim, 5 nen shu tools — are claude/agents/kurapika.md § The shu verbs'
and are handled there, not here.
When mukai calls murasaki after its coverage step, coverage is part of the publication proof. If
ao changes any tree path, murasaki stops before § 6's push and returns the caught-up tree to mukai
steps 3–5. Kotoamatsukami refreshes tests and byakugan recaptures coverage there; only the next
murasaki pass, whose catch-up is a no-op, may push. This is a caller-owned evidence dependency, not
new regression or coverage authority for murasaki.
Two things murasaki asserts on top of them, and only two:
not applicable — no tests configuredandnot applicable — no impacted suitesare carried
through unchanged when the caller reports them
(`/kotoamatsukami` § 4). Murasaki repeats the phrase in the
push report. It is not a reason to stop — an empty or fully-skipped set is not a red suite —
and it is not a pass. Hatsu's own checkout is the empty-configured case.- A red iteration check at step 2 stops the run without a stop banner of its own. The G5 on
a red required suite is `/mukai`'s, raised at the moment a pull
request was about to happen. Murasaki is not that moment: the branch is already out there, the
fix is ordinary work, and the honest report is "the merge is on disk, it does not pass, nothing
was pushed". Say that, and let the next turn fix it.
6. Step 3 — push, and only for a branch that was already published
nen wc publish --repo <path> [--dry-run] [--json] # never --set-upstream hereThe published test is the same one ao already ran, and its answer is re-used rather than
re-derived — the strategy nen wc catch-up reported:
| Ao's answer at § 3 of its own file | What murasaki does |
|---|---|
published — strategy: merge; ao merged the base in |
push. The merge is a descendant of origin/<branch>, so a plain push is a fast-forward |
not published — strategy: rebase; nothing on the remote |
push nothing. Say so, and name `/aka` as the human call that first publishes a branch |
Those two rows are one decision seen twice, and that is the structural reason murasaki can never
need a force-push. Ao merges exactly when something is published and rebases exactly when nothing
is, so the only tree murasaki ever pushes is one that already contains origin/<branch> as an
ancestor. The verb's exit 1 with needsForce: true is therefore a finding to report, never a
flag to add: something moved the remote branch under this run, and the maintainer needs to know
before anything overwrites it.
Never a force form, never a refspec, never --set-upstream. The verb refuses the first two at
exit 2 in every spelling; --set-upstream sets an upstream, which is a first publish, and a first
publish is aka's.
Never squashes. Not the turn commits, not "just the ones since the last push", not to tidy the
branch before the PR reads it. The commits below origin/<branch> are somebody else's history the
moment they are fetched, and rewriting them is the force-push this skill exists to make
unnecessary. Squashing is `/aka` § 4's, once, before the first publish.
Never pushes branch.base. The verb refuses the trunk at exit 2; the PreToolUse guard inhooks/hooks.json refuses a raw push on the trunk at the harness level; this skill refuses it at the
rule level.
RETIRED at nen
0.5, superseded at0.13. Step 1's merge half ran throughnen pr cascade-main --repo <path> --trunk <base> --no-push(verified live atv0.5.0,docs/ab/murasaki.md§ Retired at nen 0.5); `/ao` § 3 now runs both
halves throughnen wc catch-up, and step 3 isnen wc publish. The shape is unchanged: step 2
runs between the catch-up and the push, and nothing publishes a tree nothing proved.
7. What murasaki never does
No pull request, no label, no merge, no comment, no tag, no deploy. Composing three skills does
not widen what any of them may do, and murasaki adds one operation of its own — an ordinary
fast-forward push of a branch that is already published. That is the whole of its blast radius.
It never proposes `/aka` or `/mukai` as a next
step it is waiting on. Both are human calls, and a composite that ends by asking for one has
converted a human call into a nudge — the inversion `/ren` § 4 and aka § 1
both refuse.
8. Report, and stop
One line: the base and its resolved SHA, rebase-or-merge and why, the conflicts by kind and how the
mechanical ones were resolved, the iteration.checks that ran green, whether regression evidence
is still valid or was returned to the caller, and either the pushed SHA or not published — nothing pushed.
Invoked inside `/mukai` or `/en`, that line is what
the caller continues from; invoked alone, it is the end of the run.
Residue
- RETIRED at nen
0.13: the push itself isnen wc publish(§ 6), no--set-upstream; it
refuses the trunk and every force form, and reportsneedsForceinstead of taking one. - RETIRED at nen
0.5, superseded at0.13:nen pr cascade-main --no-push(§ 6). Both
halves of step 1 are nownen wc catch-up's, inside ao. - RETIRED at nen
0.13: the published/unpublished test iswc catch-up's own, reported asstrategyand re-used here rather than re-run (§ 6). - RETIRED at nen
0.5:nen shu test-report(kotoamatsukami / tsukuyomi). The suite's verdict is the
parsed{tests[], passed, failed, skipped}document, and the counts are read off it rather than
restated from memory. - RETIRED at nen
0.5:nen/workflow.jsonis validated.nen schema check --repo <path>carries
anok nen/workflow.jsonrow at the pinned build. § 2's keys are still read here; reading a file
is not residue.
Each is run in the open and reported as by-hand, per the Nen-first rule's second half
(claude/agents/kurapika.md): a missing verb is a finding, not a gap to route around silently.
Authority
- Permitted: everything `/ao` is permitted, one at a time, in § 3's
order; running the lane's declarediteration.checksover the merged tree (§ 5) —lintis
`/gyo`, the same gate `/aka` § 6 re-runs after
catch-up, not aka's former full suite; and one operation of murasaki's own: a plain, non-force
push of a non-base branch that is already on the remote. Authoring a fix for a red merged
tree is `/rasengan`'s, under rasengan's own authority. - Not permitted: a first publish; any squash or rewrite of any commit; any force-push; opening,
editing or commenting on a pull request; any label, merge, tag or deploy;--no-verify; pushingbranch.base. - Grants no delegation of its own. Composing a skill does not widen what that skill may do, and
a run-scoped delegation granted inside a step expires with that step.
Hard limits
- Never pushes a branch that is not already on the remote (§ 6). A first publish is
`/aka`'s, on the maintainer's own call, and reaching a first publish
through murasaki would make a human call reachable by a composite. - Never squashes, and never rewrites any commit (§ 6). Not the turn commits, not to tidy the
branch, not because the PR would read better. - Never force-pushes — a rejected fast-forward is reported, never flagged past (§ 6).
- Never pushes before step 2 has run green on the merged tree (§ 3).
- Never pushes past a semantic conflict — ao's G5 ends this run with nothing on the remote (§ 4).
- Never opens a pull request — that is `/shibari`'s step inside
`/mukai`. - Never proposes a human call as its next step (§ 7).
- Never restates another skill's protocol. If murasaki and a composed skill disagree, the
composed skill is right and this file is the bug. - Never presents by-hand git as a verb's output — every step in § Residue is named where it runs.