Author the requested change and its focused tests on the declared stack. It may execute the repository's declared scoped test lane for feedback and runs the inexpensive iteration checks while writing; kokusen owns the mandatory focused-test checkpoint. Rasengan runs as phase two of ren, commits nothing, pushes nothing, and never expands authoring into the full regression suite or coverage.
Install
npx skillscat add zheref/hatsu/rasengan 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.
Rasengan — the change itself, spun up on the repository's own stack
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 repositoriesnen repo classifyreports asrole: canon(nen/repos.json→maintained_tools), whose product is the process — andG2
(CON-5) in a consumer repository, where anen/contract.json,nen/workflow.jsonornen/gates.jsonis 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 isen§ 5's
either way — the ruling moves the gate, never the owner.
Nature: Enhancer carries the ordinary run — rasengan writes the code that answers the request.
The mode follows the request, exactly as `hatsu:ren`'s does: Conjurer where the
request is canon or governance, Transmuter where it is machinery. Name the mode in play, say when
it switches and why, and never blend two under one header (claude/agents/kurapika.md).
Read what I actually asked for, work out how this repository does that kind of thing, and write
it — keeping your own build honest as you go.
Rasengan is automatic: phase two of ren, taken on the branch `hatsu:breath`
cut and proved, and handed to `hatsu:kokusen` when the tree is finished. It is
human-called only to resume authoring on an effort that is already warm. It never commits and it
never pushes.
The ruling of 2026-09-10 — rasengan AUTHORS; it is not "compile before commit"
The maintainer's ruling, recorded in `docs/ROSTER.md`
§ Rulings of 2026-09-10: rasengan is the authoring phase — Kurapika builds the code that
answers the request, on the repository's stack. Build in this skill's name always meant build
the thing, and this file used to read it as run the build command.The compile-before-commit did not disappear; it moved to the phase that stages the tree.
`hatsu:kokusen` § 3 runs the declarediteration.checksover the finished
tree and refuses to commit on red, and `hatsu:breath` § 6 proves the base
tip before a line is written. What stays here is the inner loop — the same checks, run as the
author's own feedback while the change is being written, which is a different thing done for a
different reason: one tells you whether what you just wrote works, the other decides whether the
repository's history is allowed to record it. This file expands the earlier reading rather than
deleting its evidence: §§ 5–10 are the same verbs, the same exit table and the same transcripts,
now seated in the loop they belong to.
0. Standalone entry — rasengan is deliberately caller-bound
Rasengan is the one phase `docs/STANDALONE-ENTRY.md` § 4 names as bound to a caller by contract rather than by
oversight, and the reason is in § 1: rasengan authors the change the request asks for. The request is
the input. There is no version of this skill that derives what to build from a checkout, and a phase that
invented one would be guessing at the only thing in the turn that cannot be guessed.
So typed alone, it is not refused — it is completed. hatsu:rasengan <what to author> carries its own
request and runs exactly as ren step 2 does. A bare hatsu:rasengan has nothing to author: ask for
the request through the surface's own picker or in one line, and never infer it from the last thing
the session was doing (ren § 1's rule, for the same reason).
Two clauses of the contract apply. P1 — `hatsu:ten rasengan`, ten § 6 catching up the fresh base and effort branch — and,
where no `hatsu:breath` ran, say so: authoring onto an unverified base is the
one ordering relation ren § 2 names first, and a red base discovered later reads as this change's fault.
Offer breath; it will read work-in-progress as a continuation and cut nothing.
It still commits nothing and pushes nothing — `hatsu:kokusen` holds the index —
and its inner-loop checks are still the author's own feedback, never the commit gate.
Hand-back. Next in the wired run: hatsu:kokusen — verify the finished tree and commit it.
Nothing here is staged, and the inner-loop checks are not the commit gate.
1. What rasengan is
The one step of a turn whose shape comes from the request rather than from the workflow. Every
other phase of ren does the same thing on every turn; this one does whatever was asked. It is
therefore the only phase with no fixed procedure for what to write — and the procedure below is
about how to arrive at it honestly, not about what the answer is.
Four things make an authored change this repository's rather than a plausible one:
- The request, read as asked. Not the nearest familiar problem, not the larger refactor it
suggests. Where the request is genuinely ambiguous, ask once through Crazy Slots with the readings as the options (nen/decisions.jsonrowambiguous-intent) — an assumption written into code is an
assumption nobody reviewed. - The stack, resolved rather than assumed.
nen/contract.json→project.lanes.<lane>.stack
says what this repository is;project.verbs.<lane>says what it runs. A change written in the
idiom of the last repository the session was in is a change the reviewers will spend their
attention on for the wrong reason. - The repository's own conventions, read off the tree. Where the tests live, how the changelog
is kept, what the neighbouring file already does. These are not in either configuration file, and
no verb hands them out: reading them is this phase's work (§ 11). - An inner loop that is honest. The declared inexpensive checks are run while authoring. When
executable behavior changed and the repository has an explicit lane whosetestrow scopes the
authored behavior, rasengan may runnen shu test --lane <scoped-lane>for feedback too. This is
useful feedback, never the mandatory checkpoint and never the full regression or coverage gate.
The gate is somebody else's. Rasengan's green is a working answer, not a verdict:
`hatsu:kokusen` re-runs the checks over the tree it is about to stage, and
that run is what a commit rests on (§ 10).
2. Invocation, and the inputs
hatsu:rasengan [--lane <lane>]--lane overrides nen/workflow.json → iteration.lane for one run — for a repository whose second
lane is the one this effort touches. With neither, the lane is the declaration's ownproject.defaultLane, and a declaration whose defaultLane is null makes --lane required (nen's
own rule, not this skill's).
| Input | Where it comes from |
|---|---|
| The request | the maintainer's own words, this turn. hatsu:ren § 1 captured them through nen parse ren --grammar; a turn with no request is refused there, never inferred here |
| The branch to write on | the one `hatsu:breath` cut for this effort, from origin/<branch.base>'s freshly fetched tip, with the declared checks already proved green on it (§ 6 there). Rasengan cuts nothing and switches nothing |
| The lane, and the stack it names | nen/workflow.json → iteration.lane; nen/contract.json → project.lanes.<lane>.stack, .cwd |
| Which checks are the inner loop | nen/workflow.json → iteration.checks |
| What each check actually runs | nen/contract.json → project.verbs.<lane>.<check> ({exe, argv}, {steps:[…]} or {unsupported:"why"}) |
| Where they run, and with what | project.lanes.<lane>.cwd, the row's env (names only) and artifacts |
| Whether this host may | nen/contract.json → project.hosts |
| What must be true first | nen/contract.json → project.preconditions (nen asserts these and never performs them) |
| The repository's own conventions | the tree itself — no verb hands these out (§ 11) |
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 them:iteration.checks = ["build"], iteration.lane = project.defaultLane. iteration.checks namesshu verbs (build, test, lint, ui-test, coverage), never tool names: a repository that
calls its type-check build has said so in its declaration, and rasengan runs the declaration.
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
lane or verb in nen/contract.json through nen scaffold init. The request is the maintainer's
word: never derived (§ 0).
3. The protocol — understand, plan, implement, self-check, hand over
1 · Understand. Restate the request in one sentence before touching a file, and name what it does
not cover. Read the code the change lands in — the neighbouring file, the test beside it, the
declaration for the lane — before deciding the shape. A change designed from the request alone is
designed against a repository nobody looked at.
2 · Plan. Say, in the reply, which files this will touch and why, and what the change owes the
repository besides the edit itself: the test beside it, the changelog fragment, the doc that would
otherwise go stale. Where the plan grows past the request, that growth is named and offered, never
taken (§ 4).
3 · Implement. On the branch breath cut, in the repository's own idiom, with the tests written
beside the code rather than after it. One coherent step at a time: a turn that does two separable
things hands two commits to kokusen, and the boundary between them is decided here, while the work
is in front of you.
4 · Self-check — the inner loop. Run the declared iteration.checks for the lane, as your own
feedback, as often as the work wants them:
nen shu <check> --repo <path> [--lane <lane>] # one call per iteration.checks entry, in order<check> is whatever iteration.checks lists, and nothing else. On this repository that is["lint"] alone, and the plugin lane seats build: an inner loop that reached for build
because a build is what an author expects would be running a verb the policy did not ask for and the
lane says it does not have. §§ 5–9 are the whole of how those runs are read. Red is not a stop here — it is the loop working.
Fix what it named and run it again; that is what the inner loop is for. What is never done is
softening the check so it stops saying so (§ 4).
For changed executable behavior, also identify the smallest repository-declared lane whose test
row exercises that behavior and run it through `hatsu:tsukuyomi`. A lane is scoped by its declared argv; Nen supports the route as:
nen shu test --repo <path> --lane <explicit-scoped-lane> [--dry-run]There is no --scope selector and iteration.checks does not name a second, checkpoint-only list.
Never infer a lane from its name. Read its declaration and confirm the argv is focused. Rasengan may
execute this route for feedback. If no unambiguous scoped lane exists, record the missing declaration
or Nen capability for kokusen; do not type a raw runner command and do not substitute the full suite.
Prose-only, data-only, or other non-executable changes with no relevant runnable behavior reportfocused tests: not applicable with that reason; Hatsu's own Markdown-only changes are this case.
5 · Hand over. Rasengan ends by handing `hatsu:kokusen` a tree that is
finished and, so far as this loop can tell, green — and by saying what it changed and what it
deliberately left alone. Kokusen verifies it again before it stages anything (§ 10), because the
tree that is committed must be the tree that was proved, and only the phase holding the index can
know that.
Iterating is the ordinary shape. Movements 3 and 4 alternate for as long as the work takes; the
last thing to happen before the hand-over is a green movement 4 over the finished edit.
4. What rasengan never does
- Never commits and never pushes. The commit is `hatsu:kokusen`'s and the
push is `hatsu:aka`'s, which is the maintainer's own call. Authoring produces a
working copy and nothing else. - Never edits outside the request's scope. The tidy-up two directories away, the rename that
would be nicer, the dependency bump the build hinted at — each is named in the reply and offered as
its own effort. A change that is bigger than the request is a change the maintainer did not agree
to review. - Never lowers a bar to make a check pass. Not by narrowing the check, not by deleting the
assertion, not by declaring a seat where a real row failed, not by dropping a coverage threshold or
patching a test to be green. A bar that moved because the code could not clear it is a bar that no
longer measures anything (`hatsu:byakugan` for the coverage
ladder, `hatsu:gyo` for lint, and `hatsu:tsukuyomi`
hold the same rule for their own bars). - Never edits a declaration on the fly.
nen/contract.jsonandnen/workflow.jsonare the
repository's policy: a wrong row is a PR of its own at the declaration gate (G4 in a canon repository, G2 in a consumer one), not a local edit left in the checkout —
unless the declaration is what the request asked to change, and then it is the change and it is
reviewed as one. - Never cuts or switches a branch. That is breath's, once per effort.
- Never runs a build, test or lint from a remembered command line in a repository that declares
one (§ 5). - Never runs the full regression suite or coverage. Impacted unit, UI and integration tests
belong to `hatsu:kotoamatsukami` at
`hatsu:mukai`. Capture, measurement and gating belong to
`hatsu:byakugan`, also at mukai. Linting is `hatsu:gyo`,
on every Ren turn — whenlintis initeration.checks, that entry is gyo. Focused tests belong
to `hatsu:tsukuyomi`.
5. The inner loop's checks, and where they come from
Every entry of iteration.checks, in the order the file lists them, stopping at the first
non-zero that is not a seat:
nen shu build --repo <path> [--lane <lane>]
nen shu test --repo <path> [--lane <lane>]
nen shu lint --repo <path> [--lane <lane>]Never the tool's own command line typed from memory — that is the standing transmutation
(claude/agents/kurapika.md § Transmuter), and a remembered command line is how a build that passes
here fails in CI.
The dry run, once, on a repository you have not built:
nen shu <check> --repo <path> [--lane <lane>] --dry-runIt prints the exact argv, the cwd, the env names and the declared artifacts, and spawns nothing —
"the argv printed is the argv that would be spawned, from the same rendering: the thing you approve
is the thing that runs." Do this once per repository per session, on the first check of the run;
after that, run them bare. It is also the only honest way to show a maintainer what a check is about
to do without doing it.
5a. Containment — the path the kernel would reach, not the one the file spells
From nen 0.6.0 every declared path a run reads or writes is contained against the repository's
REAL root, symlinks resolved, at the moment of use — project.lanes.<lane>.cwd, a path
precondition, every artifacts[i], a launch target's artifact, a step's stdoutTo, and the
coverage and test reports shu coverage / shu test-report read back. Verified live at exit 2
before anything was spawned (docs/ab/rasengan.md § Retired at nen 0.6):
nen shu: project.lanes.a.cwd names 'build', which really resolves to '<outside>', outside the repository
at <repo>: '<repo>/build' is a symlink pointing at '<outside>'. nen touches only what its report says it
touches, so this path is refused rather than followed. # exit 2Through v0.5.0 the test was lexical: build/payload read as plainly inside the tree and walked
straight out of it whenever build/ was a symlink, and --dry-run reported ok about every one of
those paths. A symlink that stays inside the tree is ordinary and still allowed — the question is
where the path lands, never whether a link was involved.
nen schema checkis deliberately silent about it, and a clean row is NOT a containment
verdict. The loader has no filesystem, so acwdof../../../../etcreads as a well-formed
declaration and is refused at the moment of use instead: pointers are checked at load, paths at
use (verified — the symlinked fixture above reportsok nen/contract.json). Never report a greenschema checkas evidence that a declaration's paths are contained.
6. The exit table — one reaction per code
claude/agents/kurapika.md § The shu verbs is the authority; this is what rasengan does with each
inside its own loop. `hatsu:kokusen` § 3 reads the same table at the gate, and
differs in exactly one row — a 1 there ends the commit rather than the edit.
| Exit | Fact | Reaction |
|---|---|---|
0 |
the declared step ran and passed (or the dry run rendered) | next check; when the list is exhausted, keep authoring or hand over (§ 3) |
1 |
the ordinary red build — the tool ran and failed; its own code is in steps[].exitCode, nen's is always 1 |
This is the loop working. Relay the tool's own output, name the failing step (step N of M), fix the code, run it again. Never soften the check (§ 4), and never hand a red tree to kokusen (§ 10) |
1 |
also: nen/contract.json is present and malformed |
a repository defect, not a red build. The refusal names the file and the pointer — fix the declaration, and land it as machinery at the declaration gate (G4 in a canon repository, G2 in a consumer one) where it is not this effort's own file |
2 |
usage: no declaration, no project block, an unknown --lane, an unsubstituted placeholder, a path that really lands outside the repo (§ 5a), or an unsatisfied precondition |
fix the invocation or the declaration — a missing one asked for and set up inline (§ 2, § 7), never the end of the turn. A precondition is nen's to assert and never to perform: satisfy it yourself and say which one it was. § 7 covers the no-declaration case |
3 |
unsupported host — the verb is real, this machine is not on project.hosts |
G5. Name the host the declaration allows and stop; never retry, never route around it. Authoring cannot proceed on a host that cannot check it |
4 |
a seat — the lane declares no such verb, in the declaration's own words | Not a failure and not red. Quote the seat's reason verbatim, run the repository's own documented command for that check, say that you did — and where the seat should be a real row, land the declaration change as its own PR at the declaration gate (G4 in a canon repository, G2 in a consumer one) |
5 |
the declared program could not be started at all | run nen shu tools --repo <path> and relay its per-tool remedy; --install for what corepack can activate, a human for the rest. Never sudo, never a version the declaration did not pin |
7. A repository that declares nothing
Exit 2 naming the file: "no such file: <path>/nen/contract.json. 'nen shu' runs what a repository
DECLARES … and this repository declares nothing" (verified live against the zheref/nen checkout —docs/ab/rasengan.md § 2.4). That exit is the trigger to set the declaration up, not the end
(missing-configuration): say plainly that no declaration exists yet, offer the project blocknen scaffold init detects, starred, validate it with nen schema check and resume the loop in the
same turn — the file riding this effort's branch, or its own PR at the declaration gate (G4
in a canon repository, G2 in a consumer one) when it is not this effort's. Where the maintainer
picks running once without it, run the repository's own documented commands and name the gap in
Not delivered.
Read the no-declaration fact off build/test/lint, never off detect. nen shu detect
answers a different question — whether a marker on disk proposes a lane — and the two do not track
each other. Verified live in both directions (docs/ab/rasengan.md §§ 2.4–2.6): the zheref/nen
checkout is detect exit 1 and shu build exit 2, while a fixture carrying a complete,
working project block is also detect exit 1 ("no lane detected … declaration: … (present --
--write will refuse)") with shu build at exit 0. A skill that read detect would have called a
fully declared repository undeclared.
8. Preconditions, hosts and placeholders are the declaration's, not yours
- A precondition nen cannot assert — an unknown kind, or an assertable kind handed a list — is
refused rather than skipped: an unperformed check is never rendered as a clean one. Relay that
refusal; do not "check it another way." - A host row excludes this machine at exit
3. That is a G5, not a retry. - An unsubstituted placeholder is exit
2. Fill it in the declaration, not on the command line.
9. Long-running checks, and the stall guard the declaration owns
A captured verb may declare a stall guard, and at the pinned build nen runs the repository's
own remedy. The shape is "stall": { "elapsedMs", "quietMs", "onStall": { "exe", "argv" }, "maxStrikes" }, on an invocation or on one steps[] entry; it fires only once both budgets are
past — total elapsed and a quiet window with no output — because a guard acting on silence alone
would fire at a healthy build that went quiet early. Verified live at v0.5.0 against a declared
guard: --dry-run prints on stall: after 60000ms elapsed AND 30000ms with no output: sh -c 'echo kill' (up to 2 times) and the real run reports the same line, exit 0.
Read what nen does and does not do here. It never signals the child it started, at any strike
count: after maxStrikes the step is reported stalled at exit 1 with exitCode: null, nen
releases its hold and says the process is still running and is the caller's to stop. A guard is
declarable only where nen READS the output — build, test, ui-test, lint, archive,coverage, test-report; on dev/run/release/deploy it is exit 2 naming the set.
Residue: whether a lane declares one is the repository's business, not this skill's. Where a lane
declares no stall, a check that hangs still hangs and nothing times it out — watch the step, run
the declaration's prose remedy by hand, and say that you ran it by hand (§ 11). Never background
a check to escape a stall; a check nobody watched is a check nobody ran.
10. What "green" means in the inner loop — and whose the commit gate is
The inner loop's green is the author's, and it is worth exactly what it says: the tree worked a
moment ago. At the pinned build that is a FILE as well as a transcript — a greennen shu build writes .nen/proof/<lane>.json (nen.shu.proof/v0.1: contract, lane, verb,treeHash, at, exitCode) and a red one removes an existing file, so a stale proof never
outlives the tree it proved. Verified live at v0.5.0: the run's report carriesproof: .nen/proof/app.json tree c5b72124… at 2026-09-10T09:09:52.482Z, exit 0, and the file on
disk holds exactly those fields.
treeHash is git's tree object for the WORKING COPY, not the index — computed through a scratch
index under .nen/, so the repository's own index is never read or written and no ref moves. That is
what makes it cheap enough for the phase that stages to re-check a moment before committing.
So the proof is the handshake between this phase and the next, and the GATE is the next one's.
Say the checks were green in this turn and name the proof file; never "the build is green" as a
standing property, because the file's whole point is that it stops being true the moment the tree
moves — and between the inner loop's last run and the commit, the tree moves whenever the author
writes one more line. `hatsu:kokusen` § 3 runs the declared checks again over
the finished tree, and reads nen commit check --repo <path> --require-proof <lane> back only
where build is one of those checks and came back green — the proof is written by nen shu build
and by nothing else. That run is what a commit rests on.
A red tree is never handed over, never committed over, and never worked around. Not by narrowing
the check, not by handing it on "so the fix is on the branch", not by declaring a seat where a real
row failed. The one exception is a code 3 host fact and a code 4 seat, both of which are facts
about the repository that rasengan quotes and hands upward. A red check the turn cannot honestly
clear is a G5 stop for the phase that called this one — which is the same escalation kokusen raises at the
gate, from the same fact.
11. Residue — what has no verb at the pinned build
- The authoring itself. No verb writes a change: reading the request, reading the tree's own
conventions, choosing the shape, and writing the code and the tests beside it are this phase's
work end to end, and that is a boundary rather than a gap to file — nen owns operations, the
same way `hatsu:ren`'s Residue says it does not own conversations. Every
deterministic step inside the loop is still a verb: §§ 5–9 arenen shu build/test/lintandnen shu tools, and § 10's proof isnen shu build's own file. - Reading the repository's conventions — where tests live, how the changelog is kept, what the
neighbouring file already does.nen/contract.jsonsays what runs, not how this repository writes;
no verb answers the second question and none is asked to. - RETIRED at nen
0.5: build proof.nen shu buildwrites.nen/proof/<lane>.jsonon green and
removes it on red, andnen commit check --require-proof <lane>reads it back (§ 10, both verified
live, exit0). A repository that does not ignore.nen/will see the file ingit status. - RETIRED at nen
0.5: the stall guard (§ 9) — a declaredstallblock is nen's to run. What
stays this skill's is watching a lane that declares none, and running that declaration's prose
remedy by hand, named. - RETIRED at nen
0.5: validatingnen/workflow.json.nen schema checkcarries the row.
Readingiteration.checksis still this skill's (see `hatsu:breath` § 2),
and a read is not a residue. - A per-run log file.
log:reports "not captured to a file … A.nen/logs/transcript is not in
this release (zheref/nen#91)" — each step's output is relayed as it finishes, so the turn's report
is the only record. Quote what matters; do not claim a log exists. - Counting anything inside the output — how many tests, how many warnings — is
`hatsu:tsukuyomi`'s residue and its problem, not this skill's; the inner
loop reports exit codes.
12. Authority
- Permitted: write, edit and delete files in the effort's own working copy, within the request's
scope; run declared inexpensive iteration checks and an explicitly scopedtestlane for feedback; probe
the host throughnen shu tools; report every code. - Not permitted: commit, push, label, open or touch a PR, deploy, cut or switch a branch, or edit
a declaration on the fly. A declaration that is wrong is a PR of its own at the declaration gate (G4 in a canon repository, G2 in a consumer one), not a local edit
left in the checkout. - Not a gate event, with two exceptions it raises rather than owns: exit
3(unsupported host)
and a red check it cannot honestly clear in-session are G5 stops for the phase that called it.
13. Hard limits
- Never commits, never pushes — the tree is the whole of what this phase produces (§ 4).
- Never edits outside the request's scope, and never folds a second effort into this one.
- Never lowers a bar to make a check pass — not the check, not the assertion, not the threshold,
not the test (§ 4). - Never runs a build, test or lint from a remembered command line in a repository that declares one.
- Never hands a red tree to `hatsu:kokusen`, and never asks for one to be
committed "so it is saved". - Never reads the no-declaration fact off
nen shu detect(§ 7) — that is a different question,
and it answers1for repositories that build perfectly well. - Never treats exit
4as a failure or exit5as a red build. A seat is the repository speaking;
a missing program is a host that is not set up. - Never retries an exit
3, on any host, for any reason. - Never claims a check ran that it dry-ran, and never claims one passed whose exit code it did not
read. - Never claims its own green is the commit's — the gate re-runs the checks over the tree it stages
(§ 10). - Never substitutes a full-suite
test,ui-test, orcoveragerow for a missing scoped-test
declaration. Name the missing route and hand it to kokusen.
Reusable focused selection dependency
Nen #207 owns reusable dynamic test selection.
At Nen 0.8.0 a static explicitly declared focused lane is available, but there is no test-selector
passthrough. Use actual runner identifiers and separate focused artifacts; do not treat a probe-only
Python lane as focused tests for Swift behavior. One permanent lane per ad hoc selection or copied
consumer selection scripts is not the shared solution. Until that capability is released/adopted,
a missing applicable focused path remains an owned dependency, never a full-suite substitution.