zheref

jujutsu

Pair a new device with this machine and register it as a named launch target, once — walk the maintainer through the on-device steps, verify with the platform's own probe, then write the target into nen/contract.json and open the declaration PR at its repository's own gate. Use when the maintainer invokes hatsu:jujutsu pair <device>, asks to set up a new phone, tablet, simulator or desktop target, or when hatsu:amaterasu reports a launch target this machine cannot resolve. It never taps a trust prompt, never changes a security setting and never merges the declaration PR.

zheref 0 Updated 4w ago
GitHub

Install

npx skillscat add zheref/hatsu/jujutsu

Install via the SkillsCat registry.

SKILL.md

Jujutsu — the device, bound to the declaration

Nature: Transmuter. The output is a project.launch block in nen/contract.json.

Get this device paired, prove it with the probe, and write it into the declaration through a PR —
once, so nobody has to again.

Jujutsu runs once per device. Half of it is not an agent's to do: trusting a computer,
enabling Developer Mode and accepting an RSA fingerprint are acts on the device's own screen, by the
person holding it — the security boundary that makes a paired device mean anything. Jujutsu probes
read-only, writes one JSON block, and opens a pull request.

Every declaration rule it writes is `docs/LAUNCH-MIGRATION.md`
§ Launch declaration rules
. The gate is the repository's role, usually G2 here
(PROCESS.md § Authority every phase shares, which also resolves the
plugin root): resolve the target repository first and say which gate you stand at.

1. Invocation

hatsu:jujutsu pair <device>
nen parse jujutsu --grammar "pair <device>" --line "<the invocation, minus the prefix>"

<device> is required and never defaulted — registered under the wrong name, a target resolves to
somebody else's phone. It is the maintainer's word, typed, never picked (missing-maintainer-choice;
`WORKFLOW.md` § 4): a bare pair (nen parse exit 2) asks for it as
free text, the probe's rows listed for reference, none starred and none a picker option. Other gaps
are missing-configuration. The name typed is
provisional
: the declaration gets the name the probe prints, byte for byte.

2. Once per device — check before pairing anything

Read nen/contract.json → project.launch — the keys and each one's device.name.

State What jujutsu does
a key and the probe resolves it Say so and stop, naming the key
a key, the probe does not resolve it A connection problem, not pairing — report what the probe did see (§ 4), stop
a key, the probe sees it present but not usable An on-device step — name the state, quote the probe, say which § 3 step closes it, stop
not a key § 3

Pairing twice is not usefully idempotent: a second key for the same hardware leaves two targets on
one phone, and neither name means anything.

3. The pairing walk-through — the maintainer's hands, not this skill's

Present one platform's list, then wait, saying what the next probe shows once it has worked.

iOS / iPadOS. 1 · Connect by cable (Wi-Fi pairing only after the first cable pairing). 2 ·
Unlock and tap Trust This Computer on the device's prompt, then enter the passcode. 3 ·
Enable Developer Mode (Settings → Privacy & Security); the device restarts and asks again —
confirm there too. 4 · Say when all three are done.

Android. 1 · Enable Developer options: Settings → About phone → tap Build number seven
times. 2 · Enable USB debugging there. 3 · Connect by cable and accept Allow USB
debugging?
showing this computer's RSA key fingerprint, ticking Always allow from this
computer
. 4 · Wireless debugging, optional and only after step 3 worked over the cable: adb pair <host>:<port> with the six-digit code, then adb connect <host>:<debug-port> — the pairing and
connect ports differ
. 5 · Say when it is done.

Jujutsu performs none of the above — a rule, not a limitation: those prompts exist so that a
human looked at them. It never enters a passcode, accepts a trust or debugging
prompt, or toggles a security setting
(§ Authority) — a step that seems to need something turned
off is a finding to report (row on-device-act). And the waiting is not a
loop
: nen parse izanami classifies both probes [unknown] and refuses the run at exit 1, so
jujutsu asks, waits for the maintainer's word, and probes once.

4. Verify with the probe — and read the state, not just the presence

xcrun devicectl list devices  # iOS; --json-output <path> for the machine-readable form
adb devices -l                # Android; the state is the SECOND column

