feat(specify): record in-context fork resolutions as auditable issue comments

The `spec-skeptic` `scope-fork` juror reads only the seeding issue plus
the spec. On the legitimate `specify` direct-entry path — a fork settled
in a long in-context design discussion — that resolution lives only in
ephemeral chat the juror cannot replay. When the issue body lags the
discussion (still lists the fork open), the juror correctly blocks, and
a design BLOCK escalates without self-correction. The result: auto-sign
was structurally almost unreachable for the in-context entry path.

Close the blind spot by giving the juror an auditable source instead of
weakening the gate. When `specify` enters in-context and a tracker issue
still lists a now-resolved fork as open, the orchestrator posts a
reconciliation comment recording each fork's resolution WITH provenance
(a record of the user's decision, never a fresh orchestrator one) before
writing the spec. The comment is persistent and audit-able — unlike a
carrier digest — so it, not the orchestrator's confidence, is what the
juror checks.

Separation of powers keeps it honest: the orchestrator writes the
comment, the adversarial juror enforces the provenance requirement. A
bare `decision: X` with no provenance does not resolve the fork — the
re-dispatched juror blocks on it. The escalation rule and the
three-field carrier are untouched; only the juror's information changes.

Mechanics:
- specify Step 1.5: reconciliation-comment sub-step, provenance format,
  issue-less fallback (auto-sign -> human sign-off, no weak spec-note).
- spec-skeptic: replace the "quoted in the dispatch" drift; juror reads
  the issue WITH comments via `issue_tracker.show_cmd`; provenance check.
- new profile slot `issue_tracker.show_cmd` (must render comments);
  documented in schema + template.
- issue skill: `tea issues <idx>` is body-only; `--comments` required
  (verified against tea 0.14.1 and Aura #55 — 180 vs 144 lines).
- consistency: design.md out-of-scope, README, pipeline.md, boss skill.
This commit is contained in:
2026-06-12 15:54:47 +02:00
parent a87916e578
commit 268ee705f4
9 changed files with 101 additions and 14 deletions
+48
View File
@@ -121,6 +121,54 @@ the reactive-deference failure the gate exists to prevent.
Genuine doubt about whether the sources resolve a decision *is itself*
the fork signal — it resolves to a bounce, not to a guess.
**Reconciliation comment (lagging-issue case).** A load-bearing fork can
be resolved by the in-context design discussion yet still be listed
*open* by the tracker issue that seeded the cycle — the issue lags the
conversation. When that holds (entry is in-context **and** a tracker
issue still carries a now-resolved fork as open), record the resolution
as an auditable issue comment **before** writing the spec, via the
project's issue-tracker comment command (`tea comment <idx>` for Gitea;
a heredoc body per the `issue` skill's conventions). One comment, this
exact shape:
```
## Design reconciliation (specify, in-context entry)
Spec: <spec-name>. The fork(s) below are still listed open on this
issue; they were resolved in the in-context design discussion.
- **Fork: <name>** → <decision>.
Provenance: <verbatim user statement, or explicit attribution + date>.
```
The comment must carry **provenance**, and the distinction is
load-bearing: it is the *record of a user decision* (legitimate — the
user settled the fork in discussion, you are minuting it), never a *new
orchestrator decision* dressed as settled (illegitimate). A bare
`decision: B` with no provenance is the latter. If you cannot point to a
real user statement, that is the signal that *you* picked the fork, not
the user — which is a Step-1.5 bounce, not a comment. The comment is
*persistent and auditable* (author + timestamp, in the forward queue) —
which is exactly why it, and not your ephemeral confidence, is what a
downstream `scope-fork` juror reads to confirm the fork is settled (see
Step 6). Recording it keeps the forward queue honest in either run mode;
under auto-sign it is *load-bearing* — without it the `scope-fork` juror
sees only the stale issue body and (correctly) blocks.
Provenance enforcement is not yours to self-certify: you *write* the
comment, the adversarial `scope-fork` juror *checks* it carries
provenance (Step 6). Writing a provenance-less comment does not buy a
pass — the re-dispatched juror blocks on it.
Gitea writes are pre-authorized (per `~/.claude/CLAUDE.md`); post the
comment without a confirmation prompt.
**Issue-less in-context entry.** If the cycle has *no* tracker issue —
the design was settled in pure chat — there is no independent artefact to
comment on, and a provenance note *inside the spec* would be
self-referential (the spec asserting its own sources settle it). Do not
manufacture a weak spec-note path: under auto-sign this case falls back
to the human sign-off (the safe default), because no auditable source
exists for the juror to check against.
### Step 2 — Apply the project's feature-acceptance criterion
The project's `CLAUDE.md` declares the criterion a feature must