devaudit-sdlc 0.2.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/package.json +21 -0
- package/src/bin/devaudit-sdlc.js +95 -0
- package/src/blueprints/1-plan-requirement.raw.md +464 -0
- package/src/blueprints/2-implement-and-test.raw.md +302 -0
- package/src/blueprints/3-compile-evidence.raw.md +817 -0
- package/src/blueprints/4-submit-for-review.raw.md +379 -0
- package/src/blueprints/5-deploy-main.raw.md +273 -0
- package/src/blueprints/implementing-an-sdlc-issue.raw.md +441 -0
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "devaudit-sdlc",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "DevAudit SDLC CLI Engine — cross-agent terminal-driven SDLC orchestrator.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"devaudit-sdlc": "./src/bin/devaudit-sdlc.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"src/bin/devaudit-sdlc.js",
|
|
10
|
+
"src/blueprints"
|
|
11
|
+
],
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=18"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/metasession-dev/DevAudit-Installer",
|
|
18
|
+
"directory": "sdlc"
|
|
19
|
+
},
|
|
20
|
+
"license": "Apache-2.0"
|
|
21
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
let phase = null;
|
|
7
|
+
let viewOnly = args.includes('--view');
|
|
8
|
+
|
|
9
|
+
const phaseArg = args.find(arg => arg.startsWith('--phase='));
|
|
10
|
+
if (phaseArg) {
|
|
11
|
+
phase = phaseArg.split('=')[1];
|
|
12
|
+
} else {
|
|
13
|
+
const phaseIndex = args.indexOf('--phase');
|
|
14
|
+
if (phaseIndex !== -1 && args[phaseIndex + 1]) {
|
|
15
|
+
phase = args[phaseIndex + 1];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!phase) {
|
|
20
|
+
console.error("❌ ERROR: Missing required configuration property. Execution syntax: devaudit-sdlc --phase=<1-5|issue>");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const phaseMap = {
|
|
25
|
+
'1': '1-plan-requirement.raw.md',
|
|
26
|
+
'2': '2-implement-and-test.raw.md',
|
|
27
|
+
'3': '3-compile-evidence.raw.md',
|
|
28
|
+
'4': '4-submit-for-review.raw.md',
|
|
29
|
+
'5': '5-deploy-main.raw.md',
|
|
30
|
+
'issue': 'implementing-an-sdlc-issue.raw.md'
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const targetBlueprint = phaseMap[phase];
|
|
34
|
+
if (!targetBlueprint) {
|
|
35
|
+
console.error(`❌ ERROR: Invalid phase argument [${phase}]. Supported options: 1, 2, 3, 4, 5, issue`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const blueprintPath = path.join(__dirname, '..', 'blueprints', targetBlueprint);
|
|
40
|
+
const sentinelPath = path.join(process.cwd(), '.sdlc-implementer-invoked');
|
|
41
|
+
|
|
42
|
+
if (viewOnly) {
|
|
43
|
+
if (!fs.existsSync(blueprintPath)) {
|
|
44
|
+
console.error("❌ ERROR: Target operational asset blueprint could not be resolved.");
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const content = fs.readFileSync(blueprintPath, 'utf8');
|
|
48
|
+
console.log(content);
|
|
49
|
+
process.exit(0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const newRecord = {
|
|
54
|
+
activatedAt: new Date().toISOString(),
|
|
55
|
+
currentPhase: phase,
|
|
56
|
+
initializedBy: 'devaudit-cli-engine',
|
|
57
|
+
status: 'active'
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Read existing sentinel and append, or create new array
|
|
61
|
+
let phaseHistory = [];
|
|
62
|
+
if (fs.existsSync(sentinelPath)) {
|
|
63
|
+
try {
|
|
64
|
+
const existingContent = fs.readFileSync(sentinelPath, 'utf8');
|
|
65
|
+
const parsed = JSON.parse(existingContent);
|
|
66
|
+
if (Array.isArray(parsed)) {
|
|
67
|
+
phaseHistory = parsed;
|
|
68
|
+
} else {
|
|
69
|
+
// Legacy single-object format — migrate it into the array
|
|
70
|
+
console.warn('⚠️ WARNING: Sentinel file contained a legacy single-object format. Migrating to array format.');
|
|
71
|
+
phaseHistory = [parsed];
|
|
72
|
+
}
|
|
73
|
+
} catch (parseError) {
|
|
74
|
+
// Corrupt or plain-text sentinel — start fresh
|
|
75
|
+
console.warn('⚠️ WARNING: Sentinel file was corrupt or in legacy plain-text format. Overwriting with fresh phase history.');
|
|
76
|
+
phaseHistory = [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
phaseHistory.push(newRecord);
|
|
81
|
+
fs.writeFileSync(sentinelPath, JSON.stringify(phaseHistory, null, 2), 'utf8');
|
|
82
|
+
|
|
83
|
+
console.log(`\n✅ SDLC Gateway Initialized: Appended phase ${phase} record to sentinel at ${sentinelPath}`);
|
|
84
|
+
console.log(`🚀 Phase ${phase} orchestration active. Your local git commit gates are now open.`);
|
|
85
|
+
console.log(`📋 Phase history: ${phaseHistory.map(r => r.currentPhase).join(' → ')}`);
|
|
86
|
+
|
|
87
|
+
if (fs.existsSync(blueprintPath)) {
|
|
88
|
+
console.log(`\n--- PHASE EXECUTION MANIFEST ---`);
|
|
89
|
+
const content = fs.readFileSync(blueprintPath, 'utf8');
|
|
90
|
+
console.log(content);
|
|
91
|
+
}
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error("❌ SYSTEM ERROR: Failed to instantiate workspace sentinel tracking state:", error.message);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Define a new requirement in the RTM, classify risk, create implementation plan, generate test scope, and prepare for implementation
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
### 🛑 SYSTEM OVERRIDE: AUTOMATED SDLC ENFORCEMENT
|
|
6
|
+
|
|
7
|
+
If you are an AI agent reading this file, you are strictly prohibited from manually executing this workflow step-by-step unless explicitly authorized by the operator. Route immediately to your platform's valid orchestration path:
|
|
8
|
+
|
|
9
|
+
- **CLAUDE CODE:** Halt manual tracking immediately. Invoke the orchestrator skill via: `Skill(name: "sdlc-implementer", …)`
|
|
10
|
+
- **OTHER AGENTS (Cursor, Windsurf, Gemini, etc.):** Halt manual execution and output this exact message to the user:
|
|
11
|
+
"I am pausing to request authorization for the SDLC workflow on this issue. Please confirm if I should proceed."
|
|
12
|
+
|
|
13
|
+
CRITICAL WORKFLOW REQUIRED AFTER AUTHORIZATION: Once the operator grants permission to proceed, you MUST immediately execute 'npx devaudit-sdlc --phase=1' to generate the required commit sentinel file in the root directory BEFORE making any file modifications or code changes. Failure to create this file will result in your local git commits being automatically blocked by our pre-commit hooks.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Plan Requirement
|
|
18
|
+
|
|
19
|
+
**Pipeline Stage:** 1 of 5
|
|
20
|
+
**Next:** `2-implement-and-test.md`
|
|
21
|
+
**References:** Test Policy (`sdlc/files/Test_Policy.md` in DevAudit) (risk classification, AI governance), Test Strategy (risk matrix, testing depth, AI documentation)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## When to Use
|
|
26
|
+
|
|
27
|
+
- New features, enhancements, or significant changes
|
|
28
|
+
- **Bug fixes that affect financial calculations, user-facing data, or access control**
|
|
29
|
+
- Work that needs formal traceability (security, payments, RBAC, data handling)
|
|
30
|
+
- Any change a stakeholder or auditor might ask "was this tested?"
|
|
31
|
+
|
|
32
|
+
**Skip this workflow** for trivial changes (typo fixes, formatting, dependency bumps) — go straight to `2-implement-and-test.md`.
|
|
33
|
+
|
|
34
|
+
**Even for trivial changes:** review existing tests for impact and run all gates locally before pushing.
|
|
35
|
+
|
|
36
|
+
## Steps
|
|
37
|
+
|
|
38
|
+
### Step 1: Identify the GitHub Issue
|
|
39
|
+
|
|
40
|
+
Every tracked change starts from a GitHub Issue. The issue provides the _what_ and _why_; the RTM provides the compliance audit trail.
|
|
41
|
+
|
|
42
|
+
- If the user references an issue number (e.g., `#123`): fetch its title, description, and labels using `gh issue view 123`.
|
|
43
|
+
- If the user describes work without an issue: ask **"Is there a GitHub Issue for this, or should we create one?"**
|
|
44
|
+
- To create one: `gh issue create --title "[title]" --body "[description]" --label "[labels]"`
|
|
45
|
+
- Use issue labels to inform risk classification in Step 3 (e.g., `security`, `user-facing`, `internal`).
|
|
46
|
+
|
|
47
|
+
### Step 2: Determine the Next Requirement ID
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
grep -oP 'REQ-\d+' compliance/RTM.md | sort -t- -k2 -n | tail -1
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The next ID is one higher (e.g., if the last is REQ-007, use REQ-008).
|
|
54
|
+
|
|
55
|
+
### Step 3: Classify Risk Level
|
|
56
|
+
|
|
57
|
+
| Risk Level | Criteria |
|
|
58
|
+
| ---------- | ---------------------------------------------------------------- |
|
|
59
|
+
| **Low** | Internal tools, no regulated data, no auth changes |
|
|
60
|
+
| **Medium** | Touches PII, user-facing features, API changes, new dependencies |
|
|
61
|
+
| **High** | Security, payments, RBAC, data handling, authentication |
|
|
62
|
+
|
|
63
|
+
AI involvement raises risk by one level when touching Medium or High categories. See Test Policy for the full risk matrix.
|
|
64
|
+
|
|
65
|
+
### Step 4: Add Entry to RTM
|
|
66
|
+
|
|
67
|
+
Open `compliance/RTM.md`, Part B. The issue provides full context; the RTM is a traceability index, not a content store.
|
|
68
|
+
|
|
69
|
+
```markdown
|
|
70
|
+
| REQ-XXX | #NNN | [LOW/MEDIUM/HIGH] | compliance/evidence/REQ-XXX/ | DRAFT | -- | -- |
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The auditor reads one row and follows the links: Issue for context and rationale, evidence directory for test artifacts, PR for code changes.
|
|
74
|
+
|
|
75
|
+
### Step 5: Create Evidence Directory
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
mkdir -p compliance/evidence/REQ-XXX
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Step 6: Implementation Plan (MEDIUM/HIGH Risk — Required)
|
|
82
|
+
|
|
83
|
+
For MEDIUM and HIGH risk requirements, create an implementation plan before defining test scope. The implementation plan defines _what code changes are needed_ — the test scope is then derived from it.
|
|
84
|
+
|
|
85
|
+
**Skip this step** for LOW risk requirements — proceed directly to Step 7.
|
|
86
|
+
|
|
87
|
+
**6a. Explore the codebase:**
|
|
88
|
+
|
|
89
|
+
- Understand existing patterns, models, services, and API routes relevant to the change
|
|
90
|
+
- Identify files that will be created, modified, or affected
|
|
91
|
+
|
|
92
|
+
**6b. Create the implementation plan:**
|
|
93
|
+
|
|
94
|
+
Create `compliance/evidence/REQ-XXX/implementation-plan.md`:
|
|
95
|
+
|
|
96
|
+
```markdown
|
|
97
|
+
# Implementation Plan — REQ-XXX
|
|
98
|
+
|
|
99
|
+
**Requirement:** REQ-XXX
|
|
100
|
+
**GitHub Issue:** #NNN
|
|
101
|
+
**Risk Level:** [MEDIUM / HIGH]
|
|
102
|
+
**Date:** [YYYY-MM-DD]
|
|
103
|
+
|
|
104
|
+
## Approach
|
|
105
|
+
|
|
106
|
+
[1-3 sentences describing the overall approach]
|
|
107
|
+
|
|
108
|
+
## Files to Create
|
|
109
|
+
|
|
110
|
+
- `path/to/new-file.ts` — [purpose]
|
|
111
|
+
|
|
112
|
+
## Files to Modify
|
|
113
|
+
|
|
114
|
+
- `path/to/existing-file.ts` — [what changes and why]
|
|
115
|
+
|
|
116
|
+
## Architecture Decisions
|
|
117
|
+
|
|
118
|
+
> Populated by the [`adr-author` skill](../skills/adr-author/SKILL.md) at Stage 1 plan APPROVAL. The skill applies a decision tree (new third-party dependency / new database, cache, or queue / new external service / pattern change spanning > 3 files / HIGH-CRITICAL risk) and either drafts `docs/ADR/ADR-NNN-<slug>.md` + injects "Produced ADR-NNN: <title>" here, or injects "No ADR needed — <one-line rationale>" so the question is visibly asked and answered. Don't author this section inline as bullets — the persistent decision lives in `docs/ADR/`, not buried in the plan.
|
|
119
|
+
|
|
120
|
+
- ADR-NNN — <title> (`docs/ADR/ADR-NNN-<slug>.md`) — Operator edits stub + flips to _Accepted_ before APPROVAL — OR — No ADR needed — <rationale>
|
|
121
|
+
|
|
122
|
+
## Dependencies
|
|
123
|
+
|
|
124
|
+
- [New packages needed, or "None"]
|
|
125
|
+
|
|
126
|
+
## Risks / Considerations
|
|
127
|
+
|
|
128
|
+
> Populated by the [`risk-register-keeper` skill](../skills/risk-register-keeper/SKILL.md) at Stage 1 for MEDIUM/HIGH risk REQs (LOW skipped by default per `sdlc-config.json:risk_register_keeper.stage_1_min_risk_class`). The skill identifies discrete risks the change introduces, allocates `RISK-NNN` per project, drafts canonical rows in `compliance/risk-register.md`, and injects the RISK-NNN reference list here (replacing the inline bullets). Don't author this section inline as bullets — the persistent risk record lives in `compliance/risk-register.md`, not buried in the plan.
|
|
129
|
+
|
|
130
|
+
- RISK-NNN — <title> (`compliance/risk-register.md`) — Operator edits canonical row + signs off residual rating before APPROVAL — OR — @risk-deferred — <rationale>
|
|
131
|
+
|
|
132
|
+
## Post-Deploy Actions
|
|
133
|
+
|
|
134
|
+
- [Data migrations, backfill scripts, schema changes — or "None"]
|
|
135
|
+
- [If any: create script in `scripts/`, document exact command and target environment]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### WAIT CHECKPOINT: Implementation Plan Review
|
|
139
|
+
|
|
140
|
+
**Present the implementation plan to the developer.** Summarize:
|
|
141
|
+
|
|
142
|
+
- Approach and rationale
|
|
143
|
+
- Files to create/modify
|
|
144
|
+
- Architecture decisions
|
|
145
|
+
- Risks and dependencies
|
|
146
|
+
- **Surface inventory completeness** (MEDIUM/HIGH risk) — every user-touchable surface listed in Section 2's surface-inventory table is either `In scope`, `Already works`, or explicitly `Out of scope (waived)` with a follow-up issue. No surface is silently absent. _(devaudit#152)_
|
|
147
|
+
- **AC form** — the test-scope ACs (drafted in Step 7) can each be phrased in Given/When/Then against the surfaces in scope. If any AC reduces to _"the schema accepts X"_ or _"the resolver returns Y"_, the plan is incomplete — return to Section 2 and expand the surface inventory until every AC has a UI surface that delivers it. _(devaudit#152)_
|
|
148
|
+
|
|
149
|
+
**Do NOT proceed** until the developer explicitly approves the plan. If the developer requests changes, update `implementation-plan.md` and re-present. For HIGH risk, this review is especially important — it's cheaper to change the plan than to refactor the code.
|
|
150
|
+
|
|
151
|
+
**6c. Commit the plan:**
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
git add compliance/evidence/REQ-XXX/implementation-plan.md
|
|
155
|
+
git commit -m "chore(compliance): [REQ-XXX] implementation plan
|
|
156
|
+
|
|
157
|
+
Ref: REQ-XXX
|
|
158
|
+
|
|
159
|
+
Co-Authored-By: [AI tool tag]"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
### Step 7: Generate Test Scope
|
|
165
|
+
|
|
166
|
+
Create a test scope document proportional to the assessed risk level. For MEDIUM/HIGH risk, this is derived from the implementation plan — you now know what code is changing and can define what tests are needed.
|
|
167
|
+
|
|
168
|
+
This must exist **before implementation begins** — it is the evidence that testing was planned, not retroactively documented.
|
|
169
|
+
|
|
170
|
+
The AI generates this based on the risk classification, the implementation plan (if applicable), and the Test Strategy's risk-based testing depth matrix.
|
|
171
|
+
|
|
172
|
+
**For LOW risk:**
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
cat > compliance/evidence/REQ-XXX/test-scope.md << 'EOF'
|
|
176
|
+
# Test Scope — REQ-XXX
|
|
177
|
+
|
|
178
|
+
**Risk Level:** LOW
|
|
179
|
+
**Requirement:** [Brief description]
|
|
180
|
+
**GitHub Issue:** #NNN
|
|
181
|
+
**Date:** [YYYY-MM-DD]
|
|
182
|
+
|
|
183
|
+
## Test Approach
|
|
184
|
+
|
|
185
|
+
Standard gates apply. No additional testing beyond universal exit criteria.
|
|
186
|
+
|
|
187
|
+
- TypeScript compilation: 0 errors
|
|
188
|
+
- SAST scan: 0 high/critical findings
|
|
189
|
+
- Dependency audit: 0 high/critical vulnerabilities
|
|
190
|
+
- E2E suite: all pass
|
|
191
|
+
- CI independent verification: all PR checks pass
|
|
192
|
+
- Human code review via PR
|
|
193
|
+
|
|
194
|
+
### How to write acceptance criteria (devaudit#152)
|
|
195
|
+
|
|
196
|
+
Phrase each AC as a **user-observable journey**, not a technical-layer assertion. Use the Given/When/Then form:
|
|
197
|
+
|
|
198
|
+
> **Given** [pre-state + which UI surface the user is on], **When** [named user action with a named control], **Then** [observable change in a named UI surface].
|
|
199
|
+
|
|
200
|
+
If you can't phrase an AC in Given/When/Then because no UI surface delivers the change to a user, the scope is incomplete — return to the implementation plan's surface inventory (Section 2). LOW risk REQs may keep ACs shorter when the change is genuinely surface-free (refactor / dep bump / infra-only), but the journey form is still preferred when a user surface exists.
|
|
201
|
+
|
|
202
|
+
Examples:
|
|
203
|
+
|
|
204
|
+
- ✅ "Given the dependency is updated, When CI runs the universal gates, Then 0 high/critical findings."
|
|
205
|
+
- ❌ "Schema accepts optional `inventoryId` field" — internal mechanic, belongs in `test-plan.md` (this matters even for LOW when the change is user-facing).
|
|
206
|
+
|
|
207
|
+
## Acceptance Criteria
|
|
208
|
+
|
|
209
|
+
- [x] [Criterion 1 — what "done" looks like, phrased Given/When/Then where applicable]
|
|
210
|
+
- [x] [Criterion 2]
|
|
211
|
+
EOF
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**For MEDIUM risk:**
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
cat > compliance/evidence/REQ-XXX/test-scope.md << 'EOF'
|
|
218
|
+
# Test Scope — REQ-XXX
|
|
219
|
+
|
|
220
|
+
**Risk Level:** MEDIUM
|
|
221
|
+
**Requirement:** [Brief description]
|
|
222
|
+
**GitHub Issue:** #NNN
|
|
223
|
+
**Date:** [YYYY-MM-DD]
|
|
224
|
+
|
|
225
|
+
## Test Approach
|
|
226
|
+
|
|
227
|
+
Standard gates plus targeted verification.
|
|
228
|
+
|
|
229
|
+
**Universal gates (mandatory — verified locally AND in CI):**
|
|
230
|
+
- TypeScript compilation: 0 errors
|
|
231
|
+
- SAST scan: 0 high/critical findings
|
|
232
|
+
- Dependency audit: 0 high/critical vulnerabilities
|
|
233
|
+
- E2E suite: all pass (full suite local, unauthenticated subset in CI)
|
|
234
|
+
- Human code review via PR
|
|
235
|
+
|
|
236
|
+
**Additional testing required by risk level:**
|
|
237
|
+
- [ ] Access control: [which endpoints/roles need verification]
|
|
238
|
+
- [ ] Audit logging: [which actions must produce log entries]
|
|
239
|
+
- [ ] Dependency review: [if new packages, verify real/current/no CVEs]
|
|
240
|
+
- [ ] [Any other area-specific testing]
|
|
241
|
+
|
|
242
|
+
## Validation Approach
|
|
243
|
+
|
|
244
|
+
How we confirm this meets the business requirement:
|
|
245
|
+
- [e.g., "Verify public page displays new content correctly"]
|
|
246
|
+
- [e.g., "Confirm edits are visible to users within expected time"]
|
|
247
|
+
|
|
248
|
+
### How to write acceptance criteria (devaudit#152)
|
|
249
|
+
|
|
250
|
+
Phrase each AC as a **user-observable journey**, not a technical-layer assertion. Use the Given/When/Then form:
|
|
251
|
+
|
|
252
|
+
> **Given** [pre-state + which UI surface the user is on], **When** [named user action with a named control], **Then** [observable change in a named UI surface] _(plus any audit / downstream UI changes)_.
|
|
253
|
+
|
|
254
|
+
If you can't phrase an AC in Given/When/Then because no UI surface delivers the change to a user, the scope is incomplete — return to the implementation plan's surface inventory (Section 2).
|
|
255
|
+
|
|
256
|
+
Examples:
|
|
257
|
+
|
|
258
|
+
- ✅ "Given Poundo has Ogbono linked, When a staff member opens `/dashboard/orders/express/create-order`, picks Ogbono from the Soup group, and marks the order Complete, Then `/dashboard/inventory/{ogbono}` shows stock decreased by 1 and a new Sale movement row tied to the order ID."
|
|
259
|
+
- ❌ "Schema accepts optional `inventoryId` field (persistence round-trip)" — unit-test contract, belongs in `test-plan.md`, not here.
|
|
260
|
+
- ❌ "Resolver maps selected pairs to inventory link" — internal mechanic, not user value.
|
|
261
|
+
|
|
262
|
+
## Acceptance Criteria
|
|
263
|
+
|
|
264
|
+
- [ ] [Criterion 1 — Given/When/Then]
|
|
265
|
+
- [ ] [Criterion 2 — Given/When/Then]
|
|
266
|
+
- [ ] All additional testing items above pass
|
|
267
|
+
EOF
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**For HIGH risk:**
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
cat > compliance/evidence/REQ-XXX/test-scope.md << 'EOF'
|
|
274
|
+
# Test Scope — REQ-XXX
|
|
275
|
+
|
|
276
|
+
**Risk Level:** HIGH
|
|
277
|
+
**Requirement:** [Brief description]
|
|
278
|
+
**GitHub Issue:** #NNN
|
|
279
|
+
**Date:** [YYYY-MM-DD]
|
|
280
|
+
|
|
281
|
+
## Test Approach
|
|
282
|
+
|
|
283
|
+
Full verification and validation per Test Strategy high-risk requirements.
|
|
284
|
+
|
|
285
|
+
**Universal gates (mandatory — verified locally AND in CI):**
|
|
286
|
+
- TypeScript compilation: 0 errors
|
|
287
|
+
- SAST scan: 0 high/critical findings
|
|
288
|
+
- Dependency audit: 0 high/critical vulnerabilities
|
|
289
|
+
- E2E suite: all pass
|
|
290
|
+
- Human code review via PR
|
|
291
|
+
|
|
292
|
+
**Security testing (mandatory for HIGH):**
|
|
293
|
+
- [ ] Access control: [specific endpoints, roles, expected behaviors]
|
|
294
|
+
- [ ] Audit logging: [specific actions that must produce entries]
|
|
295
|
+
- [ ] Input validation: [boundary/injection testing needed]
|
|
296
|
+
- [ ] Error handling: [verify no sensitive data in error responses]
|
|
297
|
+
|
|
298
|
+
**Additional high-risk testing:**
|
|
299
|
+
- [ ] Independent review: [who will provide secondary review]
|
|
300
|
+
- [ ] Penetration testing consideration: [warranted? justification]
|
|
301
|
+
- [ ] Performance impact: [load/performance concerns]
|
|
302
|
+
- [ ] Regression scope: [areas needing manual verification beyond E2E]
|
|
303
|
+
|
|
304
|
+
## Validation Approach
|
|
305
|
+
|
|
306
|
+
How we confirm this meets the business requirement:
|
|
307
|
+
- [Specific user workflow to test end-to-end]
|
|
308
|
+
- [Business rule to validate]
|
|
309
|
+
- [Stakeholder sign-off needed? From whom?]
|
|
310
|
+
|
|
311
|
+
## AI Involvement (if applicable)
|
|
312
|
+
|
|
313
|
+
- AI tool: [tool name / none]
|
|
314
|
+
- Code categories AI will generate: [list]
|
|
315
|
+
- Elevated review required for: [security-sensitive files]
|
|
316
|
+
- Regeneration protocol: [will any components be regenerated?]
|
|
317
|
+
|
|
318
|
+
### How to write acceptance criteria (devaudit#152)
|
|
319
|
+
|
|
320
|
+
Phrase each AC as a **user-observable journey**, not a technical-layer assertion. Use the Given/When/Then form:
|
|
321
|
+
|
|
322
|
+
> **Given** [pre-state + which UI surface the user is on], **When** [named user action with a named control], **Then** [observable change in a named UI surface] _(plus any audit / downstream UI changes)_.
|
|
323
|
+
|
|
324
|
+
HIGH risk especially: every AC must pin to a named UI surface from the implementation plan's surface inventory (Section 2). If you can't phrase an AC in Given/When/Then because no UI surface delivers the change to a user, the scope is incomplete — expand the surface inventory before approving the plan. This is the gap that produced REQ-030 on a consumer project (feature shipped through every gate green, but no order-creation surface let a user select a customisation at order time).
|
|
325
|
+
|
|
326
|
+
Examples:
|
|
327
|
+
|
|
328
|
+
- ✅ "Given an admin has linked Poundo to Ogbono in `/dashboard/inventory/links`, When a staff member opens `/dashboard/orders/express/create-order`, picks Ogbono from the Soup group, and marks the order Complete, Then `/dashboard/inventory/{ogbono}` shows stock decreased by 1, a new Sale movement row appears tied to the order ID, and the activity timeline records the link-driven deduction."
|
|
329
|
+
- ❌ "Schema accepts optional `inventoryId` field (persistence round-trip)" — unit-test contract, belongs in `test-plan.md`, not here.
|
|
330
|
+
- ❌ "Resolver maps selected pairs to inventory link" — internal mechanic, not user value.
|
|
331
|
+
|
|
332
|
+
## Acceptance Criteria
|
|
333
|
+
|
|
334
|
+
- [ ] [Criterion 1 — Given/When/Then against a named UI surface]
|
|
335
|
+
- [ ] [Criterion 2 — Given/When/Then against a named UI surface]
|
|
336
|
+
- [ ] All security testing items pass
|
|
337
|
+
- [ ] All validation items confirmed
|
|
338
|
+
- [ ] Independent review completed (if required)
|
|
339
|
+
EOF
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### WAIT CHECKPOINT: Test Scope Review
|
|
343
|
+
|
|
344
|
+
**Present the test scope to the developer.** Summarize:
|
|
345
|
+
|
|
346
|
+
- Risk classification and rationale
|
|
347
|
+
- Test approach (which additional testing applies)
|
|
348
|
+
- Acceptance criteria
|
|
349
|
+
|
|
350
|
+
**Do NOT proceed** until the developer confirms the test scope is complete and correct. If the developer requests changes, update `test-scope.md` and re-present.
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
### Step 8: Create Test Plan
|
|
355
|
+
|
|
356
|
+
Create a test plan that maps acceptance criteria to specific tests. This documents what tests to add, update, or remove — evidence that testing was planned, not ad hoc.
|
|
357
|
+
|
|
358
|
+
The test plan is proportional to risk. For LOW risk, a brief plan is sufficient. For MEDIUM/HIGH, include non-functional testing and test data requirements.
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
cat > compliance/evidence/REQ-XXX/test-plan.md << 'EOF'
|
|
362
|
+
# Test Plan — REQ-XXX
|
|
363
|
+
|
|
364
|
+
**Requirement:** REQ-XXX
|
|
365
|
+
**Risk Level:** [LOW / MEDIUM / HIGH]
|
|
366
|
+
**GitHub Issue:** #NNN
|
|
367
|
+
**Date:** [YYYY-MM-DD]
|
|
368
|
+
|
|
369
|
+
## Tests to Add
|
|
370
|
+
- [ ] `e2e/[spec-file].spec.ts` — [what it tests]
|
|
371
|
+
- [ ] `__tests__/[test-file].test.ts` — [what it tests]
|
|
372
|
+
|
|
373
|
+
## Tests to Update
|
|
374
|
+
- [ ] `e2e/[existing-spec].spec.ts` — [what changes and why]
|
|
375
|
+
|
|
376
|
+
## Tests to Remove
|
|
377
|
+
- [ ] `e2e/[obsolete-spec].spec.ts` — [justification for removal]
|
|
378
|
+
- [or "None"]
|
|
379
|
+
|
|
380
|
+
## Functional Test Mapping
|
|
381
|
+
| Acceptance Criterion | Test File | Test Name |
|
|
382
|
+
|---------------------|-----------|-----------|
|
|
383
|
+
| [From test-scope.md] | [spec file] | [test name] |
|
|
384
|
+
|
|
385
|
+
## Non-Functional Tests (MEDIUM/HIGH)
|
|
386
|
+
- [ ] Security: [access control, input validation tests needed]
|
|
387
|
+
- [ ] Performance: [load/performance concerns]
|
|
388
|
+
- [ ] Accessibility: [if applicable]
|
|
389
|
+
- [or "Standard gates sufficient for LOW risk"]
|
|
390
|
+
|
|
391
|
+
## Test Data Requirements
|
|
392
|
+
- [Database seeding needed?]
|
|
393
|
+
- [Test fixtures to create?]
|
|
394
|
+
- [or "Existing test data sufficient"]
|
|
395
|
+
EOF
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### WAIT CHECKPOINT: Test Plan Review
|
|
399
|
+
|
|
400
|
+
**Present the test plan to the developer.** Summarize:
|
|
401
|
+
|
|
402
|
+
- Tests to add, update, and remove
|
|
403
|
+
- How acceptance criteria map to specific tests
|
|
404
|
+
- Any non-functional testing required
|
|
405
|
+
|
|
406
|
+
**Do NOT proceed** until the developer confirms the test plan is complete and correct. If the developer requests changes, update `test-plan.md` and re-present.
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
### Step 9: Update the Software Requirements Specification (If Applicable)
|
|
411
|
+
|
|
412
|
+
If the requirement adds, changes, or removes **observable behaviour**, update the project's Software Requirements Specification (`docs/SRS.md`) — or `docs/REQUIREMENTS.md` if the project has not adopted the SRS — to reflect the intended change. The SRS is the MoSCoW-prioritised, Given/When/Then source that developers and the `e2e-test-engineer` skill derive tests from, so keeping it current is what carries the requirement through into test cases.
|
|
413
|
+
|
|
414
|
+
Only act if the document exists; do not introduce an SRS on a project that has not adopted one.
|
|
415
|
+
|
|
416
|
+
### Step 10: Document AI Use Intent (If Applicable)
|
|
417
|
+
|
|
418
|
+
If AI will generate code (Medium/High risk):
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
cat > compliance/evidence/REQ-XXX/ai-use-note.md << 'EOF'
|
|
422
|
+
---
|
|
423
|
+
ai_contributors:
|
|
424
|
+
- tool: "[tool name]"
|
|
425
|
+
version: "[tool version]"
|
|
426
|
+
session_id: "[session id]"
|
|
427
|
+
date_range: "[YYYY-MM-DD to YYYY-MM-DD]"
|
|
428
|
+
commits: []
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
# AI Use Record — REQ-XXX
|
|
432
|
+
|
|
433
|
+
**Planned AI Use:** [implementation / test generation / both / none]
|
|
434
|
+
**Risk Classification Impact:** [note if risk was raised due to AI involvement]
|
|
435
|
+
EOF
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
For Low risk, the `Co-Authored-By` commit tag is sufficient.
|
|
439
|
+
|
|
440
|
+
### Step 11: Commit
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
# Stage the RTM + evidence. Add the requirements doc only if you updated it in Step 9
|
|
444
|
+
# — whichever the project uses; staging an unchanged tracked file is a harmless no-op.
|
|
445
|
+
git add compliance/RTM.md compliance/evidence/REQ-XXX
|
|
446
|
+
[ -f docs/SRS.md ] && git add docs/SRS.md
|
|
447
|
+
[ -f docs/REQUIREMENTS.md ] && git add docs/REQUIREMENTS.md
|
|
448
|
+
git commit -m "compliance: [REQ-XXX] define requirement and test scope - [description] [RISK: LOW/MEDIUM/HIGH]
|
|
449
|
+
|
|
450
|
+
Ref: REQ-XXX
|
|
451
|
+
Closes: #NNN"
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Output
|
|
455
|
+
|
|
456
|
+
- GitHub Issue `#NNN` identified or created as the origin of the change
|
|
457
|
+
- REQ-XXX in RTM with `DRAFT`, risk classification, and issue reference
|
|
458
|
+
- Implementation plan (MEDIUM/HIGH risk — approved by developer before test scope)
|
|
459
|
+
- Evidence directory with test scope and test plan (derived from implementation plan)
|
|
460
|
+
- AI use note (if applicable)
|
|
461
|
+
|
|
462
|
+
## Next Step
|
|
463
|
+
|
|
464
|
+
Proceed to `2-implement-and-test.md`. Refer back to `test-scope.md` during implementation.
|