@mdferdousalam/agentic-sdlc 0.0.0-stage → 3.0.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/.claude-plugin/marketplace.json +11 -0
- package/.claude-plugin/plugin.json +31 -0
- package/CHANGELOG.md +330 -0
- package/GETTING-STARTED.md +174 -0
- package/LICENSE +21 -0
- package/README.md +268 -2
- package/SECURITY.md +25 -0
- package/agents/sdlc-architecture-reviewer.md +71 -0
- package/agents/sdlc-branch-opener.md +83 -0
- package/agents/sdlc-code-reviewer.md +62 -0
- package/agents/sdlc-impact-analyst.md +70 -0
- package/agents/sdlc-implementer.md +60 -0
- package/agents/sdlc-lander.md +40 -0
- package/agents/sdlc-readiness-gate.md +128 -0
- package/agents/sdlc-release-manager.md +76 -0
- package/agents/sdlc-remediator.md +89 -0
- package/agents/sdlc-reporter.md +42 -0
- package/agents/sdlc-security-reviewer.md +62 -0
- package/agents/sdlc-spec-reviewer.md +56 -0
- package/agents/sdlc-spec-writer.md +62 -0
- package/agents/sdlc-test-author.md +32 -0
- package/agents/sdlc-triager.md +48 -0
- package/agents/sdlc-verifier.md +69 -0
- package/bin/__pycache__/sdlccpython-315.pyc +0 -0
- package/bin/sdlc +2747 -0
- package/bin/sdlc-install-opencode +10 -0
- package/commands/doctor.md +9 -0
- package/commands/feature.md +17 -0
- package/commands/gate.md +33 -0
- package/commands/impact.md +13 -0
- package/commands/implement.md +11 -0
- package/commands/init.md +15 -0
- package/commands/land.md +10 -0
- package/commands/metrics.md +12 -0
- package/commands/readiness.md +8 -0
- package/commands/release.md +16 -0
- package/commands/remediate.md +13 -0
- package/commands/report.md +11 -0
- package/commands/review.md +12 -0
- package/commands/status.md +9 -0
- package/commands/trace.md +9 -0
- package/commands/triage.md +14 -0
- package/commands/verify.md +10 -0
- package/docs/compliance.md +70 -0
- package/docs/configuration.md +106 -0
- package/docs/control-spec.md +269 -0
- package/docs/install.md +75 -0
- package/docs/maturity.md +129 -0
- package/docs/opencode.md +45 -0
- package/docs/openspec.md +58 -0
- package/docs/pipeline.md +160 -0
- package/docs/platforms.md +99 -0
- package/docs/rules.md +122 -0
- package/evals/baseline-attributes-failure/graders/criteria.md +18 -0
- package/evals/baseline-attributes-failure/prompt.md +23 -0
- package/evals/budget-stops-rather-than-asks/graders/criteria.md +19 -0
- package/evals/budget-stops-rather-than-asks/prompt.md +14 -0
- package/evals/critical-low-confidence-escalates/graders/criteria.md +22 -0
- package/evals/critical-low-confidence-escalates/prompt.md +17 -0
- package/evals/gate-refuses-unexecuted/graders/criteria.md +16 -0
- package/evals/gate-refuses-unexecuted/prompt.md +15 -0
- package/evals/refusal-is-not-negotiated/graders/criteria.md +17 -0
- package/evals/refusal-is-not-negotiated/prompt.md +7 -0
- package/evals/release-needs-rollback-and-approval/graders/criteria.md +15 -0
- package/evals/release-needs-rollback-and-approval/prompt.md +6 -0
- package/evals/remediator-refuses-weakened-test/graders/criteria.md +20 -0
- package/evals/remediator-refuses-weakened-test/prompt.md +33 -0
- package/evals/spec-review-catches-unfalsifiable/graders/criteria.md +17 -0
- package/evals/spec-review-catches-unfalsifiable/prompt.md +17 -0
- package/examples/worked-example.md +131 -0
- package/hooks/hooks.json +16 -0
- package/npm/cli.js +35 -0
- package/opencode/plugin/agentic-sdlc.ts +52 -0
- package/package.json +59 -4
- package/profiles/README.md +52 -0
- package/profiles/compiler.md +33 -0
- package/profiles/concerns/architecture.md +50 -0
- package/profiles/concerns/concurrency.md +59 -0
- package/profiles/concerns/data.md +62 -0
- package/profiles/concerns/memory.md +52 -0
- package/profiles/concerns/performance.md +54 -0
- package/profiles/concerns/platform.md +62 -0
- package/profiles/library.md +31 -0
- package/profiles/service.md +32 -0
- package/profiles/webapp.md +40 -0
- package/schema/finding.schema.json +267 -0
- package/schema/sdlc.config.schema.json +324 -0
- package/skills/agentic-sdlc-pipeline/SKILL.md +66 -0
- package/skills/openspec-with-sdlc/SKILL.md +56 -0
- package/skills/writing-specifications/SKILL.md +51 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/mdferdousalam/agentic-sdlc/schema/sdlc.config.schema.json",
|
|
4
|
+
"title": "agentic-sdlc project adapter",
|
|
5
|
+
"description": "The only file in a project that knows its stack. Every agent reads it; none hardcodes a package manager, a branch name or a test runner.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"trunk",
|
|
9
|
+
"spec"
|
|
10
|
+
],
|
|
11
|
+
"additionalProperties": true,
|
|
12
|
+
"properties": {
|
|
13
|
+
"$schema": {
|
|
14
|
+
"type": "string"
|
|
15
|
+
},
|
|
16
|
+
"version": {
|
|
17
|
+
"const": 2,
|
|
18
|
+
"description": "Adapter format version."
|
|
19
|
+
},
|
|
20
|
+
"trunk": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "The branch work merges into.",
|
|
23
|
+
"examples": [
|
|
24
|
+
"main",
|
|
25
|
+
"master",
|
|
26
|
+
"develop"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"stack": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "Detected language or ecosystem; informational."
|
|
32
|
+
},
|
|
33
|
+
"pm": {
|
|
34
|
+
"type": [
|
|
35
|
+
"string",
|
|
36
|
+
"null"
|
|
37
|
+
],
|
|
38
|
+
"description": "Package manager or build driver."
|
|
39
|
+
},
|
|
40
|
+
"monorepo": {
|
|
41
|
+
"type": [
|
|
42
|
+
"string",
|
|
43
|
+
"null"
|
|
44
|
+
],
|
|
45
|
+
"enum": [
|
|
46
|
+
"turbo",
|
|
47
|
+
"nx",
|
|
48
|
+
"lerna",
|
|
49
|
+
"workspaces",
|
|
50
|
+
null
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
"commits": {
|
|
54
|
+
"enum": [
|
|
55
|
+
"conventional",
|
|
56
|
+
"descriptive"
|
|
57
|
+
],
|
|
58
|
+
"description": "Commit message style the lander and implementer follow."
|
|
59
|
+
},
|
|
60
|
+
"test": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"additionalProperties": {
|
|
63
|
+
"type": "string"
|
|
64
|
+
},
|
|
65
|
+
"description": "Test runners by kind, e.g. {\"unit\":\"vitest\",\"e2e\":\"playwright\"}."
|
|
66
|
+
},
|
|
67
|
+
"spec": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"required": [
|
|
70
|
+
"engine"
|
|
71
|
+
],
|
|
72
|
+
"additionalProperties": false,
|
|
73
|
+
"properties": {
|
|
74
|
+
"engine": {
|
|
75
|
+
"enum": [
|
|
76
|
+
"openspec",
|
|
77
|
+
"prd-frd"
|
|
78
|
+
],
|
|
79
|
+
"description": "openspec: proposal/design/tasks + delta specs, validated by the openspec CLI. prd-frd: a PRD and an FRD with numbered requirements."
|
|
80
|
+
},
|
|
81
|
+
"docsRoot": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"description": "Where specifications live."
|
|
84
|
+
},
|
|
85
|
+
"strict": {
|
|
86
|
+
"type": "boolean",
|
|
87
|
+
"description": "openspec: validate with --strict."
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"branchScheme": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"description": "Placeholders are filled from the unit of work, e.g. {kind}/{slug}."
|
|
94
|
+
},
|
|
95
|
+
"verifyCmd": {
|
|
96
|
+
"type": [
|
|
97
|
+
"string",
|
|
98
|
+
"null"
|
|
99
|
+
],
|
|
100
|
+
"description": "The mechanical check: lint, types, tests. Without it nothing can be gated."
|
|
101
|
+
},
|
|
102
|
+
"gateCmd": {
|
|
103
|
+
"type": [
|
|
104
|
+
"string",
|
|
105
|
+
"null"
|
|
106
|
+
],
|
|
107
|
+
"description": "A heavier project-specific gate, run instead of verifyCmd when set."
|
|
108
|
+
},
|
|
109
|
+
"secretScan": {
|
|
110
|
+
"type": [
|
|
111
|
+
"string",
|
|
112
|
+
"null"
|
|
113
|
+
],
|
|
114
|
+
"description": "A command that fails when a credential appears in the branch's commits."
|
|
115
|
+
},
|
|
116
|
+
"heavy": {
|
|
117
|
+
"type": [
|
|
118
|
+
"string",
|
|
119
|
+
"null"
|
|
120
|
+
],
|
|
121
|
+
"description": "Prose rule for workloads that must be bounded or serialised."
|
|
122
|
+
},
|
|
123
|
+
"profile": {
|
|
124
|
+
"type": [
|
|
125
|
+
"string",
|
|
126
|
+
"null"
|
|
127
|
+
],
|
|
128
|
+
"description": "The kind of project this is: an opt-in standards profile from the plugin's profiles/ directory (webapp, library, service, compiler). One per project."
|
|
129
|
+
},
|
|
130
|
+
"concerns": {
|
|
131
|
+
"type": "array",
|
|
132
|
+
"items": {
|
|
133
|
+
"type": "string"
|
|
134
|
+
},
|
|
135
|
+
"description": "Cross-cutting standards from profiles/concerns/, applied in addition to the project-kind profile. A Go service needs service AND concurrency, so this is a list rather than a second single choice. Known: architecture, performance, memory, concurrency, data, platform.",
|
|
136
|
+
"examples": [
|
|
137
|
+
[
|
|
138
|
+
"concurrency",
|
|
139
|
+
"performance"
|
|
140
|
+
]
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
"reviewers": {
|
|
144
|
+
"type": "array",
|
|
145
|
+
"items": {
|
|
146
|
+
"type": "string"
|
|
147
|
+
},
|
|
148
|
+
"description": "Agents the readiness gate fans out to."
|
|
149
|
+
},
|
|
150
|
+
"protected": {
|
|
151
|
+
"type": "array",
|
|
152
|
+
"items": {
|
|
153
|
+
"type": "string"
|
|
154
|
+
},
|
|
155
|
+
"description": "Branches a push may not reach without a passed gate receipt. Globs allowed."
|
|
156
|
+
},
|
|
157
|
+
"receipts": {
|
|
158
|
+
"type": "object",
|
|
159
|
+
"additionalProperties": false,
|
|
160
|
+
"properties": {
|
|
161
|
+
"maxAgeMin": {
|
|
162
|
+
"type": "integer",
|
|
163
|
+
"minimum": 1,
|
|
164
|
+
"description": "How long a receipt stays valid."
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"enforce": {
|
|
169
|
+
"type": "object",
|
|
170
|
+
"additionalProperties": false,
|
|
171
|
+
"description": "What the PreToolUse hook refuses. Turning one off is a deliberate, recorded choice.",
|
|
172
|
+
"properties": {
|
|
173
|
+
"pushToTrunkNeedsGate": {
|
|
174
|
+
"type": "boolean"
|
|
175
|
+
},
|
|
176
|
+
"mergeNeedsReadiness": {
|
|
177
|
+
"type": "boolean"
|
|
178
|
+
},
|
|
179
|
+
"branchNeedsApprovedSpec": {
|
|
180
|
+
"type": "boolean"
|
|
181
|
+
},
|
|
182
|
+
"blockDestructiveGit": {
|
|
183
|
+
"type": "boolean"
|
|
184
|
+
},
|
|
185
|
+
"blockPublishing": {
|
|
186
|
+
"type": "boolean"
|
|
187
|
+
},
|
|
188
|
+
"blockCredentialReads": {
|
|
189
|
+
"type": "boolean"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"neverByAgent": {
|
|
194
|
+
"type": "array",
|
|
195
|
+
"items": {
|
|
196
|
+
"type": "string"
|
|
197
|
+
},
|
|
198
|
+
"description": "Actions reserved to a human, stated for the agents to read."
|
|
199
|
+
},
|
|
200
|
+
"quality": {
|
|
201
|
+
"type": "object",
|
|
202
|
+
"additionalProperties": true,
|
|
203
|
+
"description": "Deterministic analysis budget on NEW code. Peer-reviewed work on repositories that adopted coding agents reports persistent rises in analysis warnings and complexity, so the budget is on what a change adds, not on the whole repository.",
|
|
204
|
+
"properties": {
|
|
205
|
+
"cmd": {
|
|
206
|
+
"type": [
|
|
207
|
+
"string",
|
|
208
|
+
"null"
|
|
209
|
+
],
|
|
210
|
+
"description": "Static analysis / coverage command; non-zero exit fails the gate."
|
|
211
|
+
},
|
|
212
|
+
"coverageNewPct": {
|
|
213
|
+
"type": [
|
|
214
|
+
"number",
|
|
215
|
+
"null"
|
|
216
|
+
],
|
|
217
|
+
"minimum": 0,
|
|
218
|
+
"maximum": 100,
|
|
219
|
+
"description": "Minimum coverage required on changed lines."
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
"release": {
|
|
224
|
+
"type": "object",
|
|
225
|
+
"additionalProperties": false,
|
|
226
|
+
"description": "How a merged change reaches users. Merging is not shipping; this is the distance between them.",
|
|
227
|
+
"properties": {
|
|
228
|
+
"deployCmd": {
|
|
229
|
+
"type": [
|
|
230
|
+
"string",
|
|
231
|
+
"null"
|
|
232
|
+
]
|
|
233
|
+
},
|
|
234
|
+
"smokeCmd": {
|
|
235
|
+
"type": [
|
|
236
|
+
"string",
|
|
237
|
+
"null"
|
|
238
|
+
],
|
|
239
|
+
"description": "Proves the change works in the environment it was deployed to, not in CI."
|
|
240
|
+
},
|
|
241
|
+
"rollbackCmd": {
|
|
242
|
+
"type": [
|
|
243
|
+
"string",
|
|
244
|
+
"null"
|
|
245
|
+
],
|
|
246
|
+
"description": "The written way back. A deployment without one is not ready."
|
|
247
|
+
},
|
|
248
|
+
"environments": {
|
|
249
|
+
"type": "array",
|
|
250
|
+
"items": {
|
|
251
|
+
"type": "string"
|
|
252
|
+
},
|
|
253
|
+
"description": "Lowest first. Production is never deployed before the environment below it has been observed."
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"approvals": {
|
|
258
|
+
"type": "object",
|
|
259
|
+
"additionalProperties": false,
|
|
260
|
+
"description": "Which actions need a named human. An agent can never satisfy a 'human' approval: it records who is accountable, and an agent approving its own work records nothing.",
|
|
261
|
+
"properties": {
|
|
262
|
+
"merge": {
|
|
263
|
+
"enum": [
|
|
264
|
+
"agent",
|
|
265
|
+
"human"
|
|
266
|
+
]
|
|
267
|
+
},
|
|
268
|
+
"release": {
|
|
269
|
+
"enum": [
|
|
270
|
+
"agent",
|
|
271
|
+
"human"
|
|
272
|
+
]
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
"attributeCommits": {
|
|
277
|
+
"type": "boolean",
|
|
278
|
+
"description": "Add an agent identity trailer to commits, so a change can be traced to the actor that made it."
|
|
279
|
+
},
|
|
280
|
+
"budget": {
|
|
281
|
+
"type": "object",
|
|
282
|
+
"additionalProperties": false,
|
|
283
|
+
"description": "Ceilings an agent cannot raise for itself. An agent that cannot stop is a cost centre with a git token. The tool cannot see the host's token meter, so it counts what it can observe: tool calls through the hook, wall-clock since the task began, and repair attempts.",
|
|
284
|
+
"properties": {
|
|
285
|
+
"maxToolCalls": {
|
|
286
|
+
"type": "integer",
|
|
287
|
+
"minimum": 0,
|
|
288
|
+
"description": "Tool calls per task before the hook refuses. 0 means no ceiling, which means nothing will stop a runaway task."
|
|
289
|
+
},
|
|
290
|
+
"maxWallClockMin": {
|
|
291
|
+
"type": "integer",
|
|
292
|
+
"minimum": 0,
|
|
293
|
+
"description": "Minutes per task before the hook refuses. 0 means no ceiling."
|
|
294
|
+
},
|
|
295
|
+
"maxRetries": {
|
|
296
|
+
"type": "integer",
|
|
297
|
+
"minimum": 1,
|
|
298
|
+
"description": "Attempts at one stage before the pipeline says to stop and report. Default 3: past that, the specification is usually the problem, not the code."
|
|
299
|
+
},
|
|
300
|
+
"stopPolicy": {
|
|
301
|
+
"enum": [
|
|
302
|
+
"refuse",
|
|
303
|
+
"warn"
|
|
304
|
+
],
|
|
305
|
+
"description": "refuse: the hook blocks. warn: it says so and allows it. refuse is the point."
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
"suiteAudit": {
|
|
310
|
+
"type": "object",
|
|
311
|
+
"additionalProperties": false,
|
|
312
|
+
"description": "Controls for `sdlc tests audit`. Exemption is declared here rather than inferred from a line's text, because anything decided from the text can be rewritten by the actor the control exists to constrain. Adding a glob is itself reported as a weakening, so the escape hatch cannot be used quietly.",
|
|
313
|
+
"properties": {
|
|
314
|
+
"exclude": {
|
|
315
|
+
"type": "array",
|
|
316
|
+
"items": {
|
|
317
|
+
"type": "string"
|
|
318
|
+
},
|
|
319
|
+
"description": "Paths or globs exempt from the suppression-marker half of the audit. Deleted tests, removed assertions and lowered thresholds still fire on them. For files that genuinely DEFINE these patterns \u2014 a detector, its fixtures, an adversarial eval prompt \u2014 not for files that merely trip it."
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentic-sdlc-pipeline
|
|
3
|
+
description: >
|
|
4
|
+
The agent-based SDLC pipeline: how to take a unit of work from request to merged, which agent
|
|
5
|
+
owns each stage, and which receipt each stage leaves. Use when asked to set up, explain, run
|
|
6
|
+
or debug the SDLC pipeline, when a user says "use the pipeline / follow SDLC", or when
|
|
7
|
+
deciding which /agentic-sdlc command comes next.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# The pipeline
|
|
11
|
+
|
|
12
|
+
Read `${CLAUDE_PLUGIN_ROOT}/docs/rules.md` before running any stage. Read the project's
|
|
13
|
+
`sdlc.config.json` to learn its stack — never assume one.
|
|
14
|
+
|
|
15
|
+
| # | Stage | Command | Owner | Leaves |
|
|
16
|
+
| --- | --- | --- | --- | --- |
|
|
17
|
+
| 0 | Adapt | `/agentic-sdlc:init` | — | `sdlc.config.json` |
|
|
18
|
+
| 1 | Specify | `/agentic-sdlc:feature` | `sdlc-spec-writer` | a specification |
|
|
19
|
+
| 2 | Review the spec | ↑ same command | `sdlc-spec-reviewer` | `spec` receipt |
|
|
20
|
+
| 3 | Branch | ↑ same command | `sdlc-branch-opener` | a branch |
|
|
21
|
+
| 3b | Impact | `/agentic-sdlc:impact` | `sdlc-impact-analyst` | who depends on this, and in what order |
|
|
22
|
+
| 4 | Implement | `/agentic-sdlc:implement` | `sdlc-implementer` | code and tests |
|
|
23
|
+
| 5 | Verify | `/agentic-sdlc:verify` | `sdlc-verifier` | `verification` receipt |
|
|
24
|
+
| 6 | Review | `/agentic-sdlc:review` | `sdlc-code-reviewer`, `sdlc-security-reviewer` | `review`, `security` receipts |
|
|
25
|
+
| 7a | Mechanical gate | `/agentic-sdlc:gate` | — | `gate` receipt |
|
|
26
|
+
| 7b | Readiness | `/agentic-sdlc:readiness` | `sdlc-readiness-gate` | `readiness` receipt |
|
|
27
|
+
| 8 | Land | `/agentic-sdlc:land` | `sdlc-lander` | branch pushed, pull request |
|
|
28
|
+
| 9 | Report | `/agentic-sdlc:report` | `sdlc-reporter` | implementation report, docs |
|
|
29
|
+
| 10 | Release | `/agentic-sdlc:release` | `sdlc-release-manager` | `postdeploy` receipt, or a rollback |
|
|
30
|
+
| — | Triage | `/agentic-sdlc:triage` | `sdlc-triager` | a scoped unit of work, or a reasoned dismissal |
|
|
31
|
+
| — | Remediate | `/agentic-sdlc:remediate` | `sdlc-remediator` | one commit per finding, re-verified |
|
|
32
|
+
|
|
33
|
+
The branch stage also captures a **baseline** — what the verify command said before any work
|
|
34
|
+
began. Every later failure is then attributable: new, pre-existing, or fixed. Without it an
|
|
35
|
+
agent spends its retries on a test that was already red.
|
|
36
|
+
|
|
37
|
+
`/agentic-sdlc:status` says which receipts hold right now; `/agentic-sdlc:doctor` checks the
|
|
38
|
+
install and the configuration.
|
|
39
|
+
|
|
40
|
+
## What makes it different from a checklist
|
|
41
|
+
|
|
42
|
+
Three stages are enforced by a `PreToolUse` hook, not by instruction:
|
|
43
|
+
|
|
44
|
+
- a branch needs an **approved spec** receipt whose digest still matches the specification;
|
|
45
|
+
- a push to a protected branch needs a **passed gate** receipt for that exact commit;
|
|
46
|
+
- a merge needs a **READY readiness** receipt for that exact commit, plus a human
|
|
47
|
+
`approval_merge` where the project asks for one;
|
|
48
|
+
- a deployment needs a human `approval_release` **and** a READY receipt — an agent cannot
|
|
49
|
+
approve its own release.
|
|
50
|
+
|
|
51
|
+
A new commit voids a receipt. Editing an approved specification voids its approval. The hook
|
|
52
|
+
also refuses destructive git, publishing and credential reads. None of this makes a dishonest
|
|
53
|
+
verdict honest; it makes a skipped stage impossible.
|
|
54
|
+
|
|
55
|
+
## Starting in an existing repository
|
|
56
|
+
|
|
57
|
+
1. `/agentic-sdlc:init --write`, then read the config and correct it. `verifyCmd` must be real.
|
|
58
|
+
2. Choose a profile if one fits (`${CLAUDE_PLUGIN_ROOT}/profiles/`); "none" is fine.
|
|
59
|
+
3. `/agentic-sdlc:doctor` until it is clean.
|
|
60
|
+
4. `/agentic-sdlc:feature "<what you want>"`.
|
|
61
|
+
|
|
62
|
+
## When a stage says no
|
|
63
|
+
|
|
64
|
+
That is the pipeline working. Fix the cause, re-run the stage, and let it write a new receipt.
|
|
65
|
+
Never edit a receipt, and never route around the hook — if the route is blocked, the route is
|
|
66
|
+
wrong.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: openspec-with-sdlc
|
|
3
|
+
description: >
|
|
4
|
+
How the SDLC pipeline uses OpenSpec as its specification engine — creating a change,
|
|
5
|
+
validating it, turning tasks.md into acceptance criteria, and archiving after landing. Use
|
|
6
|
+
when a repo has openspec/ or spec.engine is "openspec", or when asked how OpenSpec and the
|
|
7
|
+
pipeline fit together.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# OpenSpec as the pipeline's spec engine
|
|
11
|
+
|
|
12
|
+
When `spec.engine` is `openspec`, the specification is an OpenSpec change rather than a PRD and
|
|
13
|
+
an FRD. The pipeline gains three things from it: a layout other tools understand, a validator
|
|
14
|
+
that fails on a malformed spec, and an archive step that keeps "what is proposed" honest.
|
|
15
|
+
|
|
16
|
+
## The mapping
|
|
17
|
+
|
|
18
|
+
| Pipeline idea | OpenSpec artefact |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| Why this work exists | `openspec/changes/<id>/proposal.md` |
|
|
21
|
+
| What was chosen, and over what | `<id>/design.md` |
|
|
22
|
+
| The acceptance criteria | `<id>/tasks.md` — one checklist item per deliverable |
|
|
23
|
+
| Requirements on a published capability | `<id>/specs/<capability>/spec.md` |
|
|
24
|
+
| The spec is well-formed | `openspec validate <id> --strict` |
|
|
25
|
+
| The work is done | every `tasks.md` item ticked, in the commit that did it |
|
|
26
|
+
| The change is history | `openspec archive <id>` |
|
|
27
|
+
|
|
28
|
+
## The commands that matter
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
openspec list # active changes — check before proposing
|
|
32
|
+
openspec list --specs # published capabilities
|
|
33
|
+
openspec show <id> # read one
|
|
34
|
+
openspec validate <id> --strict # the spec reviewer runs this first
|
|
35
|
+
openspec archive <id> # the reporter runs this after landing
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`openspec validate --strict --json` is machine-readable: a failure is an automatic
|
|
39
|
+
`changes-requested` and the reviewer quotes it rather than paraphrasing.
|
|
40
|
+
|
|
41
|
+
## Writing tasks.md so the rest of the pipeline works
|
|
42
|
+
|
|
43
|
+
`tasks.md` is not a to-do list; it is the acceptance criteria the verifier and the readiness
|
|
44
|
+
gate check against. Each item must name **one deliverable with an observable outcome**. "Wire up
|
|
45
|
+
the parser" cannot be verified. "`parse()` refuses an unterminated string with error `E0012`,
|
|
46
|
+
with a test" can.
|
|
47
|
+
|
|
48
|
+
The implementer ticks each item in the same commit as the work; the verifier maps each item to
|
|
49
|
+
`file:line` plus a test outcome; the readiness gate treats an unticked finished item as
|
|
50
|
+
sloppiness and a ticked unfinished item as a blocker.
|
|
51
|
+
|
|
52
|
+
## Archiving
|
|
53
|
+
|
|
54
|
+
Archive only after the change has landed and its delta specs are reflected in the published
|
|
55
|
+
ones. `openspec list` should show what is genuinely in flight — a finished change left active
|
|
56
|
+
is a lie the next session will believe.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: writing-specifications
|
|
3
|
+
description: >
|
|
4
|
+
How to write a specification this pipeline can verify — falsifiable requirements, specified
|
|
5
|
+
refusals, stated scope, named open questions. Use when writing or reviewing a PRD, FRD,
|
|
6
|
+
OpenSpec proposal or tasks list, or when a spec review returns changes-requested.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# A specification the pipeline can verify
|
|
10
|
+
|
|
11
|
+
The test of a specification here is mechanical: can the verifier, months later, take each line
|
|
12
|
+
and find evidence for or against it? If not, the line is prose, not a requirement.
|
|
13
|
+
|
|
14
|
+
## Falsifiable, one deliverable at a time
|
|
15
|
+
|
|
16
|
+
For each requirement, name the observation that would show it unmet.
|
|
17
|
+
|
|
18
|
+
| Not verifiable | Verifiable |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| Improve error handling | On a 5xx from the payment provider, the order stays `pending`, the user sees `PAY-003`, and the job retries three times at 1s/4s/16s |
|
|
21
|
+
| Make the parser robust | `parse()` refuses an unterminated string with `E0012`, naming the line and column |
|
|
22
|
+
| Add caching | A second identical request within 60s is served from cache, and a write invalidates it within one request |
|
|
23
|
+
|
|
24
|
+
## Specify the refusals
|
|
25
|
+
|
|
26
|
+
Most defects live where nothing was specified: the empty input, the duplicate, the expired
|
|
27
|
+
token, the concurrent write, the half-finished upload. Every error a user can reach has a name,
|
|
28
|
+
a code where the project uses codes, and a stated message. "The implementation will decide" is
|
|
29
|
+
how two call sites end up disagreeing.
|
|
30
|
+
|
|
31
|
+
## State the scope, both ways
|
|
32
|
+
|
|
33
|
+
Write what is **out** of scope as deliberately as what is in. An explicit non-goal stops the
|
|
34
|
+
implementer gold-plating and stops the reviewer raising it as a gap.
|
|
35
|
+
|
|
36
|
+
## Name the open questions
|
|
37
|
+
|
|
38
|
+
An unknown written down is a question; an unknown assumed is a defect with a delay. Mark the
|
|
39
|
+
ones that are the maintainer's — publishing, a safety rule, removing something users have,
|
|
40
|
+
licensing, scope — and leave them open rather than deciding them.
|
|
41
|
+
|
|
42
|
+
## Cite, do not restate
|
|
43
|
+
|
|
44
|
+
If an authority document already defines something, cite the section. A restatement is a second
|
|
45
|
+
copy that will drift, and the drift will be discovered by someone trusting the wrong one.
|
|
46
|
+
|
|
47
|
+
## Size
|
|
48
|
+
|
|
49
|
+
One unit of work is one branch, one review and one merge. If the checklist has twenty items
|
|
50
|
+
spanning three subsystems, it is three units wearing one name — split it, and say what order
|
|
51
|
+
they go in.
|