feat(specify): create a seeding issue for issue-less in-context auto-sign
Step 1.5's issue-less in-context case used to fall back unconditionally to the human sign-off: with no tracker issue, the `scope-fork` juror had no auditable source for an in-context fork resolution and (correctly) blocked, so auto-sign was structurally unreachable on that path. Close it the same way the lagging-issue case is closed — give the juror an auditable artefact instead of weakening the gate. When the cycle has no seeding issue, the orchestrator now creates one recording each resolved fork WITH provenance (a record of the user's decision, never a fresh orchestrator one). A new tracker issue is independent and auditable — unlike the self-referential spec-note the old text rejected — so it, not the orchestrator's confidence, is what the juror checks. The provenance gate is unchanged: no real user statement is a Step-1.5 bounce, not a manufactured issue; the orchestrator writes, the juror enforces. Also thread a `seeding_issue` field through the scope-fork carrier so the juror can actually find the issue to read (the lagging issue, the newly created one, or `none`). Without it the juror had no issue index and the record was invisible — a latent gap the lagging-issue path shared. - specify Step 1.5: issue-less branch creates a provenance-bearing seeding issue; body names the work (no forward ref to the unwritten spec); explicit create command; capture-the-index instruction. - specify Step 6 + handoff table: seeding_issue carrier field. - spec-skeptic: juror reads seeding_issue from the carrier; accepts provenance in a created issue's body, not only in a comment. - consistency: README, pipeline.md, design.md.
This commit is contained in:
@@ -130,12 +130,13 @@ not settled), an `INFRA_ERROR`, any objective gate not green, or an
|
|||||||
exhausted budget falls back to the human sign-off pause the spec would
|
exhausted budget falls back to the human sign-off pause the spec would
|
||||||
have hit anyway. Re-dispatching all five lenses every round is the
|
have hit anyway. Re-dispatching all five lenses every round is the
|
||||||
backstop that stops an editorial repair from quietly settling a design
|
backstop that stops an editorial repair from quietly settling a design
|
||||||
question. When a fork was settled in-context but the seeding issue still
|
question. When a fork was settled in-context, `specify` gives the
|
||||||
lists it open, `specify` records the resolution as a provenance-bearing
|
`scope-fork` juror an auditable source for it (Step 1.5): a provenance-
|
||||||
reconciliation comment on the issue (Step 1.5), which the `scope-fork`
|
bearing reconciliation comment when a seeding issue exists but lags the
|
||||||
juror reads via the project's issue show command — closing the blind spot where
|
discussion, or a freshly created seeding issue when the cycle had none —
|
||||||
the in-context entry path could otherwise never clear that lens. On a
|
either read via the project's issue show command, closing the blind spot
|
||||||
clean sign the orchestrator commits the spec
|
where the in-context entry path could otherwise never clear that lens.
|
||||||
|
On a clean sign the orchestrator commits the spec
|
||||||
(`(boss-signed)` in the subject), sends a mandatory informational notify
|
(`(boss-signed)` in the subject), sends a mandatory informational notify
|
||||||
that names the signed capability and invites a veto, and continues to
|
that names the signed capability and invites a veto, and continues to
|
||||||
`planner` without stopping. A later veto is a forward correction, never
|
`planner` without stopping. A later veto is a forward correction, never
|
||||||
|
|||||||
+11
-6
@@ -366,12 +366,17 @@ and defined there. The boss-side contract is just this:
|
|||||||
question in the user's place; the full re-panel each round is what
|
question in the user's place; the full re-panel each round is what
|
||||||
stops an editorial repair from laundering one in. The gate owns this
|
stops an editorial repair from laundering one in. The gate owns this
|
||||||
loop (`../specify/SKILL.md` Step 6) — boss only enforces the notify.
|
loop (`../specify/SKILL.md` Step 6) — boss only enforces the notify.
|
||||||
One upstream detail matters here: when a fork was settled in-context
|
One upstream detail matters here: a fork settled in-context may be
|
||||||
but the seeding issue still lists it open, `specify` Step 1.5 posts a
|
invisible to the `scope-fork` juror, which reads the seeding issue.
|
||||||
provenance-bearing reconciliation comment on the issue so the
|
`specify` Step 1.5 gives it an auditable source either way — when a
|
||||||
`scope-fork` juror ratifies the resolution from an auditable source
|
seeding issue exists but still lists the fork open, it posts a
|
||||||
rather than false-blocking on the stale body. That comment records a
|
provenance-bearing reconciliation comment; when there is *no* seeding
|
||||||
*user* decision; it never lets the orchestrator certify its own.
|
issue (design settled in pure chat), it creates one that records the
|
||||||
|
resolution with provenance and becomes the cycle's seeding issue.
|
||||||
|
Both record a *user* decision; neither lets the orchestrator certify
|
||||||
|
its own — no real user statement is a Step-1.5 bounce, not an artefact
|
||||||
|
to manufacture. The orchestrator writes the record; the juror checks
|
||||||
|
the provenance.
|
||||||
- **On a clean sign, do not stop.** Commit the spec (the auto-sign
|
- **On a clean sign, do not stop.** Commit the spec (the auto-sign
|
||||||
commit subject carries `(boss-signed)` so the act is auditable in
|
commit subject carries `(boss-signed)` so the act is auditable in
|
||||||
history), fire the auto-sign notify, and continue to `planner` in
|
history), fire the auto-sign notify, and continue to `planner` in
|
||||||
|
|||||||
+4
-4
@@ -123,7 +123,7 @@ The relationship:
|
|||||||
issue-tracker commands (the repo slug, list command, and
|
issue-tracker commands (the repo slug, list command, and
|
||||||
single-issue-with-comments command, all in its CLAUDE.md project
|
single-issue-with-comments command, all in its CLAUDE.md project
|
||||||
facts) and invokes them, and `specify` may post a reconciliation
|
facts) and invokes them, and `specify` may post a reconciliation
|
||||||
comment via the tracker's comment command — but the plugin does
|
comment or create a seeding issue via the tracker's comment / create
|
||||||
not directly call Gitea / GitHub / Linear APIs. Every read and
|
commands — but the plugin does not directly call Gitea / GitHub /
|
||||||
write goes through the configured shell command, so the plugin
|
Linear APIs. Every read and write goes through the configured shell
|
||||||
remains transport-agnostic.
|
command, so the plugin remains transport-agnostic.
|
||||||
|
|||||||
+5
-4
@@ -114,10 +114,11 @@ signs. A `BLOCK` is never signed over: an editorial one (`criterion` /
|
|||||||
that re-runs the objective gates and re-dispatches all five lenses each
|
that re-runs the objective gates and re-dispatches all five lenses each
|
||||||
round; a design one (`scope-fork` / `grounding`), an `INFRA_ERROR`, or
|
round; a design one (`scope-fork` / `grounding`), an `INFRA_ERROR`, or
|
||||||
an exhausted budget falls back to the human sign-off pause. When the
|
an exhausted budget falls back to the human sign-off pause. When the
|
||||||
entry is in-context and the seeding issue still lists a now-resolved
|
entry is in-context, `specify` gives the `scope-fork` juror an auditable
|
||||||
fork as open, `specify` posts a provenance-bearing reconciliation
|
source for an in-context fork resolution (Step 1.5) — a provenance-
|
||||||
comment on the issue (Step 1.5) so the `scope-fork` juror can ratify the
|
bearing reconciliation comment when a seeding issue lags the discussion,
|
||||||
resolution instead of blocking on the stale body. See
|
or a freshly created seeding issue when the cycle had none — so the
|
||||||
|
juror can ratify the resolution instead of blocking for lack of one. See
|
||||||
`../specify/SKILL.md` Step 6 and `../boss/SKILL.md` §"Spec auto-sign".
|
`../specify/SKILL.md` Step 6 and `../boss/SKILL.md` §"Spec auto-sign".
|
||||||
|
|
||||||
### planner
|
### planner
|
||||||
|
|||||||
+49
-8
@@ -162,12 +162,49 @@ Gitea writes are pre-authorized (per `~/.claude/CLAUDE.md`); post the
|
|||||||
comment without a confirmation prompt.
|
comment without a confirmation prompt.
|
||||||
|
|
||||||
**Issue-less in-context entry.** If the cycle has *no* tracker issue —
|
**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
|
the design was settled in pure chat — there is no existing artefact to
|
||||||
comment on, and a provenance note *inside the spec* would be
|
comment on, so *create one*: open a new tracker issue that records the
|
||||||
self-referential (the spec asserting its own sources settle it). Do not
|
resolved fork(s) with provenance, under the same discipline as the
|
||||||
manufacture a weak spec-note path: under auto-sign this case falls back
|
reconciliation comment above. The body takes this shape:
|
||||||
to the human sign-off (the safe default), because no auditable source
|
|
||||||
exists for the juror to check against.
|
```
|
||||||
|
## Design record (specify, issue-less in-context entry)
|
||||||
|
This issue seeds <one-line identity of the work>. The design was settled
|
||||||
|
in an in-context discussion with no prior tracker issue; this records it.
|
||||||
|
Load-bearing fork(s) resolved:
|
||||||
|
- **Fork: <name>** → <decision>.
|
||||||
|
Provenance: <verbatim user statement, or explicit attribution + date>.
|
||||||
|
```
|
||||||
|
|
||||||
|
The body names the *work*, not the spec file — the spec does not exist
|
||||||
|
yet at Step 1.5 (its number is assigned only in Step 3). This new issue
|
||||||
|
is the cycle's seeding issue from here on: the `scope-fork` juror reads
|
||||||
|
it via the project's issue show command — its index handed to the juror
|
||||||
|
in the Step-6 carrier (the `seeding_issue` field, below) — exactly as it
|
||||||
|
reads any seeding issue. A *new issue* is the right artefact where a spec-note
|
||||||
|
is the wrong one — a provenance note *inside the spec* is
|
||||||
|
self-referential (the spec asserting its own sources settle it) and
|
||||||
|
stays banned, but a separate issue is independent (author + timestamp,
|
||||||
|
in the forward queue, juror-readable without opening the spec), as
|
||||||
|
auditable as a reconciliation comment. Creating it is what makes
|
||||||
|
auto-sign *reachable* here, instead of the old unconditional fall-back
|
||||||
|
to the human sign-off.
|
||||||
|
|
||||||
|
The provenance gate is unchanged and load-bearing: the new issue records
|
||||||
|
*user* decisions, never fresh orchestrator ones. No real user statement
|
||||||
|
for a fork means *you* picked it — a Step-1.5 bounce, not an issue to
|
||||||
|
manufacture. You *write* the issue; the adversarial `scope-fork` juror
|
||||||
|
*checks* the provenance, and a provenance-less body buys no pass.
|
||||||
|
|
||||||
|
Create it via the project's issue-create command (the `issue` skill's
|
||||||
|
mechanics — `tea issues create` for Gitea), title and label per the
|
||||||
|
project's vocabulary as in the Step-5 failure-mode procedure. Gitea
|
||||||
|
writes are pre-authorized, so create it without a confirmation prompt.
|
||||||
|
**Capture the new issue's index** the moment it is created and carry it
|
||||||
|
into the Step-6 panel as the `seeding_issue` field — it is the only way
|
||||||
|
the `scope-fork` juror knows which issue to read. An issue created but
|
||||||
|
never handed to the panel is invisible to the juror, which leaves the
|
||||||
|
fork looking picked and the creation pointless.
|
||||||
|
|
||||||
### Step 2 — Apply the project's feature-acceptance criterion
|
### Step 2 — Apply the project's feature-acceptance criterion
|
||||||
|
|
||||||
@@ -366,7 +403,11 @@ CLAUDE.md project facts):
|
|||||||
read-only `spec-skeptic` agent **five times in parallel**, once
|
read-only `spec-skeptic` agent **five times in parallel**, once
|
||||||
per lens — `criterion`, `grounding`, `scope-fork`, `ambiguity`,
|
per lens — `criterion`, `grounding`, `scope-fork`, `ambiguity`,
|
||||||
`plan-readiness`. Carrier per dispatch: `spec_path` (absolute),
|
`plan-readiness`. Carrier per dispatch: `spec_path` (absolute),
|
||||||
`iteration_scope`, and the single `lens`. Each juror tries to
|
`iteration_scope`, the single `lens`, and `seeding_issue` — the
|
||||||
|
index of the cycle's seeding issue (the lagging issue reconciled in
|
||||||
|
Step 1.5, the issue Step 1.5 created for an otherwise issue-less
|
||||||
|
cycle, or `none` if the cycle has neither) for the `scope-fork`
|
||||||
|
juror to read; the other four lenses ignore it. Each juror tries to
|
||||||
*refute* the spec along its lens and returns `SOUND` / `BLOCK` /
|
*refute* the spec along its lens and returns `SOUND` / `BLOCK` /
|
||||||
`INFRA_ERROR`. Auto-sign requires a **unanimous `SOUND`** — that
|
`INFRA_ERROR`. Auto-sign requires a **unanimous `SOUND`** — that
|
||||||
never changes. What the partition below adds is a bounded path to
|
never changes. What the partition below adds is a bounded path to
|
||||||
@@ -455,7 +496,7 @@ discipline `tdd` applies when behaviour is not test-specifiable.
|
|||||||
| user / issue (design settled) → `specify` | the sources: issue body, in-context design discussion, design docs |
|
| user / issue (design settled) → `specify` | the sources: issue body, in-context design discussion, design docs |
|
||||||
| `brainstorm` → `specify` | ratified design narrative (approaches chosen, constraints, sections approved) — in-context; brainstorm writes no spec file |
|
| `brainstorm` → `specify` | ratified design narrative (approaches chosen, constraints, sections approved) — in-context; brainstorm writes no spec file |
|
||||||
| `specify` → `grounding-check` (Step 5) | `spec_path` (absolute) + `iteration_scope` |
|
| `specify` → `grounding-check` (Step 5) | `spec_path` (absolute) + `iteration_scope` |
|
||||||
| `specify` → `spec-skeptic` panel (Step 6, `/boss` + `spec_auto_sign` only) | `spec_path` (absolute) + `iteration_scope` + one `lens` per dispatch, five in parallel |
|
| `specify` → `spec-skeptic` panel (Step 6, `/boss` + `spec_auto_sign` only) | `spec_path` (absolute) + `iteration_scope` + one `lens` per dispatch (five in parallel) + `seeding_issue` (index for the `scope-fork` juror to read, or `none`) |
|
||||||
| `specify` → `planner` (Step 7, on PASS or overridden BLOCK) | path to spec + iteration scope |
|
| `specify` → `planner` (Step 7, on PASS or overridden BLOCK) | path to spec + iteration scope |
|
||||||
| `specify` → `brainstorm` (precondition bounce) | the unresolved design question as a cycle request; no spec written |
|
| `specify` → `brainstorm` (precondition bounce) | the unresolved design question as a cycle request; no spec written |
|
||||||
| `specify` → issue backlog (Step 5, no-override BLOCK) | new issue naming the unratified dependency; spec file deleted from the working tree |
|
| `specify` → issue backlog (Step 5, no-override BLOCK) | new issue naming the unratified dependency; spec file deleted from the working tree |
|
||||||
|
|||||||
@@ -75,23 +75,29 @@ In addition, every dispatch:
|
|||||||
project's examples / fixtures directory —
|
project's examples / fixtures directory —
|
||||||
you grep these to confirm or refute ratification.
|
you grep these to confirm or refute ratification.
|
||||||
- For the `scope-fork` lens additionally: the sources the spec was
|
- For the `scope-fork` lens additionally: the sources the spec was
|
||||||
built from. The seeding issue is reachable via the project's issue
|
built from. Your carrier names the `seeding_issue` index — append it
|
||||||
show command (its CLAUDE.md project facts) — it MUST render the issue
|
to the project's issue show command (its CLAUDE.md project facts,
|
||||||
WITH its comment thread (issue index appended last) — invoke it so
|
which MUST render the issue WITH its comment thread) and invoke it so
|
||||||
you read the issue **with its comment thread**, not the body alone.
|
you read the issue **with its comment thread**, not the body alone. If
|
||||||
|
`seeding_issue` is `none`, the cycle has no seeding issue and you have
|
||||||
|
only the spec to judge against — a load-bearing fork the spec leaves
|
||||||
|
unsourced is then a refutation.
|
||||||
You judge "resolved vs picked" against what the sources actually say,
|
You judge "resolved vs picked" against what the sources actually say,
|
||||||
not against what reads plausibly. A fork the issue *body* still lists
|
not against what reads plausibly. A fork the issue *body* still lists
|
||||||
open may have been resolved in an in-context discussion the dispatch
|
open may have been resolved in an in-context discussion the dispatch
|
||||||
cannot replay to you; the legitimate channel for that resolution is a
|
cannot replay to you; the legitimate channel for that resolution is a
|
||||||
**reconciliation comment** on the issue (`specify` Step 1.5). A
|
**provenance-bearing reconciliation record** written by `specify` Step
|
||||||
reconciliation comment counts as the sources resolving the fork **only
|
1.5 — either a reconciliation *comment* on a seeding issue that lagged
|
||||||
if it carries provenance** — a record of the user's decision (a
|
the discussion, or, for a cycle that had *no* seeding issue, the
|
||||||
verbatim statement, or explicit attribution + date). A bare
|
*body* of the issue `specify` created to record it. Either counts as
|
||||||
`decision: X` with no provenance is an orchestrator self-assertion
|
the sources resolving the fork **only if it carries provenance** — a
|
||||||
dressed as settled, not a source: it does **not** resolve the fork, and
|
record of the user's decision (a verbatim statement, or explicit
|
||||||
a load-bearing decision whose only support is such a comment is a
|
attribution + date). A bare `decision: X` with no provenance is an
|
||||||
refutation. If the project declares no issue show command, you have
|
orchestrator self-assertion dressed as settled, not a source: it does
|
||||||
only the body — a fork the body lists open is unresolved to you.
|
**not** resolve the fork, and a load-bearing decision whose only
|
||||||
|
support is such a record is a refutation. If the project declares no
|
||||||
|
issue show command, you have only what you can read — a fork no
|
||||||
|
provenance-bearing record resolves is unresolved to you.
|
||||||
|
|
||||||
You do NOT read files under `docs/plans` (the plan does not yet
|
You do NOT read files under `docs/plans` (the plan does not yet
|
||||||
exist). You do NOT read other specs unless the spec under review
|
exist). You do NOT read other specs unless the spec under review
|
||||||
@@ -104,6 +110,7 @@ references one — and then only the referenced section.
|
|||||||
| `spec_path` | absolute path to the spec under review |
|
| `spec_path` | absolute path to the spec under review |
|
||||||
| `iteration_scope` | which sections are in scope for the imminent first iteration (verbatim from specify) |
|
| `iteration_scope` | which sections are in scope for the imminent first iteration (verbatim from specify) |
|
||||||
| `lens` | exactly one of: `criterion`, `grounding`, `scope-fork`, `ambiguity`, `plan-readiness` |
|
| `lens` | exactly one of: `criterion`, `grounding`, `scope-fork`, `ambiguity`, `plan-readiness` |
|
||||||
|
| `seeding_issue` | index of the cycle's seeding issue for the `scope-fork` juror to read via the project's issue show command — the lagging issue reconciled in `specify` Step 1.5, the issue Step 1.5 created for an otherwise issue-less cycle, or `none`. The other four lenses ignore it; if absent, treat as `none`. |
|
||||||
|
|
||||||
The controller is the `specify` skill's Step 6, running inside a
|
The controller is the `specify` skill's Step 6, running inside a
|
||||||
`/boss` session. You receive the carrier inline in the dispatch
|
`/boss` session. You receive the carrier inline in the dispatch
|
||||||
@@ -134,10 +141,10 @@ YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK ARE OK.)
|
|||||||
pin; your own recall does not pin). For `scope-fork`, this means
|
pin; your own recall does not pin). For `scope-fork`, this means
|
||||||
listing the load-bearing decisions and checking each against the
|
listing the load-bearing decisions and checking each against the
|
||||||
sources read via the project's issue show command (issue **with
|
sources read via the project's issue show command (issue **with
|
||||||
comments**); a fork the
|
comments**); a fork the issue body lists open is resolved only by a
|
||||||
issue body lists open is resolved only by a reconciliation comment
|
provenance-bearing reconciliation record — a comment, or the body of
|
||||||
that carries provenance (see the standing reading list) — a
|
an issue `specify` created for an otherwise issue-less cycle (see the
|
||||||
provenance-less one does not count. For the others, read for the
|
standing reading list) — a provenance-less one does not count. For the
|
||||||
specific failure.
|
specific failure.
|
||||||
4. If you find a genuine defect along your lens → `BLOCK`, and state
|
4. If you find a genuine defect along your lens → `BLOCK`, and state
|
||||||
it concretely (section ref, the offending text, why it is a defect).
|
it concretely (section ref, the offending text, why it is a defect).
|
||||||
|
|||||||
Reference in New Issue
Block a user