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