# /sptc:knock — operative instructions

Manage **access control**: who may reach this endpoint, and which endpoints will have you. A knock
asks the *other* endpoint for a grant over named control surfaces — `MSG` (direct messages),
`RC_VIEW` / `RC_ATTACH` (terminal viewing and control), and the rest. This is NOT `/sptc:subnet`:
the subnet pairs *machines* into one network; a knock grants reach between *endpoints*.

Match the user's intent to a verb (full guidance: `spt knock --help`):

- **Ask someone to let you reach them:** `spt knock <target>` — the bare form is `send`. It asks for
  `MSG` by default; add `--surfaces <S1,S2|ALL>` only if you need more. **A directionality flag is
  required — see below.**
- **See what is waiting for you:** `spt knock list` — shows each pending knock and its id.
- **Answer one:** `spt knock approve <id>` or `spt knock deny <id>`. `--approve-requested` grants
  exactly what was asked for.
- **Hand out an invite:** `spt knock new-code [--surfaces …] [--subnet NAME[,NAME…]]` mints a code;
  whoever redeems it gets the named surfaces. **A code is sealed to subnets**: omit `--subnet` and it
  seals to *every* subnet you belong to (the default); name them — a comma list, or the flag repeated
  — to narrow it. A redeemer must share one of the sealed subnets to read the code's route at all, so
  naming subnets restricts who can redeem, it does not merely label the code.
- **Present a code you were given:** `spt knock redeem <code>` — **also takes the directionality
  flag**, because redeeming is you doing the asking.

## Directionality — CHECK YOUR BUILD, the spelling changed and there are no aliases

Which way reach runs is always chosen by the **asking** side. spt-core **0.54.0 renamed the flags and
moved where they are allowed**, with *no* deprecation aliases in either direction — so the wrong
spelling is a hard parse error, not a warning. **Run `spt knock --help` and use what it lists.**

| | spt-core **≥ 0.54.0** | **before 0.54.0** |
|---|---|---|
| `send` / `redeem` | `--send-receive` (pre-authorize the reverse) or `--send-only` (decline it, on the record). **Required — no default; a bare invocation refuses and names both.** | `--mutual` (reach becomes two-way when they answer) or `--one-way`. Optional on `send`. |
| `approve` | **Takes no directionality flag at all.** | Must say which way reach runs: `--mutual` or `--one-way`. |
| `new-code` | No directionality flag. | No directionality flag. |

<!-- [doc->REQ-KNOCK-DIRECTIONALITY-TAUGHT] -->
**What `--send-only` does not bar: replies.** Declining the reverse direction does not silence the
other endpoint — a reply correlated to your own outbound is admitted with no rule of its own. That is
the general access contract (the reply/outbound exemption precedes rules, modes and the rule store),
not an engine-room quirk; the docs state it under *networking → knocking → "Two-way reach is offered,
never imposed"*. Teach it as **they can answer what you send** — never as "messaging someone once
opens a permanent back-channel". The correlation bound is real; its width is implementation detail,
so do not quote a number for it.

The behavioural change behind the rename: on **≥ 0.54.0 the counter-knock on `approve` is REMOVED,
not renamed**. Approving grants what was asked and opens nothing in the reverse direction — **to reach
someone you approved, knock BACK.** Pre-authorizations armed under the old flags are untouched and
still honored, so nothing you granted before stops working.

If you are scripting against `spt knock list --json`, note the `mutual` key is renamed `send_receive`
on ≥ 0.54.0. That break is **silent** — a reader of the old key gets nothing back rather than an
error — so check the key rather than trusting an empty result.

A subcommand name always wins over a bare target, so an endpoint whose id is `send`, `list`,
`approve`, `deny`, `new-code` or `redeem` is knocked as `spt knock send <id>`.

**A knock is quiet on purpose.** It lands in the target endpoint's inbox and is *never pushed at its
agent* — someone has to look. That silence is a security property, not a delivery bug: nothing you
did failed, and nothing polls on your behalf. If you are expecting an answer, run `spt knock list`
(or ask the operator to) rather than waiting to be told. Likewise, do not treat "no knock notice" as
proof that nobody has knocked at you.

Grants are real access. `MSG` binds a single sender, but the machine-scoped surfaces admit the
knocker's *whole machine* — approve those only when the user means to.
<!-- [doc->REQ-SKILL-KNOCK] -->
