@rsaglobaltech/specgate 0.22.0 → 0.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +135 -51
- package/README.md +81 -96
- package/dist/packages/core/src/domain/CapabilitySpecMerge.js +83 -0
- package/dist/packages/core/src/domain/CapabilitySpecMerge.js.map +1 -0
- package/dist/packages/core/test/unit/capability-spec-merge.test.js +104 -0
- package/dist/packages/core/test/unit/capability-spec-merge.test.js.map +1 -0
- package/dist/packages/mcp-spec-driven/src/native-tools.js +1 -1
- package/dist/packages/mcp-spec-driven/src/native-tools.js.map +1 -1
- package/dist/scripts/agents/commands.js +7 -7
- package/dist/scripts/agents/commands.js.map +1 -1
- package/dist/scripts/agents/detect.js +1 -0
- package/dist/scripts/agents/detect.js.map +1 -1
- package/dist/scripts/agents/init.js +13 -0
- package/dist/scripts/agents/init.js.map +1 -1
- package/dist/scripts/alm/cli.js +3 -2
- package/dist/scripts/alm/cli.js.map +1 -1
- package/dist/scripts/cli/commands/change/ChangeCommand.js +22 -1
- package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -1
- package/dist/scripts/cli/commands/change/TicketCommand.js +64 -6
- package/dist/scripts/cli/commands/change/TicketCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/CheckCommand.js +15 -5
- package/dist/scripts/cli/commands/quality/CheckCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/DoctorCommand.js +22 -8
- package/dist/scripts/cli/commands/quality/DoctorCommand.js.map +1 -1
- package/dist/scripts/docs/journey-storyboard.js +34 -17
- package/dist/scripts/docs/journey-storyboard.js.map +1 -1
- package/dist/scripts/docs/nav.js +155 -143
- package/dist/scripts/docs/nav.js.map +1 -1
- package/dist/scripts/docs/record-journey.js +46 -19
- package/dist/scripts/docs/record-journey.js.map +1 -1
- package/dist/scripts/docs/terminal-storyboard.js +15 -11
- package/dist/scripts/docs/terminal-storyboard.js.map +1 -1
- package/dist/scripts/draft/drafting-guide.js +4 -0
- package/dist/scripts/draft/drafting-guide.js.map +1 -1
- package/dist/scripts/draft/ticket-guide.js +4 -0
- package/dist/scripts/draft/ticket-guide.js.map +1 -1
- package/dist/scripts/harness/init.js +85 -25
- package/dist/scripts/harness/init.js.map +1 -1
- package/dist/scripts/harness/prompt.js +13 -1
- package/dist/scripts/harness/prompt.js.map +1 -1
- package/dist/scripts/lib/base-ids.js +7 -0
- package/dist/scripts/lib/base-ids.js.map +1 -1
- package/dist/scripts/lib/change-base.js +230 -0
- package/dist/scripts/lib/change-base.js.map +1 -0
- package/dist/scripts/lib/change-overlap.js +234 -0
- package/dist/scripts/lib/change-overlap.js.map +1 -0
- package/dist/scripts/lib/surface.js +8 -0
- package/dist/scripts/lib/surface.js.map +1 -1
- package/dist/scripts/lib/ticket-keys.js +48 -3
- package/dist/scripts/lib/ticket-keys.js.map +1 -1
- package/dist/scripts/merge-capability-spec.js +87 -0
- package/dist/scripts/merge-capability-spec.js.map +1 -0
- package/dist/scripts/vcs/github-pr.js +1 -1
- package/dist/scripts/vcs/github-pr.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<!-- specgate:allow-placeholders — release notes quote the {{VAR}} template syntax. -->
|
|
2
|
+
|
|
2
3
|
# Changelog
|
|
3
4
|
|
|
4
5
|
Notable changes, newest first. Follows [Keep a Changelog](https://keepachangelog.com/)
|
|
@@ -8,6 +9,91 @@ The release process is in [`docs/release-process.md`](docs/release-process.md).
|
|
|
8
9
|
|
|
9
10
|
## [Unreleased]
|
|
10
11
|
|
|
12
|
+
## [0.22.2] — 2026-10-21
|
|
13
|
+
|
|
14
|
+
Parallel tickets that never overwrite each other, rehearsed end to end on a brownfield Maven project with Jira tickets and OpenCode.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **A merge driver that is gone falls back to git's merge** (REQ-169): in a
|
|
19
|
+
project without `node_modules`, the drivers run this machine's copy of
|
|
20
|
+
specgate. With that copy gone, git stopped the merge with only your side in
|
|
21
|
+
the file, no markers, and `git add` dropped the other side's text. The
|
|
22
|
+
driver now says it is missing and merges by lines; `specgate doctor` warns.
|
|
23
|
+
Re-run `specgate harness init` in clones registered before this release.
|
|
24
|
+
- **`id_taken_on_base` only for ids the branch introduced** (REQ-120): a
|
|
25
|
+
requirement the base changed after the branch started was reported as an id
|
|
26
|
+
taken, with the advice to renumber it.
|
|
27
|
+
- **A local `develop` nobody updated is not the base** (REQ-148): `pr.base`
|
|
28
|
+
resolves to `origin/develop` unless the local branch already contains it,
|
|
29
|
+
and a ticket's branch no longer tracks its base. Behind origin, every
|
|
30
|
+
colleague's commit merged from `origin/develop` was reported as missing the
|
|
31
|
+
ticket key.
|
|
32
|
+
- **`check` compares ids with `pr.base`** (REQ-120): ticket keys were
|
|
33
|
+
measured from `develop` and ids from the remote's default, `main`, so an id
|
|
34
|
+
taken on `develop` and not yet released went unseen.
|
|
35
|
+
- **`harness init` keeps a generated matrix on `merge=union`**: it appended
|
|
36
|
+
the row driver after the union line, and git takes the last matching line,
|
|
37
|
+
so the matrix could stop a merge again (ADR-0036).
|
|
38
|
+
- **A ticket's branch starts from `develop` with gitflow** (REQ-148): from
|
|
39
|
+
`pr.base`, else the branch you are on, else the remote's default. A clone
|
|
40
|
+
whose default is `main` cut the branch from `origin/main`, without the
|
|
41
|
+
team's work on `develop`; `ticket_key_missing` measures from the same base.
|
|
42
|
+
- **Readable ids from German summaries** (REQ-161): `ß` → `ss`, `ä` → `ae`…;
|
|
43
|
+
"Groß-/Kleinschreibung" made `gro-kleinschreibung`.
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- **`change_base_moved`** (REQ-168): a change records, in `based_on` in its
|
|
48
|
+
`change.yaml`, the text of each requirement it modifies or removes; `check`
|
|
49
|
+
warns and `archive` refuses when that requirement changed since, and `check`
|
|
50
|
+
warns before the branch has even brought the base in.
|
|
51
|
+
`change validate <change> --rebased` records the new text once the delta is
|
|
52
|
+
rewritten. When two tickets rewrote one requirement, the second used to
|
|
53
|
+
archive over the first with a green gate and no conflict.
|
|
54
|
+
- **Capability specs merge requirement by requirement** (REQ-166):
|
|
55
|
+
`harness init` registers a second git merge driver, `specgate-spec`, for
|
|
56
|
+
`docs/specs/capabilities/*/spec.md`, and `doctor` checks it. Two tickets
|
|
57
|
+
archiving into the same capability used to conflict on the whole file; only
|
|
58
|
+
a requirement both rewrote differently conflicts now.
|
|
59
|
+
- **OpenCode in `agents init`** (REQ-162): `/specgate-*` commands in
|
|
60
|
+
`.opencode/commands/`, detected from `.opencode/` or `opencode.json`.
|
|
61
|
+
- **Opening a ticket's change commits and pushes it** (REQ-165), so the ids it
|
|
62
|
+
reserved are visible to every other clone at once; the branch used to be
|
|
63
|
+
pushed empty, with the reservation left uncommitted on one disk.
|
|
64
|
+
- **`change_id_clash`** (REQ-164), and `propose --from-ticket` fetches
|
|
65
|
+
`origin` before reserving ids (REQ-163): two developers who opened tickets a
|
|
66
|
+
minute apart on two clones both reserved REQ-010.
|
|
67
|
+
- **`change_overlap`** (REQ-160): `check`, and the report on a change opened
|
|
68
|
+
from a ticket, warn when a requirement your open change modifies or removes
|
|
69
|
+
is also rewritten by another open change, on this branch or on any local or
|
|
70
|
+
remote-tracking branch not merged yet. Two tickets rewriting REQ-012 on two
|
|
71
|
+
branches used to surface as a git conflict at the second merge, or not at
|
|
72
|
+
all.
|
|
73
|
+
|
|
74
|
+
## [0.22.1] — 2026-10-20
|
|
75
|
+
|
|
76
|
+
Documentation a newcomer can follow, and the CLI's words brought in line with it.
|
|
77
|
+
|
|
78
|
+
### Changed
|
|
79
|
+
|
|
80
|
+
- **The documentation, rewritten** after an audit of every page against the
|
|
81
|
+
CLI and the first real end-to-end run on Jira Cloud and GitHub. Three
|
|
82
|
+
sources of work (a change, a brief, a Jira ticket) into one lifecycle of
|
|
83
|
+
four verbs; the recorded journeys run `propose`, `apply` and `archive`;
|
|
84
|
+
archive comes before the pull request everywhere. New pages: _From a Jira
|
|
85
|
+
ticket_ for a team lead setting it up, and _An existing codebase, with work
|
|
86
|
+
in Jira_ (Maven profiles, a parent POM, Bitbucket and Jenkins).
|
|
87
|
+
- **The `/specgate:draft` agent command runs `propose --from-brief`**, and the
|
|
88
|
+
MCP write guard names `specgate propose <id>`.
|
|
89
|
+
|
|
90
|
+
### Fixed
|
|
91
|
+
|
|
92
|
+
- `propose --help` lists `--no-push`; `alm --help` no longer says a ticket has
|
|
93
|
+
no acceptance criterion.
|
|
94
|
+
- `alm pr` asks for the least token it needs: Pull requests, read and write.
|
|
95
|
+
- `alm pr` is covered by an E2E journey and is not exposed as an MCP tool.
|
|
96
|
+
|
|
11
97
|
## [0.22.0] — 2026-10-20
|
|
12
98
|
|
|
13
99
|
A brief shaped like what it becomes, checked before any agent drafts from it
|
|
@@ -43,7 +129,7 @@ ticket to Done, the board moved by its own automation.
|
|
|
43
129
|
### Changed
|
|
44
130
|
|
|
45
131
|
- **A draft is not opened over a broken brief.** `propose --from-brief
|
|
46
|
-
|
|
132
|
+
<module>` refuses with `brief_not_ready` while the brief has an error: an
|
|
47
133
|
empty body, an empty module section, a module without its section once the
|
|
48
134
|
brief uses sections, or rules without examples. A brief with no module
|
|
49
135
|
sections — a pasted email — drafts as before.
|
|
@@ -165,7 +251,7 @@ while it works (ADR-0037).
|
|
|
165
251
|
|
|
166
252
|
- The placeholder rule ignores code spans, and the vague-step rule code spans
|
|
167
253
|
and quoted text: `` `tool verify <module>` `` is a command, not a template.
|
|
168
|
-
- TDD-3 asks a matrix row for a requirement a spec
|
|
254
|
+
- TDD-3 asks a matrix row for a requirement a spec _declares_ (a heading or a
|
|
169
255
|
requirement table row outside fenced code), not for every id it mentions.
|
|
170
256
|
- A generated matrix is declared `merge=union` in `.gitattributes`: parallel
|
|
171
257
|
branches no longer conflict on it, and `check` regenerates it.
|
|
@@ -229,7 +315,7 @@ while it works (ADR-0037).
|
|
|
229
315
|
runtime dependencies; `SPECGATE_FORJA_CMD` points at another forja.
|
|
230
316
|
- **`specgate add usecase|entity|port`** in a forja project: the class where the
|
|
231
317
|
architecture expects it, its test and its wiring, through `forja add`; `add
|
|
232
|
-
|
|
318
|
+
usecase` also creates the requirement and names it in the test. Outside a forja
|
|
233
319
|
project it says to use `new`. In a forja project, `status` suggests it as the
|
|
234
320
|
next step for a requirement with no code.
|
|
235
321
|
- **`arch_cmd`: your architecture check in the gate** ([ADR-0028](docs/specs/adr/0028-architecture-conformance-is-part-of-the-gate.md), points 1–2).
|
|
@@ -365,8 +451,8 @@ while it works (ADR-0037).
|
|
|
365
451
|
`transfers`, `event-registration`, `clinical-record`, `appointment-booking`,
|
|
366
452
|
`shop-orders` and `time-attendance`: 65 requirements and 85 scenarios, each
|
|
367
453
|
implemented and tested by the product it came from (Spring Boot, Quarkus and
|
|
368
|
-
TypeScript stacks). Questions a pilot could not answer ship as
|
|
369
|
-
|
|
454
|
+
TypeScript stacks). Questions a pilot could not answer ship as _Needs
|
|
455
|
+
Clarification_ — drug interaction alerts, shipping costs — instead of an
|
|
370
456
|
invented answer. Separate id ranges, so a project can install all seven.
|
|
371
457
|
Install them with `specops add` into a project made by `specgate init`;
|
|
372
458
|
`init --from-pack` does not handle a requirement with two scenarios yet.
|
|
@@ -531,9 +617,9 @@ while it works (ADR-0037).
|
|
|
531
617
|
|
|
532
618
|
### Documentation
|
|
533
619
|
|
|
534
|
-
- **Two new guides.**
|
|
620
|
+
- **Two new guides.** _From a client brief_ — the brief, a draft per module,
|
|
535
621
|
assumptions and open questions, the D1–D10 checklist, writing in Spanish, and
|
|
536
|
-
what the checklist cannot see.
|
|
622
|
+
what the checklist cannot see. _Already on OpenSpec_ — `verify`, scenario ids,
|
|
537
623
|
V1–V7, adopting with `--since`, the GitHub Action.
|
|
538
624
|
- **The harness** documents when it does not retry, the per-attempt time limit,
|
|
539
625
|
and the build in the gate; **the README** covers drafting from a brief,
|
|
@@ -620,7 +706,7 @@ From a second and third cycle on the same product (reservas_app), on 0.17.1.
|
|
|
620
706
|
- **`plan` and `status` agree with `validate` about untested scenarios.** A
|
|
621
707
|
requirement with two scenarios no test named was "Ready to close — its test
|
|
622
708
|
is in place", and `NEEDS_STATUS_UPDATE` to the harness, while `validate
|
|
623
|
-
|
|
709
|
+
--strict` said "Nothing proves" them. It is now `NEEDS_TEST`.
|
|
624
710
|
- **`draft --check`:** a requirement can say it lives on one surface
|
|
625
711
|
(`surfaces=web` in its trace), so a menu is not asked for an API scenario
|
|
626
712
|
(D3); a value already in the project's specification — reviewed in an
|
|
@@ -646,7 +732,7 @@ Found building a second real product from a client brief (reservas_app,
|
|
|
646
732
|
written in Spanish).
|
|
647
733
|
|
|
648
734
|
- **A draft archives into feature files, in its own language.** `change
|
|
649
|
-
|
|
735
|
+
archive` wrote no `.feature` for a requirement whose trace named none — a
|
|
650
736
|
draft that passed `draft --check` archived with "0 materialised". Each
|
|
651
737
|
requirement with scenarios now gets `features/<capability>/<REQ>.feature`.
|
|
652
738
|
Scenarios written with `DADO / CUANDO / ENTONCES` become Spanish Gherkin
|
|
@@ -670,7 +756,7 @@ written in Spanish).
|
|
|
670
756
|
the one line that turns it on (`specgate harness init`). The first gate after
|
|
671
757
|
adoption still checks the specification only, as documented.
|
|
672
758
|
- **`draft --check`:** an answered question (an `Answer` column, or `Answer
|
|
673
|
-
|
|
759
|
+
(Q1): …` below the table) no longer keeps its requirement waiting; a value
|
|
674
760
|
repeated in a scenario is one finding, not one per mention; "responsive" is
|
|
675
761
|
not read as a promised response time, and `px` is a unit.
|
|
676
762
|
- **`status` shows the title of a requirement archived from a change** instead
|
|
@@ -686,6 +772,7 @@ written in Spanish).
|
|
|
686
772
|
version, commit or variables do.
|
|
687
773
|
|
|
688
774
|
## [0.16.0] — 2026-10-09
|
|
775
|
+
|
|
689
776
|
### Changed
|
|
690
777
|
|
|
691
778
|
- **`AGENTS.md` is the agent contract; `AI_RULES.md` folds into it**
|
|
@@ -761,7 +848,7 @@ written in Spanish).
|
|
|
761
848
|
(`--run`), or after a scenario's text changed since `--record` pinned it.
|
|
762
849
|
`--since <ref>` gates only claims made after the ref, so adopting it never
|
|
763
850
|
fails a project for its past. `--ids` prints the ids to name; `--format
|
|
764
|
-
|
|
851
|
+
github` annotates the spec lines; `actions/verify` runs it on pull requests.
|
|
765
852
|
Read against OpenSpec's own repository: 747 scenarios, 108 claims, including
|
|
766
853
|
its archived history from before the structured format.
|
|
767
854
|
|
|
@@ -851,7 +938,7 @@ published 0.14.1:
|
|
|
851
938
|
|
|
852
939
|
- **A pack keeps a generated matrix generated.** Installing a pack wrote
|
|
853
940
|
matrix rows and turned the project back into a hand-kept matrix; `matrix
|
|
854
|
-
|
|
941
|
+
--migrate` then wrote 47 placeholder sections into `spec.md` titled after
|
|
855
942
|
use cases. Now each requirement's use case, command, aggregate, event and
|
|
856
943
|
context go into the `csda:trace` of its section — the pack's capability
|
|
857
944
|
spec, or a new `spec.md` section carrying the pack's own description — and
|
|
@@ -866,7 +953,7 @@ published 0.14.1:
|
|
|
866
953
|
scenario: a requirement with two scenarios ran two paid agent sessions on
|
|
867
954
|
the same branch.
|
|
868
955
|
- **`setup_cmd`** prepares each fresh worktree before the agent (`harness
|
|
869
|
-
|
|
956
|
+
init` proposes `npm ci` / `pnpm install` / `yarn install` from the
|
|
870
957
|
lockfile), so the agent can run the tests it writes and `check` no longer
|
|
871
958
|
needs `npm ci` in `test_cmd`. The generated prompt prefix teaches linking by
|
|
872
959
|
mention instead of "the test named in the matrix".
|
|
@@ -889,7 +976,7 @@ domain packs in a specops repository:
|
|
|
889
976
|
lines, and the `''` / `\"` escapes inside quotes. A pack generated with
|
|
890
977
|
PyYAML's defaults failed with "Unexpected YAML token".
|
|
891
978
|
- **"tag work" is not a vague step.** The vague-step check matched the bare
|
|
892
|
-
word
|
|
979
|
+
word _work_; it now flags verdicts ("it works", "should work"), not trade
|
|
893
980
|
terms.
|
|
894
981
|
- **A requirement can have several scenarios.** On a generated matrix a
|
|
895
982
|
requirement with two scenarios has two rows, and the gate called it a
|
|
@@ -970,7 +1057,7 @@ Found by following the documentation step by step on the published 0.13.0:
|
|
|
970
1057
|
published.
|
|
971
1058
|
- **Diagrams render on every docs page.** A blank line inside an inlined SVG
|
|
972
1059
|
ended Markdown's HTML block, so the rest of the diagram showed as a block of
|
|
973
|
-
escaped markup on
|
|
1060
|
+
escaped markup on _Domain packs_ and in _Specs that cannot lie_. Blank lines
|
|
974
1061
|
are dropped when a diagram is inlined, and a test fails on any page showing
|
|
975
1062
|
diagram markup as text.
|
|
976
1063
|
- **`mcp install --help` names the clients it supports.** It offered
|
|
@@ -1064,7 +1151,7 @@ Found by following the documentation step by step on the published 0.13.0:
|
|
|
1064
1151
|
`completion`, `studio`, `onboard` — take it from 14 to 34 of 60 commands, and
|
|
1065
1152
|
offline journeys for packs — `specops add/diff/sync/remove` against a local
|
|
1066
1153
|
git remote with tags, `pack bundle` for an air-gapped install, `pack
|
|
1067
|
-
|
|
1154
|
+
init/lint/infer`, `expand` — to 43, and the change cycle (`new` → `archive`
|
|
1068
1155
|
→ delivered with `done`), `change author` reverting an agent's write outside
|
|
1069
1156
|
the change, `harness init/prompt/run/report` and `specops contribute` to 55.
|
|
1070
1157
|
|
|
@@ -1252,13 +1339,13 @@ Agent files generated by earlier versions are named `csda`; run
|
|
|
1252
1339
|
short help and keep working. `adopt`'s next steps now teach `check`, `new`,
|
|
1253
1340
|
`status` and `ci init`.
|
|
1254
1341
|
- **`status` lists the queue itself.** One line per requirement — its title and
|
|
1255
|
-
what it still needs — split into
|
|
1342
|
+
what it still needs — split into _Ready to close_ and _To do_, capped at 12
|
|
1256
1343
|
per group. `Next` names a requirement (`specgate done REQ-003 --strict`)
|
|
1257
1344
|
instead of answering `specgate plan`. `--json` gains a `requirements` array.
|
|
1258
1345
|
`plan` leaves the daily help and keeps the full detail.
|
|
1259
1346
|
- **`plan` no longer says "code & test exist" over a row with no code.** A
|
|
1260
|
-
declared code path is optional; the heading now says
|
|
1261
|
-
code
|
|
1347
|
+
declared code path is optional; the heading now says _its declared test and
|
|
1348
|
+
code exist_.
|
|
1262
1349
|
- **The scenario rules are owed on delivery, like the files.** A Draft row's
|
|
1263
1350
|
feature file is not held to `--strict-scenarios`, so a fresh `specgate new`
|
|
1264
1351
|
does not turn CI red. The three rules that make a suite report a pass it
|
|
@@ -1323,7 +1410,7 @@ Agent files generated by earlier versions are named `csda`; run
|
|
|
1323
1410
|
and `--from` repeats and accepts a directory, so a command shared by three
|
|
1324
1411
|
files is proposed once.
|
|
1325
1412
|
|
|
1326
|
-
`--llm` is
|
|
1413
|
+
`--llm` is _not_ here: ADR-0014 defers it, and reopening that needs an ADR
|
|
1327
1414
|
rather than a flag. Everything above stays a skeleton to review with every
|
|
1328
1415
|
guess carrying its `TODO` — an inference that stops looking like a guess is
|
|
1329
1416
|
the failure mode the ADR names. Closes #32.
|
|
@@ -1367,7 +1454,7 @@ Agent files generated by earlier versions are named `csda`; run
|
|
|
1367
1454
|
runs in its own process and every one creates a worktree in the same
|
|
1368
1455
|
repository; git writes `.git/worktrees/<name>/` incrementally, so a sibling
|
|
1369
1456
|
read an entry that was half there and failed with `failed to read …
|
|
1370
|
-
|
|
1457
|
+
/commondir`. Worse, the failure was _attributed_: the run reported the
|
|
1371
1458
|
requirement as failed with "the agent produced no files", so a race in the
|
|
1372
1459
|
harness read as the agent's fault.
|
|
1373
1460
|
|
|
@@ -1405,7 +1492,7 @@ Agent files generated by earlier versions are named `csda`; run
|
|
|
1405
1492
|
[`spec-gate`](https://www.npmjs.com/package/spec-gate) normalises to exactly
|
|
1406
1493
|
`specgate`, so the registry refuses the name to everyone and reports it as a
|
|
1407
1494
|
credentials error. ADR-0024 had checked availability with `npm view specgate`
|
|
1408
|
-
→ 404, which says
|
|
1495
|
+
→ 404, which says _not published_ and never _creatable_; the
|
|
1409
1496
|
[2026-09-01 addendum](docs/specs/adr/0024-the-tool-is-renamed-the-format-is-not.md)
|
|
1410
1497
|
records both the decision and the bad check that led to it.
|
|
1411
1498
|
|
|
@@ -1447,7 +1534,7 @@ the one that finishes the rename past the layer where it had stopped.
|
|
|
1447
1534
|
**The on-disk format is deliberately unchanged.** `csda:trace`, `csda:value`,
|
|
1448
1535
|
`csda:allow-placeholders` and the `.csda/` directory keep their names. Those
|
|
1449
1536
|
are not branding: they are a parsed format and a config directory that live
|
|
1450
|
-
inside
|
|
1537
|
+
inside _user_ repositories, and renaming them would be a silent breaking
|
|
1451
1538
|
change to every adopted project — surfacing as "requirement not found" rather
|
|
1452
1539
|
than as "your marker prefix changed". Reading both prefixes is a real
|
|
1453
1540
|
migration feature, not a find-and-replace, and it is not built here.
|
|
@@ -1462,7 +1549,7 @@ the one that finishes the rename past the layer where it had stopped.
|
|
|
1462
1549
|
rebuilt in place and keep working.
|
|
1463
1550
|
|
|
1464
1551
|
`docs/release-process.md` gains the one-time cutover: the exact `npm
|
|
1465
|
-
|
|
1552
|
+
deprecate` invocation for `create-spec-driven-app`, why the old package is
|
|
1466
1553
|
deprecated and never unpublished (npm blocks reusing an unpublished name, and
|
|
1467
1554
|
a pinned dependency would break for no gain), and the sequencing constraint —
|
|
1468
1555
|
the rename and the release that publishes `specgate` are one event, because
|
|
@@ -1498,7 +1585,7 @@ The release that starts checking content instead of only paperwork. Every check
|
|
|
1498
1585
|
until now answered "are these documents internally consistent?"; none answered
|
|
1499
1586
|
"does the code say what the spec says?". These do — for the narrow slice where
|
|
1500
1587
|
that question has an honest answer. The reasoning, including what was
|
|
1501
|
-
deliberately
|
|
1588
|
+
deliberately _not_ built, is [ADR-0023](docs/specs/adr/0023-checking-content-gate-or-report.md).
|
|
1502
1589
|
|
|
1503
1590
|
### Added
|
|
1504
1591
|
|
|
@@ -1510,7 +1597,7 @@ deliberately *not* built, is [ADR-0023](docs/specs/adr/0023-checking-content-gat
|
|
|
1510
1597
|
the H13 mistake. These two rules are what a regex can assert honestly.
|
|
1511
1598
|
|
|
1512
1599
|
The point is upstream of any code checking: `- Max 5 failed attempts per hour
|
|
1513
|
-
|
|
1600
|
+
per user` is not something a machine can hold code to. RFC 2119 detection also
|
|
1514
1601
|
stops being duplicated — `DeltaSpec` enforced it for requirements inside a
|
|
1515
1602
|
change while a capability spec at rest was never checked; both now read one
|
|
1516
1603
|
definition.
|
|
@@ -1523,7 +1610,7 @@ deliberately *not* built, is [ADR-0023](docs/specs/adr/0023-checking-content-gat
|
|
|
1523
1610
|
Opt-in, and that was measured rather than assumed: the first version ran
|
|
1524
1611
|
unconditionally on the theory that a missing path has no legitimate reading,
|
|
1525
1612
|
and the test suite disproved it at once — a `Draft` or `In Dev` row routinely
|
|
1526
|
-
names the file a requirement is
|
|
1613
|
+
names the file a requirement is _going to_ land in. Planning ahead is not
|
|
1527
1614
|
documentary drift.
|
|
1528
1615
|
|
|
1529
1616
|
- **Declared-value drift in `csda report`.** Annotate a value on both sides —
|
|
@@ -1547,7 +1634,7 @@ deliberately *not* built, is [ADR-0023](docs/specs/adr/0023-checking-content-gat
|
|
|
1547
1634
|
|
|
1548
1635
|
- **`csda change new <id> --from-value-drift <REQ-ID>:<value_id>`** turns a
|
|
1549
1636
|
diverging value into a reviewable change. It writes a `## MODIFIED
|
|
1550
|
-
|
|
1637
|
+
Requirements` delta carrying the full requirement, with the structured
|
|
1551
1638
|
`value_<id>` rewritten to the value the code declares.
|
|
1552
1639
|
|
|
1553
1640
|
**The prose is left alone.** Turning "expires after 15 minutes" into "after
|
|
@@ -1563,7 +1650,7 @@ deliberately *not* built, is [ADR-0023](docs/specs/adr/0023-checking-content-gat
|
|
|
1563
1650
|
|
|
1564
1651
|
### Fixed
|
|
1565
1652
|
|
|
1566
|
-
- **The gate approved an agent that wrote nothing (H19).** The gate runs
|
|
1653
|
+
- **The gate approved an agent that wrote nothing (H19).** The gate runs _before_
|
|
1567
1654
|
`csda done`, so at gate time the requirement is still `Draft` — and
|
|
1568
1655
|
`--strict-tdd`'s "no `Test Artifact = TBD` past Draft" rule does not apply to a
|
|
1569
1656
|
Draft row. `done` then moved the status to `Implemented` and nothing validated
|
|
@@ -1595,8 +1682,8 @@ deliberately *not* built, is [ADR-0023](docs/specs/adr/0023-checking-content-gat
|
|
|
1595
1682
|
|
|
1596
1683
|
Worse than a red gate on day one: `csda harness run` on a new project **burned
|
|
1597
1684
|
all three agent attempts** failing on something the agent neither caused nor
|
|
1598
|
-
could fix. And it contradicted the README's L2 —
|
|
1599
|
-
test coverage, ~1 hour"
|
|
1685
|
+
could fix. And it contradicted the README's L2 — _"a PR gate enforcing spec and
|
|
1686
|
+
test coverage, ~1 hour"_ — since the gate was red before the hour started.
|
|
1600
1687
|
|
|
1601
1688
|
The placeholder row is gone, replaced by a comment pointing at
|
|
1602
1689
|
`csda req add "<what the requirement does>"`, which writes the row in `spec.md`
|
|
@@ -1652,7 +1739,7 @@ deliberately *not* built, is [ADR-0023](docs/specs/adr/0023-checking-content-gat
|
|
|
1652
1739
|
- **`specgate adopt` did not run at all.** `templates/adopt/spec.md.tpl` asks
|
|
1653
1740
|
for `{{PROPOSED_REQUIREMENTS}}` and nothing supplied it, so the brownfield
|
|
1654
1741
|
entry point died on `Missing variable 'PROPOSED_REQUIREMENTS' required by
|
|
1655
|
-
|
|
1742
|
+
template` for every repository.
|
|
1656
1743
|
|
|
1657
1744
|
Two parallel branches caused it. P6 taught `adopt` to seed one requirement per
|
|
1658
1745
|
capability `onboard` reads off the layout, and added `--monorepo` and
|
|
@@ -1719,7 +1806,7 @@ deliberately *not* built, is [ADR-0023](docs/specs/adr/0023-checking-content-gat
|
|
|
1719
1806
|
- **The landing page claimed 24 commands against a surface of 25.**
|
|
1720
1807
|
|
|
1721
1808
|
- **CI had not run this repository's own gate since the rename.** The rename
|
|
1722
|
-
commit changed the
|
|
1809
|
+
commit changed the _references_ to `bin/specgate.{ts,js}` in `ci.yml`,
|
|
1723
1810
|
`CONTRIBUTING.md` and `AI_RULES.md` without renaming the file, so the step
|
|
1724
1811
|
named "Validate this repository against its own spec gate" ran
|
|
1725
1812
|
`node bin/specgate.js validate .` against a path that did not exist and every
|
|
@@ -1737,7 +1824,6 @@ deliberately *not* built, is [ADR-0023](docs/specs/adr/0023-checking-content-gat
|
|
|
1737
1824
|
masked: the `adopt` regression above failed those files on every platform, so
|
|
1738
1825
|
nothing distinguished "broken everywhere" from "broken on Windows".
|
|
1739
1826
|
|
|
1740
|
-
|
|
1741
1827
|
## [0.7.0] — 2026-08-23
|
|
1742
1828
|
|
|
1743
1829
|
The release that closes the gate on itself. Every item below came from running
|
|
@@ -1754,7 +1840,7 @@ H16, all four measured before anything was written and reproduced after.
|
|
|
1754
1840
|
|
|
1755
1841
|
- **`csda harness run --skip-not-ready`** skips a requirement an agent could not
|
|
1756
1842
|
succeed at — no feature file, unmet dependencies, `Deprecated`, or `Needs
|
|
1757
|
-
|
|
1843
|
+
Clarification`. `csda plan --format json` now carries `ready` and `blockers[]`
|
|
1758
1844
|
per requirement, each blocker with a fix. Default is to warn and run it
|
|
1759
1845
|
anyway; an unrunnable scenario skips regardless, because an empty scenario
|
|
1760
1846
|
passes and a green run over one proves nothing.
|
|
@@ -1762,7 +1848,7 @@ H16, all four measured before anything was written and reproduced after.
|
|
|
1762
1848
|
- **`csda harness run --resume`** continues an interrupted run: it re-attaches to
|
|
1763
1849
|
the branch and, when git still knows of one, to the worktree holding the
|
|
1764
1850
|
agent's uncommitted work. Where it picks up is read from the prompt archive,
|
|
1765
|
-
not the run ledger — the ledger is written when a run
|
|
1851
|
+
not the run ledger — the ledger is written when a run _finishes_, so an
|
|
1766
1852
|
interrupted run leaves none.
|
|
1767
1853
|
|
|
1768
1854
|
- **`csda harness run --budget-seconds` and `--max-requirements`** put a ceiling
|
|
@@ -1787,7 +1873,7 @@ H16, all four measured before anything was written and reproduced after.
|
|
|
1787
1873
|
|
|
1788
1874
|
- **`csda harness report`** gains where attempts end, which requirements spend
|
|
1789
1875
|
every attempt, a series over time, and `--mark-false-failure REQ-NNN --reason
|
|
1790
|
-
|
|
1876
|
+
"…"`. The real-failure rate reads `—` until somebody marks one: nothing
|
|
1791
1877
|
recorded can tell a gate that was wrong from work that was.
|
|
1792
1878
|
|
|
1793
1879
|
- **`depends_on`** on a pack's requirements. The harness cuts a dependent's
|
|
@@ -1837,7 +1923,7 @@ H16, all four measured before anything was written and reproduced after.
|
|
|
1837
1923
|
|
|
1838
1924
|
- **`parseYamlLite` split inline sequences on every comma**, including the ones
|
|
1839
1925
|
inside quotes, so `responsibilities: ["Invoice line items, totals, status,
|
|
1840
|
-
|
|
1926
|
+
aging"]` parsed as four items carrying stray quote characters.
|
|
1841
1927
|
|
|
1842
1928
|
### Security
|
|
1843
1929
|
|
|
@@ -1892,9 +1978,9 @@ date.
|
|
|
1892
1978
|
- **The scenarios shipped in the curated packs were never executed.** 27 of the
|
|
1893
1979
|
28 scenarios under `packs/**` wrote their keywords in upper case —
|
|
1894
1980
|
`GIVEN` / `WHEN` / `THEN` — and Gherkin keywords are case-sensitive. Cucumber
|
|
1895
|
-
read those lines as the scenario's
|
|
1981
|
+
read those lines as the scenario's _description_, so the scenario existed with
|
|
1896
1982
|
**zero steps**, and an empty scenario passes: `1 scenario (1 passed) · 0 steps
|
|
1897
|
-
|
|
1983
|
+
· exit 0`.
|
|
1898
1984
|
|
|
1899
1985
|
Every project seeded with `csda specops add` therefore inherited an acceptance
|
|
1900
1986
|
criterion that approves anything, and a harness run over those requirements
|
|
@@ -1924,7 +2010,7 @@ date.
|
|
|
1924
2010
|
first run already had.
|
|
1925
2011
|
|
|
1926
2012
|
The attempt is now committed on the branch with a `wip(REQ-NNN): FAILED the
|
|
1927
|
-
|
|
2013
|
+
gate — do not merge as is` subject. The requirement stays `Draft`, because
|
|
1928
2014
|
`csda done` never ran, so nothing about the matrix claims the work is good. A
|
|
1929
2015
|
human reads it and decides; git just stops throwing it away. The report says
|
|
1930
2016
|
whether the work was preserved, and distinguishes that from an agent that
|
|
@@ -1935,7 +2021,7 @@ date.
|
|
|
1935
2021
|
a filter silently fails to apply — a runner config pinning its own paths will
|
|
1936
2022
|
override the CLI argument — the gate rejects correct work and the failure is
|
|
1937
2023
|
indistinguishable from broken code. It cost two agent runs to explain the
|
|
1938
|
-
first time. The harness cannot know how many tests
|
|
2024
|
+
first time. The harness cannot know how many tests _should_ run, but it can
|
|
1939
2025
|
notice a command that asked for one feature against output reporting many, and
|
|
1940
2026
|
warn. A hint, not a verdict: a genuine failure must not be explained away.
|
|
1941
2027
|
|
|
@@ -1976,7 +2062,7 @@ date.
|
|
|
1976
2062
|
version and path.
|
|
1977
2063
|
|
|
1978
2064
|
Reported by a user whose `csda -v` kept printing 0.1.2 after installing "the
|
|
1979
|
-
latest". The tool was right — it
|
|
2065
|
+
latest". The tool was right — it _was_ 0.1.2, from a global install made
|
|
1980
2066
|
months earlier. `npx create-spec-driven-app@latest` runs a temporary copy and
|
|
1981
2067
|
never touches a global one, so the two answer different questions and nothing
|
|
1982
2068
|
said so. Three minor versions behind, with no way to notice.
|
|
@@ -1986,8 +2072,7 @@ date.
|
|
|
1986
2072
|
newest is not doctor's business, and a lookup would break the offline and
|
|
1987
2073
|
air-gapped modes the tool promises.
|
|
1988
2074
|
|
|
1989
|
-
- **Doctor's Node check read `>= 20`** for a release after the floor moved to
|
|
1990
|
-
22. It now reads the floor from `package.json` rather than repeating it — the
|
|
2075
|
+
- **Doctor's Node check read `>= 20`** for a release after the floor moved to 22. It now reads the floor from `package.json` rather than repeating it — the
|
|
1991
2076
|
same drift the floor guard exists to prevent, in the one file the guard did
|
|
1992
2077
|
not cover.
|
|
1993
2078
|
|
|
@@ -1996,7 +2081,7 @@ date.
|
|
|
1996
2081
|
### Fixed
|
|
1997
2082
|
|
|
1998
2083
|
- **The gate could not run the scenario it was gating.** `test_cmd` was a fixed
|
|
1999
|
-
string with no substitution, and the gate runs
|
|
2084
|
+
string with no substitution, and the gate runs _before_ `csda done` — so the
|
|
2000
2085
|
requirement is still Draft and `validate --strict-tdd` does not demand its
|
|
2001
2086
|
test either. Between them, `harness run` could mark a requirement Implemented
|
|
2002
2087
|
with its scenario never executed.
|
|
@@ -2011,7 +2096,7 @@ date.
|
|
|
2011
2096
|
With that, the same no-op agent fails at the requirement's own scenario.
|
|
2012
2097
|
|
|
2013
2098
|
- **The harness blocked its own second run.** It archived each prompt into the
|
|
2014
|
-
|
|
2099
|
+
_project_ directory, which left untracked files behind — and the harness
|
|
2015
2100
|
refuses to start on a dirty tree. The archive now goes in the worktree, where
|
|
2016
2101
|
`git add -A` commits it with the work, so the prompt arrives in the branch
|
|
2017
2102
|
under review. That is what an audit copy was for.
|
|
@@ -2107,7 +2192,6 @@ date.
|
|
|
2107
2192
|
migrating is the shape that never worked, and `pack lint` now names exactly
|
|
2108
2193
|
what is wrong with it.
|
|
2109
2194
|
|
|
2110
|
-
|
|
2111
2195
|
- **The CLI is called `csda` in every place it is a command.** The package
|
|
2112
2196
|
ships two binaries — `create-spec-driven-app` and the `csda` alias — and the
|
|
2113
2197
|
two were used interchangeably, so the same command appeared under different
|
|
@@ -2183,7 +2267,7 @@ date.
|
|
|
2183
2267
|
`schema_version` and `.specops.lock`'s `specops_version` were both written by
|
|
2184
2268
|
the CLI and read by nothing, so a file from a newer version was accepted and
|
|
2185
2269
|
then misread field by field. Both now fail up front, naming the versions and
|
|
2186
|
-
the upgrade command. Older files still load — only
|
|
2270
|
+
the upgrade command. Older files still load — only _newer than this CLI_ is
|
|
2187
2271
|
refused.
|
|
2188
2272
|
|
|
2189
2273
|
- **`SECURITY.md`, `MAINTAINERS.md` and `CODEOWNERS`**, with private
|
|
@@ -2287,7 +2371,7 @@ date.
|
|
|
2287
2371
|
runner. The workflow needed QEMU alongside buildx to cross-build.
|
|
2288
2372
|
|
|
2289
2373
|
The 0.2.0 image tag could not be rebuilt in place: re-running a workflow
|
|
2290
|
-
against an old tag checks out the workflow
|
|
2374
|
+
against an old tag checks out the workflow _as it was at that tag_, which did
|
|
2291
2375
|
not yet have the fix. Hence a patch release rather than moving a published
|
|
2292
2376
|
tag.
|
|
2293
2377
|
|
|
@@ -2323,7 +2407,7 @@ and brownfield onboarding have all landed since.
|
|
|
2323
2407
|
### Added
|
|
2324
2408
|
|
|
2325
2409
|
- **Change lifecycle** — `csda change new | list | show | status | validate |
|
|
2326
|
-
|
|
2410
|
+
archive`. Modify a spec that already shipped through a reviewable delta.
|
|
2327
2411
|
Archiving merges it into the spec tree, writes the traceability rows and
|
|
2328
2412
|
materialises the feature files.
|
|
2329
2413
|
- **`csda change instructions <artifact>`** — the single context engine.
|