Skip to content

feat: every implemented issue leaves a spec change or a declared exemption (#480) - #490

Merged
kiki830621 merged 36 commits into
mainfrom
idd/480-spec-on-every-issue
Nov 11, 2026
Merged

kiki830621 merged 36 commits into
mainfrom
idd/480-spec-on-every-issue

Conversation

@kiki830621

@kiki830621 kiki830621 commented Nov 10, 2026 •

Copy link
Copy Markdown
Member

Every issue IDD implements now leaves a spec change, or declares why it does not. Refs #480.

What changes

  • scripts/spec-change.py: declared, archived, links, preflight, ic, plan, one JSON line each. The spec directory is read from .spectra.yaml spec_dir (openspec when absent; Spectra 3 initialises new repositories at docs/spectra).
  • references/spec-wrapper.md: the shared contract. idd-implement wraps the implementation of a Simple or Plan issue in a Spectra change in the light form (propose, apply, close out). In the attended Plan tier idd-plan has the maintainer approve the Implementation Plan in plan mode, then hands the approved change name to idd-implement. idd-all closes out the Spectra tier the same way. The change is archived on the branch before verify.
  • Implementation Complete carries a marker and exactly one **Spec**: line: change <names>, no behaviour change (four closed cases) or third-party clone. The Implementation Plan carries a **Spec plan**: line; an open change is used only when the newest plan names it as approved.
  • idd-verify (code profile): every reviewer gets the declaration, the spec files changed in the range, and the results of links and archived. Behaviour no requirement states is HIGH; a false no behaviour change is HIGH; a check that is not ok/pass and an unreadable declaration are Blocking.
  • idd-close Step 1.57: refuses while the declared change is not archived on the default branch.
  • A fix after a verify round that adds or changes a requirement is a further change idd-<N>-fix<k>.

BREAKING for the flow, not for any file format: Simple and Plan issues that change behaviour now go through Spectra. See the CHANGELOG [Unreleased] entry for the known limits (linked worktrees stop; a repository without Spectra stops with the install or init command).

How it was checked

  • spec-change 428, spec-wrapper-contract 238, spec-close-gate 29 checks. CI (suites) passes on 87bd9d0, and verify round 8 ran run-all-tests.sh (73 suites) on the same commit.
  • End-to-end runs in a private sandbox repository with this branch's plugin: a Simple issue, a README-only issue, a Spectra-tier issue, two verify scenarios and one fix run. Results per task in openspec/changes/archive/2026-11-11-spec-on-every-issue/tasks.md. The attended Plan tier was checked by contract tests only, not run end to end.
  • Eight verify rounds. Rounds 1 to 7 were fixed as the changes idd-480-fix1 to idd-480-fix7, each archived on the branch. Round 8 is PASS with 0 blocking; its one HIGH (raised by Codex, rejected in the report) was accepted as rejected by the maintainer, who decided the merge: feat: IDD 的每一張 issue 不論走哪個 tier 都要更新規格(與 Spectra 深度整合) #480 (comment)
  • spec-change.py links --base 03f5559 prints ok and archived --ref HEAD prints pass on 87bd9d0.

Left for later

…ent (#480)

Spectra change spec-on-every-issue: proposal, design, two spec deltas (new capability spec-on-every-issue; one added requirement in idd-verify) and 17 tasks. Proposal only: implementation waits until #392 is in main.

Refs #480
spectra validate and analyze are clean on 03f5559. design.md records the three places the implementation must meet #392: idd-close's orchestrated mode, the verify gate's table format, and the idd-all permissions table (unchanged).

Refs #480
…t, tests first (#480)

Tasks 2.1 to 2.5 of the Spectra change spec-on-every-issue. Four
subcommands, each printing one JSON line with a fixed exit code:

- declared: reads the **Spec**: line of an Implementation Complete
  comment (change <names> / no behaviour change / third-party clone /
  legacy / invalid). Lines inside code fences are not read.
- archived: for a declared change, the change directory is gone and
  exactly one dated archive directory has its name, at the revision
  named; the three other forms pass without reading the repository.
- links: every requirement added or changed in base..head has Examples
  whose titles are unique in the capability and whose markers
  (spec-example: <capability> / <title>) sit in a tracked file outside
  openspec/ that is not .md, or a `No executable check:` line with a
  reason. --base is required.
- preflight: third-party clone, linked worktree, no spectra on PATH,
  no openspec/ directory, or ready.

Anything that cannot be read is error (exit 2), never ok or pass; a
revision that starts with a dash is a usage error.

Tests: scripts/tests/spec-change, 221 checks, one per row of the four
Example tables plus boundaries; they failed against an empty skeleton
before the code was written.

Refs #480
…d-all; spec directory as Spectra resolves it (#480)

Tasks 2.6 and 3.1 of spec-on-every-issue, and the SKILL text of 3.2 to
3.4 (their end-to-end runs are still open).

- references/spec-wrapper.md: the contract both wrappers follow —
  preflight, what the issue leaves (change, or one of four closed
  no-behaviour-change cases), light-form propose through
  spectra-propose, apply through spectra-apply with each Example's test
  first, the close-out in a fixed order (spectra-verify, spectra
  archive, check it landed, commit, links, archived), the declaration
  line, and fix rounds as idd-<N>-fix<k>.
- idd-implement: Step 0.6 spec preflight before any artifact or commit,
  propose in Step 2 unless idd-plan already did, apply in Step 3,
  Step 4.5 close-out, the marker and the **Spec**: line in the
  Implementation Complete template; the tree-lock step says a linked
  worktree cannot write a spec change.
- idd-plan: proposes, presents the proposal and the tasks in plan mode,
  hands the change name to idd-implement.
- idd-all: Step 3b.6 closes out the Spectra tier and posts the
  Implementation Complete with the marker and no Checklist section.
- spec-change.py reads the spec directory from .spectra.yaml spec_dir
  (openspec when absent), at the revision checked; an absolute or
  escaping value is an error. Spectra 3 initialises new repositories at
  docs/spectra, found while running spectra init for the tests; the
  requirement, an Example table and task 2.6 were added to the change.

Tests: spec-change 257 (the 18 spec-directory checks failed first; a
chain with the real spectra CLI archives under docs/spectra),
spec-wrapper-contract 42 (failed before the text existed),
authoritative-source-producer 28 (the new comment shape leaves the
checklist source at Current Status > Tasks), and every suite that reads
the three skills passes.

Refs #480
…ts for the archive (#480)

Task 4.3 of spec-on-every-issue, and the SKILL text of 4.1 and 4.2
(their end-to-end runs are still open).

- idd-close Step 1.57, spec archive gate: the newest Implementation
  Complete by a writer is checked with spec-change.py archived against
  origin/<default>; refuse or error stops the close, in manual and
  orchestrated runs alike. An issue with no Implementation Complete is
  not held to it.
- idd-verify: the shared pre-step builds a spec context after the
  external-writes block (code profile only): the declaration, the spec
  files changed in BASE_SHA..FROZEN_SHA, and the results of links and
  archived, with the review rules (behaviour no requirement states is
  HIGH; a false no-behaviour-change declaration is HIGH; a marked test
  that does not check its Example is MEDIUM or above). Staged to
  spec-block.md, read by the five manual reviewers and the codex leg,
  appended to the pai contextBlock. Step 3 turns missing links, an
  archive refuse and either check's error into Blocking rows. The lens
  focus strings are unchanged.
- idd-all auto-fix and idd-implement Step 0.6: a fix that adds or
  changes a requirement is a further change idd-<N>-fix<k>, archived
  before the next verify round, and a new Implementation Complete lists
  every change; a Blocking fix leaves a test that fails before it.

Tests: spec-close-gate 16 (the skill-text checks failed first; rows 1-4
run against a real remote, before and after the merge),
spec-wrapper-contract 61 (19 new checks failed first). Every suite that
reads idd-verify, idd-close, idd-all or idd-implement passes.

Refs #480
…per; follow-ups filed (#480)

Task 5.3 of spec-on-every-issue and the documentation part of 5.1 (the
measured cost of a Simple issue still waits for the end-to-end runs).

- rules/sdd-integration.md: the flow of every tier archives before
  verify; rule 4 is now "archive on the branch before verify (every
  tier)" and points at idd-close Step 1.57; progress for an issue with a
  change lives in its tasks.md.
- CLAUDE.md, idd-diagnose's next-step table and usecase-routing row 10
  say the same; no document still says Simple skips the spec or that
  archiving happens at close.
- CHANGELOG [Unreleased]: the BREAKING entry, spec-change.py, and the
  known limits (linked worktree, a repository without Spectra, markers
  tie by name only). README rows of idd-implement, idd-plan, idd-close.
- Follow-ups: #487 (Examples and checks for the existing requirements),
  #488 (isolate with a standalone clone, so issues that write a spec can
  run while the main tree is locked).

Refs #480
…en a run is unattended (#480)

Found while preparing the end-to-end runs: spectra-propose parks the change
it creates, and spectra-apply asks with AskUserQuestion whether to continue a
parked change. Inside an unattended /idd-all that question has no one to
answer it.

- Step 3: the wrapper checks is_unattended "$CWD" (unattended-contract.md)
  and, when unattended, appends an UNATTENDED MODE note to the propose and
  apply args: no AskUserQuestion (conservative choice written as an
  ASSUMPTION: line), no park or continue questions, commits end in (#N).
- Step 4: the wrapper runs spectra unpark itself when the change is parked,
  before spectra-apply. Tried against Spectra 3: a parked change is listed
  again after the lines run.
- unattended-contract.md lists the wrapper among the detectors.

spec-wrapper-contract 67 (6 new checks failed first).

Refs #480
…rements (#480)

Found by the self-check of task 5.2: archiving spec-on-every-issue in a
scratch clone appended its requirement to openspec/specs/idd-verify/spec.md
as "\n\n---\n### Requirement: ...". The requirement before it (Codex channel
is fully dependency-resolved) then read as changed, because its block ran
to the end of the file and now carried the blank lines and the ---, and
links reported it as missing an Example.

requirements() now drops trailing blank lines and thematic breaks (---,
***, ___) from each block. A block whose text really changed is still
reported (new test). After the fix the self-check prints ok for links
and pass for archived.

spec-change 265 (the appended-requirement case failed first).

Refs #480
…eps 3 and 4 (#480)

The two lines still called spectra-apply directly and did not mention the
unattended note; they now say to unpark first (step 4) and to append the
UNATTENDED MODE note when the run is unattended (step 3).

spec-wrapper-contract 69 (2 new checks failed first).

Refs #480
…5.1 (#480)

Sandbox runs on 2026-11-11 with a snapshot of this branch:
- 3.2: unattended /idd-all on a Simple issue left an archived change and
  a new docs/spectra spec on the branch; declared reads change, archived
  prints pass, links prints ok.
- 3.5: a README-only issue declared no behaviour change (case a), no
  change directory. The third-party half rests on the preflight tests.
- 3.3: accepted by contract tests only, by the decision of 2026-11-11.
- 4.1: verify reported a Blocking naming the Example whose marker was
  removed and a HIGH for behaviour no requirement states; with the
  declaration switched to no behaviour change it reported a HIGH that
  the exemption does not hold.
- 5.1: the CHANGELOG gives the one measured cost (5 minutes, about 3 in
  propose and close-out; one run, no control).

Refs #480
A fix run after the 4.1 verify left an archived idd-27-fix1 on the branch
(a new requirement for -h, two existing ones changed), restored the
missing marker, and posted a new Implementation Complete listing both
changes; archived prints pass and links prints ok. The idd-all auto-fix
half is covered by the contract suite only. The run hit the actionability
gate reading verify findings in ### Blocking as external blockers, which
is tracked separately.

Refs #480
- 3.4: an unattended /idd-all run that diagnose routed to the Spectra tier
  archived its change after apply and posted an Implementation Complete
  with the marker and a Spec line and no Checklist section; archived
  prints pass at that head. The same run fixed a verify finding by a
  further archived change idd-29-...-fix1, so the idd-all half of 4.2 ran
  as well; its note now says so.
- 5.2: ticked on the scratch-clone self-check (links ok, archived pass);
  the check runs again after the real archive commit.

Refs #480
…dit seen in a sandbox run (#480)

spectra-verify (contract step 5.1) reported one critical and ten warnings;
a Spectra-tier sandbox run edited a file under archive/ to make the link
check pass. All fixed here before archiving:

- critical: idd-all's end-of-run report still asked for /spectra-archive on
  the default branch after the merge, citing the removed "Close triggers
  archive". Removed; the report says Step 3b.6 already archived. The
  merge-and-close test that pinned the #392 reminder now pins its absence.
- idd-all Phase 3b runs the spec preflight first (Step 3b.0.5): a
  third-party clone goes to the Simple path, the other stops halt.
- idd-diagnose's Spectra hand-off points at contract steps 5 and 6 and at
  the archived tasks path, so a hand-run Spectra issue is not left legacy.
- idd-implement Step 5a fills the checklist from the archived tasks.md when
  the issue has a change; the template no longer says TaskList only.
- idd-verify: the spec context runs only under VERIFY_PROFILE=code; a failed
  comment fetch is caught at the fetch (SPEC_FETCH_OK) and reported as
  unreadable instead of reading an empty file as legacy (tried with a gh
  that fails, and against a sandbox issue); the DA focus carries a closed
  summary (declaration form, links and archived status); Step 3 writes a
  Blocking row for any links result but ok, any archived result but pass,
  and an unreadable or invalid declaration.
- contract: after the archive, a requirement fix is a further change
  through step 7, never an edit under archive/ or of the main spec; a fix
  change is named exactly idd-<N>-fix<k>; the Spec line holds only the
  declaration.
- spec: the requirement on the wrappers now states the unpark and the
  unattended note (plus a scenario), and the Spectra tier's preflight.
  design: six Examples; the acceptance runs are the ones done. README:
  the linked-worktree limit.

spec-wrapper-contract 87 (17 new checks failed first); every suite that
reads the edited files passes (27 suites). spectra validate: valid;
spectra analyze: no findings.

Refs #480
…ed, preflight before the Spectra check (#480)

Change idd-480-fix1 (contract step 7: the fix adds and modifies
requirements, so it is a further Spectra change). Round 1 reported five
HIGH findings and several MEDIUM; fixed here:

- spec-change.py ic: chooses the issue's Implementation Complete from the
  comments JSON (several pages accepted), newest by OWNER, MEMBER or
  COLLABORATOR. idd-verify and idd-close both use it.
- idd-close Step 1.57 fetched nothing: it used IC_BODY, which no step
  set, so every case read an empty file and passed. It now fetches with
  gh api --paginate, chooses with ic, and stops with error when the
  comments cannot be read. spec-close-gate runs the block as written with
  a stand-in gh (row 5 is now executed, not grepped); the three new rows
  failed before the fix.
- links: error for a heading meant as a requirement that does not parse
  (### Requirement Missing colon, or no name) and for a head with no
  tracked file under specs/; a marker counts only when nothing but
  whitespace or a comment closer follows the title (alpha table no longer
  satisfies alpha). A specs/ holding only .gitkeep stays ok.
- idd-all Phase 3b: the spec preflight runs before the Spectra presence
  gate, so a third-party clone without Spectra proceeds; propose gets the
  Example and marker rules; the fix rule covers a rejected exemption.
- Contract and idd-all: an unreadable permission stops instead of passing
  --can-write no; step 7 says a rejected no-behaviour-change is fixed by
  the issue's first change.
- idd-verify: reviewers judge No executable check reasons. A backtick put
  into the SPEC_BLOCK string ran as a command; the contract suite now
  refuses one there.
- Docs: a linked worktree stops every issue (idd-implement, idd-all batch
  mode, CHANGELOG).

Not fixed here, filed as #491: legacy comments pass every gate, a
declared change is not tied to the issue, and the round's LOW findings.

Tests: spec-change 304, spec-close-gate 23, spec-wrapper-contract 101;
the 30 suites that read the changed files pass.

Refs #480
- ic exits 2 on an empty file (gh exited 0 and printed nothing is not
  "no comments"), and skips a comment whose body is not a string.
- links treats only headings that start with ### Requirement as meant
  for a requirement, as the spec says; a level-2 "Requirement notes"
  heading is not an error.
- An unreadable permission sets PF to an error JSON, so the existing
  status table stops on it (tried with a gh that prints nothing).
- The idd-verify requirement exempts third-party clones as the code does.
- Stale text: idd-all phase 0 warning, the verify comment on selection,
  the close-gate test header; a third-party Spectra-tier issue rerouted
  to idd-implement keeps a TaskList.

spec-change 312, spec-wrapper-contract 106, spec-close-gate 23 (new
checks failed first); the 30 suites that read the changed files pass.

Refs #480
…op on any preflight failure, fenced spec data (#480)

Change idd-480-fix2 (contract step 7). Round 2 had no HIGH; six MEDIUM and
one LOW were Blocking, two MEDIUM and five LOW In-scope fix. Fixed here:

- links: CommonMark fences (same character, at least as long, nothing
  after); Example and No-executable-check lines inside a fence do not
  count; a requirement name used twice in a capability is an error.
- preflight: an unreadable .spectra.yaml is error (one JSON line, exit 2);
  a spec_dir starting with '-' or naming the root is error; git ls-tree
  gets '--'; no --path-format (git 2.31).
- The contract and idd-all Step 3b.0 stop on no output, non-JSON or an
  unknown status. Both preflight blocks are now run by the contract suite
  with a stand-in gh and a PATH with and without spectra: the six rows of
  the new Example give the same status in both copies.
- ic: the marker may follow leading whitespace.
- idd-close Step 1.57: a failed gh repo view or git fetch is error, not a
  pass on a stale ref; --retroactive lists Step 1.57 among the skipped
  gates.
- idd-verify: the spec context runs only with a git range; its data sits
  in a per-run fence with the rules outside; the DA focus gains the spec
  checks only when a spec context was built (run without a range: no
  block, context and DA focus unchanged). verify-profiles says what of
  the default profile is unchanged.
- The manual Spectra path (diagnose hand-off, routing rule) runs the
  preflight first; the checklist-source rule is in the wrapper
  requirement; docs/commands.md no longer says archive after close.
- Tests: every nested bash runs with --norc --noprofile and stdin from
  /dev/null. /bin/bash 3.2 read ~/.bashrc when stdin was a socket and put
  a real spectra on the "clean" PATH (one run in ten failed).

spec-change 334, spec-close-gate 25, spec-wrapper-contract 132 (new checks
failed first); the 31 suites that read the changed files pass.

Refs #480
- idd-verify: under the code profile a missing range is reported as an
  error (fails closed) instead of skipping the spec checks; only prose and
  academic skip them (VERIFY_PROFILE defaults to code in this shell). The
  contract suite now runs the block three ways: prose, code without a
  range, code with a range and the fence token planted in the data.
- idd-close Step 1.57 reads the declaration first and fetches the default
  branch only for a declared change, so a failed fetch no longer holds an
  issue with no Implementation Complete or with an exemption.
- spec_dir starting with - or naming the root, a .spectra.yaml that is
  not a regular file, and a code fence that never closes are errors, now
  stated in the spec with Example rows.
- Docs: diagnose hand-off wording and route table, verify-profiles on the
  DA focus; the proposal no longer lists CHANGELOG.

spec-change 345, spec-close-gate 27, spec-wrapper-contract 138 (new
checks failed first); the 31 suites that read the changed files pass.

Refs #480
…literal paths, the fetched commit (#480)

Change idd-480-fix3 (contract step 7). Round 3 had no HIGH; nine MEDIUM were
Blocking and nine LOW or INFO In-scope fix, mostly parsers letting an edge
case through. Fixed here:

- declared and requirements() share the CommonMark fence rule; a fence
  counts at any indentation (inside a list item too); lines end only at
  \n, \r\n or \r (str.splitlines also broke at U+2028); a requirement
  heading may carry up to three leading spaces, as Spectra reads it.
- A .spectra.yaml that is a directory or a symlink at the revision is an
  error; a spec_dir starting with ':' is an error, and every git call uses
  literal pathspecs; no git on PATH is an error with one JSON line; spec_dir
  values in messages are cut at 60 characters.
- idd-close Step 1.57 checks the commit the fetch returned (FETCH_HEAD),
  reads the declaration form with python instead of jq, and its result
  table stops on no output. The spec now limits the default-branch stop to
  a declared change, as the code does.
- idd-verify: the spec's No-executable-check line gives way to an Example
  (the spec context the reviewers get) whose three rows the contract suite
  already runs; VERIFY_PROFILE and the no-range error are written into the
  spec; the changed-spec list names main specs only; stale comments fixed.
- The contract's close-out link check stops when it cannot find SPEC_BASE.

spec-change 370, spec-close-gate 29, spec-wrapper-contract 144 (new checks
failed first; the indented-heading row now names the right requirement);
the 31 suites that read the changed files pass.

Refs #480
- The marker search reads lines the CommonMark way too: a marker followed
  by U+2028 and more text no longer counts.
- A .spectra.yaml that is a symbolic link is an error in the working tree
  as it is at a revision (now tested at both).
- The contract and idd-all explain the close-out base as the merge-base
  with the freshly fetched default branch (FETCH_HEAD).
- The Example row "code without a range" asserts both errors and the DA
  suffix; FENCE_RE (no longer used) is gone; spec_dir_of splits lines the
  same way; the declared rows sit in the declared section.

spec-change 378, spec-close-gate 29, spec-wrapper-contract 148 (new
checks failed first); the 31 suites that read the changed files pass.

Refs #480
…c plan line, unquoted paths (#480)

Change idd-480-fix4 (contract step 7). Round 4 had two HIGH and three MEDIUM
Blocking, four In-scope fix. Fixed here:

- HIGH: idd-implement Step 2.5's "skip this step when there is a change"
  also skipped the routing table, so a direct /idd-implement on a Plan issue
  no longer offered /idd-plan. A change now skips only the TaskList.
- HIGH: the Implementation Plan's **Spec plan**: line, which later steps
  read, is now in the spec and the contract, in three forms: change <name>,
  no behaviour change (<a|b|c|d>), rejected (change <name> left parked).
  idd-plan writes rejected when the maintainer aborts; the wrapper applies an
  existing change only when the newest plan names it, so a rejected proposal
  is no longer applied by the next /idd-implement or /idd-all.
- Every git call runs with core.quotePath=false (and verify's changed-spec
  list): a capability named 中文能力 came back quoted and went unchecked.
- Contract steps 3 and 4 (unattended check, unpark) are fixed bash and now
  have an Example that runs them with a stand-in spectra; the preflight
  rows also check whether the run proceeds or stops (PF_RC).
- spec_dir: a value in quotes is read whole (" #" inside it is not a
  comment); ic catches RecursionError and exits 2.

spec-change 387, spec-wrapper-contract 166, spec-close-gate 29 (new checks
failed first); the 31 suites that read the changed files pass.

Refs #480
…fore the propose (#480)

spectra-verify on idd-480-fix4 found two critical gaps in the round-4 fix:
the rule "apply an existing change only when the newest plan names it" was
in the contract only, while idd-implement still applied any idd-<N>- change
(and its own Step 2 plan would have become the newest plan); and the
/idd-plan offer sat in Step 2.5, after the propose.

- spec-change.py plan reads the **Spec plan**: line of the newest
  Implementation Plan by a writer (four forms: change, no behaviour
  change, third-party clone, rejected), with an Example of nine rows.
- Contract step 3 runs it before any propose or comment and stops on
  rejected or on a change no approved plan names; idd-implement Step 0.6
  does this before Step 2 posts its plan, and asks a direct Plan-tier
  invocation about /idd-plan before it proposes.
- idd-plan writes the line for every form and re-presents a rejected
  change for approval instead of leaving the issue stuck.
- "spec_dir: # a comment" is an error again (a regression of fix4).
- Tests: steps 3-4 rows also assert "attended"; PF_RC must be set.

spec-change 416, spec-wrapper-contract 184, spec-close-gate 29 (new
checks failed first); the 31 suites that read the changed files pass.

Refs #480
…d, NUL-separated paths (#480)

- idd-plan writes `**Spec plan**: proposed (change <name>)` before plan mode and
  changes it to `change <name>` only on Approved; contract step 3 stops on
  `proposed` and `rejected` and names /idd-plan
- step 3 checks `spectra list`; an unreadable list stops instead of proposing
- idd-implement and fix rounds post their plan line before they propose
- git paths are read NUL-separated (ls-tree -z, diff -z)
- install-spectra names `brew install --cask spectra-app`
- PLAN_RE needs the end of the heading; the Plan question is asked once

Change: idd-480-fix5
…proved (#480)

spectra-verify on idd-480-fix5 found that a `proposed` change sent the user
back to /idd-plan, which then stopped again. idd-plan now presents the open
change whenever contract step 3 stops because it is not approved (proposed,
rejected, no plan names it, or a plan names another change). Step 3 also
stops when `spectra list` prints something that is not JSON. Two text
checks that passed before fix5 now check the changed passages.

Change: idd-480-fix5
Verify round 6 found that idd-plan could not read a parked change's files
(spectra-propose parks it; spectra 3.0.0 keeps parked files outside the
changes directory) and that a revision changed only the plan comment.
idd-plan now runs Step 3.5 before plan mode: unpark if parked, find the
change directory with `spectra instructions apply --json`, stop when the
proposal, the tasks or a spec delta is missing, and show those files in
plan mode. A revision edits the files and runs `spectra validate`; an
abort parks the change again.

Change: idd-480-fix6
The ExitPlanMode template has a place for the change files; Step 0 lists Step 3.5 and handle_plan_response follows the new Revised and Aborted rows; "proposal and tasks" becomes "proposal, spec delta and tasks".

Change: idd-480-fix6
…d-implement proposes (#480)

Verify rounds 4 to 7 each found a HIGH in approving the Spectra proposal in
plan mode; round 7 showed that a revision cannot be made in the change's
files while the session stays in plan mode. Per the maintainer's decision,
idd-plan no longer proposes: it writes `proposed (change <name>)` before
plan mode and `change <name>` on approval, and idd-implement proposes in
the light form, as in the Simple tier. Step 3.5 and the unreleased
`rejected` form are removed. Approving the proposal itself moves to #497.

Change: idd-480-fix7
idd-plan looks up the open change with spectra list; the README, the Step 6 example and the flow diagram match the new flow; the contract test, pasted twice by mistake in f5b6199, is one file again.

Change: idd-480-fix7
@kiki830621
kiki830621 merged commit 2dc56ab into main Nov 11, 2026
1 check passed
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.

1 participant