Skip to content

feat(gate): --supersedes — a correction points at the request it replaces - #462

Merged
nao-amj merged 1 commit into
mainfrom
feat/gate-supersedes
Sep 3, 2026
Merged

nao-amj merged 1 commit into
mainfrom
feat/gate-supersedes

Conversation

@nao-amj

@nao-amj nao-amj commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

What

--supersedes <id> on gate request and gate fast-track: a forward-only link from a correcting request to the older one it corrects.

gate fast-track --supersedes 2026-04-15-0007 \
  --action "the judge was run; the earlier conclusion does not hold" \
  --reason "..."

gate show renders supersedes: above the action, and gate chain <old-id> now resolves forward to the correction.

Why

Principle 04 has described this shape since it was written — "a correction is a new record that references the old, which preserves the trail of thinking, not just the latest conclusion." The ctx passage shipped ctx supersede; gate never had the equivalent, so corrections lived in action prose.

Measured against a 2213-record content_root:

count share
requests using correction wording 445 20.1%
requests naming another id in prose 148 6.7%
both — a correction whose target is written but not traversable 67 3.0%

Those 67 are principle 17's failure mode: a restatement bound to nothing. This PR binds them to structure going forward. It does not backfill.

The population matters: an earlier reading of this put the number at 407. Re-measuring with a real YAML parse (rather than a grep that matched each file's own id: line) and hand-classifying a deterministic 15-record sample showed most correction-worded records are not correcting a gate request at all. The mechanism's job is to bind the 67, not to invent corrections.

Design decisions

A flag, not a verb. ctx could afford a verb because it has one record-creating shape. gate has two entry points, and a correction-only verb would leave the other unable to correct anything. A flag on an existing verb also inherits its principle 13 shape instead of requiring a new classification.

Forward-only. The correcting record carries the link. The superseded record is never mutated and there is no inverse superseded_by — writing one would mean amending an immutable record. Both stay in the ledger.

Validated before allocation. A target that does not resolve is refused at the write boundary before the new id is allocated, so a bad link never leaves a half-written record behind. Self-supersession is rejected in the domain.

chain learns the field. Corrections used to name the older id in action text, which gatherRequestText picked up for free. Moving that mention into a structured field would otherwise have made chain blind to exactly the links the field exists to make traversable — more precise and less reachable at the same time. source_agora_play has that gap today; this one is closed at introduction.

Not included

  • Any taxonomy of correction kinds — --reason carries which shape applies (claim wrong / grounds wrong but judgment stands / addendum / withdrawal).
  • Surfacing corrections from gate show <old-id>. The inverse lookup costs a full scan: 0.11s versus 0.91s on the same root, an 8.3x difference. It belongs on chain, which now resolves it.

Verification

  • npm test: 1954 → 1962 (+8). Failing set identical to the branch point in both directions (26 pre-existing on main).
  • KNOWN_FLAGS ↔ schema.input.properties drift detector green; the doc-sync guard required and received the docs/plugin-schema.md row.
  • Exercised end to end against a live content_root: the record renders, and gate chain <old-id> traverses to it.
  • Example and fixture ids are synthetic, per 5195a5f.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HbrpT13G92kRawJXZuzH49

…aces

Principle 04 has described this shape since it was written: "a correction
is a new record that references the old — which preserves the trail of
thinking, not just the latest conclusion." The `ctx` passage shipped
`ctx supersede`; `gate` never had the equivalent, so corrections lived in
`action` prose. Measured against a 2213-record content_root: 445 requests
(20.1%) use correction wording, 67 (3.0%) name an older id in prose that
no reader can traverse mechanically. That is principle 17 — a restatement
bound to nothing.

A flag, not a verb. `ctx` could afford a verb because it has one
record-creating shape; `gate` has two entry points (`request` and
`fast-track`), and a correction-only verb would leave the other unable to
correct anything. A flag on an existing verb also inherits its principle
13 shape rather than requiring a new classification.

Forward-only. The correcting record carries the link; the superseded
record is never mutated, and there is no inverse `superseded_by` field —
writing one would mean amending an immutable record. Both stay in the
ledger.

Validated at the write boundary, before the new id is allocated: a target
that does not resolve is refused, so a bad link never leaves a
half-written record behind. Self-supersession is rejected in the domain.

`chain` had to learn the field. Corrections used to name the older id in
`action` text, which `gatherRequestText` picked up for free; moving that
mention into a structured field would otherwise have made `chain` blind
to exactly the links the field exists to make traversable — more precise
and less reachable at the same time. `source_agora_play` has the same
gap today, so this one is closed at introduction rather than later.

Not included: any taxonomy of correction kinds (`--reason` carries it),
and surfacing corrections from `gate show <old-id>` — the inverse lookup
costs a full scan, measured at 0.11s versus 0.91s on the same root, and
belongs on `chain`, which now resolves it.

Tests: 1954 -> 1962 (+8). Failing set identical to the branch point in
both directions (26 pre-existing).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HbrpT13G92kRawJXZuzH49
@nao-amj
nao-amj merged commit 82fc525 into main Sep 3, 2026
5 checks passed
@nao-amj
nao-amj deleted the feat/gate-supersedes branch September 3, 2026 09:56
nao-amj added a commit that referenced this pull request Sep 3, 2026
Collects the 19 fragments accumulated since 0.7.2 into a versioned block
and syncs package.json / package-lock.json.

Minor rather than patch: `Request` is on the stable surface enumerated in
docs/POLICY.md, and #462 added an optional `supersedes` field to it. The
policy requires a minor bump *and a migration note* for that layer, so the
block opens with a Migration section — the change is additive and needs no
action, but the note has to exist for the bump to be legible.

Highlights: --supersedes on gate request / fast-track (#462), the ROM
envelope work (#456-#458), principle 17 (#455), the observations store,
and the stdin sentinel fixes.


Claude-Session: https://claude.ai/code/session_01HbrpT13G92kRawJXZuzH49

Co-authored-by: eris-ths <255252906+eris-ths@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants