# releases#67 — the retired access verb that answered plausibly (todlando, PORTER wave 3)

STATUS 2026-08-21: BUILT, UNPUSHED. Lane `.worktrees/fix-67`, branch
`fix/67-superseded-verb-refusal`, base `b88fab2a`, pool claimed for lane
`fix-67`.

## Measured first, and the measurement WIDENED the filing

Reproduced at the base in an isolated `SPT_HOME`, verbatim:

```
$ spt endpoint access list
no access entities ruled for 'list' (default-open; posture comes from the node
and subnet tiers — see `spt node access`)
exit=0

$ spt endpoint access rules
no access entities ruled for 'rules' (default-open; posture comes from the node
and subnet tiers — see `spt node access`)
```

The issue named `list`. **`rules` falls through identically**, so the population
is the retired-token FAMILY, not the one token filed. Confirmed against
CHANGELOG.md, which retires exactly these two: *"`spt endpoint access list` and
`spt endpoint access rules` are retired; the roster views above replace them."*

**The node tier was checked rather than assumed:** `spt node access` declares no
positional at all, so clap refuses an extra argument natively. The defect is
endpoint-only, and that bound is measured rather than asserted.

## Why this is worse than a missing error message

The sentence is TRUE of any name nobody has ruled. It is therefore
indistinguishable from the correct answer for a real endpoint — so an operator
or agent still carrying the old form reads a well-formed report and stops
looking. Exit 0, no diagnostic on either stream. The same failure shape as a
stale carried-forward instruction: the surface looks diligent and is wrong.

## What shipped

`REQ-ACCESS-RETIRED-VERB-REFUSAL`, minted and activated at impl+unit.

- `RETIRED_ACCESS_VERBS` — the token table, each token beside the form that
  replaced it. Listed rather than inferred because there is nothing left in the
  grammar to infer from: a retired token is not a subcommand any more.
- `retired_access_verb` — case-folded lookup. An operator who typed the old verb
  in any casing typed the old verb.
- `retired_access_verb_refusal` — names the token, says it is retired, names the
  working form, and states that nothing was read and nothing was written.
- The guard inside `cmd_access_view`, placed AFTER the known-target check.

## THE NARROWING FAILS OPEN, and it has its own cell

This guard is added to a path that previously accepted EVERY positional, so it
is a narrowing — and a narrowing has an unruled arm. An endpoint genuinely named
`list` must stay viewable. The known-target check (store rules it, or a local
perch carries the id) runs FIRST and wins, off the store already loaded at that
point, so it costs no extra read.

It lives in its own test cell deliberately: a refusal keyed on the token alone
would pass every other assertion in this lane while making a real target
unreachable — a new defect wearing the old one's repair.

## PER-ARM MUTATION (predictions registered BEFORE the run)

Two arms mutated in ONE build:

- **M1** — dropped the known-target carve-out (refuse on the token alone).
- **M2** — made the token match case-SENSITIVE.

Registered predictions: M1 reddens only the fail-open cell, M2 reddens only the
refusal cell, and the grammar walk stays green under both. Measured, exactly:

```
a_retired_access_subcommand_refuses_by_name_and_says_the_working_form ... FAILED
a_real_endpoint_named_like_a_retired_verb_is_still_viewable ............. FAILED
every_retired_access_token_still_reaches_the_positional ................. ok
```

Restored from the committed baseline and re-greened. This is why the cells were
SPLIT — the first draft put every arm in one test, where two mutations produce
one red and prove nothing about which arm each reached.

## The grammar walk is the table's own guard

`every_retired_access_token_still_reaches_the_positional` drives the REAL parser
for each token in the table and asserts it lands on the positional with no
subcommand. If a retired token is ever brought back as a live verb, that cell
reddens and says to take it out of the table rather than leave it refusing
itself. A table of strings with no parser behind it would drift silently.

## LANE SLATE (tip after the mutation restore)

- 3 unit cells: grammar walk, refusal + honest-silence, fail-open carve-out
- `cargo test -p spt --bins`: **645 passed, 0 failed**
- `cargo clippy --workspace --all-targets`: **exit 0, zero warnings**
- `traceable-reqs check` / `xtask check`: see the report
- Fixture bins prebuilt before the filtered run (the #172 lane trap: a fresh
  pool has no `translate_proof_fixture.exe`, and `--bins` never emits one)

## What is owed

1. Report to doyle.
2. Then #186 — the last wave-3 lane.
3. Pool release when the lane is picked at assembly. DO NOT rebase or push.
