jorgex-stack 1.0.29 → 1.0.30
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/README.md +17 -9
- package/package.json +1 -1
- package/stack/agents/orchestrator.md +16 -0
- package/stack/agents/test-analyzer.md +26 -62
- package/stack/agents/tester.md +52 -27
- package/stack/skills/agent-delegation/SKILL.md +2 -2
- package/stack/skills/tdd/SKILL.md +54 -72
- package/stack/skills/tdd/mocking.md +22 -47
- package/stack/skills/tdd/tests.md +42 -44
- package/stack/skills/to-prd/SKILL.md +10 -4
- package/stack/skills/work-lifecycle/references/plan-template.md +10 -0
- package/stack/system-prompt/AGENTS.md +5 -3
- package/upstreams.json +2 -1
package/README.md
CHANGED
|
@@ -8,16 +8,24 @@ Portable multi-agent harness: one configuration source — 15 agents, 17 skills,
|
|
|
8
8
|
|
|
9
9
|
Install and run via npm without cloning the repository:
|
|
10
10
|
|
|
11
|
+
```bash
|
|
12
|
+
# First installation
|
|
13
|
+
pnpm dlx jorgex-stack install
|
|
14
|
+
|
|
15
|
+
# Already installed: apply the latest published stack while keeping the existing model selection
|
|
16
|
+
pnpm dlx jorgex-stack sync
|
|
11
17
|
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
pnpm dlx jorgex-stack
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
pnpm dlx jorgex-stack
|
|
20
|
-
pnpm dlx jorgex-stack
|
|
18
|
+
|
|
19
|
+
Other important commands:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm dlx jorgex-stack doctor # check Engram, config drift, hooks and keys
|
|
23
|
+
pnpm dlx jorgex-stack models # change models by runtime, tier or subagent
|
|
24
|
+
pnpm dlx jorgex-stack update --check # report available stack, Engram and skill updates
|
|
25
|
+
pnpm dlx jorgex-stack update # interactively review and apply available updates
|
|
26
|
+
pnpm dlx jorgex-stack restore --list # list automatic backups
|
|
27
|
+
pnpm dlx jorgex-stack restore <id> # restore one backup
|
|
28
|
+
pnpm dlx jorgex-stack uninstall # remove managed files; keep Engram data intact
|
|
21
29
|
```
|
|
22
30
|
|
|
23
31
|
For development from a clone, run the same commands through `pnpm cli <command>` (see [Development](#development)).
|
package/package.json
CHANGED
|
@@ -137,14 +137,30 @@ Commit after each task or bounded group of tasks, with a message that reflects t
|
|
|
137
137
|
|
|
138
138
|
The analyst's **Recommendation** is the implementer's input. Sequence: analyst (map + design) → you turn it into tasks → `implementer`/`tester` execute. Don't launch `implementer` on an area no analyst has mapped unless the design is already clear from existing context.
|
|
139
139
|
|
|
140
|
+
### Testing decision
|
|
141
|
+
|
|
142
|
+
Every implementation task needs a testing decision, not automatically a new test. Establish:
|
|
143
|
+
|
|
144
|
+
- the meaningful regression risk introduced by the change
|
|
145
|
+
- the existing test that already protects it, if any
|
|
146
|
+
- the new or changed behavior that needs protection
|
|
147
|
+
- the strongest seam closest to that risk
|
|
148
|
+
- the action: TDD/new test, update, reuse existing coverage, or no new test with a concrete trivial/mechanical/already-covered reason
|
|
149
|
+
|
|
150
|
+
Prefer one authoritative test per behavior. Another layer is justified only when it protects a distinct contract. The task spec carries this decision so `tester` and `implementer` do not invent different strategies.
|
|
151
|
+
|
|
140
152
|
### TDD mode
|
|
141
153
|
|
|
154
|
+
Use for business rules, bugs/regressions, public contracts, invariants, security/data boundaries, or other behavior whose risk warrants new protection.
|
|
155
|
+
|
|
142
156
|
```text
|
|
143
157
|
tester (RED) → implementer (GREEN/REFACTOR)
|
|
144
158
|
```
|
|
145
159
|
|
|
146
160
|
### Direct mode
|
|
147
161
|
|
|
162
|
+
Use for styling, wiring, generated code, mechanical refactors, trivial code, or changes already covered by an authoritative test. Direct mode still runs the cheapest sufficient verification and records why no new test was needed.
|
|
163
|
+
|
|
148
164
|
```text
|
|
149
165
|
implementer (direct change)
|
|
150
166
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: test-analyzer
|
|
3
|
-
description: Read-only
|
|
3
|
+
description: Read-only risk-coverage analyst. Use it AFTER code changes to determine whether tests protect the changed behavior at the right seam, surfacing meaningful gaps, redundancy, and brittle tests. Reports analysis only — NEVER writes tests (that's the tester).
|
|
4
4
|
mode: subagent
|
|
5
5
|
tier: standard
|
|
6
6
|
readonly: true
|
|
@@ -9,90 +9,54 @@ bash: git-read
|
|
|
9
9
|
|
|
10
10
|
# Test Analyzer
|
|
11
11
|
|
|
12
|
-
You
|
|
12
|
+
You determine whether the diff has sufficient evidence for its meaningful regression risks—not whether it maximizes coverage or test count. Recommending no new tests is a valid and often correct result.
|
|
13
13
|
|
|
14
14
|
**First actions, in order**:
|
|
15
15
|
|
|
16
|
-
1. **Get the diff.** When
|
|
16
|
+
1. **Get the diff.** When given BASE and HEAD, review only `git diff <BASE>...HEAD` using exactly those branches—never assume `main`. Otherwise review the working diff (`git diff`).
|
|
17
17
|
2. Load the `agent-delegation` skill.
|
|
18
18
|
|
|
19
|
-
**Final output, last of all**:
|
|
19
|
+
**Final output, last of all**: save memory before the final report. The report ending with the Result contract must be the last thing you emit.
|
|
20
20
|
|
|
21
21
|
## Scope boundary
|
|
22
22
|
|
|
23
|
-
You are read-only
|
|
23
|
+
You are read-only. Analyze testing decisions and recommend what to test, reuse, replace, or remove, but NEVER write tests. Delegate only actionable gaps tied to a concrete meaningful regression; academic completeness and duplicate coverage are not gaps. General code quality and error handling belong to other specialists.
|
|
24
24
|
|
|
25
25
|
## 4R Reliability Lens
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
- Flag brittle or non-deterministic tests, accidental `test.only`/exclusive-focus slips, and selectors that depend on implementation instead of stable UI semantics.
|
|
29
|
-
- Call out missing negative cases, edge cases, async/concurrency behavior, and examples that document API contracts.
|
|
30
|
-
- Keep the focus on reliability evidence: if the test suite would still pass while behavior breaks, that gap matters.
|
|
27
|
+
Focus on behavioral coverage rather than line coverage.
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
1. Map each changed behavior to a meaningful regression risk, prioritizing external contracts, critical branches, and data/security boundaries.
|
|
30
|
+
2. Identify the existing test that already protects it, if any.
|
|
31
|
+
3. Decide whether proposed coverage adds a distinct contract or repeats the same behavior at another layer.
|
|
32
|
+
4. Evaluate refactor resistance, determinism, accidental `test.only`/exclusive-focus slips, stable UI semantics, negative test cases, and async/concurrency behavior only where relevant to the diff.
|
|
33
|
+
5. Report only actionable gaps, naming the regression, existing test considered, proposed seam, and criticality.
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
Prefer one authoritative test at the strongest seam closest to the risk. Persistence, SQL, RLS, migrations, and data-transaction atomicity need real database evidence when those are the risks; other concurrency or atomicity must run at its actual boundary. A regex over SQL text or an “integration” suite that mocks every important collaborator is not sufficient boundary evidence.
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
- Untested error handling paths that could cause silent failures
|
|
38
|
-
- Missing edge case coverage for boundary conditions
|
|
39
|
-
- Uncovered critical business logic branches
|
|
40
|
-
- Absent negative test cases for validation logic
|
|
41
|
-
- Missing tests for concurrent or async behavior where relevant
|
|
37
|
+
Styling, decorative DOM, wiring, aliases, wrappers, generated code, function existence, internal call choreography, and mechanical refactors do not need new tests without a meaningful behavior change. Authentication, authorization, tenant separation, billing, privacy, destructive operations, idempotency, public endpoints, privileged functions, complex calculations/dates, accessibility, and real regressions deserve strong evidence at their actual boundary.
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
- Test behavior and contracts rather than implementation details
|
|
45
|
-
- Would catch meaningful regressions from future code changes
|
|
46
|
-
- Are resilient to reasonable refactoring
|
|
47
|
-
- Follow DAMP principles (Descriptive and Meaningful Phrases) for clarity
|
|
39
|
+
## Rating guidelines
|
|
48
40
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- Consider whether existing tests might already cover the scenario
|
|
41
|
+
- **9-10**: Data loss, security issue, or system failure
|
|
42
|
+
- **7-8**: Important business logic or substantial user-facing failure
|
|
43
|
+
- **5-6**: Concrete user-facing or operational regression with moderate impact
|
|
44
|
+
- **1-4**: Do not report as a missing-test finding; mention only a brittle or redundant existing test worth removing
|
|
54
45
|
|
|
55
|
-
|
|
46
|
+
## Output format
|
|
56
47
|
|
|
57
|
-
1.
|
|
58
|
-
2.
|
|
59
|
-
3.
|
|
60
|
-
4.
|
|
61
|
-
5.
|
|
62
|
-
6. Consider integration points and their test coverage
|
|
48
|
+
1. **Summary**: Brief risk-coverage assessment
|
|
49
|
+
2. **Critical Gaps**: Risks rated 8-10 lacking sufficient evidence
|
|
50
|
+
3. **Important Improvements**: Actionable risks rated 5-7
|
|
51
|
+
4. **Test Quality Issues**: Brittle, redundant, nondeterministic, or implementation-coupled tests
|
|
52
|
+
5. **Positive Observations**: Strong existing decisions and evidence
|
|
63
53
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- 9-10: Critical functionality that could cause data loss, security issues, or system failures
|
|
67
|
-
- 7-8: Important business logic that could cause user-facing errors
|
|
68
|
-
- 5-6: Edge cases that could cause confusion or minor issues
|
|
69
|
-
- 3-4: Nice-to-have coverage for completeness
|
|
70
|
-
- 1-2: Minor improvements that are optional
|
|
71
|
-
|
|
72
|
-
**Output Format:**
|
|
73
|
-
|
|
74
|
-
1. **Summary**: Brief overview of test coverage quality
|
|
75
|
-
2. **Critical Gaps** (if any): Tests rated 8-10 that must be added
|
|
76
|
-
3. **Important Improvements** (if any): Tests rated 5-7 that should be considered
|
|
77
|
-
4. **Test Quality Issues** (if any): Tests that are brittle or overfit to implementation
|
|
78
|
-
5. **Positive Observations**: What's well-tested and follows best practices
|
|
79
|
-
|
|
80
|
-
**Important Considerations:**
|
|
81
|
-
|
|
82
|
-
- Focus on tests that prevent real bugs, not academic completeness
|
|
83
|
-
- Consider the project's testing standards and conventions
|
|
84
|
-
- Remember that some code paths may be covered by existing integration tests
|
|
85
|
-
- Avoid suggesting tests for trivial getters/setters unless they contain logic
|
|
86
|
-
- Consider the cost/benefit of each suggested test
|
|
87
|
-
- Be specific about what each test should verify and why it matters
|
|
88
|
-
- Note when tests are testing implementation rather than behavior
|
|
89
|
-
|
|
90
|
-
You are thorough but pragmatic, focusing on tests that provide real value in catching bugs and preventing regressions rather than achieving metrics. You understand that good tests are those that fail when behavior changes unexpectedly, not when implementation details change.
|
|
54
|
+
For every recommendation, state the failure it would catch, why existing protection is insufficient, and why the proposed seam is stronger than another layer.
|
|
91
55
|
|
|
92
56
|
## Result contract
|
|
93
57
|
|
|
94
58
|
End your report with exactly three lines:
|
|
95
59
|
|
|
96
60
|
- **Status**: done | partial | blocked (+ why if not done)
|
|
97
|
-
- **Delegations**: `→ [agent]: [work] — [paths] — [inputs]` per item, or "none" (
|
|
61
|
+
- **Delegations**: `→ [agent]: [work] — [paths] — [inputs]` per item, or "none" (only actionable risk gaps go here)
|
|
98
62
|
- **Risks**: what the orchestrator must know, or "none"
|
package/stack/agents/tester.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tester
|
|
3
|
-
description:
|
|
3
|
+
description: Risk-based testing specialist. Use it to decide the right testing action, write RED tests, fix tests after real contract changes, or run targeted verification. Writes tests only when they add protection; not for repository-wide coverage analysis (that's test-analyzer).
|
|
4
4
|
mode: subagent
|
|
5
5
|
tier: standard
|
|
6
6
|
readonly: false
|
|
@@ -9,61 +9,86 @@ bash: full
|
|
|
9
9
|
|
|
10
10
|
# Tester
|
|
11
11
|
|
|
12
|
-
Your job is to
|
|
12
|
+
Your job is to produce the strongest testing evidence for the risk—not to maximize test count. A valid result may add or update a test, reuse an existing test, or conclude that no new test has material value.
|
|
13
13
|
|
|
14
14
|
**Mandatory first action**: load the `tdd` and `agent-delegation` skills.
|
|
15
15
|
|
|
16
16
|
**Never run destructive git** (`reset`, `clean`, `checkout --`, `restore`, `push --force`) — it can discard work or rewrite history. Commit forward; if you think you need to discard or reset repo state, stop and ask the main agent/orchestrator.
|
|
17
17
|
|
|
18
|
-
## Before
|
|
18
|
+
## Before acting
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Detect the project's real runner, scripts, configuration, existing tests, and helpers. Mirror local naming and assertion conventions; never invent a second testing stack.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
- **Existing tests**: mirror their file location, naming, assertion style and helpers. Don't invent a stack if the repo already has one.
|
|
22
|
+
Make one explicit testing decision:
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
1. **Risk** — what meaningful regression could this change introduce?
|
|
25
|
+
2. **Existing protection** — which existing test already catches it?
|
|
26
|
+
3. **New behavior** — what changed behavior or real regression needs protection?
|
|
27
|
+
4. **Seam** — which focused unit, component, database, integration, contract, or end-to-end test is closest to that failure mode?
|
|
28
|
+
5. **Action** — add, update, reuse, or no new test. Explain why.
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
If task-critical uncertainty could make the decision wrong, verify narrowly and follow `agent-delegation`: do the safe part when clear, then route one concrete question to the main agent/orchestrator instead of improvising.
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
+
## Modes
|
|
33
|
+
|
|
34
|
+
- **DECIDE**: determine the appropriate testing action. Do not write a test merely to have a file change.
|
|
35
|
+
- **RED**: write one authoritative test that fails for the intended behavioral reason.
|
|
36
|
+
- **FIX**: update tests broken by a real contract change; do not rewrite them to hide a product regression.
|
|
37
|
+
- **VERIFY**: run the cheapest relevant existing test or check, even when its file was not modified.
|
|
38
|
+
|
|
39
|
+
Repository-wide coverage analysis and suite-cleanup strategy remain `test-analyzer` work. Removing an obviously redundant test is allowed only when the task explicitly includes that cleanup and a stronger test demonstrably protects the same behavior.
|
|
32
40
|
|
|
33
41
|
## Test quality
|
|
34
42
|
|
|
35
|
-
- Verify behavior
|
|
36
|
-
-
|
|
43
|
+
- Verify behavior or a real boundary contract, not implementation details.
|
|
44
|
+
- Prefer one authoritative test at the seam closest to the risk.
|
|
45
|
+
- Add another layer only when it protects a distinct contract.
|
|
46
|
+
- Do not assert Tailwind classes, decorative DOM, trivial wrappers/aliases/constants/callbacks, function existence, or exact internal mock choreography unless that detail is itself public behavior.
|
|
47
|
+
- Persistence, SQL, RLS, migrations, and data-transaction atomicity require execution at a real database boundary when that is the risk; regex-only SQL checks are not sufficient evidence. Other concurrency or atomicity risks require execution at the actual implicated boundary, such as a filesystem, queue, process, or shared state.
|
|
48
|
+
- A test must fail for the right reason: behavior missing or broken, not invalid setup, stale mocks, or fixture noise.
|
|
49
|
+
|
|
50
|
+
## Valid no-new-test decisions
|
|
51
|
+
|
|
52
|
+
`no new test` is valid when the change is trivial, styling-only, wiring-only, generated, mechanical, or already protected by an authoritative test. Name the existing evidence or explain why no meaningful behavioral branch exists. “Small change” by itself is not a reason.
|
|
37
53
|
|
|
38
54
|
## Strict DONE
|
|
39
55
|
|
|
40
56
|
You are only done when:
|
|
41
57
|
|
|
42
|
-
1.
|
|
43
|
-
2. You have
|
|
44
|
-
3. You have
|
|
45
|
-
4. You have
|
|
58
|
+
1. The testing decision is explicit and tied to a concrete risk.
|
|
59
|
+
2. You have added/fixed the relevant test, identified sufficient existing coverage, or justified no new test.
|
|
60
|
+
3. You have run the narrowest useful verification for RED/FIX/VERIFY when execution is possible, and confirmed it fails or passes for the right reason.
|
|
61
|
+
4. You have saved anything that belongs in memory (if applicable, using the topic_key the orchestrator gave you) — this happens BEFORE the final report.
|
|
62
|
+
5. You have reported the decision and evidence, ending with the Result contract. Nothing after it.
|
|
46
63
|
|
|
47
|
-
##
|
|
64
|
+
## Targeted execution
|
|
48
65
|
|
|
49
|
-
Never run the full suite
|
|
66
|
+
Never run the full suite by default. Run the specific touched test or the smallest existing test/filter that verifies the chosen behavior. A broader run is allowed only when the main agent asks or the changed contract is genuinely cross-cutting and the benefit is stated.
|
|
50
67
|
|
|
51
68
|
## Rules
|
|
52
69
|
|
|
53
70
|
- Don't implement production code.
|
|
54
|
-
- If code is missing to reach GREEN,
|
|
55
|
-
-
|
|
56
|
-
- If you extract logic into a pure function to make it testable, production must consume that function in the
|
|
57
|
-
- Tests must never write outside temp directories: no real HOME,
|
|
71
|
+
- If code is missing to reach GREEN, report it as a delegation to `implementer`.
|
|
72
|
+
- Do not add a dependency or new test framework without explicit approval.
|
|
73
|
+
- If you extract logic into a pure function to make it testable, production must consume that function in the same change. If wiring it exceeds your lane, delegate it to `implementer`; a tested copy outside the shipped path is false coverage.
|
|
74
|
+
- Tests must never write outside temp directories: no real HOME, config, or project data directories. Inject a fixture/temp path when the code defaults to a real location.
|
|
58
75
|
|
|
59
76
|
## Output format
|
|
60
77
|
|
|
61
78
|
```markdown
|
|
62
|
-
##
|
|
79
|
+
## Testing decision
|
|
80
|
+
|
|
81
|
+
**Risk:** [meaningful regression]
|
|
82
|
+
**Existing protection:** [test/evidence, or none]
|
|
83
|
+
**New behavior:** [behavior needing protection, or none]
|
|
84
|
+
**Chosen seam:** [test level and why it is closest to the risk]
|
|
85
|
+
**Action:** [add | update | reuse | no new test] — [reason]
|
|
86
|
+
|
|
87
|
+
## Evidence
|
|
63
88
|
|
|
64
|
-
**Files:** [tests created or
|
|
65
|
-
**Ran:** [exact command
|
|
66
|
-
**Result:** [RED/GREEN, and why
|
|
89
|
+
**Files:** [tests created/modified, or none]
|
|
90
|
+
**Ran:** [exact targeted command/filter, or why execution was unnecessary/impossible]
|
|
91
|
+
**Result:** [RED/GREEN/no-new-test, and why the evidence is sufficient]
|
|
67
92
|
```
|
|
68
93
|
|
|
69
94
|
## Result contract
|
|
@@ -23,7 +23,7 @@ Importante sobre el mecanismo:
|
|
|
23
23
|
| Agente | Scope | Delega aquí cuando aparezca... |
|
|
24
24
|
|---|---|---|
|
|
25
25
|
| `implementer` | escribe código de producción | falta código para que algo funcione; hay que implementar el cambio real |
|
|
26
|
-
| `tester` | escribe/ejecuta tests |
|
|
26
|
+
| `tester` | decide/escribe/ejecuta tests según riesgo | hay que decidir la protección adecuada, falta un test valioso, hay tests rotos por un cambio de contrato, o hay que verificar comportamiento |
|
|
27
27
|
| `translator` | traducciones, locales, multiidioma | strings hardcodeadas visibles, locales desincronizados, copy en varios idiomas |
|
|
28
28
|
| `docs-maintainer` | documentación (/docs y docs site público) | el cambio deja docs desactualizadas o requiere nueva documentación |
|
|
29
29
|
| `backend-analyst` | análisis backend (read-only) | hace falta mapear servicios, DB, APIs o riesgos backend antes de actuar |
|
|
@@ -54,7 +54,7 @@ Una línea por delegación, al final de tu output:
|
|
|
54
54
|
- `tester` detecta que falta código de producción → `implementer`
|
|
55
55
|
- cualquier agente detecta auth, permisos o datos sensibles → `security-auditor`
|
|
56
56
|
- cualquier agente detecta cambio documental relevante → `docs-maintainer`
|
|
57
|
-
- `test-analyzer` detecta
|
|
57
|
+
- `test-analyzer` detecta un gap de riesgo concreto → `tester` (que decide si añade, actualiza o reutiliza cobertura)
|
|
58
58
|
|
|
59
59
|
## Regla de conflicto
|
|
60
60
|
|
|
@@ -1,109 +1,91 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tdd
|
|
3
|
-
description:
|
|
3
|
+
description: Risk-based test-driven development with a red-green-refactor loop. Use for business rules, bugs/regressions, public contracts, invariants, or explicit test-first work; not automatically for styles, wiring, or mechanical changes.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Test-Driven Development
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Core principle
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Tests protect behavior and risk, not files, layers, or coverage percentages. A change needs a **testing decision**, not automatically a new test.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
For every change, establish:
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
1. **Risk** — what meaningful failure could this change introduce?
|
|
15
|
+
2. **Existing protection** — which existing test already catches it, if any?
|
|
16
|
+
3. **New behavior** — what changed contract or regression needs new protection?
|
|
17
|
+
4. **Seam** — what is the strongest test closest to that risk?
|
|
18
|
+
5. **Decision** — add/update a test, reuse existing coverage, or add no test with a concrete reason.
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
One behavior should normally have one authoritative test. Test it again at another layer only when that layer protects a distinct contract.
|
|
17
21
|
|
|
18
|
-
|
|
22
|
+
See [tests.md](tests.md) for examples and [mocking.md](mocking.md) for boundary-double guidance.
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
## When to use TDD
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
Use red-green-refactor when the change defines or repairs:
|
|
23
27
|
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
+
- Business rules, calculations, validation, dates, or time zones
|
|
29
|
+
- A real bug/regression
|
|
30
|
+
- Public API, event, schema, or protocol contracts
|
|
31
|
+
- Authentication, authorization, RLS, tenant separation, billing, privacy, or data integrity
|
|
32
|
+
- Destructive, concurrent, atomic, or idempotent behavior
|
|
33
|
+
- Important accessibility or user interactions
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
Do not impose TDD merely because a file changed. Styling, decorative DOM, wiring, aliases, wrappers, generated code, mechanical refactors, and trivial callbacks usually need existing verification or no new test unless they change meaningful behavior.
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
WRONG (horizontal):
|
|
33
|
-
RED: test1, test2, test3, test4, test5
|
|
34
|
-
GREEN: impl1, impl2, impl3, impl4, impl5
|
|
35
|
-
|
|
36
|
-
RIGHT (vertical):
|
|
37
|
-
RED→GREEN: test1→impl1
|
|
38
|
-
RED→GREEN: test2→impl2
|
|
39
|
-
RED→GREEN: test3→impl3
|
|
40
|
-
...
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Workflow
|
|
37
|
+
## Choose the seam from the risk
|
|
44
38
|
|
|
45
|
-
|
|
39
|
+
Use the cheapest seam that can fail for the real regression:
|
|
46
40
|
|
|
47
|
-
|
|
41
|
+
- Pure rule or calculation → focused unit/module test
|
|
42
|
+
- Component interaction or accessibility contract → component/browser test through stable semantics
|
|
43
|
+
- Persistence, SQL, RLS, migration, or data-transaction atomicity → real database/integration test
|
|
44
|
+
- Other concurrency or atomicity → execute at the implicated filesystem, queue, process, or shared-state boundary
|
|
45
|
+
- Public endpoint or privileged function → contract/integration test at that boundary
|
|
46
|
+
- Critical cross-system user journey → end-to-end test
|
|
48
47
|
|
|
49
|
-
|
|
48
|
+
“Integration-style” is not inherently stronger. A broad test full of mocks may be weaker than a focused rule test, while a regex over SQL text is weaker than executing the database behavior it claims to protect.
|
|
50
49
|
|
|
51
|
-
-
|
|
52
|
-
- [ ] Confirm with user which behaviors to test (prioritize)
|
|
53
|
-
- [ ] Identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation)
|
|
54
|
-
- [ ] Design interfaces for [testability](interface-design.md)
|
|
55
|
-
- [ ] List the behaviors to test (not implementation steps)
|
|
56
|
-
- [ ] Get user approval on the plan
|
|
50
|
+
## Anti-pattern: horizontal slices
|
|
57
51
|
|
|
58
|
-
|
|
52
|
+
Do not write all tests first and then all implementation. This outruns what has been learned and encourages tests of imagined shapes.
|
|
59
53
|
|
|
60
|
-
|
|
54
|
+
Use vertical tracer bullets for each behavior that merits new protection:
|
|
61
55
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
RED: Write test for first behavior → test fails
|
|
68
|
-
GREEN: Write minimal code to pass → test passes
|
|
56
|
+
```text
|
|
57
|
+
RED → one test fails for the intended behavioral reason
|
|
58
|
+
GREEN → minimal production change makes it pass
|
|
59
|
+
REFACTOR → improve structure while behavior stays green
|
|
69
60
|
```
|
|
70
61
|
|
|
71
|
-
|
|
62
|
+
Then repeat for the next distinct behavior. Do not create separate tests merely to split assertions that describe one coherent outcome.
|
|
72
63
|
|
|
73
|
-
|
|
64
|
+
## Workflow
|
|
74
65
|
|
|
75
|
-
|
|
66
|
+
### 1. Make the testing decision
|
|
76
67
|
|
|
77
|
-
|
|
78
|
-
RED: Write next test → fails
|
|
79
|
-
GREEN: Minimal code to pass → passes
|
|
80
|
-
```
|
|
68
|
+
Complete the five-part decision under **Core principle**. If no new protection is warranted, record the reason and run the cheapest sufficient verification; otherwise continue to RED.
|
|
81
69
|
|
|
82
|
-
|
|
70
|
+
### 2. RED, when new protection is warranted
|
|
83
71
|
|
|
84
|
-
|
|
85
|
-
- Only enough code to pass current test
|
|
86
|
-
- Don't anticipate future tests
|
|
87
|
-
- Keep tests focused on observable behavior
|
|
72
|
+
Write one test that fails because the behavior is missing or broken—not because setup, mocks, or fixtures are wrong.
|
|
88
73
|
|
|
89
|
-
###
|
|
74
|
+
### 3. GREEN
|
|
90
75
|
|
|
91
|
-
|
|
76
|
+
Write only enough production code to satisfy the behavior. Do not anticipate speculative cases.
|
|
92
77
|
|
|
93
|
-
|
|
94
|
-
- [ ] Deepen modules (move complexity behind simple interfaces)
|
|
95
|
-
- [ ] Apply SOLID principles where natural
|
|
96
|
-
- [ ] Consider what new code reveals about existing code
|
|
97
|
-
- [ ] Run tests after each refactor step
|
|
78
|
+
### 4. Refactor
|
|
98
79
|
|
|
99
|
-
|
|
80
|
+
Refactor only while green. Remove duplication in production and tests, and delete lower-value tests when a stronger test now protects the same behavior.
|
|
100
81
|
|
|
101
|
-
## Checklist
|
|
82
|
+
## Checklist
|
|
102
83
|
|
|
103
|
-
```
|
|
104
|
-
[ ]
|
|
105
|
-
[ ]
|
|
106
|
-
[ ]
|
|
107
|
-
[ ]
|
|
108
|
-
[ ] No
|
|
84
|
+
```text
|
|
85
|
+
[ ] When new protection is warranted, RED fails for the intended behavioral reason
|
|
86
|
+
[ ] The chosen seam observes behavior or the real boundary at risk
|
|
87
|
+
[ ] Another layer would protect a distinct contract, not duplicate this one
|
|
88
|
+
[ ] Mocks do not encode internal call choreography
|
|
89
|
+
[ ] No-test decisions have a concrete trivial/mechanical/already-covered reason
|
|
90
|
+
[ ] Production code is minimal and non-speculative
|
|
109
91
|
```
|
|
@@ -1,59 +1,34 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Boundary Doubles and Mocks
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Mocks are a cost/risk tradeoff, not a goal or a categorical ban.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- Databases (sometimes - prefer test DB)
|
|
7
|
-
- Time/randomness
|
|
8
|
-
- File system (sometimes)
|
|
5
|
+
## Prefer real behavior when practical
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
Use real owned code when it is fast, deterministic, safe, and easy to set up. Mocking internal collaborators just to assert call choreography couples the test to implementation and can let broken behavior pass.
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
- Internal collaborators
|
|
14
|
-
- Anything you control
|
|
9
|
+
Prefer real test infrastructure when the risk lives there:
|
|
15
10
|
|
|
16
|
-
|
|
11
|
+
- RLS, SQL, migrations, transactions, and data-transaction atomicity → test database
|
|
12
|
+
- Other concurrency or atomicity → the actual filesystem, queue, process, or shared-state boundary
|
|
13
|
+
- Filesystem semantics → isolated temp directory
|
|
14
|
+
- Serialization/protocol parsing → real encoder/decoder
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
## Use a boundary double when it is the reliable seam
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
A fake, stub, or mock is appropriate for a boundary that is unavailable, expensive, nondeterministic, destructive, or controlled by a third party:
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
- Payment, email, identity, or other external APIs
|
|
21
|
+
- Time, randomness, process execution, or network failures
|
|
22
|
+
- A slow service when its protocol—not its implementation—is the contract under test
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
// Easy to mock
|
|
26
|
-
function processPayment(order, paymentClient) {
|
|
27
|
-
return paymentClient.charge(order.total);
|
|
28
|
-
}
|
|
24
|
+
Assert only the boundary contract needed by the behavior: payload, headers, idempotency key, returned error mapping, or observable result. Avoid exhaustive call counts and ordering unless the external protocol requires them.
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
function processPayment(order) {
|
|
32
|
-
const client = new StripeClient(process.env.STRIPE_KEY);
|
|
33
|
-
return client.charge(order.total);
|
|
34
|
-
}
|
|
35
|
-
```
|
|
26
|
+
## Keep doubles simple
|
|
36
27
|
|
|
37
|
-
|
|
28
|
+
- Inject the narrow boundary instead of mocking a large internal module graph.
|
|
29
|
+
- Return one explicit shape per scenario.
|
|
30
|
+
- Do not rebuild production branching logic inside the mock.
|
|
31
|
+
- If every important collaborator is mocked, do not call the suite integration testing.
|
|
32
|
+
- Prefer a reusable fake only after repeated real need; do not create abstraction for a single test.
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
// GOOD: Each function is independently mockable
|
|
43
|
-
const api = {
|
|
44
|
-
getUser: (id) => fetch(`/users/${id}`),
|
|
45
|
-
getOrders: (userId) => fetch(`/users/${userId}/orders`),
|
|
46
|
-
createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// BAD: Mocking requires conditional logic inside the mock
|
|
50
|
-
const api = {
|
|
51
|
-
fetch: (endpoint, options) => fetch(endpoint, options),
|
|
52
|
-
};
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
The SDK approach means:
|
|
56
|
-
- Each mock returns one specific shape
|
|
57
|
-
- No conditional logic in test setup
|
|
58
|
-
- Easier to see which endpoints a test exercises
|
|
59
|
-
- Type safety per endpoint
|
|
34
|
+
The question is not “can this be mocked?” It is “which setup gives the strongest evidence for this risk at acceptable cost?”
|
|
@@ -1,61 +1,59 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Choosing Valuable Tests
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## One behavior, one authoritative seam
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Choose the seam from the regression you need to catch.
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
|
-
//
|
|
9
|
-
test("
|
|
10
|
-
|
|
11
|
-
cart.add(product);
|
|
12
|
-
const result = await checkout(cart, paymentMethod);
|
|
13
|
-
expect(result.status).toBe("confirmed");
|
|
8
|
+
// Pure pricing rule: a focused module test is closest to the risk.
|
|
9
|
+
test("applies the reduced tax rate to eligible items", () => {
|
|
10
|
+
expect(calculateTax(eligibleItem)).toBe(4.2);
|
|
14
11
|
});
|
|
15
12
|
```
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
```typescript
|
|
15
|
+
// User interaction: verify the accessible outcome, not DOM decoration.
|
|
16
|
+
test("submits a valid checkout", async () => {
|
|
17
|
+
await user.click(screen.getByRole("button", { name: "Pay" }));
|
|
18
|
+
expect(await screen.findByText("Payment confirmed")).toBeVisible();
|
|
19
|
+
});
|
|
20
|
+
```
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- One logical assertion per test
|
|
22
|
+
```sql
|
|
23
|
+
-- Tenant isolation: execute against a real test database with two users.
|
|
24
|
+
-- Regex matching a CREATE POLICY statement does not prove RLS behavior.
|
|
25
|
+
```
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
Characteristics of valuable tests:
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
- Catch a concrete user, business, security, data, or contract regression
|
|
30
|
+
- Observe a public interface or the real boundary at risk
|
|
31
|
+
- Survive an internal refactor
|
|
32
|
+
- Use the narrowest reliable setup
|
|
33
|
+
- Add a second layer only for a different contract
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
// BAD: Tests implementation details
|
|
31
|
-
test("checkout calls paymentService.process", async () => {
|
|
32
|
-
const mockPayment = jest.mock(paymentService);
|
|
33
|
-
await checkout(cart, payment);
|
|
34
|
-
expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
|
|
35
|
-
});
|
|
36
|
-
```
|
|
35
|
+
## Low-value and redundant tests
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
Avoid tests whose only purpose is to assert:
|
|
39
38
|
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
39
|
+
- Tailwind classes, decorative DOM, or incidental markup
|
|
40
|
+
- That a wrapper, alias, constant, callback, or function exists
|
|
41
|
+
- Exact internal call counts/order when the observable result is what matters
|
|
42
|
+
- The same behavior already protected at a stronger seam
|
|
43
|
+
- SQL policy or migration correctness exclusively through text/regex shape
|
|
44
|
+
- “Integration” while every important collaborator is mocked
|
|
46
45
|
|
|
47
46
|
```typescript
|
|
48
|
-
// BAD:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
|
|
52
|
-
expect(row).toBeDefined();
|
|
53
|
-
});
|
|
47
|
+
// BAD: locks internal choreography.
|
|
48
|
+
expect(paymentService.charge).toHaveBeenCalledTimes(1);
|
|
49
|
+
expect(emailService.send).toHaveBeenCalledAfter(paymentService.charge);
|
|
54
50
|
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
const user = await createUser({ name: "Alice" });
|
|
58
|
-
const retrieved = await getUser(user.id);
|
|
59
|
-
expect(retrieved.name).toBe("Alice");
|
|
60
|
-
});
|
|
51
|
+
// BETTER: assert the contract callers rely on.
|
|
52
|
+
expect(result).toMatchObject({ status: "confirmed", receiptId: expect.any(String) });
|
|
61
53
|
```
|
|
54
|
+
|
|
55
|
+
Exact calls are valid only when the call itself is the external contract—for example, the precise payload sent to a payment provider or an idempotency key required by its protocol.
|
|
56
|
+
|
|
57
|
+
## Valid no-new-test decisions
|
|
58
|
+
|
|
59
|
+
A change may need no new test when it is styling-only, mechanical, generated, already covered by an authoritative test, or has no meaningful behavioral branch. State the reason and run the cheapest existing verification that could catch an accidental break.
|
|
@@ -9,7 +9,9 @@ This skill takes the current conversation context and codebase understanding and
|
|
|
9
9
|
|
|
10
10
|
1. Explore the repo to understand the current state of the codebase, if you haven't already. Use the project's domain glossary vocabulary throughout the PRD, and respect any ADRs in the area you're touching.
|
|
11
11
|
|
|
12
|
-
2. Sketch out the seams at which you're going to test the feature.
|
|
12
|
+
2. Sketch out the seams at which you're going to test the feature. Prefer an existing seam when it is strong enough, and choose the closest seam that can fail for the concrete regression risk. Introduce a new seam only when existing ones cannot provide reliable evidence.
|
|
13
|
+
|
|
14
|
+
Do not choose from a fixed test pyramid or a requirement to add tests. Prefer one authoritative test at the strongest seam closest to the risk; another layer is justified only for a distinct contract. Record existing coverage and valid no-new-test decisions for trivial, mechanical, generated, styling, or wiring changes.
|
|
13
15
|
|
|
14
16
|
Check with the user that these seams match their expectations.
|
|
15
17
|
|
|
@@ -67,9 +69,13 @@ Keep this static: describe the planned delivery slices, not the current state.
|
|
|
67
69
|
|
|
68
70
|
A list of testing decisions that were made. Include:
|
|
69
71
|
|
|
70
|
-
-
|
|
71
|
-
- Which
|
|
72
|
-
-
|
|
72
|
+
- The meaningful regression risk introduced by each behavior change
|
|
73
|
+
- Which existing tests already protect it
|
|
74
|
+
- Which new behavior requires protection
|
|
75
|
+
- The chosen seam and why it is closest to the risk
|
|
76
|
+
- Why another layer would protect a distinct contract rather than duplicate the same behavior
|
|
77
|
+
- Why no new test is needed for trivial, mechanical, generated, styling, wiring, or already-covered changes
|
|
78
|
+
- Prior art for the selected tests (i.e. similar valuable tests in the codebase)
|
|
73
79
|
|
|
74
80
|
## Out of Scope
|
|
75
81
|
|
|
@@ -146,6 +146,16 @@ Status, wave and dependencies live in the plan.md table (single home) — do NOT
|
|
|
146
146
|
|
|
147
147
|
- [Rule]
|
|
148
148
|
|
|
149
|
+
## Testing decision
|
|
150
|
+
|
|
151
|
+
- **Risk**: [meaningful regression this task can introduce]
|
|
152
|
+
- **Existing protection**: [specific existing test/evidence, or none]
|
|
153
|
+
- **New behavior**: [behavior needing new protection, or none]
|
|
154
|
+
- **Chosen seam**: [unit/component/database/integration/contract/e2e and why it is closest to the risk]
|
|
155
|
+
- **Action**: [add | update | reuse | no new test] — [concrete reason]
|
|
156
|
+
|
|
157
|
+
Prefer one authoritative test per behavior. Another layer is justified only when it protects a distinct contract. Styling, wiring, generated code, mechanical refactors, and trivial changes may use `no new test`; business rules, bugs/regressions, public contracts, and invariants should normally use TDD.
|
|
158
|
+
|
|
149
159
|
## Acceptance criteria
|
|
150
160
|
|
|
151
161
|
[VERIFIABLE and SPECIFIC criteria — not generic. Each must be checkable manually or automatically.]
|
|
@@ -110,9 +110,11 @@ Every piece of information about a piece of work has exactly ONE home — never
|
|
|
110
110
|
|
|
111
111
|
## Testing and Verification
|
|
112
112
|
|
|
113
|
-
- When the project has tests or the change affects behavior,
|
|
114
|
-
-
|
|
115
|
-
- Use
|
|
113
|
+
- When the project has tests or the change affects behavior, verification is mandatory. A new test is not.
|
|
114
|
+
- Make one explicit testing decision per change: what risk it introduces, what existing test already covers it, what new behavior needs protection, and why no new test is needed when the change is trivial, mechanical, or already covered.
|
|
115
|
+
- Use TDD for business rules, bugs/regressions, public contracts, and invariants. Do not impose it on styling, wiring, generated code, mechanical refactors, or trivial code unless they change meaningful behavior.
|
|
116
|
+
- Prefer one authoritative test at the strongest seam closest to the risk. Add coverage at another layer only when it protects a distinct contract, not to repeat the same behavior.
|
|
117
|
+
- Use the `tdd` skill for red-green-refactor, test-first work, or risk-based behavior testing.
|
|
116
118
|
- Prefer targeted verification before broad suites.
|
|
117
119
|
- Default order: specific test > partial suite > full suite.
|
|
118
120
|
- Use the real test commands and test stack of the project.
|
package/upstreams.json
CHANGED
|
@@ -74,7 +74,8 @@
|
|
|
74
74
|
"tdd": {
|
|
75
75
|
"source": "github:mattpocock/skills",
|
|
76
76
|
"path": "skills/engineering/tdd",
|
|
77
|
-
"commit": "694fa30311e02c2639942308513555e61ee84a6f"
|
|
77
|
+
"commit": "694fa30311e02c2639942308513555e61ee84a6f",
|
|
78
|
+
"modified": true
|
|
78
79
|
},
|
|
79
80
|
"to-issues": {
|
|
80
81
|
"source": "github:mattpocock/skills",
|