@luizsantiago/spec-guardrails 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +206 -0
  3. package/index.js +335 -0
  4. package/lib/archive.js +208 -0
  5. package/lib/assets.js +145 -0
  6. package/lib/brownfield.js +446 -0
  7. package/lib/config.js +293 -0
  8. package/lib/constants.js +262 -0
  9. package/lib/cursorrules.js +92 -0
  10. package/lib/delta-merge.js +248 -0
  11. package/lib/doctor.js +343 -0
  12. package/lib/download.js +133 -0
  13. package/lib/feature.js +272 -0
  14. package/lib/fs-utils.js +114 -0
  15. package/lib/gates.js +138 -0
  16. package/lib/install.js +140 -0
  17. package/lib/memory.js +34 -0
  18. package/lib/next-steps.js +50 -0
  19. package/lib/presets.js +176 -0
  20. package/lib/project-rules.js +210 -0
  21. package/lib/specs-utils.js +117 -0
  22. package/lib/token-cost.js +124 -0
  23. package/package.json +46 -0
  24. package/rules/engineering-baseline.mdc +56 -0
  25. package/scripts/_common.py +356 -0
  26. package/scripts/analyze_artifacts.py +187 -0
  27. package/scripts/check_commit.py +140 -0
  28. package/scripts/lessons.py +447 -0
  29. package/scripts/loop_plan.py +217 -0
  30. package/scripts/validate_spec.py +345 -0
  31. package/scripts/validate_state.py +385 -0
  32. package/scripts/validate_tasks.py +379 -0
  33. package/skills/agent-architecture.md +221 -0
  34. package/skills/appsec.md +83 -0
  35. package/skills/code-simplify.md +49 -0
  36. package/skills/engineering-standards.md +98 -0
  37. package/skills/git-handoff.md +213 -0
  38. package/skills/qa-strategy.md +83 -0
  39. package/skills/references/analyze.md +56 -0
  40. package/skills/references/archive.md +60 -0
  41. package/skills/references/constitution.md +66 -0
  42. package/skills/references/context-limits.md +73 -0
  43. package/skills/references/converge.md +47 -0
  44. package/skills/references/design.md +88 -0
  45. package/skills/references/discuss.md +68 -0
  46. package/skills/references/explore.md +61 -0
  47. package/skills/references/implement.md +175 -0
  48. package/skills/references/lessons.md +71 -0
  49. package/skills/references/memory.md +98 -0
  50. package/skills/references/project-init.md +62 -0
  51. package/skills/references/quick-mode.md +84 -0
  52. package/skills/references/specify.md +144 -0
  53. package/skills/references/sub-agents.md +117 -0
  54. package/skills/references/tasks.md +178 -0
  55. package/skills/references/validate.md +210 -0
  56. package/skills/security-review.md +120 -0
  57. package/skills/ship-ready.md +50 -0
  58. package/skills/task-graph-engineering.md +180 -0
  59. package/templates/GETTING_STARTED.md +61 -0
  60. package/templates/config.yaml.example +28 -0
  61. package/templates/presets/default.yaml +16 -0
  62. package/templates/presets/node-ts.yaml +22 -0
  63. package/templates/presets/python.yaml +22 -0