Which states register, which are present-but-unusable and which absent is
LAUNCH-MIGRATION § The probe's states, and the third
outcome
.
At pairing time there is no declaration yet, so reading the state is THIS SKILL'S —
readyWhen is what it is about to write.

  • Refuse to register it, saying "<name> is attached and unauthorized; the probe
    saw: <the whole list>"
    — and say which of § 3's steps closes it.
  • Never register it anyway "so the declaration is ready": a target written from a row nothing can
    talk to resolves at run time, reports itself resolved, and fails in an after step.
  • Never fall through to the "absent" branch (its remedy is the cable, not a tap); when the probe
    does not see it at all, report what it did see
    — the whole list.
  • The first probe is the platform's documented command, named as such: device.resolve is what
    jujutsu writes, so the argv typed here goes into the declaration, and later runs read it from the
    file, never retyped.

Delivery is proved, not assumed. Register a lane that actually builds for the target's declared
platform
, a matching artifact path and the install/launch steps it needs, then prove the whole
target through its declared dev/run verb with --repo <core-checkout> --target <declared-target>
: pairing, probe, dry run and build are intermediate outcomes, and a validation
the absent device cannot finish leaves registration unverified for delivery, never a launch. A reusable missing capability goes through
the discovery protocol and upstream
(nen#204).

5. The name is bytes, and it is copied, never retyped

device.name is matched byte for byte (LAUNCH-MIGRATION), so Sergio’s iPhone Pro carries
U+2019, three bytes, not a keyboard's ASCII ' — and a terminal may render it Sergio?s iPhone Pro. Neither the rendered nor the typed form is the name: copy the bytes out of the probe's JSON,
and where a name carries anything non-ASCII, say so in the PR body so nobody "fixes" it.

6. Register it — one project.launch key, then the declaration PR

The block's shape and every rule for filling it are LAUNCH-MIGRATION
§ The canonical block
. This skill's part: it writes readyWhen every time — a target with no
readiness rule is one it has not finished writing — and the PR body says which states the rule
admits and which the probe offered
, pasting the probe's object and naming the key it took.

Prove the file first with nen schema check --repo <path>: a misspelt key is refused by
pointer
, but ok says only that the block parses, never that the target works. What says it
works is § 4's probe resolving the name, run and shown, and — once on main — nen shu dev --repo <path> --target <name> --dry-run.

Then the PR, at the declaration gate: `aka` publishes on the maintainer's call
and `mukai` opens it; jujutsu writes the block, states the gate, never
merges
. The body names the device, the target key, what the probe printed, whether launch.default
changed, and that a non-ASCII name was copied.

7. Simulators, the Mac desktop, and the report

Nothing to pair, and that is why they come through here: one path, one set of rules — forms in
LAUNCH-MIGRATION's canonical block, the schema check and the declaration PR all the same, because
skipping the PR for "no pairing" is how a declaration gains an entry nobody reviewed.

The report is one line, then the block: the device as the probe named it, its state quoted from
the probe's column
, the target key, the resolve argv, whether launch.default moved, the PR's
gate. A run stopped at § 2 or § 4 reports that, with the probe's full output and the on-device step
that closes it.

Residue

The pairing steps have no verb and never will — a boundary, not a gap; waiting has no loop
primitive
, so jujutsu asks and waits. The first probe is the platform's documented command,
named every run, and its state column is read by eye (no target exists yet); at launch the
state is nen's, through the readyWhen written here.

Authority and hard limits

  • Permitted: read-only device probes; reading nen/contract.json and nen/workflow.json; writing
    a project.launch block and, on the maintainer's word, launch.default/launch.fallback; nen schema check; committing that change on a branch.
  • Not permitted: any on-device step; installing anything; merging the PR. It carries no
    delegation
    ; reached from `amaterasu`'s failure path, it borrows none.
  • Never taps, confirms or bypasses a trust, pairing, Developer-Mode or USB-debugging prompt, never
    changes a security setting or asks the maintainer to disable one (row on-device-act), and never enters a
    passcode, PIN, password or any credential
    , anywhere, for any reason.
  • Never registers a device it has not seen the probe resolve, one whose row is present but not in
    a usable state, or one without a readyWhen rule; never reports a present-but-unusable device
    as absent
    ; and never retypes a device name (§ 5).
  • Never writes an install or a launch into the target's verb, never appends a second -scheme
    through args, and never writes a UDID, serial or hardware identifier into the declaration.
  • Never reports nen schema check's ok as evidence the target works.
  • Never registers a second target for a device that already has one, and never changes
    launch.default silently.
  • Never merges the declaration PR — G4 in a canon repository, G2 in a consumer one, both the
    maintainer's
    : the gate moves with the repository, the prohibition does not.
  • Never polls for the device on a timer, or presents a by-hand probe as a verb's output.