<!-- [doc->REQ-LIAISON] -->
# Liaison playbook

How to run a Liaison: a dedicated endpoint that accepts Requests submitted in
conversation and mints them into a Project's Requests Hub. One per Project at
most, and optional (CONTEXT "Liaison"). A Liaison is typically
tool-restricted — it drives Alchemy exclusively through `#< … #>` Request tags
written in its own turns (CONTEXT "Request tag"), which its shell instance
reads out of its session digest and acts on.

## Standing up

1. **Spawn your shell instance**: `spt shell spawn alchemy`. You get a
   canonical id (`alchemy-<n>`); everything below assumes `alchemy-1`.
2. **Bind the Project's repo**: `spt shell cmd alchemy-1 bind-repo
   BigscreenVR/spt-progress-tool` (the node's GitHub credential chain is the
   shell's problem, not yours).
3. **Arm the scanner**. The shell learns who its owner is from the first
   drive frame — the bind in step 2 already did that. From then on it scans
   your digest every few seconds. The first scan baselines at your digest's
   current tip: nothing you wrote *before* arming ever fires.
4. **Smoke-test**: write a read tag in your own turn — e.g. `#&lt;` `list`
   `#&gt;` without the quoting — and the shell answers over `spt send` within
   a few seconds. (This document spells tags in backticks precisely so THIS
   file never fires one: a tag inside backticks or a code block is a
   quotation and never acts.)

If you run more than one instance, address every write to one of them with a
leading `@<instance-id>` (`@alchemy-1 create …`) — every instance you own
scans the same digest, and a bare write would fire on each.

## Accepting a submission

A submitter (any endpoint, or the Operator) messages you a request in plain
conversation. Your job:

1. **Shape it**: settle the type (`bugfix` / `change` / `addition` /
   `feature` / `idea`), a crisp title, and enough body to act on. Ask the
   submitter what's missing; don't mint noise.
2. **Mint it** with a create tag in your own turn — attribute the submitter
   in the body, because the issue's Requester footer names *you* (the shell's
   owner), not them:

   ```
   #< create --type bugfix
   Title on this line
   Body from here.

   Submitted by: <submitter-endpoint> #>
   ```

   **Mint and then wait — that is all.** The scanner acts on a turn once it is
   sealed, and going idle seals it, so a tag you write and then stop on fires on
   its own within a scan interval. You do not need to manufacture a follow-up
   action to shake it loose. (Requires spt-core 0.42.0 or newer, where a
   finished turn is readable as soon as the endpoint goes idle; before that a
   completed turn stayed `partial` until its next prompt and minting-then-idling
   deadlocked.)

3. **Register their Watch** so they hear when it progresses, without them
   doing anything: `watch #N --for <submitter-endpoint>` (as a tag or a
   drive). The Watch's owner is the submitter — fires land on *their* perch
   as durable spt messages from the Hub Daemon.
4. **Answer the submitter** with the minted issue number and link (the
   shell's reply to your tag carries both).

An `idea` always mints flagged Needs Operator — tell the submitter it awaits
the Operator's eye, not a build queue.

## Destructive asks

`state … cut`, `state … shelved`, `milestone remove`, and `unwatch` never
fire straight from a tag. The shell parks the call and messages you a confirm
token; the call runs only when you write the pre-addressed confirm tag it
hands you, within 24 hours. Relay the consequence honestly to the submitter
("declined and shelved", not "deleted") and only confirm what you actually
mean — an expired confirm reports itself and nothing runs.

## Rules of the road

- **One Liaison per Project, at most.** You are the funnel, not a gate: reads
  are open to everyone, and any endpoint may still submit directly through
  its own shell.
- **Never write to a foreign repo.** Your instance is bound to your Project;
  cross-Project interest is a `watch` on a qualified ref, never a write
  (ADR-0003).
- **Quotation discipline**: when *discussing* a tag rather than firing it,
  keep it in backticks or a code block.
- **Missed-rows notice**: if the shell tells you its cursor fell behind the
  digest window ("tags issued in the gap may have been missed"), re-issue
  anything unanswered — the shell never silently drops or double-fires.
