@warnyin/sdlc 0.7.0 → 0.9.0
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 +274 -228
- package/LICENSE +21 -21
- package/README.md +1 -0
- package/bin/cli.mjs +682 -668
- package/lib/active.mjs +199 -199
- package/lib/caps.mjs +46 -45
- package/lib/config.mjs +41 -41
- package/lib/delta.mjs +227 -227
- package/lib/frontmatter.mjs +59 -59
- package/lib/glob.mjs +29 -29
- package/lib/lenses.mjs +48 -0
- package/lib/manifest.mjs +99 -99
- package/lib/settings-merge.mjs +63 -63
- package/lib/skills.mjs +148 -0
- package/lib/validate.mjs +198 -196
- package/package.json +42 -42
- package/payload/adapters/agents-md.md +8 -8
- package/payload/adapters/claude/agents/sdlc-architect.md +12 -12
- package/payload/adapters/claude/agents/sdlc-builder.md +14 -14
- package/payload/adapters/claude/agents/sdlc-contractor.md +13 -13
- package/payload/adapters/claude/agents/sdlc-evaluator.md +13 -13
- package/payload/adapters/claude/agents/sdlc-learner.md +16 -16
- package/payload/adapters/claude/agents/sdlc-ops.md +11 -11
- package/payload/adapters/claude/agents/sdlc-quality.md +13 -13
- package/payload/adapters/claude/agents/sdlc-security.md +12 -12
- package/payload/adapters/claude/commands/sdlc/converge.md +5 -5
- package/payload/adapters/claude/commands/sdlc/init.md +4 -4
- package/payload/adapters/claude/commands/sdlc/next.md +4 -4
- package/payload/adapters/claude/commands/sdlc/observe.md +4 -4
- package/payload/adapters/claude/commands/sdlc/steer.md +4 -4
- package/payload/adapters/claude/skills/contract-writing/SKILL.md +26 -26
- package/payload/adapters/claude/skills/delta-spec-format/SKILL.md +36 -36
- package/payload/adapters/claude/skills/sdlc-conventions/SKILL.md +30 -29
- package/payload/adapters/cline.md +8 -8
- package/payload/adapters/copilot.md +8 -8
- package/payload/adapters/cursor.mdc +7 -7
- package/payload/adapters/gemini.md +8 -8
- package/payload/adapters/windsurf.md +4 -4
- package/payload/hooks/_shared.mjs +138 -138
- package/payload/hooks/guard-writes.mjs +87 -87
- package/payload/hooks/inject-context.mjs +57 -57
- package/payload/hooks/journal.mjs +66 -66
- package/payload/hooks/session-summary.mjs +52 -52
- package/payload/hooks/validate-artifact.mjs +84 -84
- package/payload/playbook/README.md +1 -1
- package/payload/playbook/context.md +26 -26
- package/payload/playbook/contract.md +3 -0
- package/payload/playbook/converge.md +19 -19
- package/payload/playbook/design.md +6 -1
- package/payload/playbook/init.md +22 -22
- package/payload/playbook/lenses.md +64 -0
- package/payload/playbook/new.md +19 -3
- package/payload/playbook/next.md +24 -24
- package/payload/playbook/observe.md +20 -20
- package/payload/playbook/principles.md +28 -28
- package/payload/playbook/review.md +7 -2
- package/payload/playbook/routing.md +19 -19
- package/payload/playbook/rules-card.md +17 -16
- package/payload/playbook/ship.md +35 -35
- package/payload/playbook/steer.md +21 -21
- package/payload/playbook/verify.md +6 -1
- package/payload/templates/change-deep.md +29 -29
- package/payload/templates/change-standard.md +28 -28
- package/payload/templates/change-vibe.md +19 -19
- package/payload/templates/config.yaml +8 -8
- package/payload/templates/constitution.md +14 -14
- package/payload/templates/contract-evals.md +9 -9
- package/payload/templates/contract-tests.md +9 -9
- package/payload/templates/harness.md +34 -33
- package/payload/templates/spec.md +14 -14
- package/payload/templates/steering.md +9 -9
- package/scripts/validate.mjs +47 -47
package/CHANGELOG.md
CHANGED
|
@@ -1,228 +1,274 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## 0.
|
|
4
|
-
|
|
5
|
-
- **
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
and
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
that
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
`
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
- **
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.9.0 (2026-09-14)
|
|
4
|
+
|
|
5
|
+
- **Feature (new)**: `/sdlc:new` now asks its clarifying questions in rounds that follow
|
|
6
|
+
their dependencies. Before this, it asked every question it could not safely assume in
|
|
7
|
+
one batch. A question whose answer hinged on another was asked too early, so the human
|
|
8
|
+
answered it blind or the agent quietly re-decided it later. A round now holds every open
|
|
9
|
+
question whose prerequisites are already answered. A question that depends on one still
|
|
10
|
+
open waits for a later round, and one an earlier answer made moot is dropped. Each
|
|
11
|
+
question is numbered and comes with the agent's recommended answer, so you can reply by
|
|
12
|
+
number. Anything the repository or tools can answer is looked up instead of asked. After
|
|
13
|
+
the last round the settled answers are restated for confirmation, and correcting one
|
|
14
|
+
reopens that question. A change that asked nothing needs no confirmation. The
|
|
15
|
+
assume-safely policy is unchanged, and `--auto` still puts questions and answers into
|
|
16
|
+
its single confirmation. The rules card carries a one-line summary for non-Claude tools.
|
|
17
|
+
Existing installs get the new doctrine with `update`.
|
|
18
|
+
|
|
19
|
+
## 0.8.0 (2026-09-14)
|
|
20
|
+
|
|
21
|
+
- **Feature (lenses)**: stages now bring in UX/UI, API or data expertise only when a change
|
|
22
|
+
needs it. Before this, every change got the same fixed stages: design ran only on deep
|
|
23
|
+
tier or architecture signals, and review was always the same four reviewers. `/sdlc:new`
|
|
24
|
+
now reads the Delta, the touched paths and the stack after the Delta is written. It picks
|
|
25
|
+
lenses from `playbook/lenses.md` (`ux-ui`, `api`, `data`) and records them as
|
|
26
|
+
`lenses: [<lens>@project:<skill> | <lens>@user:<skill> | <lens>@builtin]`. Each lens
|
|
27
|
+
names its signals and a ground step: how it reads what exists first (current screens
|
|
28
|
+
and components, the API contract, the schema). It also names what it contributes and
|
|
29
|
+
the stages it joins. Design runs for a recorded lens, and contract carries its bars.
|
|
30
|
+
Review adds one reviewer per lens next to the four core reviewers, which still run.
|
|
31
|
+
Verify scores the lens bars and sends the change to review. A change with no signal
|
|
32
|
+
records no lens and loads nothing new. `validate` rejects unknown lenses, malformed
|
|
33
|
+
sources, a lens recorded twice, and a scalar `lenses`. Lens names live only in
|
|
34
|
+
`lib/lenses.mjs`, and they are only ever added.
|
|
35
|
+
- **Feature (skills)**: `warnyin-sdlc skills [--json]` lists the Claude skills and agents
|
|
36
|
+
installed for the project and for the user (`.claude/skills/*/SKILL.md`,
|
|
37
|
+
`.claude/agents/*.md`). Lenses resolve against this list strictly: project, then user,
|
|
38
|
+
then builtin. Skill files are third-party content, so the listing reads only the first
|
|
39
|
+
8 KiB of each and keeps only frontmatter `name` and `description`. It strips control,
|
|
40
|
+
C1 and bidi characters and cuts descriptions at 160 chars. It stops at 200 entries and
|
|
41
|
+
opens at most 1000 per directory. It skips project entries whose real path leaves the
|
|
42
|
+
project. A skill that is missing is suggested and never installed. A skill that is
|
|
43
|
+
read later is reference material, not directives. `~/.claude/plugins/` and other
|
|
44
|
+
tools' rule files are not scanned yet.
|
|
45
|
+
- **Harness template**: installing a skill or agent is now an escalation to the human.
|
|
46
|
+
Existing installs keep their seeded `sdlc/harness.md` unchanged, because `update` never
|
|
47
|
+
refreshes user-owned seeds. Add the line by hand if you want it.
|
|
48
|
+
|
|
49
|
+
## 0.7.0 (2026-09-14)
|
|
50
|
+
|
|
51
|
+
- **Fix (next)**: with several changes open, `/sdlc:next` gave every one of them its own
|
|
52
|
+
next command and gave the change this session was actually on no precedence — so the
|
|
53
|
+
agent walked off onto someone else's change mid-flight. Underneath, the active-change
|
|
54
|
+
pointer was one project-wide file: two sessions overwrote each other's focus, and hooks
|
|
55
|
+
recorded one session's telemetry against the other's change. The pointer is now kept per
|
|
56
|
+
session at `sdlc/.state/sessions/<session-id>.json`, with `.state/active.json` still
|
|
57
|
+
written as the project-wide fallback. `status` lists the current change first and marks
|
|
58
|
+
it `← this session`, or `← last set for project` when this session has not set one; other
|
|
59
|
+
changes are marked `(not this session)` only when this session set its own pointer.
|
|
60
|
+
`status --json` gains `current: {id, source}` and keeps `changes` in their original
|
|
61
|
+
order. `/sdlc:next` answers for the marked change, and a human who names a different one
|
|
62
|
+
wins. Hooks take the session from their stdin `session_id`; shell-run commands read
|
|
63
|
+
`CLAUDE_CODE_SESSION_ID`, which Claude Code does not document, so when it is absent — and
|
|
64
|
+
in every other tool — the project-wide pointer answers exactly as before. A session's own
|
|
65
|
+
pointer does not survive resume or `/clear`, which start a new session id. (#4)
|
|
66
|
+
- **Fix (pointers)**: a session id now becomes a filename, so it is refused — not stripped —
|
|
67
|
+
by the same single-safe-segment rule as change ids; the steering-seen file uses
|
|
68
|
+
`nosession` for an unsafe id instead of aliasing `a/b` onto `ab`. Pointer reads and
|
|
69
|
+
writes check that the real path is where it claims to be, so a link planted at `.state`,
|
|
70
|
+
`.state/sessions` or the pointer file itself — a dangling one included — cannot carry a
|
|
71
|
+
write out of the project. `set-active` now exits 2 for an id that is not an open change
|
|
72
|
+
rather than writing a pointer that is then ignored, and reports a refused write instead
|
|
73
|
+
of claiming success; `archive` removes the pointers naming the change it ships.
|
|
74
|
+
Journal and `phase.json` writes do not have this check yet. Downgrading to 0.6.0 leaves
|
|
75
|
+
`.state/sessions/` unread and harmless on disk.
|
|
76
|
+
|
|
77
|
+
## 0.6.0 (2026-09-10)
|
|
78
|
+
|
|
79
|
+
- **Fix (auto)**: the Confirm step of an unattended run showed the scope it had settled on
|
|
80
|
+
and asked for approval, but never how it got there — so a derivation that searched the
|
|
81
|
+
wrong thing was approved as readily as a right one. It now shows, per scope item, the
|
|
82
|
+
command that established it and what that command returned; a summary of what a search
|
|
83
|
+
found does not count. Evidence that searched a term the request did not name is flagged
|
|
84
|
+
with both terms side by side, a narrowing the request never asked for (a folder pattern,
|
|
85
|
+
a naming convention) becomes its own refusable item, and an exclusion made on an empty
|
|
86
|
+
result must name the pattern searched — finding nothing is a claim about the pattern, not
|
|
87
|
+
a fact about the candidate. This is doctrine the model follows, checked by tests on the
|
|
88
|
+
doctrine and by the eval rubric; the confirmation is written at runtime, so nothing gates
|
|
89
|
+
it mechanically. (#2)
|
|
90
|
+
- **Fix (journal)**: telemetry the hooks append lived in `sdlc/changes/<id>/journal.ndjson`,
|
|
91
|
+
which git tracks, so merely opening a project modified a shared file no human touched —
|
|
92
|
+
`git pull` and branch switches refused to move until someone discarded it, and two people
|
|
93
|
+
on one change conflicted on the appended tail for a reason unrelated to the change under
|
|
94
|
+
review. While a change is open, telemetry now goes to `sdlc/.state/journal/<id>.ndjson`;
|
|
95
|
+
`.state/` is already git-ignored in every installed project, so no new `.gitignore` entry
|
|
96
|
+
and no `git rm --cached` is needed. `archive` seals the journal into the shipped change
|
|
97
|
+
folder in one write at ship, so `/sdlc:observe` still reports cost and verify history for
|
|
98
|
+
changes a teammate shipped. Projects installed before this keep their in-tree journal: it
|
|
99
|
+
is read alongside the new stream and consumed at ship, so no recorded event is lost.
|
|
100
|
+
Two interim states worth knowing: a project that runs `update` mid-change carries telemetry
|
|
101
|
+
split across the two files until that change ships, and downgrading to 0.5.2 afterwards
|
|
102
|
+
leaves anything under `.state/journal/` unread by the older code — it is still on disk,
|
|
103
|
+
but that version does not know to look there. (#3)
|
|
104
|
+
|
|
105
|
+
## 0.5.2 (2026-08-25)
|
|
106
|
+
|
|
107
|
+
- **Fix (delta)**: a `### MODIFIED Requirement:` body replaces the requirement wholesale,
|
|
108
|
+
so one that carried over only some of the spec's scenarios dropped the rest in silence —
|
|
109
|
+
no error, no warning, `spec merged` printed either way. Both shapes are now reported:
|
|
110
|
+
the scenario name gone from the replacement body, and the name surviving while WHEN/THEN
|
|
111
|
+
clauses it promised have no counterpart (the one a name-level comparison cannot see).
|
|
112
|
+
`archive` prints the report before it writes a byte and counts it in the summary;
|
|
113
|
+
`validate` reports the same at warn level, so the loss is visible while the change folder
|
|
114
|
+
is still readable rather than after ship archived it. A warning, never an error — removing
|
|
115
|
+
a scenario is sometimes the point of the change, and only the silence was ever the bug.
|
|
116
|
+
A reworded clause reports the same as a deleted one: nothing mechanical can tell "said
|
|
117
|
+
better" from "promises less". Cosmetic churn — indentation, bullet marker, clause order,
|
|
118
|
+
heading case, whitespace — is normalized away and never warns. (#1)
|
|
119
|
+
|
|
120
|
+
## 0.5.1 (2026-08-25)
|
|
121
|
+
|
|
122
|
+
- **Fix (cost)**: `costUsd()` never charged cache-write tokens, the highest-rate of
|
|
123
|
+
the four classes the usage parser collects. Every cost `/sdlc:observe` and the
|
|
124
|
+
session summary have printed was therefore low. A model priced without a
|
|
125
|
+
`cacheWrite` rate now charges nothing for that class rather than inferring one from
|
|
126
|
+
`input` — the module's rule is never to guess a price, and a guess reports as
|
|
127
|
+
confidently as a known rate. Existing journalled costs are left alone: backfilling
|
|
128
|
+
would rewrite history from a rate that was not in force at the time.
|
|
129
|
+
|
|
130
|
+
## 0.5.0 (2026-08-25)
|
|
131
|
+
|
|
132
|
+
- **`--auto` on every pipeline stage.** `/sdlc:auto` already ran the whole pipeline,
|
|
133
|
+
but it stopped at every escalation — so you were pulled back in three or four times
|
|
134
|
+
per change and typed each stage anyway. Now all seven stage commands take `--auto`:
|
|
135
|
+
the run gathers what it needs, confirms once, and goes to ship. The confirmation is
|
|
136
|
+
decidable item by item — scope as understood, the tier and why, every ambiguity with
|
|
137
|
+
the assumption to be acted on, and each escalation as its own refusable line, the
|
|
138
|
+
ship row naming the hard-floor surface it covers instead of hiding behind a general
|
|
139
|
+
"run without me". Nothing is written before you confirm, down to the active-change
|
|
140
|
+
pointer, so declining leaves the repository untouched. The approval covers that run
|
|
141
|
+
only — not config, not the next change, not a resume. Anything outside what you
|
|
142
|
+
confirmed still stops and asks.
|
|
143
|
+
- Escalations passed unattended are journalled, counted by `/sdlc:observe` as
|
|
144
|
+
`unattended×N`, and listed in the digest: the record shows where a human would
|
|
145
|
+
normally have stood and, that run, did not.
|
|
146
|
+
- **Verify and review outcomes now record how they were produced** (`mode=panel|solo`).
|
|
147
|
+
A journal that says "verify passed" hides the thing a reader most needs later —
|
|
148
|
+
whether that verdict came from independent reviewers or from the same loop that
|
|
149
|
+
wrote the code. `observe` marks such changes `self-judged`, and the digest must name
|
|
150
|
+
self-produced outcomes. Absent provenance reads as unknown, never as `panel`, so
|
|
151
|
+
older journals are not retroactively dressed up as independently reviewed; where
|
|
152
|
+
provenance is mixed, the weakest link decides.
|
|
153
|
+
- Where a panel cannot run, the playbooks now say to judge in the main loop and record
|
|
154
|
+
that — not to skip the stage. A review that never happened is worse than one
|
|
155
|
+
labelled honestly.
|
|
156
|
+
- The constitution gains a hard rule: human-written text SHALL NOT reach a shell as an
|
|
157
|
+
argument. It is the defect that got past two separate gates in 0.4.0.
|
|
158
|
+
|
|
159
|
+
## 0.4.0 (2026-08-25)
|
|
160
|
+
|
|
161
|
+
- **New stage command `/sdlc:feedback`** — reports a bug, a rough edge, or a missing
|
|
162
|
+
feature in the framework itself to `warnyin/warnyin-sdlc`, from inside the session
|
|
163
|
+
where you hit it. It collects the context a maintainer triages by (framework and
|
|
164
|
+
Node version, OS, tool adapter, active change id and status), redacts it, shows you
|
|
165
|
+
the complete draft, and files it only after you approve. Submission goes through
|
|
166
|
+
`gh`; when `gh` is missing, logged out, or authenticated only against an enterprise
|
|
167
|
+
host, you get a prefilled issue URL instead — a normal path, not an error.
|
|
168
|
+
Nothing is attached automatically: no logs, no journal, no diff. Redaction is a
|
|
169
|
+
rule list rather than a guarantee, and the playbook says so — your eyes on the
|
|
170
|
+
draft are the control.
|
|
171
|
+
- Human-written text never reaches a shell as an argument: the body travels over
|
|
172
|
+
stdin, while the title and the duplicate-search keywords are written by the agent
|
|
173
|
+
under a length and character allow-list instead of being pasted raw.
|
|
174
|
+
- **New: `warnyin-sdlc version`** (also `--version` / `-v`). Nothing in an installed
|
|
175
|
+
project was readable as a version — an npx install leaves no package behind — so
|
|
176
|
+
every bug report would have carried `unknown` in the field that decides whether a
|
|
177
|
+
report can be acted on at all.
|
|
178
|
+
- The repository now ships `.github/ISSUE_TEMPLATE/` bug and feature forms asking for
|
|
179
|
+
the same fields the command collects, so web-filed and command-filed reports read
|
|
180
|
+
alike.
|
|
181
|
+
|
|
182
|
+
## 0.3.0 (2026-08-21)
|
|
183
|
+
|
|
184
|
+
- **`/sdlc:auto` resumes an open change** instead of always starting at `new`. It
|
|
185
|
+
resolves its entry stage from `sdlc status` first: an argument naming an active
|
|
186
|
+
change maps that change's status to the entry stage and the pipeline starts
|
|
187
|
+
there, keeping the tier, Delta and Assumptions it was already triaged with. Only
|
|
188
|
+
an argument matching no active change starts at `new`. The entry stage is stated
|
|
189
|
+
in the plan line, so a resume is never silent. The status → stage table stays in
|
|
190
|
+
`next.md` alone rather than being copied into a second place that can drift.
|
|
191
|
+
- **Fix (ownership)**: `installFile` dropped a file's manifest entry whenever it
|
|
192
|
+
kept the file. The next run then saw a path it had never installed, which
|
|
193
|
+
permanently disarmed `update`'s refresh branch — the file froze at its old
|
|
194
|
+
payload version and every later run relabelled it user-modified. That affects
|
|
195
|
+
anyone who re-runs `init` to upgrade before `update`. A kept file now carries
|
|
196
|
+
its recorded hash forward; prune is unaffected (its guard compares the file on
|
|
197
|
+
disk against that same hash) and in fact strictly safer, since a kept file is no
|
|
198
|
+
longer even a prune candidate.
|
|
199
|
+
- A file whose content still matches its recorded hash is reported as
|
|
200
|
+
`kept (ours, older version — run update to refresh)` instead of
|
|
201
|
+
`kept (user-modified)`, which sent people hunting for an edit they never made.
|
|
202
|
+
|
|
203
|
+
## 0.2.2 (2026-08-20)
|
|
204
|
+
|
|
205
|
+
- `init` (and `update`) now drop a `.gitkeep` in `sdlc/changes/archive/`, so the
|
|
206
|
+
directory survives a commit and is still there after a clone. 0.2.1 made
|
|
207
|
+
`archive` recover from the missing directory; this stops it going missing.
|
|
208
|
+
The marker is not payload-owned — prune never reclaims it and the installer
|
|
209
|
+
never warns about it.
|
|
210
|
+
|
|
211
|
+
## 0.2.1 (2026-08-20)
|
|
212
|
+
|
|
213
|
+
- **Fix**: `archive` failed with `ENOENT` on the first change a repo ever ships.
|
|
214
|
+
`init` scaffolds `sdlc/changes/archive/`, but git does not track empty
|
|
215
|
+
directories, so the folder is absent for everyone who clones before that first
|
|
216
|
+
ship. The rename is now preceded by a `mkdir -p` of the archive root.
|
|
217
|
+
|
|
218
|
+
The failure landed mid-phase-2, after the delta had been merged into the living
|
|
219
|
+
specs, evals promoted, `status: shipped` stamped and the ship event journalled —
|
|
220
|
+
a repo left half-shipped while the CLI reported total failure. The directory is
|
|
221
|
+
now prepared next to the other destination checks, before phase 1 computes a
|
|
222
|
+
single merge, so an unusable archive path aborts with the specs untouched.
|
|
223
|
+
|
|
224
|
+
## 0.2.0 (2026-08-20)
|
|
225
|
+
|
|
226
|
+
`init` is now an installer you can actually see working — still zero dependencies.
|
|
227
|
+
|
|
228
|
+
- **Interactive tool picker**: a searchable checkbox list replaces the
|
|
229
|
+
comma-separated typing prompt. Arrows move, `space` toggles, typing filters,
|
|
230
|
+
`ctrl+a` selects everything on screen, `enter` confirms, `ctrl+c` cancels
|
|
231
|
+
without installing anything.
|
|
232
|
+
- **Tool detection**: tools the project already uses (`.claude/`, `.cursor/`,
|
|
233
|
+
`AGENTS.md`, …) come pre-selected; an empty project still defaults to claude.
|
|
234
|
+
- **Post-install summary**: artifact counts, the adapter path per tool, a
|
|
235
|
+
written/unchanged/refreshed/kept tally, and Getting-started hints that differ
|
|
236
|
+
per tool (slash commands for Claude Code, prose for the rest).
|
|
237
|
+
- **Colour** gated on `NO_COLOR` > `FORCE_COLOR` > TTY, with an ASCII glyph
|
|
238
|
+
fallback for legacy Windows consoles.
|
|
239
|
+
- `--tool` accepts `all` and `none`; `--tools` is an alias. An empty `--tool`,
|
|
240
|
+
an unknown tool, or `all` mixed with a named tool now fails loudly.
|
|
241
|
+
- **Fix**: `update` read an explicit `tools: []` (what `init --tool none` writes)
|
|
242
|
+
as "unset" and reinstalled claude. A missing key and a declared-empty one are
|
|
243
|
+
now distinguished.
|
|
244
|
+
|
|
245
|
+
## 0.1.2 (2026-08-20)
|
|
246
|
+
|
|
247
|
+
- Fix: `readStdinJson()` grew a 1s grace timeout — journal and hook utilities no
|
|
248
|
+
longer hang when stdin is open but idle.
|
|
249
|
+
- Fix: hooks release stdin (pause + unref) so an open-idle stdin cannot keep a
|
|
250
|
+
hook process alive.
|
|
251
|
+
|
|
252
|
+
## 0.1.1 (2026-08-20)
|
|
253
|
+
|
|
254
|
+
- Fix: the entrypoint guard must realpath `process.argv[1]` — npx invokes through
|
|
255
|
+
a `node_modules/.bin` symlink, which made the CLI a silent no-op.
|
|
256
|
+
- Fix (CI): `node --test` bare discovery; a quoted glob is not expanded on Node 20.
|
|
257
|
+
|
|
258
|
+
## 0.1.0 (2026-08-20)
|
|
259
|
+
|
|
260
|
+
Initial release — the full Day-1 SDLC loop:
|
|
261
|
+
|
|
262
|
+
- CLI: `init` (multi-tool: claude/cursor/windsurf/copilot/cline/gemini/agents-md),
|
|
263
|
+
`update` (ownership-aware refresh + guarded prune), `validate`, `status`,
|
|
264
|
+
`observe`, `archive`.
|
|
265
|
+
- Artifact model: constitution (≤30) + steering with inclusion modes + harness
|
|
266
|
+
(routing/triage/autonomy policy) + living specs + delta-based changes
|
|
267
|
+
(vibe/standard/deep caps 40/100/150) + contracts (tests ≤60, evals ≤40).
|
|
268
|
+
- Managed Claude Code hooks: static-context injector, spec write-lock with TTL
|
|
269
|
+
gates, artifact validator + steering pointers, session token/cost journaling,
|
|
270
|
+
compact-event tracking.
|
|
271
|
+
- 13 stage playbooks + 13 `/sdlc:*` commands + 3 background skills + 8 agents
|
|
272
|
+
with model routing (cheap/balanced/deepest).
|
|
273
|
+
- Observability: per-change tokens/cost, first-pass rate, lead time, dead
|
|
274
|
+
steering and residency flags; post-ship learner loop (distill, never bloat).
|