@warnyin/sdlc 0.3.0 → 0.4.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 +118 -95
- package/README.md +85 -84
- package/bin/cli.mjs +13 -2
- package/package.json +1 -1
- package/payload/adapters/claude/commands/sdlc/feedback.md +5 -0
- package/payload/playbook/README.md +31 -30
- package/payload/playbook/feedback.md +69 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,95 +1,118 @@
|
|
|
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
|
-
|
|
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
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.4.0 (2026-08-25)
|
|
4
|
+
|
|
5
|
+
- **New stage command `/sdlc:feedback`** — reports a bug, a rough edge, or a missing
|
|
6
|
+
feature in the framework itself to `warnyin/warnyin-sdlc`, from inside the session
|
|
7
|
+
where you hit it. It collects the context a maintainer triages by (framework and
|
|
8
|
+
Node version, OS, tool adapter, active change id and status), redacts it, shows you
|
|
9
|
+
the complete draft, and files it only after you approve. Submission goes through
|
|
10
|
+
`gh`; when `gh` is missing, logged out, or authenticated only against an enterprise
|
|
11
|
+
host, you get a prefilled issue URL instead — a normal path, not an error.
|
|
12
|
+
Nothing is attached automatically: no logs, no journal, no diff. Redaction is a
|
|
13
|
+
rule list rather than a guarantee, and the playbook says so — your eyes on the
|
|
14
|
+
draft are the control.
|
|
15
|
+
- Human-written text never reaches a shell as an argument: the body travels over
|
|
16
|
+
stdin, while the title and the duplicate-search keywords are written by the agent
|
|
17
|
+
under a length and character allow-list instead of being pasted raw.
|
|
18
|
+
- **New: `warnyin-sdlc version`** (also `--version` / `-v`). Nothing in an installed
|
|
19
|
+
project was readable as a version — an npx install leaves no package behind — so
|
|
20
|
+
every bug report would have carried `unknown` in the field that decides whether a
|
|
21
|
+
report can be acted on at all.
|
|
22
|
+
- The repository now ships `.github/ISSUE_TEMPLATE/` bug and feature forms asking for
|
|
23
|
+
the same fields the command collects, so web-filed and command-filed reports read
|
|
24
|
+
alike.
|
|
25
|
+
|
|
26
|
+
## 0.3.0 (2026-08-21)
|
|
27
|
+
|
|
28
|
+
- **`/sdlc:auto` resumes an open change** instead of always starting at `new`. It
|
|
29
|
+
resolves its entry stage from `sdlc status` first: an argument naming an active
|
|
30
|
+
change maps that change's status to the entry stage and the pipeline starts
|
|
31
|
+
there, keeping the tier, Delta and Assumptions it was already triaged with. Only
|
|
32
|
+
an argument matching no active change starts at `new`. The entry stage is stated
|
|
33
|
+
in the plan line, so a resume is never silent. The status → stage table stays in
|
|
34
|
+
`next.md` alone rather than being copied into a second place that can drift.
|
|
35
|
+
- **Fix (ownership)**: `installFile` dropped a file's manifest entry whenever it
|
|
36
|
+
kept the file. The next run then saw a path it had never installed, which
|
|
37
|
+
permanently disarmed `update`'s refresh branch — the file froze at its old
|
|
38
|
+
payload version and every later run relabelled it user-modified. That affects
|
|
39
|
+
anyone who re-runs `init` to upgrade before `update`. A kept file now carries
|
|
40
|
+
its recorded hash forward; prune is unaffected (its guard compares the file on
|
|
41
|
+
disk against that same hash) and in fact strictly safer, since a kept file is no
|
|
42
|
+
longer even a prune candidate.
|
|
43
|
+
- A file whose content still matches its recorded hash is reported as
|
|
44
|
+
`kept (ours, older version — run update to refresh)` instead of
|
|
45
|
+
`kept (user-modified)`, which sent people hunting for an edit they never made.
|
|
46
|
+
|
|
47
|
+
## 0.2.2 (2026-08-20)
|
|
48
|
+
|
|
49
|
+
- `init` (and `update`) now drop a `.gitkeep` in `sdlc/changes/archive/`, so the
|
|
50
|
+
directory survives a commit and is still there after a clone. 0.2.1 made
|
|
51
|
+
`archive` recover from the missing directory; this stops it going missing.
|
|
52
|
+
The marker is not payload-owned — prune never reclaims it and the installer
|
|
53
|
+
never warns about it.
|
|
54
|
+
|
|
55
|
+
## 0.2.1 (2026-08-20)
|
|
56
|
+
|
|
57
|
+
- **Fix**: `archive` failed with `ENOENT` on the first change a repo ever ships.
|
|
58
|
+
`init` scaffolds `sdlc/changes/archive/`, but git does not track empty
|
|
59
|
+
directories, so the folder is absent for everyone who clones before that first
|
|
60
|
+
ship. The rename is now preceded by a `mkdir -p` of the archive root.
|
|
61
|
+
|
|
62
|
+
The failure landed mid-phase-2, after the delta had been merged into the living
|
|
63
|
+
specs, evals promoted, `status: shipped` stamped and the ship event journalled —
|
|
64
|
+
a repo left half-shipped while the CLI reported total failure. The directory is
|
|
65
|
+
now prepared next to the other destination checks, before phase 1 computes a
|
|
66
|
+
single merge, so an unusable archive path aborts with the specs untouched.
|
|
67
|
+
|
|
68
|
+
## 0.2.0 (2026-08-20)
|
|
69
|
+
|
|
70
|
+
`init` is now an installer you can actually see working — still zero dependencies.
|
|
71
|
+
|
|
72
|
+
- **Interactive tool picker**: a searchable checkbox list replaces the
|
|
73
|
+
comma-separated typing prompt. Arrows move, `space` toggles, typing filters,
|
|
74
|
+
`ctrl+a` selects everything on screen, `enter` confirms, `ctrl+c` cancels
|
|
75
|
+
without installing anything.
|
|
76
|
+
- **Tool detection**: tools the project already uses (`.claude/`, `.cursor/`,
|
|
77
|
+
`AGENTS.md`, …) come pre-selected; an empty project still defaults to claude.
|
|
78
|
+
- **Post-install summary**: artifact counts, the adapter path per tool, a
|
|
79
|
+
written/unchanged/refreshed/kept tally, and Getting-started hints that differ
|
|
80
|
+
per tool (slash commands for Claude Code, prose for the rest).
|
|
81
|
+
- **Colour** gated on `NO_COLOR` > `FORCE_COLOR` > TTY, with an ASCII glyph
|
|
82
|
+
fallback for legacy Windows consoles.
|
|
83
|
+
- `--tool` accepts `all` and `none`; `--tools` is an alias. An empty `--tool`,
|
|
84
|
+
an unknown tool, or `all` mixed with a named tool now fails loudly.
|
|
85
|
+
- **Fix**: `update` read an explicit `tools: []` (what `init --tool none` writes)
|
|
86
|
+
as "unset" and reinstalled claude. A missing key and a declared-empty one are
|
|
87
|
+
now distinguished.
|
|
88
|
+
|
|
89
|
+
## 0.1.2 (2026-08-20)
|
|
90
|
+
|
|
91
|
+
- Fix: `readStdinJson()` grew a 1s grace timeout — journal and hook utilities no
|
|
92
|
+
longer hang when stdin is open but idle.
|
|
93
|
+
- Fix: hooks release stdin (pause + unref) so an open-idle stdin cannot keep a
|
|
94
|
+
hook process alive.
|
|
95
|
+
|
|
96
|
+
## 0.1.1 (2026-08-20)
|
|
97
|
+
|
|
98
|
+
- Fix: the entrypoint guard must realpath `process.argv[1]` — npx invokes through
|
|
99
|
+
a `node_modules/.bin` symlink, which made the CLI a silent no-op.
|
|
100
|
+
- Fix (CI): `node --test` bare discovery; a quoted glob is not expanded on Node 20.
|
|
101
|
+
|
|
102
|
+
## 0.1.0 (2026-08-20)
|
|
103
|
+
|
|
104
|
+
Initial release — the full Day-1 SDLC loop:
|
|
105
|
+
|
|
106
|
+
- CLI: `init` (multi-tool: claude/cursor/windsurf/copilot/cline/gemini/agents-md),
|
|
107
|
+
`update` (ownership-aware refresh + guarded prune), `validate`, `status`,
|
|
108
|
+
`observe`, `archive`.
|
|
109
|
+
- Artifact model: constitution (≤30) + steering with inclusion modes + harness
|
|
110
|
+
(routing/triage/autonomy policy) + living specs + delta-based changes
|
|
111
|
+
(vibe/standard/deep caps 40/100/150) + contracts (tests ≤60, evals ≤40).
|
|
112
|
+
- Managed Claude Code hooks: static-context injector, spec write-lock with TTL
|
|
113
|
+
gates, artifact validator + steering pointers, session token/cost journaling,
|
|
114
|
+
compact-event tracking.
|
|
115
|
+
- 13 stage playbooks + 13 `/sdlc:*` commands + 3 background skills + 8 agents
|
|
116
|
+
with model routing (cheap/balanced/deepest).
|
|
117
|
+
- Observability: per-change tokens/cost, first-pass rate, lead time, dead
|
|
118
|
+
steering and residency flags; post-ship learner loop (distill, never bloat).
|
package/README.md
CHANGED
|
@@ -1,84 +1,85 @@
|
|
|
1
|
-
# @warnyin/sdlc
|
|
2
|
-
|
|
3
|
-
**Spec-driven, AI-driven SDLC for coding agents — token-lean by construction.**
|
|
4
|
-
|
|
5
|
-
Operationalizes the *"New SDLC with Vibe Coding"* (Day-1) work process: the human configures
|
|
6
|
-
the harness once; the AI drives changes end-to-end through contract-first gates; deterministic
|
|
7
|
-
hooks and a validator enforce the rules; a journal prices every change in real tokens.
|
|
8
|
-
|
|
9
|
-
Inspired by OpenSpec (delta specs, archive lifecycle), spec-kit (artifact grammar), and
|
|
10
|
-
Kiro (steering + enforced hooks) — tuned for minimum context residency.
|
|
11
|
-
|
|
12
|
-
## Install
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
cd your-project
|
|
16
|
-
npx @warnyin/sdlc init # interactive picker; tools already in the project are pre-selected
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
The picker is a checkbox list — arrows move, `space` toggles, typing filters, `ctrl+a` selects
|
|
20
|
-
everything on screen, `enter` confirms. Skip it in CI or scripts:
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npx @warnyin/sdlc init --tool claude,cursor # explicit list
|
|
24
|
-
npx @warnyin/sdlc init --tool all # every supported tool
|
|
25
|
-
npx @warnyin/sdlc init --tool none # sdlc/ framework only, no agent adapters
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Then in your coding agent:
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
/sdlc:init # interview → constitution + harness (the one human gate)
|
|
32
|
-
/sdlc:auto Add rate limiting # AI runs new → contract → build → verify → ship
|
|
33
|
-
/sdlc:auto add-rate-limiting # already opened it with /sdlc:new? auto resumes from there
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## How it works
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
sdlc/
|
|
40
|
-
├── context/constitution.md ≤30 lines — the ONLY always-loaded prose (hook-injected)
|
|
41
|
-
├── context/steering/*.md scoped knowledge · inclusion: always|paths|manual|agent
|
|
42
|
-
├── harness.md tools, model routing, tier triage, autonomy policy
|
|
43
|
-
├── specs/<capability>/ living specs — WHEN/THEN SHALL, merged mechanically at ship
|
|
44
|
-
├── changes/<id>/ one change: change.md (Why+Delta+Tasks) + contract/ + journal
|
|
45
|
-
└── changes/archive/ shipped changes + digests (the async human touchpoint)
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
- **Contract-first**: tests + evals are written *before* code and gate everything after.
|
|
49
|
-
- **AI-driven, exception-only humans**: the autonomy policy in `harness.md` decides what
|
|
50
|
-
auto-ships and what escalates (hard-floor: security/payments/data-loss/irreversible).
|
|
51
|
-
- **Managed hooks** (Claude Code): SessionStart injects ≤60 lines of static context;
|
|
52
|
-
PreToolUse write-locks living specs; PostToolUse validates caps and points at steering;
|
|
53
|
-
Stop journals real token usage. Other tools get the same rules as prose + the validator.
|
|
54
|
-
- **Self-improving, leaner over time**: a post-ship learner proposes rules with evidence;
|
|
55
|
-
the always-loaded budget is fixed, so learning must distill, not accumulate.
|
|
56
|
-
- **Measured**: `npx @warnyin/sdlc observe` — tokens/cost per change, first-pass rate,
|
|
57
|
-
lead time, dead steering, context-overflow flags.
|
|
58
|
-
|
|
59
|
-
## CLI
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
warnyin-sdlc init [--tool all|none|a,b] scaffold + adapters + hooks (picker when omitted)
|
|
63
|
-
warnyin-sdlc update [--force] refresh payload, guarded prune of stale files
|
|
64
|
-
warnyin-sdlc validate [id] [--strict]
|
|
65
|
-
warnyin-sdlc status | observe [--json]
|
|
66
|
-
warnyin-sdlc archive <id> merge deltas into living specs + archive
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
· `/sdlc:
|
|
73
|
-
· `/sdlc:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
`sdlc/.
|
|
83
|
-
|
|
84
|
-
|
|
1
|
+
# @warnyin/sdlc
|
|
2
|
+
|
|
3
|
+
**Spec-driven, AI-driven SDLC for coding agents — token-lean by construction.**
|
|
4
|
+
|
|
5
|
+
Operationalizes the *"New SDLC with Vibe Coding"* (Day-1) work process: the human configures
|
|
6
|
+
the harness once; the AI drives changes end-to-end through contract-first gates; deterministic
|
|
7
|
+
hooks and a validator enforce the rules; a journal prices every change in real tokens.
|
|
8
|
+
|
|
9
|
+
Inspired by OpenSpec (delta specs, archive lifecycle), spec-kit (artifact grammar), and
|
|
10
|
+
Kiro (steering + enforced hooks) — tuned for minimum context residency.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cd your-project
|
|
16
|
+
npx @warnyin/sdlc init # interactive picker; tools already in the project are pre-selected
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The picker is a checkbox list — arrows move, `space` toggles, typing filters, `ctrl+a` selects
|
|
20
|
+
everything on screen, `enter` confirms. Skip it in CI or scripts:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx @warnyin/sdlc init --tool claude,cursor # explicit list
|
|
24
|
+
npx @warnyin/sdlc init --tool all # every supported tool
|
|
25
|
+
npx @warnyin/sdlc init --tool none # sdlc/ framework only, no agent adapters
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Then in your coding agent:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
/sdlc:init # interview → constitution + harness (the one human gate)
|
|
32
|
+
/sdlc:auto Add rate limiting # AI runs new → contract → build → verify → ship
|
|
33
|
+
/sdlc:auto add-rate-limiting # already opened it with /sdlc:new? auto resumes from there
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## How it works
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
sdlc/
|
|
40
|
+
├── context/constitution.md ≤30 lines — the ONLY always-loaded prose (hook-injected)
|
|
41
|
+
├── context/steering/*.md scoped knowledge · inclusion: always|paths|manual|agent
|
|
42
|
+
├── harness.md tools, model routing, tier triage, autonomy policy
|
|
43
|
+
├── specs/<capability>/ living specs — WHEN/THEN SHALL, merged mechanically at ship
|
|
44
|
+
├── changes/<id>/ one change: change.md (Why+Delta+Tasks) + contract/ + journal
|
|
45
|
+
└── changes/archive/ shipped changes + digests (the async human touchpoint)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- **Contract-first**: tests + evals are written *before* code and gate everything after.
|
|
49
|
+
- **AI-driven, exception-only humans**: the autonomy policy in `harness.md` decides what
|
|
50
|
+
auto-ships and what escalates (hard-floor: security/payments/data-loss/irreversible).
|
|
51
|
+
- **Managed hooks** (Claude Code): SessionStart injects ≤60 lines of static context;
|
|
52
|
+
PreToolUse write-locks living specs; PostToolUse validates caps and points at steering;
|
|
53
|
+
Stop journals real token usage. Other tools get the same rules as prose + the validator.
|
|
54
|
+
- **Self-improving, leaner over time**: a post-ship learner proposes rules with evidence;
|
|
55
|
+
the always-loaded budget is fixed, so learning must distill, not accumulate.
|
|
56
|
+
- **Measured**: `npx @warnyin/sdlc observe` — tokens/cost per change, first-pass rate,
|
|
57
|
+
lead time, dead steering, context-overflow flags.
|
|
58
|
+
|
|
59
|
+
## CLI
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
warnyin-sdlc init [--tool all|none|a,b] scaffold + adapters + hooks (picker when omitted)
|
|
63
|
+
warnyin-sdlc update [--force] refresh payload, guarded prune of stale files
|
|
64
|
+
warnyin-sdlc validate [id] [--strict]
|
|
65
|
+
warnyin-sdlc status | observe [--json]
|
|
66
|
+
warnyin-sdlc archive <id> merge deltas into living specs + archive
|
|
67
|
+
warnyin-sdlc version | --version print the installed framework version
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Commands (in your agent)
|
|
71
|
+
|
|
72
|
+
`/sdlc:init` · `/sdlc:auto` · `/sdlc:new` · `/sdlc:design` · `/sdlc:contract` · `/sdlc:build`
|
|
73
|
+
· `/sdlc:verify` · `/sdlc:review` · `/sdlc:ship` · `/sdlc:observe` · `/sdlc:converge`
|
|
74
|
+
· `/sdlc:steer` · `/sdlc:next` · `/sdlc:feedback`
|
|
75
|
+
|
|
76
|
+
Playbooks live in `sdlc/.playbook/` — behavior is defined once there; commands are thin pointers.
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
Zero dependencies, Node ≥ 20. `npm test` runs the black-box suite (temp dirs, real CLI spawns).
|
|
81
|
+
This repo self-hosts: its own development flows through `sdlc/changes/`. After cloning, run
|
|
82
|
+
`npm run setup:dogfood` to regenerate the installer-owned mirrors (`sdlc/.playbook/`,
|
|
83
|
+
`sdlc/.hooks/`, `.claude/`).
|
|
84
|
+
|
|
85
|
+
MIT
|
package/bin/cli.mjs
CHANGED
|
@@ -45,7 +45,7 @@ export function sha256(content) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export function parseArgs(argv) {
|
|
48
|
-
const args = { _: [], tool: null, toolProvided: false, strict: false, force: false, json: false, help: false };
|
|
48
|
+
const args = { _: [], tool: null, toolProvided: false, strict: false, force: false, json: false, help: false, version: false };
|
|
49
49
|
for (let i = 0; i < argv.length; i++) {
|
|
50
50
|
const a = argv[i];
|
|
51
51
|
if (a === '--tool' || a === '--tools') {
|
|
@@ -56,6 +56,7 @@ export function parseArgs(argv) {
|
|
|
56
56
|
else if (a === '--force') args.force = true;
|
|
57
57
|
else if (a === '--json') args.json = true;
|
|
58
58
|
else if (a === '--help' || a === '-h') args.help = true;
|
|
59
|
+
else if (a === '--version' || a === '-v') args.version = true;
|
|
59
60
|
else if (a.startsWith('--')) console.warn(`unknown flag ${a} (ignored)`);
|
|
60
61
|
else args._.push(a);
|
|
61
62
|
}
|
|
@@ -526,6 +527,12 @@ function runValidate(projectRoot, args) {
|
|
|
526
527
|
process.exitCode = res.status ?? 0;
|
|
527
528
|
}
|
|
528
529
|
|
|
530
|
+
// Read from our own package.json: an npx install leaves nothing readable in the
|
|
531
|
+
// target project, and a report whose version is `unknown` cannot be triaged.
|
|
532
|
+
function pkgVersion() {
|
|
533
|
+
return JSON.parse(fs.readFileSync(path.join(PKG_ROOT, 'package.json'), 'utf8')).version;
|
|
534
|
+
}
|
|
535
|
+
|
|
529
536
|
const HELP = `@warnyin/sdlc — spec-driven AI-SDLC framework
|
|
530
537
|
|
|
531
538
|
usage: warnyin-sdlc <command> [options]
|
|
@@ -536,14 +543,18 @@ usage: warnyin-sdlc <command> [options]
|
|
|
536
543
|
status [--json] list active changes and their stage
|
|
537
544
|
observe [--json] tokens/cost per change, residency, steering hits, drift flags
|
|
538
545
|
archive <id> merge delta specs into living specs and archive the change
|
|
546
|
+
version | --version | -v print the installed framework version
|
|
539
547
|
help this text
|
|
540
548
|
`;
|
|
541
549
|
|
|
542
550
|
export async function main(argv = process.argv.slice(2), projectRoot = process.cwd()) {
|
|
543
551
|
const args = parseArgs(argv);
|
|
544
552
|
const cmd = args._[0];
|
|
545
|
-
if (args.help || !cmd || cmd === 'help') { console.log(HELP); return; }
|
|
546
553
|
try {
|
|
554
|
+
// before the help branch: `--version` carries no command, and `!cmd` would
|
|
555
|
+
// otherwise print help instead of the version.
|
|
556
|
+
if (args.version || cmd === 'version') { console.log(pkgVersion()); return; }
|
|
557
|
+
if (args.help || !cmd || cmd === 'help') { console.log(HELP); return; }
|
|
547
558
|
if (cmd === 'init') await cmdInit(projectRoot, args);
|
|
548
559
|
else if (cmd === 'update') cmdUpdate(projectRoot, args);
|
|
549
560
|
else if (cmd === 'validate') runValidate(projectRoot, args);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@warnyin/sdlc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Spec-driven, AI-driven SDLC framework — token-lean specs, contract-first changes, autonomous pipeline with managed hooks. Operationalizes the Day-1 'New SDLC with Vibe Coding' work process.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Report a bug or request a feature in the framework itself — drafts a GitHub issue upstream, redacted, and files it only after you approve
|
|
3
|
+
argument-hint: "[bug|idea] <one line>"
|
|
4
|
+
---
|
|
5
|
+
Read `sdlc/.playbook/feedback.md` and execute it now. Arguments: $ARGUMENTS
|
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
# @warnyin/sdlc playbook
|
|
2
|
-
|
|
3
|
-
One change = one folder in `sdlc/changes/<id>/` moving through:
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
new → [design] → contract → build → verify → [review] → ship
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
| Command | Day-1 phase | Reads | Writes | Gate (automatic unless noted) |
|
|
10
|
-
|---|---|---|---|---|
|
|
11
|
-
| /sdlc:init | Configure harness | interview | constitution, harness.md | human approves (once) |
|
|
12
|
-
| /sdlc:auto | whole loop | status (resumes an open change) | everything below | escalation only |
|
|
13
|
-
| /sdlc:new | Requirements | specs Purpose headers | change.md | validator: delta + assumptions |
|
|
14
|
-
| /sdlc:design | Architecture | change + touched specs | change.md § Design | escalate irreversible only |
|
|
15
|
-
| /sdlc:contract | Contract-first | change.md | contract/*, failing tests | adversarial panel + validator |
|
|
16
|
-
| /sdlc:build | Run harness | change + contract + steering | code, task boxes | tasks done; specs locked by hook |
|
|
17
|
-
| /sdlc:verify | Feedback loop | contract | journal events | tests green AND evals ≥ bar |
|
|
18
|
-
| /sdlc:review | Review | diff + change | findings in change.md | blockers = 0 |
|
|
19
|
-
| /sdlc:ship | Ship | change | specs merge, archive, digest | validate --strict; policy may require human |
|
|
20
|
-
| /sdlc:observe | Observe | journals | report (chat) | — |
|
|
21
|
-
| /sdlc:converge | Maintenance | specs + code | proposed change | — |
|
|
22
|
-
| /sdlc:steer | Configure | context/ | steering, constitution | always-budget ≤ 60 |
|
|
23
|
-
| /sdlc:next | — | status | chat only | — |
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
`
|
|
30
|
-
|
|
1
|
+
# @warnyin/sdlc playbook
|
|
2
|
+
|
|
3
|
+
One change = one folder in `sdlc/changes/<id>/` moving through:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
new → [design] → contract → build → verify → [review] → ship
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
| Command | Day-1 phase | Reads | Writes | Gate (automatic unless noted) |
|
|
10
|
+
|---|---|---|---|---|
|
|
11
|
+
| /sdlc:init | Configure harness | interview | constitution, harness.md | human approves (once) |
|
|
12
|
+
| /sdlc:auto | whole loop | status (resumes an open change) | everything below | escalation only |
|
|
13
|
+
| /sdlc:new | Requirements | specs Purpose headers | change.md | validator: delta + assumptions |
|
|
14
|
+
| /sdlc:design | Architecture | change + touched specs | change.md § Design | escalate irreversible only |
|
|
15
|
+
| /sdlc:contract | Contract-first | change.md | contract/*, failing tests | adversarial panel + validator |
|
|
16
|
+
| /sdlc:build | Run harness | change + contract + steering | code, task boxes | tasks done; specs locked by hook |
|
|
17
|
+
| /sdlc:verify | Feedback loop | contract | journal events | tests green AND evals ≥ bar |
|
|
18
|
+
| /sdlc:review | Review | diff + change | findings in change.md | blockers = 0 |
|
|
19
|
+
| /sdlc:ship | Ship | change | specs merge, archive, digest | validate --strict; policy may require human |
|
|
20
|
+
| /sdlc:observe | Observe | journals | report (chat) | — |
|
|
21
|
+
| /sdlc:converge | Maintenance | specs + code | proposed change | — |
|
|
22
|
+
| /sdlc:steer | Configure | context/ | steering, constitution | always-budget ≤ 60 |
|
|
23
|
+
| /sdlc:next | — | status | chat only | — |
|
|
24
|
+
| /sdlc:feedback | — | context + your words | an issue upstream | human approves the draft |
|
|
25
|
+
|
|
26
|
+
Statuses: `new → contracted → building → verified → shipped`. Tiers: `vibe | standard | deep`
|
|
27
|
+
(triage table + Autonomy policy live in `sdlc/harness.md`).
|
|
28
|
+
|
|
29
|
+
Doctrine: `principles.md` (factory model, anti-garbage), `context.md` (static/dynamic),
|
|
30
|
+
`routing.md` (model tiers). Non-Claude harnesses: `rules-card.md` is embedded in your
|
|
31
|
+
tool's rules file; `npx @warnyin/sdlc validate` is the enforcement floor.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# /sdlc:feedback [bug|idea] <one line> — file an issue upstream
|
|
2
|
+
|
|
3
|
+
Reports a bug, a rough edge, or a missing feature in the **framework itself** to
|
|
4
|
+
`warnyin/warnyin-sdlc`. Bugs in the project you are working on belong in that
|
|
5
|
+
project's own tracker — say so and stop.
|
|
6
|
+
|
|
7
|
+
1. Collect context in one shot; never interrogate the human for it:
|
|
8
|
+
- version: `npx @warnyin/sdlc version` · node: `node --version` · OS and arch
|
|
9
|
+
- tool adapter: `tools:` in `sdlc/config.yaml`
|
|
10
|
+
- active change id + status: `npx @warnyin/sdlc status --json`
|
|
11
|
+
Any field you cannot read is `unknown` — continue, and never guess a value.
|
|
12
|
+
2. If the invocation carried no description, ask once, in one message: what you
|
|
13
|
+
did, what you expected, what happened instead.
|
|
14
|
+
3. Look for it first, when `gh` is available:
|
|
15
|
+
`gh issue list --repo warnyin/warnyin-sdlc --search "<keywords>" --state all --limit 5`.
|
|
16
|
+
Choose `<keywords>` yourself — two to four plain words, letters/digits/hyphen
|
|
17
|
+
only — never the reporter's raw sentence: it reaches the shell as an argument
|
|
18
|
+
exactly like the title does. If an existing thread matches, show it and ask
|
|
19
|
+
whether to comment there rather than open a duplicate.
|
|
20
|
+
4. Redact before the draft is shown to anyone or sent anywhere:
|
|
21
|
+
- absolute paths → project-relative paths (a home directory or host name in a
|
|
22
|
+
path identifies the reporter's machine and employer)
|
|
23
|
+
- token-, key-, password- and connection-string-shaped values → `<redacted>`,
|
|
24
|
+
and tell the human which values you removed
|
|
25
|
+
- never copy the contents of `sdlc/context/constitution.md`, steering files,
|
|
26
|
+
`.env` files, credential files, journals, or diffs into the report
|
|
27
|
+
- this is a rule list, not a guarantee: the human reading the draft is the
|
|
28
|
+
real control, so never claim the report has been fully scrubbed
|
|
29
|
+
5. Show the full draft — destination repo, title, labels, complete body — and ask
|
|
30
|
+
for approval. No network call happens before that approval. On anything other
|
|
31
|
+
than approval: revise the draft and ask again.
|
|
32
|
+
6. Submit, once approved:
|
|
33
|
+
- `gh auth status` must report an authenticated **github.com** account; an
|
|
34
|
+
enterprise-only login goes to step 7 instead of publishing to the wrong host
|
|
35
|
+
- `gh issue create --repo warnyin/warnyin-sdlc --title "<title>"
|
|
36
|
+
--label <bug|enhancement> --body-file -`, body on stdin
|
|
37
|
+
- never pass the body as an inline `--body` argument: report text carries
|
|
38
|
+
backticks, quotes and newlines — inline it breaks on PowerShell and is a
|
|
39
|
+
shell-injection path straight from human-written text
|
|
40
|
+
- the title is human text on a command line too: write it yourself as a plain
|
|
41
|
+
summary (≤80 chars, no newline, no `` ` ``, `$`, `"`, `\`, `|`, `;`, `&`),
|
|
42
|
+
never paste the reporter's words in raw. If a needed character is not
|
|
43
|
+
allowed, reword the title — do not escape your way around it
|
|
44
|
+
- report the resulting issue URL back
|
|
45
|
+
7. Fallback when `gh` is absent, logged out, or not on github.com — a normal
|
|
46
|
+
path, not an error: hand over a prefilled link
|
|
47
|
+
`https://github.com/warnyin/warnyin-sdlc/issues/new?labels=<label>&title=<t>&body=<b>`
|
|
48
|
+
with `<t>` and `<b>` URL-encoded. If the encoded link exceeds ~6000 characters,
|
|
49
|
+
truncate the body it carries and tell the human to paste the rest from the
|
|
50
|
+
draft shown above.
|
|
51
|
+
|
|
52
|
+
Body shape (keep it this short — a maintainer triages it in one screen):
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
### What happened
|
|
56
|
+
<one paragraph, redacted>
|
|
57
|
+
|
|
58
|
+
### Expected
|
|
59
|
+
<one line>
|
|
60
|
+
|
|
61
|
+
### Steps
|
|
62
|
+
1. <command or stage>
|
|
63
|
+
|
|
64
|
+
### Environment
|
|
65
|
+
sdlc <version> · node <version> · <os> · adapter <tool> · change <id> [<status>]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Labels: `bug` for something broken, `enhancement` for an idea or a request.
|
|
69
|
+
Nothing else is attached — no logs, no journal, no diff.
|