@torus-engineering/tas-kit 1.14.0 → 2.1.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/.tas/_platform/claude-code/settings.json +58 -46
- package/.tas/_platform/hooks/code-quality.js +127 -127
- package/.tas/_platform/hooks/session-end.js +111 -111
- package/.tas/agents/architect.md +53 -53
- package/.tas/agents/aws-reviewer.md +71 -71
- package/.tas/agents/build-resolver.md +89 -59
- package/.tas/agents/code-explorer.md +63 -63
- package/.tas/agents/csharp-reviewer.md +62 -62
- package/.tas/agents/database-reviewer.md +73 -73
- package/.tas/agents/doc-updater.md +68 -66
- package/.tas/agents/python-reviewer.md +67 -67
- package/.tas/agents/security-reviewer.md +79 -79
- package/.tas/agents/software-engineer.md +53 -0
- package/.tas/agents/typescript-reviewer.md +65 -65
- package/.tas/commands/ado-create.md +33 -28
- package/.tas/commands/ado-delete.md +26 -22
- package/.tas/commands/ado-get.md +24 -20
- package/.tas/commands/ado-status.md +22 -18
- package/.tas/commands/ado-update.md +31 -27
- package/.tas/commands/tas-adr.md +37 -33
- package/.tas/commands/tas-apitest-plan.md +177 -173
- package/.tas/commands/tas-apitest.md +147 -143
- package/.tas/commands/tas-brainstorm.md +23 -19
- package/.tas/commands/tas-brd.md +50 -0
- package/.tas/commands/tas-bug.md +127 -113
- package/.tas/commands/tas-checklist.md +180 -0
- package/.tas/commands/tas-debug.md +103 -0
- package/.tas/commands/tas-design.md +41 -37
- package/.tas/commands/tas-dev.md +225 -125
- package/.tas/commands/tas-e2e-mobile.md +146 -155
- package/.tas/commands/tas-e2e-web.md +150 -163
- package/.tas/commands/tas-e2e.md +289 -102
- package/.tas/commands/tas-feature.md +181 -47
- package/.tas/commands/tas-fix.md +72 -51
- package/.tas/commands/tas-functest-mobile.md +138 -144
- package/.tas/commands/tas-functest-web.md +176 -192
- package/.tas/commands/tas-functest.md +225 -76
- package/.tas/commands/tas-init.md +22 -17
- package/.tas/commands/tas-master-plan.md +300 -0
- package/.tas/commands/tas-orchestrate.md +159 -0
- package/.tas/commands/tas-plan.md +152 -117
- package/.tas/commands/tas-prd.md +57 -37
- package/.tas/commands/tas-review-pr.md +174 -0
- package/.tas/commands/tas-review.md +115 -113
- package/.tas/commands/tas-sad.md +47 -43
- package/.tas/commands/tas-security.md +91 -87
- package/.tas/commands/tas-spec.md +54 -50
- package/.tas/commands/tas-status.md +25 -16
- package/.tas/project-status-example.yaml +3 -1
- package/.tas/rules/ado-integration.md +67 -65
- package/.tas/rules/common/api-design.md +517 -517
- package/.tas/rules/common/build-debug-loop.md +233 -0
- package/.tas/rules/common/code-review.md +4 -0
- package/.tas/rules/common/feature-done.md +42 -0
- package/.tas/rules/common/post-implementation-review.md +4 -0
- package/.tas/rules/common/project-status.md +33 -16
- package/.tas/rules/common/sad-impact.md +81 -0
- package/.tas/rules/common/tdd.md +104 -89
- package/.tas/rules/csharp/api-testing.md +2 -2
- package/.tas/rules/csharp/torus-core-framework.md +128 -0
- package/.tas/tas-example.yaml +9 -32
- package/.tas/templates/AGENTS.md +13 -0
- package/.tas/templates/API-Test-Spec.md +5 -4
- package/.tas/templates/BRD.md +133 -0
- package/.tas/templates/Bug.md +15 -0
- package/.tas/templates/E2E-Execution-Report.md +8 -8
- package/.tas/templates/E2E-Mobile-Spec.md +6 -8
- package/.tas/templates/E2E-Report.md +2 -2
- package/.tas/templates/E2E-Scenario.md +22 -22
- package/.tas/templates/E2E-Test-Spec.md +274 -0
- package/.tas/templates/E2E-Web-Spec.md +4 -4
- package/.tas/templates/Feature-Technical-Part.md +69 -0
- package/.tas/templates/Feature-Technical-Stack.md +74 -0
- package/.tas/templates/Feature-Technical.md +329 -0
- package/.tas/templates/Feature.md +50 -26
- package/.tas/templates/Func-Test-Script.md +29 -56
- package/.tas/templates/Func-Test-Spec.md +144 -142
- package/.tas/templates/PRD.md +173 -142
- package/.tas/templates/TestChecklist.md +96 -0
- package/.tas/templates/torus-dotnet-bootstrap.md +223 -0
- package/.tas/tools/tas-ado-readme.md +24 -27
- package/.tas/tools/tas-ado.py +328 -25
- package/.tas/tools/tas-github.py +339 -0
- package/README.md +131 -54
- package/bin/cli.js +90 -90
- package/lib/adapters/antigravity.js +131 -131
- package/lib/adapters/claude-code.js +71 -35
- package/lib/adapters/codex.js +157 -157
- package/lib/adapters/cursor.js +80 -80
- package/lib/adapters/index.js +20 -20
- package/lib/adapters/utils.js +81 -81
- package/lib/deleted-files.json +7 -0
- package/lib/install.js +546 -546
- package/package.json +1 -1
- package/.tas/commands/tas-epic.md +0 -35
- package/.tas/commands/tas-story.md +0 -91
- package/.tas/rules/common/story-done.md +0 -30
- package/.tas/templates/Epic.md +0 -46
- package/.tas/templates/Story.md +0 -90
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Build & Debug Loop
|
|
2
|
+
|
|
3
|
+
Protocol for Step 3.5 in `/tas-dev`. Runs in **main session** (required for MCP browser tools).
|
|
4
|
+
|
|
5
|
+
## Stack Commands
|
|
6
|
+
|
|
7
|
+
| Stack | Start command | Ready signal | Browser check |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `.NET` | `dotnet run` | `Now listening on:` | No |
|
|
10
|
+
| `Next.js` | `npm run dev` | `Ready in` / `✓ compiled` | Yes |
|
|
11
|
+
| `NestJS` | `npm run start:dev` | `Nest application successfully started` | No (API only) |
|
|
12
|
+
| `Astro` | `npm run dev` | `astro v` + port line | Yes |
|
|
13
|
+
| `ReactJS` | `npm run dev` OR `npm start` | `compiled successfully` / `Local:` | Yes |
|
|
14
|
+
| `React Native` | `npx expo start` | `Metro waiting on` | No (native) |
|
|
15
|
+
| `Python FastAPI` | `uvicorn main:app --reload` | `Application startup complete` | No (API only) |
|
|
16
|
+
| `Python Django` | `python manage.py runserver` | `Starting development server at` | No (API only) |
|
|
17
|
+
| `Python Flask` | `flask run` OR `python app.py` | `Running on http://` | No (API only) |
|
|
18
|
+
| `Node.js` | `npm run start` OR `node src/index.js` | Port listen line OR exit code 0 | No |
|
|
19
|
+
|
|
20
|
+
**Port detection**: extract port from ready signal line. Default fallbacks: .NET→5000, Next.js→3000, NestJS→3000, Astro→4321, React→3000, Python→8000, Flask→5000, Node→3000.
|
|
21
|
+
|
|
22
|
+
**Working dir**: use path from Feature Technical Plan's stack section. If absent, infer from `package.json` / `*.csproj` / `*.py` location relative to changed files.
|
|
23
|
+
|
|
24
|
+
## Loop Protocol
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
max_attempts = tas.yaml[build_debug_attempts] ?? 3
|
|
28
|
+
attempt = 0
|
|
29
|
+
server_pid = null
|
|
30
|
+
|
|
31
|
+
PRE-FLIGHT (before loop): run Pre-flight Cleanup (see section below).
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
while attempt < max_attempts:
|
|
35
|
+
1. Start server (background process, timeout 60s waiting for ready signal)
|
|
36
|
+
→ capture PID returned by Bash run_in_background → server_pid = PID
|
|
37
|
+
2. Capture stdout + stderr for 30s after ready (or until crash)
|
|
38
|
+
3. Evaluate result:
|
|
39
|
+
a. Server crashed (exit code != 0 OR no ready signal in 60s)
|
|
40
|
+
→ extract error lines → call build-resolver agent with error context
|
|
41
|
+
→ apply returned fix → kill_server(server_pid) → attempt++ → retry
|
|
42
|
+
b. Server up but error patterns in log (see Error Patterns below)
|
|
43
|
+
→ same as (a)
|
|
44
|
+
c. Server up, no errors → proceed to Browser Check (if applicable)
|
|
45
|
+
→ if browser check passes → kill_server(server_pid) → PASS, exit loop
|
|
46
|
+
→ if browser check fails → call build-resolver with browser error context
|
|
47
|
+
→ apply fix → kill_server(server_pid) → attempt++ → retry
|
|
48
|
+
4. After applying fix: tick attempted action in log
|
|
49
|
+
|
|
50
|
+
if attempt >= max_attempts:
|
|
51
|
+
STOP. Output warning block (see Warning Format below).
|
|
52
|
+
Do NOT proceed to Step 4 review.
|
|
53
|
+
|
|
54
|
+
finally:
|
|
55
|
+
TEAR DOWN (always): kill_server(server_pid) if alive. See Tear Down section.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**MANDATORY**: kill_server() must run on every exit path — PASS, FAIL, max_attempts, exception, user interrupt. Orphan dev servers cause RAM exhaustion, port conflicts, and `.next`/`node_modules/.cache` corruption on next run.
|
|
59
|
+
|
|
60
|
+
## Pre-flight Cleanup
|
|
61
|
+
|
|
62
|
+
Run **before** loop starts. Kills orphan dev servers from prior runs/crashes that hold target port or pile up RAM.
|
|
63
|
+
|
|
64
|
+
### Windows (PowerShell)
|
|
65
|
+
```powershell
|
|
66
|
+
# Kill process holding target port (if any)
|
|
67
|
+
$port = {target_port}
|
|
68
|
+
$conn = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue
|
|
69
|
+
if ($conn) {
|
|
70
|
+
$procId = $conn.OwningProcess
|
|
71
|
+
$proc = Get-Process -Id $procId -ErrorAction SilentlyContinue
|
|
72
|
+
if ($proc -and $proc.ProcessName -match '^(node|dotnet|python|npm)$') {
|
|
73
|
+
Stop-Process -Id $procId -Force
|
|
74
|
+
Write-Host "Killed stale $($proc.ProcessName) PID=$procId on port $port"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Unix (bash)
|
|
80
|
+
```bash
|
|
81
|
+
port={target_port}
|
|
82
|
+
pid=$(lsof -ti :$port 2>/dev/null)
|
|
83
|
+
if [ -n "$pid" ]; then
|
|
84
|
+
pname=$(ps -p $pid -o comm= 2>/dev/null)
|
|
85
|
+
case "$pname" in
|
|
86
|
+
node|dotnet|python|python3|npm) kill -9 $pid; echo "Killed stale $pname PID=$pid on port $port" ;;
|
|
87
|
+
esac
|
|
88
|
+
fi
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Safety**: only kill if process name matches dev server pattern (`node`/`dotnet`/`python`/`npm`). Skip kill if foreign process — surface port conflict to user instead.
|
|
92
|
+
|
|
93
|
+
## Tear Down
|
|
94
|
+
|
|
95
|
+
Run on **every** loop exit path (success, failure, exception, interrupt).
|
|
96
|
+
|
|
97
|
+
### Windows
|
|
98
|
+
```powershell
|
|
99
|
+
$pid = {server_pid}
|
|
100
|
+
if ($pid) {
|
|
101
|
+
# Graceful: kill process tree (dev servers spawn child workers)
|
|
102
|
+
taskkill /PID $pid /T 2>$null
|
|
103
|
+
Start-Sleep -Seconds 3
|
|
104
|
+
# Force if still alive
|
|
105
|
+
if (Get-Process -Id $pid -ErrorAction SilentlyContinue) {
|
|
106
|
+
taskkill /PID $pid /T /F 2>$null
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Unix
|
|
112
|
+
```bash
|
|
113
|
+
pid={server_pid}
|
|
114
|
+
if [ -n "$pid" ] && kill -0 $pid 2>/dev/null; then
|
|
115
|
+
# SIGTERM tree (negative PID = process group)
|
|
116
|
+
kill -TERM -$pid 2>/dev/null || kill -TERM $pid
|
|
117
|
+
sleep 3
|
|
118
|
+
# SIGKILL if still alive
|
|
119
|
+
kill -0 $pid 2>/dev/null && (kill -KILL -$pid 2>/dev/null || kill -KILL $pid)
|
|
120
|
+
fi
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Why graceful first**: SIGTERM lets Next.js/Vite finish writing `.next`/`.vite` cache. SIGKILL mid-write corrupts cache → next start fails with ENOENT/SyntaxError on chunk files.
|
|
124
|
+
|
|
125
|
+
**Multi-stack runs**: tear down current stack's server BEFORE starting next stack. Never overlap.
|
|
126
|
+
|
|
127
|
+
## Error Patterns (log scan)
|
|
128
|
+
|
|
129
|
+
Match any of these as "error in log" even when exit code = 0:
|
|
130
|
+
|
|
131
|
+
- `.NET`: `Unhandled exception`, `Application is shutting down`, `fail:`
|
|
132
|
+
- `Node/TS`: `Error:`, `UnhandledPromiseRejection`, `Cannot find module`, `SyntaxError`
|
|
133
|
+
- `NestJS`: `[ExceptionHandler]`, `Nest can't resolve dependencies`
|
|
134
|
+
- `Python`: `Traceback (most recent call last)`, `ModuleNotFoundError`, `ImportError`
|
|
135
|
+
- `React/Next`: `Failed to compile`, `Module not found`, `error TS`
|
|
136
|
+
- `Astro`: `[ERROR]`, `Build failed`
|
|
137
|
+
|
|
138
|
+
## Browser Check (frontend stacks only)
|
|
139
|
+
|
|
140
|
+
Token-cheap path: **single curl snapshot + Grep presence test**. No MCP browser, no screenshot, no headless render.
|
|
141
|
+
|
|
142
|
+
### Single-snapshot rule
|
|
143
|
+
|
|
144
|
+
Fetch each URL **once per session**. Cache to `.tas/tmp/snap-{slug}.html`. Re-Grep the cached file for every subsequent check. Re-fetch only if server code changed since last snapshot.
|
|
145
|
+
|
|
146
|
+
### 1. HTTP status probe (cheapest)
|
|
147
|
+
```bash
|
|
148
|
+
curl -sI http://localhost:{port}{path}
|
|
149
|
+
```
|
|
150
|
+
FAIL if status ≥ 500, or status ≠ expected from AC.
|
|
151
|
+
|
|
152
|
+
### 2. HTML snapshot
|
|
153
|
+
```bash
|
|
154
|
+
mkdir -p .tas/tmp
|
|
155
|
+
curl -s -o .tas/tmp/snap-{slug}.html -w "%{http_code}\n" http://localhost:{port}{path}
|
|
156
|
+
```
|
|
157
|
+
FAIL if exit ≠ 0 or file size < 200 bytes (likely blank/error page).
|
|
158
|
+
|
|
159
|
+
### 3. Section-presence Grep (no re-fetch)
|
|
160
|
+
For each expected element from AC "Then" clause:
|
|
161
|
+
```
|
|
162
|
+
Grep -F "{expected marker}" .tas/tmp/snap-{slug}.html
|
|
163
|
+
```
|
|
164
|
+
Markers: heading text, element id, data-testid attr, route-specific class. FAIL if any required marker missing.
|
|
165
|
+
|
|
166
|
+
### 4. Error-overlay Grep
|
|
167
|
+
```
|
|
168
|
+
Grep -i -E "(unhandled|exception|stack trace|error overlay|hydration failed)" .tas/tmp/snap-{slug}.html
|
|
169
|
+
```
|
|
170
|
+
FAIL if any match (inline error page rendered).
|
|
171
|
+
|
|
172
|
+
### 5. AC-based API verification
|
|
173
|
+
```
|
|
174
|
+
For each AC with HTTP verb + path (GET/POST/PUT/DELETE /path):
|
|
175
|
+
curl -s -w "\n%{http_code}" http://localhost:{port}{path}
|
|
176
|
+
check status matches expected
|
|
177
|
+
Grep response body for fields from AC "Then" clause
|
|
178
|
+
```
|
|
179
|
+
Skip if no HTTP endpoint patterns in ACs.
|
|
180
|
+
|
|
181
|
+
## Context to pass build-resolver agent
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
Stack: {stack}
|
|
185
|
+
Command run: {command}
|
|
186
|
+
Attempt: {N} of {max}
|
|
187
|
+
Exit code: {code}
|
|
188
|
+
Error output:
|
|
189
|
+
{last 50 lines of stdout+stderr}
|
|
190
|
+
Browser errors (if any):
|
|
191
|
+
{console errors list}
|
|
192
|
+
AC being verified (if functional check):
|
|
193
|
+
{AC text}
|
|
194
|
+
Feature scope files: {list of files changed in this stack}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Warning Format (max attempts exceeded)
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
⚠️ Build debug limit reached ({N}/{max} attempts) — manual intervention required.
|
|
201
|
+
|
|
202
|
+
Stack: {stack}
|
|
203
|
+
Command: {command}
|
|
204
|
+
|
|
205
|
+
Issues found:
|
|
206
|
+
{numbered list of distinct errors across all attempts}
|
|
207
|
+
|
|
208
|
+
Actions taken:
|
|
209
|
+
{numbered list of fixes attempted, each with: attempt N → fix description}
|
|
210
|
+
|
|
211
|
+
Last build-resolver diagnosis:
|
|
212
|
+
{paste diagnosis from final attempt}
|
|
213
|
+
|
|
214
|
+
Predicted root cause:
|
|
215
|
+
{build-resolver's last "Root cause" field}
|
|
216
|
+
|
|
217
|
+
Recommended next step:
|
|
218
|
+
{build-resolver's "Fix" field from last attempt}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Logging
|
|
222
|
+
|
|
223
|
+
After loop completes (pass or fail), append to Feature Technical file `## Build Debug Log` section (create if absent):
|
|
224
|
+
|
|
225
|
+
```markdown
|
|
226
|
+
## Build Debug Log
|
|
227
|
+
|
|
228
|
+
### {datetime} — {stack}
|
|
229
|
+
- Result: PASS / FAIL (attempt {N}/{max})
|
|
230
|
+
- Command: {command}
|
|
231
|
+
- Attempts: {list each attempt + outcome}
|
|
232
|
+
- Fixes applied: {list}
|
|
233
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Definition of Done — Feature
|
|
2
|
+
|
|
3
|
+
Workflow gate used by `/tas-dev` Step 5 — verify each item before marking the Feature `Done`.
|
|
4
|
+
|
|
5
|
+
## Code
|
|
6
|
+
|
|
7
|
+
- [ ] Code implemented per all Acceptance Criteria (Given/When/Then)
|
|
8
|
+
- [ ] Follows conventions in CLAUDE.md
|
|
9
|
+
- [ ] Each public method has doc comment (XML doc / JSDoc / docstring)
|
|
10
|
+
- [ ] No dead code, no commented-out blocks, no debug prints
|
|
11
|
+
|
|
12
|
+
## Testing
|
|
13
|
+
|
|
14
|
+
- [ ] Unit tests pass (Happy + Edge + Negative tables from Feature-Technical)
|
|
15
|
+
- [ ] Functional tests run if Func-Test-Spec exists (`/tas-functest-mobile` / `/tas-functest-web`)
|
|
16
|
+
- [ ] No regression on existing tests
|
|
17
|
+
- [ ] Coverage ≥ 80% on changed files (per `tdd.md`)
|
|
18
|
+
|
|
19
|
+
## Review
|
|
20
|
+
|
|
21
|
+
- [ ] Code review passed (per `.tas/rules/common/code-review.md`)
|
|
22
|
+
- [ ] Security review: no Critical/High open findings
|
|
23
|
+
- [ ] If `auto_review: true`, automated review pass
|
|
24
|
+
|
|
25
|
+
## Documentation
|
|
26
|
+
|
|
27
|
+
- [ ] If Technical-file `sad_impact: true` → `docs/sad.md` updated AND Changelog has entry referencing `Feature-{NNN}` (gate; per `.tas/rules/common/sad-impact.md`)
|
|
28
|
+
- [ ] If API/schema changed beyond SAD scope, related docs updated (README, API docs)
|
|
29
|
+
- [ ] If new ADR was needed, ADR file created and linked from Feature-Technical
|
|
30
|
+
- [ ] Feature Changelog has entry for this dev cycle
|
|
31
|
+
|
|
32
|
+
## Status
|
|
33
|
+
|
|
34
|
+
- [ ] Feature `Status:` updated in Feature file
|
|
35
|
+
- [ ] `project-status.yaml` updated (`features.{ID}.status`, `done_date`)
|
|
36
|
+
- [ ] Commit message follows conventions in CLAUDE.md
|
|
37
|
+
- [ ] If using ADO: `/ado-update feature {ado-id} --status "Done"` run
|
|
38
|
+
|
|
39
|
+
## Release Gate (PE owns)
|
|
40
|
+
|
|
41
|
+
- [ ] Acceptance criteria verified by PE — all G/W/T pass on staging
|
|
42
|
+
- [ ] Ready for production release
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
File `project-status.yaml` at project root is aggregate index of project status.
|
|
4
4
|
Commands update this file after each artifact or status change.
|
|
5
5
|
|
|
6
|
+
> **Schema v3 (Feature-only):** Epic and Story are removed. Features are stored in a flat map at the root.
|
|
7
|
+
|
|
6
8
|
## Always update
|
|
7
9
|
|
|
8
10
|
```yaml
|
|
@@ -15,6 +17,12 @@ Update when creating new or changing version:
|
|
|
15
17
|
|
|
16
18
|
```yaml
|
|
17
19
|
artifacts:
|
|
20
|
+
brd:
|
|
21
|
+
file: docs/brd.md
|
|
22
|
+
status: Draft | Review | Approved
|
|
23
|
+
last_updated: YYYY-MM-DD
|
|
24
|
+
version: "1.0"
|
|
25
|
+
|
|
18
26
|
prd:
|
|
19
27
|
file: docs/prd.md
|
|
20
28
|
status: Draft | Review | Approved
|
|
@@ -40,26 +48,34 @@ artifacts:
|
|
|
40
48
|
last_updated: YYYY-MM-DD
|
|
41
49
|
```
|
|
42
50
|
|
|
43
|
-
##
|
|
51
|
+
## Features (flat map — no Epic / Story nesting)
|
|
52
|
+
|
|
53
|
+
Update when creating a Feature or changing its status / plan_status.
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
features:
|
|
57
|
+
Feature-001:
|
|
58
|
+
path: docs/features/{CODE}-Feature-001-{slug}/
|
|
59
|
+
file: docs/features/{CODE}-Feature-001-{slug}/{CODE}-Feature-001-{slug}.md
|
|
60
|
+
technical_file: docs/features/{CODE}-Feature-001-{slug}/{CODE}-Feature-001-{slug}-Technical.md
|
|
61
|
+
title: "..."
|
|
62
|
+
stack: app | web | service | integration
|
|
63
|
+
status: New | In Design | In Development | Done | Removed
|
|
64
|
+
plan_status: pending | completed
|
|
65
|
+
plan_date: YYYY-MM-DD # set by /tas-plan
|
|
66
|
+
done_date: YYYY-MM-DD # set when status flips to Done
|
|
67
|
+
```
|
|
44
68
|
|
|
45
|
-
|
|
69
|
+
## Bugs
|
|
46
70
|
|
|
47
71
|
```yaml
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
status:
|
|
72
|
+
bugs:
|
|
73
|
+
Bug-001:
|
|
74
|
+
file: docs/bugs/Bug-001-{slug}.md
|
|
75
|
+
status: Open | In Progress | Fixed | Verified | Closed
|
|
76
|
+
severity: Critical | High | Medium | Low
|
|
52
77
|
title: "..."
|
|
53
|
-
|
|
54
|
-
features:
|
|
55
|
-
Feature-001:
|
|
56
|
-
status: New | In Progress | Ready To Verify | Verified | Done
|
|
57
|
-
title: "..."
|
|
58
|
-
stories:
|
|
59
|
-
Story-001:
|
|
60
|
-
status: New | Committed | In Progress | Deploy Test | Verify Test | Done
|
|
61
|
-
title: "..."
|
|
62
|
-
plan_status: pending | completed
|
|
78
|
+
feature_id: Feature-NNN # if linked
|
|
63
79
|
```
|
|
64
80
|
|
|
65
81
|
## ADRs
|
|
@@ -78,3 +94,4 @@ adrs:
|
|
|
78
94
|
- If key doesn't exist yet: add new
|
|
79
95
|
- If key exists: update value
|
|
80
96
|
- Version: minor (+0.1) when updating content; major (+1.0) when large structure change
|
|
97
|
+
- **Never add `epics:` or `stories:` keys** — schema v3 dropped them
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# SAD Impact Detection
|
|
2
|
+
|
|
3
|
+
Single source of truth for "does this change affect `docs/sad.md`?" Consumed by `/tas-plan`, `/tas-dev`, `/tas-bug`, `/tas-fix`, `/tas-debug`.
|
|
4
|
+
|
|
5
|
+
## When to read this file
|
|
6
|
+
|
|
7
|
+
- `/tas-plan` Step 5 — fill `## SAD Impact Matrix` in Feature-Technical file
|
|
8
|
+
- `/tas-bug` analyze step — fill `## SAD Impact Matrix` in Bug file
|
|
9
|
+
- `/tas-dev` Step 5 / `/tas-bug` post-fix — check `sad_impact` flag, auto-invoke `/tas-sad` if true
|
|
10
|
+
- `/tas-fix` / `/tas-debug` — run grep heuristic (Quick Heuristic section below); if hit → stop + escalate
|
|
11
|
+
|
|
12
|
+
## 8 Trigger Categories
|
|
13
|
+
|
|
14
|
+
Each category covers a class of changes that requires a SAD section update + Changelog entry. Mark `Detected: Yes` if any signal in the category applies.
|
|
15
|
+
|
|
16
|
+
| # | Category | Signals to detect | SAD section(s) | ADR-worthy? |
|
|
17
|
+
|---|----------|------------------|----------------|-------------|
|
|
18
|
+
| 1 | **Tech Stack** | New runtime library (package.json / *.csproj / requirements.txt add), new SaaS runtime dep (Stripe, Auth0, Sendgrid), DB engine swap or new DB instance, license-risk dep (GPL/AGPL) | §4 Technology Baseline (4.2 Stack / 4.3 Dependencies) | If swap or vendor lock-in |
|
|
19
|
+
| 2 | **System Boundary** | New actor / user role / service account, new external system, new egress target (3rd-party API / domain), new webhook (in or out) | §5 System Context, §9 Integration | If new trust boundary |
|
|
20
|
+
| 3 | **Container / Topology** | New service / cache (Redis, Memcached) / queue (Kafka, SQS, RabbitMQ) / scheduled job / file storage (S3, blob), monolith → microservice split, stateful service where was stateless | §6 Logical View, §7 Component View | Yes for split / stateful shift |
|
|
21
|
+
| 4 | **Data Architecture** | New table / schema, new column on PII-classified table, retention or archival policy change, sharding / partitioning change, new column-level encryption | §8 Data Architecture & ERD | If data classification shifts |
|
|
22
|
+
| 5 | **API Contract** | New API style (add GraphQL alongside REST), API major-version bump (breaking), auth-scheme change on existing endpoint, new rate-limit / throttling rule, pagination convention change | §9.1 API Design Principles | If breaking or style change |
|
|
23
|
+
| 6 | **Security** | New auth mechanism / token type, RBAC / permission-model change, new secret (API key / cert) — beyond generic ENV, new encryption requirement (KMS, at-rest), new network zone / VPC / subnet, new inbound port or egress firewall rule, new compliance scope (GDPR / PCI / SOC2 expand), new audit-log event class | §10 Security Architecture | Yes for auth / compliance changes |
|
|
24
|
+
| 7 | **NFR / Ops** | New SLO / SLA target, new observability target (metric / dashboard / alert), new circuit breaker / retry / timeout policy, sync → async conversion, DR change (RPO / RTO) | §11 NFR Strategies | If SLO commits |
|
|
25
|
+
| 8 | **Deployment** | New region / AZ, new environment tier (UAT, sandbox), CI/CD pipeline gate change, orchestration change (K8s namespace, ECS task), new CDN config, new production ENV var (≠ dev-only config) | §12 Deployment Topology | If env-tier or pipeline change |
|
|
26
|
+
|
|
27
|
+
> ADR-worthy = decision is cross-cutting and irreversible. Log to `Architecture Decisions` table with `ADR Candidate: Yes`. ADR creation stays **human-triggered** (`/tas-adr`).
|
|
28
|
+
|
|
29
|
+
## Quick Heuristic (for `/tas-fix`, `/tas-debug`)
|
|
30
|
+
|
|
31
|
+
Lightweight commands skip the matrix. Run grep over staged / changed files. Any hit → stop, escalate to `/tas-bug`.
|
|
32
|
+
|
|
33
|
+
| Signal | File pattern | Category hit |
|
|
34
|
+
|--------|--------------|--------------|
|
|
35
|
+
| New dependency | `package.json`, `*.csproj`, `requirements.txt`, `go.mod`, `Cargo.toml` — diff has `+` on deps section | 1 Tech Stack |
|
|
36
|
+
| New ENV var | `.env*`, `*.env.example`, `appsettings*.json` — diff has new key | 6 / 8 |
|
|
37
|
+
| Dockerfile change | `Dockerfile*`, `docker-compose*.yml` — `EXPOSE`, `ENV`, new service | 3 / 6 / 8 |
|
|
38
|
+
| Migration / schema | `migrations/**`, `*.sql`, EF migration files | 4 Data |
|
|
39
|
+
| Infra-as-code | `terraform/**`, `*.tf`, `cdk/**`, `pulumi/**`, `k8s/**`, `helm/**` | 8 Deployment |
|
|
40
|
+
| CI config | `.github/workflows/**`, `azure-pipelines*.yml`, `.gitlab-ci.yml` | 8 Deployment |
|
|
41
|
+
| New top-level dir under apps/services root | `apps/{new}`, `services/{new}` | 3 Container |
|
|
42
|
+
|
|
43
|
+
## Matrix Template (paste into Feature-Technical / Bug files)
|
|
44
|
+
|
|
45
|
+
```markdown
|
|
46
|
+
## SAD Impact Matrix
|
|
47
|
+
> Fill per `.tas/rules/common/sad-impact.md`. Set frontmatter `sad_impact: true` if any row Detected: Yes.
|
|
48
|
+
|
|
49
|
+
| # | Category | Detected | SAD Section | Change Summary | ADR Candidate |
|
|
50
|
+
|---|----------|----------|-------------|----------------|---------------|
|
|
51
|
+
| 1 | Tech Stack | No | — | — | No |
|
|
52
|
+
| 2 | System Boundary | No | — | — | No |
|
|
53
|
+
| 3 | Container / Topology | No | — | — | No |
|
|
54
|
+
| 4 | Data Architecture | No | — | — | No |
|
|
55
|
+
| 5 | API Contract | No | — | — | No |
|
|
56
|
+
| 6 | Security | No | — | — | No |
|
|
57
|
+
| 7 | NFR / Ops | No | — | — | No |
|
|
58
|
+
| 8 | Deployment | No | — | — | No |
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Auto-invoke `/tas-sad` rules
|
|
62
|
+
|
|
63
|
+
When `sad_impact: true` in working file:
|
|
64
|
+
|
|
65
|
+
| Caller | When to invoke | Description argument | Changelog ref |
|
|
66
|
+
|--------|---------------|---------------------|---------------|
|
|
67
|
+
| `/tas-dev` Step 5 | After post-impl review passes | `"Feature-{NNN}: {summary aggregated from matrix Yes rows}"` | `Feature-{NNN}` |
|
|
68
|
+
| `/tas-bug` Status=Committed | After post-fix review passes | `"Bug-{NNN}: {summary}"` | `Bug-{NNN}` |
|
|
69
|
+
| Autonomous mode | Pass `--autonomous=true` flag through | Same as above | Same |
|
|
70
|
+
|
|
71
|
+
`/tas-sad` UPDATE mode writes Changelog entry to `docs/sad.md`. Caller verifies entry exists before marking Done.
|
|
72
|
+
|
|
73
|
+
## Done Gate
|
|
74
|
+
|
|
75
|
+
Used by `/tas-dev` Step 6 and `/tas-bug` Done transition:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
if working_file.frontmatter.sad_impact == true:
|
|
79
|
+
grep docs/sad.md changelog for {Feature-ID | Bug-ID}
|
|
80
|
+
if no match → BLOCK Done, surface: "SAD updated but Changelog missing ref to {ID}"
|
|
81
|
+
```
|
package/.tas/rules/common/tdd.md
CHANGED
|
@@ -1,89 +1,104 @@
|
|
|
1
|
-
# TDD Workflow Rules
|
|
2
|
-
|
|
3
|
-
When `use_tdd=true` in `tas.yaml`, enforce strict Red-Green-Refactor cycle.
|
|
4
|
-
No exceptions — every feature starts with test.
|
|
5
|
-
|
|
6
|
-
## When to Apply
|
|
7
|
-
|
|
8
|
-
- Implement new
|
|
9
|
-
- Bug fix: write regression test before fixing
|
|
10
|
-
- Refactor: ensure test coverage before changing code
|
|
11
|
-
- DON'T use TDD for: config changes, documentation, pure data migration scripts
|
|
12
|
-
|
|
13
|
-
## Always / Ask / Never
|
|
14
|
-
|
|
15
|
-
| | Action |
|
|
16
|
-
|---|---|
|
|
17
|
-
| **Always** | Write test FIRST, run to confirm FAIL, then write code |
|
|
18
|
-
| **Always** | Commit after each successful Green phase |
|
|
19
|
-
| **Always** | Run full test suite after Refactor phase |
|
|
20
|
-
| **Ask** | When acceptance criteria vague — clarify before writing test |
|
|
21
|
-
| **Ask** | When test too hard to write — interface/design may need improvement |
|
|
22
|
-
| **Never** | Write implementation before test (even "just to try") |
|
|
23
|
-
| **Never** | Skip Red phase because "test will obviously fail" |
|
|
24
|
-
| **Never** | Write more than minimal code needed to pass test in Green phase |
|
|
25
|
-
|
|
26
|
-
## Process
|
|
27
|
-
|
|
28
|
-
### Red Phase — Write Test First
|
|
29
|
-
|
|
30
|
-
1. Read
|
|
31
|
-
2. Write test cases covering each
|
|
32
|
-
3. Run tests: `npm test` / `yarn test` / `dotnet test` / `python -m pytest`
|
|
33
|
-
4. **Verify**: tests MUST FAIL — if pass immediately → test is wrong, rewrite
|
|
34
|
-
|
|
35
|
-
### Green Phase — Minimal Code
|
|
36
|
-
|
|
37
|
-
1. Write minimal code to pass tests
|
|
38
|
-
2. Don't refactor, don't optimize in this phase
|
|
39
|
-
3. Run tests: confirm PASS
|
|
40
|
-
4. **Verify**: all new tests pass, no regression
|
|
41
|
-
|
|
42
|
-
### Refactor Phase — Clean Up
|
|
43
|
-
|
|
44
|
-
1. Remove duplication, improve naming, reduce complexity
|
|
45
|
-
2. DON'T change behavior — tests are safety net
|
|
46
|
-
3. Run full test suite after each refactor step
|
|
47
|
-
4. **Verify**: coverage >= 80%, all tests still pass
|
|
48
|
-
5. Commit after successful refactor
|
|
49
|
-
|
|
50
|
-
## Red Flags
|
|
51
|
-
|
|
52
|
-
- Test passes on first run before implementation → test doesn't test what it should
|
|
53
|
-
- Test too broad ("everything works") → no value, write more specific test
|
|
54
|
-
- Green phase has too much logic → only write enough to pass, no more
|
|
55
|
-
- Refactor phase makes tests fail → refactor is wrong, roll back step by step
|
|
56
|
-
- Writing multiple tests at once before fixing each → only fix one test at a time
|
|
57
|
-
|
|
58
|
-
## Verification Checklist
|
|
59
|
-
|
|
60
|
-
- [ ] Red: test file exists and runs with FAIL output
|
|
61
|
-
- [ ] Green: test output changes from FAIL → PASS after adding implementation
|
|
62
|
-
- [ ] Refactor: `npm test` / `dotnet test` / `pytest` full suite PASS
|
|
63
|
-
- [ ] Coverage report: >= 80% for changed files
|
|
64
|
-
- [ ] No tests skipped or commented out
|
|
65
|
-
|
|
66
|
-
## Test Naming Convention
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
|
85
|
-
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
89
|
-
|
|
1
|
+
# TDD Workflow Rules
|
|
2
|
+
|
|
3
|
+
When `use_tdd=true` in `tas.yaml`, enforce strict Red-Green-Refactor cycle.
|
|
4
|
+
No exceptions — every feature starts with test.
|
|
5
|
+
|
|
6
|
+
## When to Apply
|
|
7
|
+
|
|
8
|
+
- Implement new Feature with clear Acceptance Criteria (Given/When/Then)
|
|
9
|
+
- Bug fix: write regression test before fixing
|
|
10
|
+
- Refactor: ensure test coverage before changing code
|
|
11
|
+
- DON'T use TDD for: config changes, documentation, pure data migration scripts
|
|
12
|
+
|
|
13
|
+
## Always / Ask / Never
|
|
14
|
+
|
|
15
|
+
| | Action |
|
|
16
|
+
|---|---|
|
|
17
|
+
| **Always** | Write test FIRST, run to confirm FAIL, then write code |
|
|
18
|
+
| **Always** | Commit after each successful Green phase |
|
|
19
|
+
| **Always** | Run full test suite after Refactor phase |
|
|
20
|
+
| **Ask** | When acceptance criteria vague — clarify before writing test |
|
|
21
|
+
| **Ask** | When test too hard to write — interface/design may need improvement |
|
|
22
|
+
| **Never** | Write implementation before test (even "just to try") |
|
|
23
|
+
| **Never** | Skip Red phase because "test will obviously fail" |
|
|
24
|
+
| **Never** | Write more than minimal code needed to pass test in Green phase |
|
|
25
|
+
|
|
26
|
+
## Process
|
|
27
|
+
|
|
28
|
+
### Red Phase — Write Test First
|
|
29
|
+
|
|
30
|
+
1. Read Acceptance Criteria in the Feature, plus Unit Test Cases tables in `Feature-{NNN}-Technical.md`
|
|
31
|
+
2. Write test cases covering each AC (platform-specific stacks per `/tas-dev`)
|
|
32
|
+
3. Run tests: `npm test` / `yarn test` / `dotnet test` / `python -m pytest`
|
|
33
|
+
4. **Verify**: tests MUST FAIL — if pass immediately → test is wrong, rewrite
|
|
34
|
+
|
|
35
|
+
### Green Phase — Minimal Code
|
|
36
|
+
|
|
37
|
+
1. Write minimal code to pass tests
|
|
38
|
+
2. Don't refactor, don't optimize in this phase
|
|
39
|
+
3. Run tests: confirm PASS
|
|
40
|
+
4. **Verify**: all new tests pass, no regression
|
|
41
|
+
|
|
42
|
+
### Refactor Phase — Clean Up
|
|
43
|
+
|
|
44
|
+
1. Remove duplication, improve naming, reduce complexity
|
|
45
|
+
2. DON'T change behavior — tests are safety net
|
|
46
|
+
3. Run full test suite after each refactor step
|
|
47
|
+
4. **Verify**: coverage >= 80%, all tests still pass
|
|
48
|
+
5. Commit after successful refactor
|
|
49
|
+
|
|
50
|
+
## Red Flags
|
|
51
|
+
|
|
52
|
+
- Test passes on first run before implementation → test doesn't test what it should
|
|
53
|
+
- Test too broad ("everything works") → no value, write more specific test
|
|
54
|
+
- Green phase has too much logic → only write enough to pass, no more
|
|
55
|
+
- Refactor phase makes tests fail → refactor is wrong, roll back step by step
|
|
56
|
+
- Writing multiple tests at once before fixing each → only fix one test at a time
|
|
57
|
+
|
|
58
|
+
## Verification Checklist
|
|
59
|
+
|
|
60
|
+
- [ ] Red: test file exists and runs with FAIL output
|
|
61
|
+
- [ ] Green: test output changes from FAIL → PASS after adding implementation
|
|
62
|
+
- [ ] Refactor: `npm test` / `dotnet test` / `pytest` full suite PASS
|
|
63
|
+
- [ ] Coverage report: >= 80% for changed files
|
|
64
|
+
- [ ] No tests skipped or commented out
|
|
65
|
+
|
|
66
|
+
## Test Naming Convention
|
|
67
|
+
|
|
68
|
+
Anchor on **AC**, not Story (Story removed in kit v3).
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
{PROJECT}_F{FEATURE}_AC{N}_{TYPE}_{NUMBER}_{MODIFIER}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
For E2E (which spans multiple Features), drop the Feature/AC segment:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
{PROJECT}_E2E_{NUMBER}_{MODIFIER} # single-stack
|
|
78
|
+
{PROJECT}_XSTACK_E2E_{NUMBER}_{MODIFIER} # cross-stack
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| TYPE | Meaning | Layer |
|
|
82
|
+
|------|---------|-------|
|
|
83
|
+
| UT | Unit Test | 1 |
|
|
84
|
+
| IT | Integration Test | 1 |
|
|
85
|
+
| API | API Test | 1 |
|
|
86
|
+
| FT | Functional Test | 2 |
|
|
87
|
+
| E2E | End-to-End Test | 3 |
|
|
88
|
+
|
|
89
|
+
MODIFIER: `H` (Happy), `N` (Negative), `E` (Edge), `S` (Security), `P` (Performance)
|
|
90
|
+
|
|
91
|
+
Examples:
|
|
92
|
+
- `AL_F012_AC1_UT_001_H` — Feature 012, AC-1, Unit Test 001, Happy
|
|
93
|
+
- `AL_F012_AC2_FT_003_N` — Feature 012, AC-2, Functional Test 003, Negative
|
|
94
|
+
- `AL_E2E_005_H` — End-to-End scenario 005, Happy
|
|
95
|
+
- `AL_XSTACK_E2E_002_H` — Cross-stack End-to-End scenario 002, Happy
|
|
96
|
+
|
|
97
|
+
## Anti-Rationalization
|
|
98
|
+
|
|
99
|
+
| Rationalization | Counter |
|
|
100
|
+
|---|---|
|
|
101
|
+
| "Test will obviously fail, no need to run" | Skipping Red phase loses verification point — always run |
|
|
102
|
+
| "Writing test after is faster" | TDD saves more debugging time than time spent writing tests first |
|
|
103
|
+
| "This code is too simple for tests" | Simple today, complex after refactor — tests protect future changes |
|
|
104
|
+
| "Interface not clear, write code first for clarity" | Test hard to write is signal interface needs improvement — Ask, don't skip |
|
|
@@ -121,7 +121,7 @@ public abstract class TestBase : IAsyncLifetime
|
|
|
121
121
|
```csharp
|
|
122
122
|
// ============================================================
|
|
123
123
|
// {Resource} API Tests — v{N}
|
|
124
|
-
// Spec: {spec-file} | Generated: {YYYY-MM-DD} |
|
|
124
|
+
// Spec: {spec-file} | Generated: {YYYY-MM-DD} | Feature: {ID}
|
|
125
125
|
// APPEND-ONLY: don't modify existing methods.
|
|
126
126
|
// ============================================================
|
|
127
127
|
namespace ApiTests.V{N};
|
|
@@ -160,7 +160,7 @@ public async Task ...
|
|
|
160
160
|
| Insufficient permission | 403 | RBAC / ownership |
|
|
161
161
|
| `{id}` doesn't exist | 404 | Has path param |
|
|
162
162
|
| Required field missing/invalid | 400/422 | Has request body |
|
|
163
|
-
| Business rule (from AC) | 4xx |
|
|
163
|
+
| Business rule (from AC) | 4xx | Feature has corresponding AC |
|
|
164
164
|
|
|
165
165
|
## CI/CD Env Vars
|
|
166
166
|
|