@@ -0,0 +1,98 @@
1
+ # Memory
2
+
3
+ Project memory that survives session amnesia: decisions, handoff, and resume.
4
+
5
+ ## When to Use
6
+
7
+ - Session start (resume)
8
+ - Session end (pause / handoff)
9
+ - Any time a project-level decision is made
10
+ - Any time verification produces a grounded lesson
11
+
12
+ ## Artifacts
13
+
14
+ | File | Owner | Purpose |
15
+ | --- | --- | --- |
16
+ | `.specs/STATE.md` | Agent + owner | Decision log (`AD-NNN`) and handoff snapshot |
17
+ | `.specs/lessons.json` | `lessons.py` | Canonical lessons store |
18
+ | `.specs/LESSONS.md` | `lessons.py` | Generated playbook of confirmed lessons |
19
+ | `.specs/project/PROJECT.md` | Owner | Vision, stack, constraints |
20
+ | `.specs/project/ROADMAP.md` | Owner | Milestones and feature status |
21
+
22
+ ## Resume Protocol
23
+
24
+ Run at every session start, before writing any code:
25
+
26
+ 1. **Read `STATE.md`** — active feature, phase, next step, blockers.
27
+ 2. **Reconcile against git.** The snapshot can be stale; evidence wins:
28
+ ```bash
29
+ git branch --show-current
30
+ git status --porcelain
31
+ git log --oneline -10
32
+ ```
33
+ Compare with `tasks.md` checkboxes. If commits exist for tasks that STATE says are pending, git is right — update STATE.
34
+ 3. **Run the project harness** (tests, lint) before adding new code, so you know the starting baseline.
35
+ 4. **Load only what this step needs** — the current feature's spec, plus `context.md` or `design.md` when relevant. Never load two feature specs at once. See `context-limits.md`.
36
+ 5. **Propose the reconciled next step** and confirm it with the owner when it is ambiguous or stale.
37
+
38
+ ## Pause / Handoff Protocol
39
+
40
+ Run at session end or at a phase milestone:
41
+
42
+ 1. Refresh every section of `STATE.md` (template below).
43
+ 2. Append a grounded lesson with `lessons.py add` if verification failed. Never hand-edit `LESSONS.md`.
44
+ 3. Run the relevant gates and tests — never hand off a red tree silently.
45
+ 4. Commit `.specs/` per `git-handoff.md`. **Never auto-push.**
46
+
47
+ ## STATE.md Template
48
+
49
+ ```markdown
50
+ # Project State & Decisions
51
+
52
+ ## Active Feature
53
+ - Feature: [name]
54
+ - Phase: [Specify|Discuss|Design|Tasks|Execute|Verify]
55
+ - Branch: [branch-name]
56
+
57
+ ## Next Step (single item)
58
+ - [ ] [one concrete action]
59
+
60
+ ## Blockers
61
+ - [open questions or dependencies, or "none"]
62
+
63
+ ## Deferred Ideas
64
+ - [good ideas found during Execute that were out of scope]
65
+
66
+ ## Decisions
67
+
68
+ ### AD-001: [Decision title]
69
+ - **Date**: [ISO date]
70
+ - **Context**: [why this came up]
71
+ - **Decision**: [what was decided]
72
+ - **Consequences**: [what this constrains going forward]
73
+ ```
74
+
75
+ ## Decision Log Rules
76
+
77
+ - `AD-NNN` numbers are sequential and never reused.
78
+ - Record a decision when it constrains **future work beyond this feature**. Feature-local choices belong in `context.md` or `design.md`.
79
+ - Superseding a decision adds a new `AD-NNN` that references the old one — never edit history in place.
80
+
81
+ ## Lessons Rules
82
+
83
+ Lessons are owned by `lessons.py`, not by hand. See `lessons.md`.
84
+
85
+ - Record only from a **grounded failure** in `validation.md`: a surviving mutant, an imprecise acceptance criterion, a failed requirement, or a spec deviation.
86
+ - A clean PASS records nothing.
87
+ - `--source` is mandatory. Candidates are not guidance; only `list --status confirmed` is.
88
+ - Do not edit `LESSONS.md`. The engine generates it from `lessons.json`.
89
+
90
+ ## Rules
91
+
92
+ - Write every artifact in **English**.
93
+ - Lazy artifacts: never scaffold empty files to look organized.
94
+ - `STATE.md` has exactly one "Next Step" item. A list of five is not a handoff.
95
+
96
+ ## Next
97
+
98
+ `git-handoff.md` — what to stage, how to word the commit, and why no auto-push.
@@ -0,0 +1,62 @@
1
+ # Project Init (Brownfield)
2
+
3
+ Map an existing codebase into `.specs/` project memory before the first `/specify`.
4
+
5
+ ## When to Use
6
+
7
+ - Adopting Spec Guardrails on a repo that already has code
8
+ - Owner wants domain specs and `PROJECT.md` before feature work
9
+ - Before `/constitution` or the first Medium+ feature on a brownfield repo
10
+
11
+ ## When NOT to Use
12
+
13
+ - Greenfield repo with no code yet — use `install` + `feature-init`
14
+ - Quick-tier-only work with no domain map — optional
15
+
16
+ ## Inputs
17
+
18
+ - Repository layout (`packages/`, `apps/`, `src/domains/`, etc.)
19
+ - Stack markers (`package.json`, `pyproject.toml`, `go.mod`, `Cargo.toml`)
20
+ - Optional `.specs/config.yaml` preset choice
21
+
22
+ ## Output
23
+
24
+ - `.specs/project/PROJECT.md` — vision, detected stack, domain map
25
+ - `.specs/project/ROADMAP.md` — planned domain drafting items
26
+ - `.specs/domains/[domain]/spec.md` — brownfield stubs (one per detected/manual domain)
27
+ - `.specs/config.yaml` — from auto-detected or chosen preset (when missing)
28
+
29
+ ## Procedure
30
+
31
+ 1. **Run the scan (Tier 0):**
32
+ ```bash
33
+ npx @luizsantiago/spec-guardrails project-init --dry-run
34
+ npx @luizsantiago/spec-guardrails project-init [--preset node-ts] [--domains auth,billing]
35
+ ```
36
+ 2. **Review with the owner** — edit `PROJECT.md`, trim false-positive domains, fill Vision/Constraints.
37
+ 3. **Draft domain truth** — replace stub requirements in `.specs/domains/*/spec.md` from code review (or leave stubs until features archive in).
38
+ 4. **Optional constitution** — `references/constitution.md` when principles are not yet written.
39
+ 5. **First feature** — `feature-init` then `specify.md` using **delta specs** when domain truth exists.
40
+
41
+ ## Flags
42
+
43
+ | Flag | Effect |
44
+ | --- | --- |
45
+ | `--dry-run` | Print stack/domains only |
46
+ | `--preset <name>` | Force config preset (`default`, `node-ts`, `python`) |
47
+ | `--domains a,b` | Manual domain list (overrides auto-detect) |
48
+ | `--no-domains` | Skip domain folder scaffolding |
49
+ | `--no-project` | Skip `PROJECT.md` |
50
+ | `--force` | Overwrite generated project/domain/config files |
51
+
52
+ ## Rules
53
+
54
+ - Scan results are **hints**, not approved requirements.
55
+ - Never treat stub domain specs as enforced gates — populate or merge via `archive-feature`.
56
+ - Commit `.specs/project/` and `.specs/domains/` locally (Tier 0); push needs owner go-ahead.
57
+
58
+ ## Next
59
+
60
+ - Principles missing → `constitution.md`
61
+ - First change → `feature-init` then `specify.md` (delta spec when brownfield)
62
+ - Back → `agent-architecture.md`
@@ -0,0 +1,84 @@
1
+ # Quick Mode
2
+
3
+ Express lane for small, low-risk changes. Full pipeline ceremony would cost more than the change itself.
4
+
5
+ ## When to Use
6
+
7
+ All of these must hold:
8
+
9
+ - 3 files or fewer
10
+ - No architectural decision
11
+ - No new dependency
12
+ - No change to auth, payments, or data migrations
13
+ - The fix is describable in one sentence
14
+
15
+ Typical: a bug fix, a copy change, a config tweak, a version bump.
16
+
17
+ ## When NOT to Use
18
+
19
+ If any guardrail is exceeded, stop and route to `specify.md`. Explicitly:
20
+
21
+ | Signal | Route to |
22
+ | --- | --- |
23
+ | More than 3 files | `specify.md` → Simple tier |
24
+ | A design decision appears | `design.md` |
25
+ | More than 5 steps emerge | `tasks.md` |
26
+ | Auth, payments, or data safety touched | Full pipeline + `security-review.md` |
27
+
28
+ Announce the switch — do not silently expand a quick task into a feature.
29
+
30
+ ## Output
31
+
32
+ `.specs/quick/NNN-slug/`
33
+
34
+ | File | Content |
35
+ | --- | --- |
36
+ | `TASK.md` | What, where, approach, verification |
37
+ | `SUMMARY.md` | What changed, commit hash, evidence |
38
+
39
+ `NNN` is sequential across the project (`001`, `002`, …).
40
+
41
+ ## Procedure
42
+
43
+ 1. **Restate the change in one sentence**, name the files, and state how you will verify it.
44
+ 2. **Write `TASK.md`** before touching code. Two minutes of writing prevents the wrong fix.
45
+ 3. **Write or extend a test** that fails for the current defect. A quick fix with no test is only allowed for changes with no behavior — copy, formatting, comments.
46
+ 4. **Implement the smallest change.**
47
+ 5. **Run the project harness** — tests and linter.
48
+ 6. **Commit atomically**, Conventional Commits format:
49
+ ```bash
50
+ python3 .specs/guardrails/scripts/check_commit.py --message "fix(theme): persist dark mode preference"
51
+ ```
52
+ 7. **Write `SUMMARY.md`** with the commit hash and the evidence line.
53
+ 8. **Record a lesson** with `lessons.py add --source` if the defect revealed a gap that will recur and a `validation.md` exists. Quick-mode copy fixes usually record nothing.
54
+
55
+ ## Verification Standard
56
+
57
+ Quick mode compresses ceremony, not carelessness — but it is **not** the full Verify gate:
58
+
59
+ - Prove the change with a test or an explicit, documented manual check.
60
+ - Record evidence in `SUMMARY.md` (`file:line` or the exact manual steps). That is a **process** requirement; `validate_state.py` does not run on Quick artifacts.
61
+ - Blast radius still applies — local commit only; `git push` and deploy need an explicit go-ahead.
62
+ - If any Quick guardrail is exceeded, stop and route to `specify.md` (see When NOT to Use).
63
+
64
+ ## Templates
65
+
66
+ ```markdown
67
+ # Quick Task: [one-line title]
68
+
69
+ - **Files**: src/hooks/useTheme.ts
70
+ - **Approach**: persist the preference to localStorage on toggle
71
+ - **Verify**: toggle dark mode, reload, preference persists
72
+ ```
73
+
74
+ ```markdown
75
+ # Summary
76
+
77
+ - **Changed**: persisted theme preference on toggle
78
+ - **Commit**: fix(theme): persist dark mode preference (a1b2c3d)
79
+ - **Evidence**: test/hooks/useTheme.test.ts:18
80
+ ```
81
+
82
+ ## Next
83
+
84
+ Back to normal work. If the same class of defect appears again, promote it to a real feature with `specify.md`.
@@ -0,0 +1,144 @@
1
+ # Specify
2
+
3
+ Capture WHAT to build as testable, traceable requirements. Always required (except Quick tier).
4
+
5
+ ## When to Use
6
+
7
+ - Any change beyond the Quick tier (see `quick-mode.md`)
8
+ - Before writing production code or tests
9
+
10
+ ## When NOT to Use
11
+
12
+ - Quick-tier changes (≤3 files, no design decisions) — use `quick-mode.md`
13
+
14
+ ## Inputs
15
+
16
+ - Owner's request, in their own words
17
+ - `.specs/STATE.md` decisions (`AD-NNN`) relevant to this area
18
+ - `.specs/project/CONSTITUTION.md` when present
19
+ - `.specs/LESSONS.md` entries that apply — load them with `python3 .specs/guardrails/scripts/lessons.py list --status confirmed`
20
+ - Existing codebase conventions
21
+ - `context-limits.md` — this feature only; do not load sibling specs
22
+
23
+ ## Output
24
+
25
+ `.specs/features/[NNN-slug]/spec.md` (created by `feature-init`)
26
+
27
+ ## Procedure
28
+
29
+ 0. **Allocate feature identity (Tier 0).** Before drafting:
30
+ ```bash
31
+ npx @luizsantiago/spec-guardrails feature-init "owner description here"
32
+ ```
33
+ Creates `.specs/features/003-slug/`, updates `STATE.md`, and `git checkout -b feat/003-slug`. Skip on Quick tier.
34
+ Optional project context: `npx @luizsantiago/spec-guardrails phase-context specify` when `.specs/config.yaml` exists.
35
+ 1. **Act as a thinking partner, not an interviewer.** Challenge vagueness; restate the goal in one sentence and confirm it.
36
+ 2. **Surface assumptions before drafting criteria.** State stack/auth/data guesses and ask for corrections; lasting ones go under `## Assumptions` only after that (or after `discuss.md`).
37
+ 3. **Mark unknowns explicitly.** Use `[NEEDS CLARIFICATION: specific question]` — never guess. Resolve or remove before owner approval.
38
+ 4. **Load confirmed lessons.** Run `python3 .specs/guardrails/scripts/lessons.py list --status confirmed` and apply every rule that matches this work. Candidates are not guidance.
39
+ 5. **Detect gray areas.** If the feature touches persistence, external calls, auth, payments, concurrency, or state transitions — or if intent is ambiguous — run `discuss.md` before finalizing.
40
+ 6. **Choose spec shape:**
41
+ - **Greenfield** — full spec (`## Requirements`, `## Assumptions`, `## Out of Scope`)
42
+ - **Brownfield** — delta spec (`## ADDED Requirements`, `## MODIFIED Requirements`, `## REMOVED Requirements`)
43
+ 7. **Write requirements with stable IDs.** `REQ-001`, `AUTH-002` — prefix plus a zero-padded number. IDs never change once approved; retire them instead.
44
+ 8. **Write binary acceptance criteria.** Every criterion is objectively pass or fail. The gate **blocks** a criterion that does not state a required outcome with `SHALL` or `MUST`. Soft verbs (`should`, `will`, `can`, `may`) are not testable — rewrite them before confirming.
45
+ Prefer **EARS** (one pattern per criterion). The gate **warns** when a `SHALL`/`MUST` line has no `WHEN`/`IF` … `THEN` trigger; missing EARS is not a hard fail.
46
+
47
+ | Pattern | Shape | Use when |
48
+ | --- | --- | --- |
49
+ | Ubiquitous | The system SHALL [invariant] | Always-on constraints |
50
+ | Event-driven | WHEN [trigger] THEN the system SHALL [outcome] | A discrete action or event |
51
+ | State-driven | WHILE [state] the system SHALL [outcome] | Behavior that holds during a state |
52
+ | Optional-feature | WHERE [capability] the system SHALL [outcome] | Flag- or plan-gated behavior |
53
+ | Unwanted-behavior | IF [undesired] THEN the system SHALL [outcome] | Errors, invalid input, timeouts |
54
+ | Complex | WHILE [state], WHEN [trigger] the system SHALL [outcome] | Combined state + event |
55
+
56
+ One criterion = one behavior. Use concrete values (status, code, bound), not “gracefully” or “quickly”.
57
+ 9. **State out of scope explicitly.** This is what prevents scope creep during Execute.
58
+ 10. **Record assumptions.** Anything inferred rather than confirmed goes under `## Assumptions`. The section is required; write `- none` only when nothing was inferred.
59
+ 11. **Run the gate.** Fix every blocking issue before showing the spec to the owner.
60
+ 12. **Get approval.** Do not write implementation code until the spec and derived tests are approved.
61
+ 13. **Commit spec (Tier 0).** `docs(spec): add requirements for 003-slug`
62
+
63
+ ## Gate
64
+
65
+ ```bash
66
+ python3 .specs/guardrails/scripts/validate_spec.py .specs/features/[feature]/spec.md
67
+ python3 .specs/guardrails/scripts/validate_spec.py [feature]
68
+ python3 .specs/guardrails/scripts/validate_spec.py # single-feature projects
69
+ ```
70
+
71
+ Checks required sections (`Requirements`, `Assumptions`, `Out of Scope`), well-formed IDs, a `SHALL`/`MUST` outcome per criterion, and unresolved placeholders. Sections, IDs, criteria, and placeholders are read from visible markdown — fenced samples and HTML comments do not count. A criterion with `SHALL` but no `WHEN`/`IF` … `THEN` trigger is a warning. Non-zero exit means STOP.
72
+
73
+ ## Template
74
+
75
+ ```markdown
76
+ # Spec: [Feature]
77
+
78
+ ## Goal
79
+ [One sentence: what the owner gets when this ships.]
80
+
81
+ ## Requirements
82
+
83
+ ### REQ-001: [Short title]
84
+ - **Acceptance Criteria**: WHEN [valid credentials are submitted] THEN the system SHALL [create a session] <!-- event-driven -->
85
+ - IF [the token is expired] THEN the system SHALL [return 401 with code TOKEN_EXPIRED] <!-- unwanted-behavior -->
86
+
87
+ ### REQ-002: [Short title]
88
+ - **Acceptance Criteria**: WHILE [a session is active] the system SHALL [reject reuse of a rotated refresh token] <!-- state-driven -->
89
+ - The system SHALL [store passwords only as argon2 hashes] <!-- ubiquitous -->
90
+
91
+ ## Assumptions
92
+ - [Anything inferred rather than confirmed]
93
+
94
+ ## Out of Scope
95
+ - [Explicitly excluded work]
96
+ ```
97
+
98
+ ### Delta spec (brownfield)
99
+
100
+ ```markdown
101
+ # Spec: 004-dark-mode (delta)
102
+
103
+ ## Goal
104
+ Add theme switching without new dependencies.
105
+
106
+ ## ADDED Requirements
107
+
108
+ ### UI-001: Theme toggle
109
+ - **Acceptance Criteria**: WHEN the user clicks the theme toggle THEN the system SHALL persist the choice in localStorage
110
+
111
+ ## MODIFIED Requirements
112
+
113
+ ### AUTH-001: Session banner
114
+ - **Acceptance Criteria**: WHILE dark mode is active the system SHALL render the session banner with contrast ratio ≥ 4.5:1
115
+
116
+ ## REMOVED Requirements
117
+ - none
118
+
119
+ ## Assumptions
120
+ - CSS variables already exist for primary colors
121
+
122
+ ## Out of Scope
123
+ - Server-side theme preference sync
124
+ ```
125
+
126
+ ## Anti-Patterns
127
+
128
+ | Avoid | Prefer |
129
+ | --- | --- |
130
+ | "Login should work well" | "WHEN valid credentials are submitted THEN the system SHALL create a session" |
131
+ | "The system will return 401" | "WHEN the token is expired THEN the system SHALL return 401 with code `TOKEN_EXPIRED`" |
132
+ | Omitting `## Assumptions` | Record inferences, or write `- none` |
133
+ | Guessing when unsure | `[NEEDS CLARIFICATION: auth method not specified]` |
134
+ | Manual slug folders without numbering | `feature-init` before drafting |
135
+ | Renaming `REQ-001` mid-flight | Retire the ID and add a new one |
136
+ | Implementation detail in the spec | Keep HOW in `design.md` |
137
+
138
+ ## Next
139
+
140
+ - Gray areas remain → `discuss.md`
141
+ - Tasks drafted → `analyze.md` before approval
142
+ - Architectural decisions needed → `design.md`
143
+ - ≤3 obvious steps → `implement.md`
144
+ - Otherwise → `tasks.md`
@@ -0,0 +1,117 @@
1
+ # Sub-Agents
2
+
3
+ Operational protocol for multi-agent Execute. Sister material to `task-graph-engineering.md`
4
+ (topology) — this file is the **payload, summary, failure, and merge** contract.
5
+
6
+ ## When to Use
7
+
8
+ - `loop-plan` shows a parallel group with 2+ ready tasks (disjoint `Files`)
9
+ - `task-graph.md` marks a parallel group and the owner accepted the split
10
+ - `tasks.md` packs into more than one ~7-task batch (roughly more than 8 tasks total)
11
+ - Diamond verify needs a fresh context that never wrote the code
12
+
13
+ ## When NOT to Use
14
+
15
+ - ≤8 tasks that fit one batch — execute inline
16
+ - Sequential work where each step needs the previous step's full picture
17
+ - The owner declined the sub-agent offer
18
+
19
+ **Never auto-spawn.** Offer the split, wait for an explicit yes.
20
+
21
+ ## Batch packing
22
+
23
+ 1. Walk `### Phase N` groups in order (or document order when phases are unused).
24
+ 2. Pack consecutive **whole** phases into a batch until the batch would exceed ~7 tasks.
25
+ 3. Never split a phase across workers.
26
+ 4. Batches run **sequentially**. Parallelism lives *inside* a batch only when `task-graph.md` marks a parallel group and Files are disjoint.
27
+
28
+ ## Worker payload
29
+
30
+ Hand each worker exactly this and nothing else from sibling features:
31
+
32
+ ```markdown
33
+ # Worker brief
34
+
35
+ - Feature: [feature]
36
+ - Batch: B[n] of [total]
37
+ - Tasks: T[a] … T[b] (in order)
38
+ - Spec excerpt: only the REQ IDs those tasks name
39
+ - Files ownership: the union of those tasks' Files fields (exclusive)
40
+ - Constraints: AD-NNN that apply; confirmed lessons that apply
41
+ - Forbidden: git push, deploy, editing files outside ownership, spawning further sub-agents
42
+ ```
43
+
44
+ Load per `context-limits.md`. Do not paste the author's chat.
45
+
46
+ ## Worker loop
47
+
48
+ For each task in order:
49
+
50
+ 1. Read the task fields. Implement test-first from the named criteria.
51
+ 2. Run the task `Gate`. Non-zero → fix (max 3 loops) or stop and report failure.
52
+ 3. Run `check_commit.py` on the message, mark the task `[x]`, commit atomically.
53
+ 4. Do not start the next task until the commit exists.
54
+
55
+ ## Compact summary (required return)
56
+
57
+ Every worker returns this shape — no narrative dump:
58
+
59
+ ```markdown
60
+ ## Batch B[n] summary
61
+ - Status: PASS | FAIL
62
+ - Tasks done: T1, T2
63
+ - Commits: abc1234, def5678
64
+ - Tests: 12 passed / 0 failed
65
+ - Deviations: none | [what changed vs tasks.md]
66
+ - Blockers: none | [gate output excerpt]
67
+ ```
68
+
69
+ ## Failure handling
70
+
71
+ | Event | Action |
72
+ | --- | --- |
73
+ | Gate fails 3 times on one task | Stop the batch. Return FAIL summary. Do not continue later tasks in the batch. |
74
+ | Worker edits a file outside ownership | Treat as FAIL. Merge owner reverts or reassigns. |
75
+ | Batch FAIL | Orchestrator does not start the next batch. Escalate or rewrite tasks. |
76
+ | Verify FAIL | Gaps become fix tasks; fix → re-verify loop bounded to 3, then escalate. |
77
+
78
+ ## Merge owner
79
+
80
+ One agent (usually the orchestrator) owns merge after each batch and after Verify:
81
+
82
+ 1. Confirm every task checkbox in the batch is `[x]` and commits are present.
83
+ 2. Run the project harness once on the integrated tree.
84
+ 3. Resolve conflicts; never ask two workers to touch the same file in the same round.
85
+ 4. Only after the final batch: dispatch the **Verifier** (fresh context). See `validate.md`.
86
+ 5. Hand off via `git-handoff.md` — push only with an explicit go-ahead.
87
+
88
+ ## Verifier dispatch
89
+
90
+ Always-on after the last task commit. Payload:
91
+
92
+ - `spec.md` (+ `context.md` when present)
93
+ - Diff range for the feature
94
+ - Tests named by the spec / tasks
95
+ - `security-review.md` checklist
96
+ - **Not** the author chat, worker summaries as proof, or `STATE.md` Next Step as evidence
97
+
98
+ The verifier writes `validation.md` and runs `validate_state.py`. A PASS WITH GAPS is FAIL.
99
+
100
+ ## Model tier (optional)
101
+
102
+ When Spec Guardrails can pick a model per sub-agent:
103
+
104
+ | Role | Tier |
105
+ | --- | --- |
106
+ | Mechanical batch | Fast |
107
+ | Ambiguous / core-domain batch | High reasoning |
108
+ | Verifier | Mid-to-high |
109
+
110
+ Otherwise ignore and invest more care on heavy steps.
111
+
112
+ ## Related
113
+
114
+ - `task-graph-engineering.md` — DAG, stop rule, diamond, one writer per file
115
+ - `references/implement.md` — when to offer delegation
116
+ - `references/validate.md` — verifier procedure
117
+ - `references/context-limits.md` — what a worker may load
@@ -0,0 +1,178 @@
1
+ # Tasks
2
+
3
+ Break the work into atomic tasks with real dependencies and binary done criteria. Optional phase.
4
+
5
+ ## When to Use
6
+
7
+ - More than 3 obvious steps
8
+ - Multiple files, modules, or people involved
9
+ - Any work that could be split across parallel agents
10
+
11
+ ## When NOT to Use
12
+
13
+ - ≤3 obvious steps — list them inline at the start of Execute instead
14
+
15
+ **Safety valve:** if the inline listing in Execute reveals more than 5 steps or real dependencies, STOP and create a formal `tasks.md`. The Tasks phase was skipped in error.
16
+
17
+ ## Inputs
18
+
19
+ - Approved `spec.md` (and `design.md` when it exists)
20
+ - `task-graph-engineering.md` for topology rules
21
+ - `context-limits.md` if the breakdown is large — keep each task's file list short enough to load
22
+
23
+ ## Output
24
+
25
+ `.specs/features/[feature]/tasks.md`, plus `task-graph.md` when the feature has 3+ tasks or parallel work.
26
+
27
+ ## Procedure
28
+
29
+ 1. **Write one task per deliverable.** A task is something you would hand to a single agent and check in one commit.
30
+ 2. **Prefer vertical slices.** One thin verifiable path per **feature** (e.g. register), not “all schema then all APIs then all UI” as *phases*. If `.cursor/rules/fullstack-layer.mdc` is present (`@luizsantiago/fullstack-floor-map`), keep each task `Files` list on **one Lane** (path layer; 0.4.x docs may still say “Floor”). Split UI vs API into T1/T2 with `Depends on`. Vertical still means a thin *feature*, not one task mixing `apps/web` + `apps/api`. See [Companion: Full Stack Floor Map](https://github.com/luizssantiago92/spec-guardrails/blob/main/docs/guide/Companion-fullstack-floor-map.md).
31
+ 3. **Give every task the full field set.** Authoring and the gate require all six:
32
+ - `Requirement` — the spec ID it serves (gated)
33
+ - `Files` — where the change lands (gated; required; `none` / `—` rejected; overlap across independent tasks blocks)
34
+ - `Depends on` — real dependencies only, or `—` (gated; `—` means none)
35
+ - `Tests` — the test file that proves it (gated; `none` / `—` rejected)
36
+ - `Gate` — the command that must pass (gated; `none` / `—` rejected)
37
+ - `Done when` — binary criterion (gated; `none` / `—` rejected)
38
+ 4. **Delete fake edges.** For every "and then", ask whether the next task actually reads the previous task's output. If not, the edge is fake — remove it and the tasks can run in parallel. See `task-graph-engineering.md`.
39
+ 5. **Order tasks so dependencies come first.** Forward dependencies fail the gate. When grouping under `### Phase N`, a task must not depend on a task in a later phase.
40
+ 6. **Apply the stop rule.** Only split work that never reads its siblings' results; sequential work stays with one agent.
41
+ 7. **Cover every acceptance criterion.** Fill `## Test Coverage Matrix` and `## Gate Check Commands` **before** presenting the list. An unmapped requirement is a missing task. Align each task `Tests` / `Gate` field with those sections.
42
+ 8. **Draw the graph** in `task-graph.md` when there are 3+ tasks or any parallel group.
43
+ 9. **Run analyze, then the tasks gate**, then present the breakdown for approval.
44
+ ```bash
45
+ python3 .specs/guardrails/scripts/analyze_artifacts.py [feature]
46
+ python3 .specs/guardrails/scripts/validate_tasks.py [feature]
47
+ ```
48
+
49
+ **Authoring vs gate.** `validate_tasks.py` already enforces REQ coverage and `Tests`/`Gate` fields. The matrix and Gate Check Commands sections are an owner/verifier checklist (judgment) until a future form gate — do not skip them when Tasks ran.
50
+
51
+ ## Gate
52
+
53
+ ```bash
54
+ python3 .specs/guardrails/scripts/validate_tasks.py .specs/features/[feature]/tasks.md
55
+ python3 .specs/guardrails/scripts/validate_tasks.py [feature]
56
+ python3 .specs/guardrails/scripts/validate_tasks.py # single-feature projects
57
+ ```
58
+
59
+ Checks task IDs, required fields (including `Files` and `Done when`), dependency direction, later-phase dependencies, cycles, granularity smells, **spec requirement coverage**, and **Files overlap** across independent tasks. `Files`/`Tests`/`Gate`/`Done when` set to `none` or `—` fail. Non-zero exit means STOP.
60
+
61
+ Task headings, fields, and spec requirement IDs are read from visible markdown — fenced samples and HTML comments do not count. When a sibling `spec.md` exists, every requirement heading ID under `## Requirements` must appear in at least one task `Requirement` field. Independent tasks (no dependency path either way) must not share a path in `Files` (`./path`, `/path`, `../path`, quotes, markdown links, case variants, and `path` count as one).
62
+
63
+ The gate does not check that `Done when` is philosophically binary — you do. A passing gate is necessary, not sufficient. Path overlap uses the shared `normalize_file_path` helper (quotes, markdown links, `./`, `/`, `../`, drive letters, casefold).
64
+
65
+ ## Execution Plan (phases)
66
+
67
+ Use `### Phase N` when the work has a real staging constraint (schema before handlers, handlers before UI). Phases are ordered groups, not a second ID scheme.
68
+
69
+ ```markdown
70
+ # Tasks: Authentication
71
+
72
+ ### Phase 1
73
+
74
+ ### T1: Create session token module
75
+ - **Requirement**: REQ-001
76
+ - **Files**: src/auth/token.ts
77
+ - **Depends on**: —
78
+ - **Tests**: test/auth/token.test.ts
79
+ - **Gate**: npm test
80
+ - **Done when**: module signs and verifies tokens
81
+ - [ ] complete
82
+
83
+ ### Phase 2
84
+
85
+ ### T2: Add login endpoint handler
86
+ - **Requirement**: REQ-001
87
+ - **Files**: src/routes/login.ts
88
+ - **Depends on**: T1
89
+ - **Tests**: test/routes/login.test.ts
90
+ - **Gate**: npm test
91
+ - **Done when**: endpoint returns 200 for valid credentials
92
+ - [ ] complete
93
+ ```
94
+
95
+ Rules the gate enforces:
96
+
97
+ - A task in Phase 1 must not depend on a task in Phase 2 or later
98
+ - Document order still matters: dependencies must appear before dependents
99
+ - Tasks with no phase heading are treated as phase 0 (ungrouped) and may depend only on other ungrouped or earlier-phase tasks
100
+
101
+ Do not invent phases to make the list look organized. Two tasks that can run in the same round belong in the same phase, or in no phase at all.
102
+
103
+ ## Template
104
+
105
+ ```markdown
106
+ # Tasks: [Feature]
107
+
108
+ ### T1: [Imperative, specific title]
109
+ - **Requirement**: REQ-001
110
+ - **Files**: src/auth/token.ts
111
+ - **Depends on**: —
112
+ - **Tests**: test/auth/token.test.ts
113
+ - **Gate**: npm test
114
+ - **Done when**: token module signs and verifies tokens
115
+ - [ ] complete
116
+
117
+ ### T2: [Imperative, specific title]
118
+ - **Requirement**: REQ-001
119
+ - **Files**: src/routes/login.ts
120
+ - **Depends on**: T1
121
+ - **Tests**: test/routes/login.test.ts
122
+ - **Gate**: npm test
123
+ - **Done when**: endpoint returns 200 for valid credentials
124
+ - [ ] complete
125
+
126
+ ## Test Coverage Matrix
127
+ | Requirement | Task | Tests | Notes |
128
+ | --- | --- | --- | --- |
129
+ | REQ-001 | T1, T2 | test/auth/token.test.ts, test/routes/login.test.ts | |
130
+
131
+ ## Gate Check Commands
132
+ | Level | Command |
133
+ | --- | --- |
134
+ | Task | the per-task `Gate` field |
135
+ | Feature | npm test |
136
+ ```
137
+
138
+ ## Granularity
139
+
140
+ | Too coarse | Atomic |
141
+ | --- | --- |
142
+ | "Create form" | T1: add email input component · T2: add email validation · T3: add submit handler |
143
+ | "Implement feature" | One task per file or per contract |
144
+ | "Fix bugs" | One task per reproducible defect |
145
+ | "Add auth" | T1: token module · T2: login handler · T3: refresh handler |
146
+ | "Write tests" | The tests belong on the task that produces the behavior, not as a follow-up |
147
+
148
+ A task that cannot be verified by a single named test is not atomic yet. A title under three words is a smell the gate warns about (`"Add endpoint"` → `"Add login endpoint handler"`).
149
+
150
+ ## Good and bad dependencies
151
+
152
+ | Edge | Real or fake | Why |
153
+ | --- | --- | --- |
154
+ | Login handler depends on token module | Real | The handler imports and calls the module |
155
+ | README update depends on login tests | Fake | README does not read test output |
156
+ | Refresh handler depends on login handler | Fake, unless it shares a type the login task creates | Same auth package can land in parallel if files differ |
157
+ | UI form depends on API contract | Real if the form types are generated from the handler | Otherwise the form can mock the contract and run in parallel |
158
+
159
+ Delete fake edges before drawing `task-graph.md`. Most first drafts hide two or three.
160
+
161
+ ## Coverage matrix
162
+
163
+ Before approval, map every spec requirement heading under `## Requirements` to at least one task. Every task `Tests` path should appear in the matrix. Fill `## Test Coverage Matrix` and `## Gate Check Commands` in `tasks.md` (see Template).
164
+
165
+ | Requirement | Task | Tests | Notes |
166
+ | --- | --- | --- | --- |
167
+ | REQ-001 | T2 | test/routes/login.test.ts | valid credentials → session |
168
+ | REQ-001 | T2 | test/routes/login.test.ts | invalid → 401 `AUTH_INVALID` |
169
+ | REQ-002 | T3 | test/routes/refresh.test.ts | refresh rotates the token |
170
+
171
+ A requirement with no row is unimplemented by construction. Do not present the breakdown until the matrix is complete. The Python gate already fails uncovered REQ IDs; the table is for humans and Execute.
172
+
173
+ `Files` lists on parallel tasks must be disjoint. If two tasks name the same file, they are one task, or they are sequential.
174
+
175
+ ## Next
176
+
177
+ - 3+ tasks or parallel groups → `/task-graph` per `task-graph-engineering.md`
178
+ - Otherwise → `implement.md`