prizmkit 1.1.85 → 1.1.87
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/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +462 -4
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +14 -0
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +18 -3
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +18 -3
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +2 -2
- package/bundled/dev-pipeline/templates/sections/phase-commit.md +2 -2
- package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +260 -0
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +5 -1
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +5 -1
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +429 -0
- package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +462 -4
- package/bundled/dev-pipeline-windows/templates/bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +14 -0
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +18 -3
- package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +18 -3
- package/bundled/dev-pipeline-windows/templates/sections/phase-commit-full.md +2 -2
- package/bundled/dev-pipeline-windows/templates/sections/phase-commit.md +2 -2
- package/bundled/dev-pipeline-windows/templates/sections/phase-prizmkit-test.md +186 -0
- package/bundled/dev-pipeline-windows/templates/sections/phase-review-agent.md +5 -1
- package/bundled/dev-pipeline-windows/templates/sections/phase-review-full.md +5 -1
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/prizmkit-code-review/SKILL.md +7 -2
- package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +6 -2
- package/bundled/skills/prizmkit-test/SKILL.md +107 -13
- package/bundled/skills/prizmkit-test/references/boundary-coverage-protocol.md +220 -0
- package/bundled/skills/prizmkit-test/references/examples.md +82 -9
- package/bundled/skills/prizmkit-test/references/service-boundary-test-catalog.md +225 -0
- package/bundled/skills/prizmkit-test/references/test-generation-steps.md +74 -14
- package/bundled/skills/prizmkit-test/references/test-report-template.md +74 -5
- package/bundled/skills/prizmkit-test/scripts/validate_boundary_report.py +347 -0
- package/bundled/skills-windows/prizmkit-code-review/SKILL.md +7 -2
- package/bundled/skills-windows/prizmkit-code-review/references/reviewer-agent-prompt.md +6 -2
- package/bundled/skills-windows/prizmkit-test/SKILL.md +107 -13
- package/bundled/skills-windows/prizmkit-test/references/boundary-coverage-protocol.md +220 -0
- package/bundled/skills-windows/prizmkit-test/references/examples.md +82 -9
- package/bundled/skills-windows/prizmkit-test/references/service-boundary-test-catalog.md +225 -0
- package/bundled/skills-windows/prizmkit-test/references/test-generation-steps.md +74 -14
- package/bundled/skills-windows/prizmkit-test/references/test-report-template.md +74 -5
- package/bundled/skills-windows/prizmkit-test/scripts/validate_boundary_report.py +347 -0
- package/package.json +1 -1
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Boundary Coverage Protocol
|
|
2
|
+
|
|
3
|
+
Use this protocol during `/prizmkit-test` Phase 4 and update it during Phase 5. The goal is to prevent a common false positive: treating "there is a test for this interface" as equivalent to "this interface is safely covered." A happy path proves that the interface can work once; boundary tests prove that the interface handles realistic invalid inputs, authorization failures, ownership rules, state transitions, and dependency failures.
|
|
4
|
+
|
|
5
|
+
## Required Boundary Matrix
|
|
6
|
+
|
|
7
|
+
Build this matrix before writing tests and update it after generated tests pass or produce `needs-review` findings. In `scope=this-change`, build the matrix only for in-scope feature interfaces/endpoints; unrelated interfaces are recorded under `Out of Scope Gaps` and do not trigger generated tests.
|
|
8
|
+
|
|
9
|
+
| Module | Interface | Service Type | Happy Path | Request Validation | Auth / Permission / Ownership | Domain Invariants | Collection / Pagination | Date / Time | State Transitions | Dependency Failure | Response Contract | N/A Reasons | Final Status |
|
|
10
|
+
|--------|-----------|--------------|------------|--------------------|-------------------------------|-------------------|-------------------------|-------------|-------------------|-------------------|-------------------|-------------|--------------|
|
|
11
|
+
| auth | POST /auth/login | Auth / Session | covered | generated | N/A — public route | generated | N/A — no collection input | N/A — no date input | covered | skipped — password hasher not injectable | covered | ... | boundary-covered |
|
|
12
|
+
|
|
13
|
+
## Status Values
|
|
14
|
+
|
|
15
|
+
Use these values consistently:
|
|
16
|
+
|
|
17
|
+
- `covered` — an existing test already asserts this behavior.
|
|
18
|
+
- `generated` — this run generated a test and the test passed.
|
|
19
|
+
- `needs-review` — a generated test is valid, but production behavior mismatched the expected contract.
|
|
20
|
+
- `unresolved` — the test could not be made runnable after the allowed fix attempts.
|
|
21
|
+
- `skipped` — not applicable or not practical in this run, with a concrete reason in `N/A Reasons`.
|
|
22
|
+
- `boundary-missing` — applicable boundary exists but no test covers it yet.
|
|
23
|
+
|
|
24
|
+
## Completion Gate
|
|
25
|
+
|
|
26
|
+
An in-scope interface is complete only when:
|
|
27
|
+
|
|
28
|
+
1. It has happy-path coverage when a happy path exists.
|
|
29
|
+
2. Every applicable boundary category is `covered`, `generated`, or `needs-review`.
|
|
30
|
+
3. Every non-applicable category has a concrete reason.
|
|
31
|
+
4. No applicable category remains `boundary-missing`.
|
|
32
|
+
5. The final status is one of:
|
|
33
|
+
- `boundary-covered`
|
|
34
|
+
- `generated-needs-review`
|
|
35
|
+
- `skipped-with-reason`
|
|
36
|
+
|
|
37
|
+
If an interface has only happy-path coverage, set `Final Status` to `boundary-missing` and continue generating applicable boundary tests. Do not call the run complete while any in-scope interface is `boundary-missing` or `happy-path-only`.
|
|
38
|
+
|
|
39
|
+
## How to Decide Whether Existing Tests Count
|
|
40
|
+
|
|
41
|
+
An existing test counts for a boundary category only when it:
|
|
42
|
+
|
|
43
|
+
- targets the same public interface or endpoint,
|
|
44
|
+
- creates the boundary input, state, dependency failure, or authorization context,
|
|
45
|
+
- asserts the expected error code, exception, state change, response shape, or side effect,
|
|
46
|
+
- verifies behavior rather than only checking that the call returned a response.
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
|
|
50
|
+
- `POST /users/create` returns HTTP 200 with non-empty data → happy path only.
|
|
51
|
+
- `POST /users/create` with missing email asserts `code=10001` → request validation boundary.
|
|
52
|
+
- `POST /items/delete` with another user's item asserts forbidden/not-found code → ownership boundary.
|
|
53
|
+
- Service create method with mocked repository failure asserts no partial side effect → dependency failure boundary.
|
|
54
|
+
|
|
55
|
+
## Boundary Categories
|
|
56
|
+
|
|
57
|
+
### Request Validation
|
|
58
|
+
|
|
59
|
+
Use when the interface accepts client input or public parameters.
|
|
60
|
+
|
|
61
|
+
Generate applicable cases for:
|
|
62
|
+
- missing required fields,
|
|
63
|
+
- empty string / empty array / empty object,
|
|
64
|
+
- malformed JSON or wrong content type when the framework exposes that behavior,
|
|
65
|
+
- wrong type,
|
|
66
|
+
- unsupported enum,
|
|
67
|
+
- invalid numeric values: zero, negative, min/max, just above max,
|
|
68
|
+
- invalid string format: URL, email, phone, date, timestamp, UUID/ULID, object key.
|
|
69
|
+
|
|
70
|
+
### Auth / Permission / Ownership
|
|
71
|
+
|
|
72
|
+
Use when the interface depends on identity, roles, tenant, ownership, entitlement, or token state.
|
|
73
|
+
|
|
74
|
+
Generate applicable cases for:
|
|
75
|
+
- missing auth,
|
|
76
|
+
- malformed auth header,
|
|
77
|
+
- invalid/expired/revoked token,
|
|
78
|
+
- authenticated user accessing another user's resource,
|
|
79
|
+
- missing role/permission/entitlement,
|
|
80
|
+
- default-deny when ownership cannot be proven.
|
|
81
|
+
|
|
82
|
+
### Domain Invariants
|
|
83
|
+
|
|
84
|
+
Use when business rules constrain combinations of fields or state.
|
|
85
|
+
|
|
86
|
+
Generate applicable cases for:
|
|
87
|
+
- ratios or totals that must sum to a value,
|
|
88
|
+
- start date before end date,
|
|
89
|
+
- calorie/weight/amount ranges,
|
|
90
|
+
- unsupported lifecycle status,
|
|
91
|
+
- duplicate unique identifiers,
|
|
92
|
+
- device binding requirements,
|
|
93
|
+
- token rotation/reuse semantics,
|
|
94
|
+
- image quality / provider classification rules,
|
|
95
|
+
- product-specific thresholds such as 90%-110% calorie hit boundaries.
|
|
96
|
+
|
|
97
|
+
### Collection / Pagination
|
|
98
|
+
|
|
99
|
+
Use when the interface accepts or returns lists, pages, filters, or cursors.
|
|
100
|
+
|
|
101
|
+
Generate applicable cases for:
|
|
102
|
+
- empty result,
|
|
103
|
+
- one item,
|
|
104
|
+
- many items,
|
|
105
|
+
- duplicate IDs,
|
|
106
|
+
- omitted page / page size defaults,
|
|
107
|
+
- page 0, negative page, max page size, max + 1,
|
|
108
|
+
- invalid filters,
|
|
109
|
+
- nullable filters such as true/false/null,
|
|
110
|
+
- stable ordering or total count when specified.
|
|
111
|
+
|
|
112
|
+
### Date / Time
|
|
113
|
+
|
|
114
|
+
Use when the interface parses, stores, filters, expires, schedules, or compares time.
|
|
115
|
+
|
|
116
|
+
Generate applicable cases for:
|
|
117
|
+
- invalid date / timestamp format,
|
|
118
|
+
- timezone assumptions,
|
|
119
|
+
- inclusive vs exclusive date range boundaries,
|
|
120
|
+
- start after end,
|
|
121
|
+
- exact expiry instant and just before/after expiry,
|
|
122
|
+
- today/yesterday/stale streak or schedule semantics,
|
|
123
|
+
- leap day/month end when relevant.
|
|
124
|
+
|
|
125
|
+
### State Transitions
|
|
126
|
+
|
|
127
|
+
Use when the interface creates, updates, deletes, confirms, unbinds, retries, logs out, refreshes, or changes status.
|
|
128
|
+
|
|
129
|
+
Generate applicable cases for:
|
|
130
|
+
- create then read,
|
|
131
|
+
- update sets expected derived fields,
|
|
132
|
+
- delete excludes from later reads,
|
|
133
|
+
- double delete / unbind idempotency when specified,
|
|
134
|
+
- refresh rotates token and rejects old token,
|
|
135
|
+
- batch operation with empty list vs explicit IDs,
|
|
136
|
+
- retry count below/at/above max,
|
|
137
|
+
- no partial writes when one operation fails.
|
|
138
|
+
|
|
139
|
+
### Dependency Failure
|
|
140
|
+
|
|
141
|
+
Use when collaborators are mockable or the test layer can safely simulate failures.
|
|
142
|
+
|
|
143
|
+
Generate applicable cases for:
|
|
144
|
+
- repository/database error,
|
|
145
|
+
- storage/signing provider failure,
|
|
146
|
+
- SMS/push/email provider failure,
|
|
147
|
+
- LLM/API client error,
|
|
148
|
+
- timeout/network failure,
|
|
149
|
+
- malformed provider response,
|
|
150
|
+
- ID/random/clock failure when injectable.
|
|
151
|
+
|
|
152
|
+
If a dependency cannot be mocked in the current test layer, mark it `skipped` with a reason and consider a lower-level unit test where it can be mocked.
|
|
153
|
+
|
|
154
|
+
### Response Contract
|
|
155
|
+
|
|
156
|
+
Use for API endpoints and public adapters.
|
|
157
|
+
|
|
158
|
+
Generate applicable cases for:
|
|
159
|
+
- unified envelope fields (`code`, `message`, `data`) or framework-specific response format,
|
|
160
|
+
- fixed business error codes,
|
|
161
|
+
- response field names and snake_case/camelCase contract,
|
|
162
|
+
- omitted vs empty data shape,
|
|
163
|
+
- generated IDs and derived fields,
|
|
164
|
+
- side-effect visibility in response.
|
|
165
|
+
|
|
166
|
+
## Endpoint and Interface Mapping
|
|
167
|
+
|
|
168
|
+
Use names, routes, methods, schemas, binding tags, repository calls, and service logic to choose categories. When names and behavior disagree, trust behavior.
|
|
169
|
+
|
|
170
|
+
| Pattern | Likely Categories |
|
|
171
|
+
|---------|-------------------|
|
|
172
|
+
| register / signup / create user | request validation, auth/session, domain invariants, dependency failure, response contract |
|
|
173
|
+
| login | request validation, auth/session, rate limit, token response, dependency failure |
|
|
174
|
+
| refresh / logout | token state, rotation/revocation, idempotency, dependency failure |
|
|
175
|
+
| get / detail | auth/ownership, not found, response contract, dependency failure |
|
|
176
|
+
| list / search / trends | auth, filters, pagination/empty result, date range, response contract, dependency failure |
|
|
177
|
+
| create | request validation, domain invariants, state transition, dependency failure, response contract |
|
|
178
|
+
| update / set goal / confirm | request validation, ownership, partial update semantics, domain invariants, state transition |
|
|
179
|
+
| delete / unbind | request validation, ownership, not found, soft delete, double operation behavior |
|
|
180
|
+
| upload / sign url | request validation, file/storage rules, provider failure, response contract |
|
|
181
|
+
| AI / provider / recognize | request validation, date/time, provider error mapping, quality classifications, async job state |
|
|
182
|
+
| stats / analytics | date range, empty data, boundary thresholds, response shape, dependency failure |
|
|
183
|
+
| achievement / streak | empty state, date continuity, threshold boundaries, state persistence |
|
|
184
|
+
|
|
185
|
+
## N/A Reason Rules
|
|
186
|
+
|
|
187
|
+
A skipped category must explain why it does not apply or why it cannot be exercised at this level.
|
|
188
|
+
|
|
189
|
+
Good reasons:
|
|
190
|
+
- `N/A — public route; no authenticated principal expected`
|
|
191
|
+
- `N/A — endpoint has no collection input or paginated response`
|
|
192
|
+
- `N/A — dependency is not injectable at handler level; covered by service unit test`
|
|
193
|
+
- `N/A — function is pure and has no stateful side effects`
|
|
194
|
+
- `N/A — E2E skipped because project has no UI layer`
|
|
195
|
+
|
|
196
|
+
Bad reasons:
|
|
197
|
+
- `N/A`
|
|
198
|
+
- `not tested`
|
|
199
|
+
- `probably fine`
|
|
200
|
+
- `covered by happy path`
|
|
201
|
+
|
|
202
|
+
## Report Requirements
|
|
203
|
+
|
|
204
|
+
The final report must include:
|
|
205
|
+
|
|
206
|
+
1. The Boundary Matrix.
|
|
207
|
+
2. A Completion Gate summary:
|
|
208
|
+
- interfaces total,
|
|
209
|
+
- boundary-covered count,
|
|
210
|
+
- generated-needs-review count,
|
|
211
|
+
- skipped-with-reason count,
|
|
212
|
+
- boundary-missing count,
|
|
213
|
+
- happy-path-only count.
|
|
214
|
+
3. A clear final status:
|
|
215
|
+
- `All tests passing and boundary coverage complete`, or
|
|
216
|
+
- `Tests passing, but boundary coverage incomplete`, or
|
|
217
|
+
- `Tests failing`, or
|
|
218
|
+
- `Needs human review`.
|
|
219
|
+
|
|
220
|
+
If any interface remains `boundary-missing` or `happy-path-only`, the final report must not say "ready for commit" without qualifying that boundary coverage is incomplete.
|
|
@@ -26,17 +26,26 @@ Scope: Full project (all modules, all specs)
|
|
|
26
26
|
| payment | api/checkout | integration | missing |
|
|
27
27
|
| — | Checkout flow | e2e | missing |
|
|
28
28
|
|
|
29
|
-
**Phase 4
|
|
29
|
+
**Phase 4 — Boundary Matrix** (excerpt):
|
|
30
|
+
| Module | Interface | Service Type | Happy Path | Request Validation | Auth / Permission / Ownership | Domain Invariants | Dependency Failure | Final Status |
|
|
31
|
+
|--------|-----------|--------------|------------|--------------------|-------------------------------|-------------------|-------------------|--------------|
|
|
32
|
+
| auth | login() | Auth / Session | covered | boundary-missing | boundary-missing | skipped | boundary-missing | boundary-missing |
|
|
33
|
+
| payment | processPayment() | Payment / Billing | covered | boundary-missing | boundary-missing | boundary-missing | boundary-missing | boundary-missing |
|
|
30
34
|
|
|
31
|
-
**Phase 5
|
|
35
|
+
**Phase 5**: Generated 5 unit boundary tests (3 passing, 2 assertion failures marked `needs-review`), 1 integration boundary test (passing), 1 E2E test (passing).
|
|
36
|
+
|
|
37
|
+
**Phase 6 — Report Summary**:
|
|
32
38
|
```
|
|
33
39
|
Generated: 5 unit (2 needs-review), 1 integration, 1 E2E
|
|
40
|
+
Boundary gate: failed — 2 interfaces need human review
|
|
34
41
|
Report: .prizmkit/test/2026_05_23_14_30_00_testresult/test-report.md
|
|
35
42
|
Needs human review: processPayment (returns 400 for negative amounts, expected 422), refund (missing authorization header causes 500 instead of 401)
|
|
36
43
|
```
|
|
37
44
|
|
|
38
45
|
## Example 2: Single-Feature Targeted Test
|
|
39
46
|
|
|
47
|
+
This is an interactive single-feature selection. It is different from headless `scope=this-change`, which is driven by `.prizmkit/specs/<FEATURE_SLUG>/` and changed files.
|
|
48
|
+
|
|
40
49
|
**User**: `/prizmkit-test`
|
|
41
50
|
|
|
42
51
|
**Phase 0 — Architecture Detection**:
|
|
@@ -49,22 +58,86 @@ Test framework: Vitest
|
|
|
49
58
|
```
|
|
50
59
|
Scope: Single feature — 042-payment-gateway
|
|
51
60
|
Test files in scope: 2
|
|
61
|
+
```
|
|
52
62
|
|
|
53
63
|
**Phase 2 — Existing Tests**: 2 test files, 8 tests, all passing.
|
|
54
64
|
|
|
55
65
|
**Phase 3 — Gap Analysis** (excerpt):
|
|
56
66
|
| Module | Interface | Type | Status |
|
|
57
67
|
|--------|-----------|------|--------|
|
|
58
|
-
| payment | processPayment() | unit | missing |
|
|
59
|
-
| payment | refund() | unit | missing |
|
|
68
|
+
| payment | processPayment() | unit | boundary-missing |
|
|
69
|
+
| payment | refund() | unit | boundary-missing |
|
|
70
|
+
|
|
71
|
+
**Phase 4 — Boundary Matrix**:
|
|
72
|
+
| Module | Interface | Service Type | Happy Path | Request Validation | Auth / Permission / Ownership | Domain Invariants | State Transitions | Dependency Failure | Final Status |
|
|
73
|
+
|--------|-----------|--------------|------------|--------------------|-------------------------------|-------------------|-------------------|-------------------|--------------|
|
|
74
|
+
| payment | processPayment() | Payment / Billing | covered | boundary-missing | boundary-missing | boundary-missing | generated | boundary-missing | boundary-missing |
|
|
75
|
+
| payment | refund() | Payment / Refund | covered | boundary-missing | boundary-missing | boundary-missing | boundary-missing | skipped — provider sandbox unavailable | boundary-missing |
|
|
60
76
|
|
|
61
|
-
**Phase
|
|
77
|
+
**Phase 5**: Generated 8 unit tests covering amount boundaries, currency mismatch, missing entitlement, duplicate idempotency key, partial refund, full refund, over-refund, and repository failure. All passing.
|
|
62
78
|
|
|
63
|
-
**Phase
|
|
79
|
+
**Phase 6 — Report Summary**:
|
|
64
80
|
```
|
|
65
|
-
Generated:
|
|
81
|
+
Generated: 8 unit tests (all passing)
|
|
82
|
+
Boundary gate: passed
|
|
66
83
|
Report: .prizmkit/test/2026_05_23_15_00_00_testresult/test-report.md
|
|
67
|
-
All tests passing. Ready for commit.
|
|
84
|
+
All tests passing and boundary coverage complete. Ready for commit.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Example 3: Existing Happy Path Is Not Enough
|
|
88
|
+
|
|
89
|
+
**User**: `/prizmkit-test user module`
|
|
90
|
+
|
|
91
|
+
**Existing tests found**:
|
|
92
|
+
```
|
|
93
|
+
TestHandler_UpdateProfile_Success
|
|
94
|
+
TestHandler_GetProfile_Success
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Boundary Matrix result**:
|
|
98
|
+
| Module | Interface | Service Type | Happy Path | Request Validation | Auth / Permission / Ownership | Domain Invariants | Dependency Failure | Final Status |
|
|
99
|
+
|--------|-----------|--------------|------------|--------------------|-------------------------------|-------------------|-------------------|--------------|
|
|
100
|
+
| user | POST /user/update-profile | Validation / CRUD | covered | boundary-missing | boundary-missing | boundary-missing | boundary-missing | boundary-missing |
|
|
101
|
+
| user | POST /user/get-profile | CRUD / Auth | covered | N/A — empty request | boundary-missing | N/A — no domain input | boundary-missing | boundary-missing |
|
|
102
|
+
|
|
103
|
+
**Correct action**:
|
|
104
|
+
Generate tests for:
|
|
105
|
+
- missing auth,
|
|
106
|
+
- invalid gender,
|
|
107
|
+
- invalid activity level,
|
|
108
|
+
- implausible height/weight when specified by service contract,
|
|
109
|
+
- user not found,
|
|
110
|
+
- repository failure,
|
|
111
|
+
- response envelope shape.
|
|
112
|
+
|
|
113
|
+
**Incorrect action**:
|
|
114
|
+
Do not report `user` as covered just because both endpoints have success tests.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
## Example 3: Feature Pipeline this-change Run
|
|
118
|
+
|
|
119
|
+
**Caller**: `/prizmkit-test scope=this-change artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`
|
|
120
|
+
|
|
121
|
+
**Expected behavior**:
|
|
122
|
+
- Reads `.prizmkit/specs/{{FEATURE_SLUG}}/spec.md`, `plan.md`, and optional `context-snapshot.md`.
|
|
123
|
+
- Builds in-scope files from changed files and feature artifacts.
|
|
124
|
+
- Generates or updates only tests for this feature's changed files, public interfaces, and acceptance criteria.
|
|
125
|
+
- Records unrelated historical gaps under `Out of Scope Gaps`.
|
|
126
|
+
- Does not generate tests for unrelated modules.
|
|
127
|
+
- Does not infer this-change mode from `.prizmkit/bugfix/{{BUG_ID}}/` or `.prizmkit/refactor/{{REFACTOR_ID}}/`.
|
|
128
|
+
|
|
129
|
+
**Report excerpt**:
|
|
130
|
+
```markdown
|
|
131
|
+
## Scope
|
|
132
|
+
- Mode: this-change
|
|
133
|
+
- Artifact Dir: .prizmkit/specs/{{FEATURE_SLUG}}/
|
|
134
|
+
- Generation Policy: in-scope-only
|
|
135
|
+
|
|
136
|
+
## Out of Scope Gaps
|
|
137
|
+
- payment: missing legacy tests, but this feature did not change payment code.
|
|
138
|
+
|
|
139
|
+
## Verdict
|
|
140
|
+
PASS
|
|
68
141
|
```
|
|
69
142
|
|
|
70
|
-
**HANDOFF**: Independent skill — no handoff. User may proceed to `/prizmkit-committer` if
|
|
143
|
+
**HANDOFF**: Independent skill — no handoff. User may proceed to `/prizmkit-committer` only if tests pass and the boundary completion gate passes, or fix issues manually if tests are marked `needs-review`.
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Service Boundary Test Catalog
|
|
2
|
+
|
|
3
|
+
Use this catalog during `/prizmkit-test` Phase 4a when generating unit tests for service-like functions or class methods. The goal is to turn "write boundary tests" into service-specific scenarios that match the unit's business responsibility.
|
|
4
|
+
|
|
5
|
+
## How to Use This Catalog
|
|
6
|
+
|
|
7
|
+
1. Classify the tested unit by reading its name, module path, parameters, dependencies, state changes, and related Prizm docs/spec acceptance criteria.
|
|
8
|
+
2. Select every service type that applies. A function can be both a payment service and an idempotency service, or both a repository and pagination service.
|
|
9
|
+
3. Map candidate boundaries to the actual contract in code/docs. Assert behavior that is specified or clearly implied; if expected behavior is unclear, mark the case as `needs-review` instead of inventing production behavior.
|
|
10
|
+
4. Mock external dependencies for unit tests: databases, network calls, file storage, queues, payment gateways, email providers, clocks, and random ID generators.
|
|
11
|
+
5. Record non-applicable categories as `N/A` with a short reason in the boundary coverage report so skipped categories are explicit.
|
|
12
|
+
|
|
13
|
+
## Service Type Detection
|
|
14
|
+
|
|
15
|
+
| Signal | Likely Service Type |
|
|
16
|
+
|--------|---------------------|
|
|
17
|
+
| login, logout, signup, password, session, token, jwt, oauth, refresh | Auth / Session / Token |
|
|
18
|
+
| role, permission, policy, access, entitlement, plan, quota, ownership | Authorization / Permission / Entitlement |
|
|
19
|
+
| payment, wallet, billing, subscription, invoice, refund, balance, currency | Payment / Wallet / Billing / Refund |
|
|
20
|
+
| repository, model, dao, create, read, update, delete, insert, save, remove | CRUD / Repository / Database |
|
|
21
|
+
| search, list, page, cursor, filter, sort, query, limit, offset | Search / List / Pagination |
|
|
22
|
+
| validate, parse, normalize, transform, schema, sanitize, format | Validation / Parser / Normalizer |
|
|
23
|
+
| upload, download, storage, file, blob, s3, image, mime, path | File Upload / Storage |
|
|
24
|
+
| notify, email, sms, webhook, template, recipient, provider | Notification / Email / Webhook |
|
|
25
|
+
| job, queue, worker, scheduler, cron, retry, backoff, task | Job / Queue / Scheduler |
|
|
26
|
+
| cache, ttl, rate limit, throttle, idempotency, dedupe, lock | Cache / Rate Limit / Idempotency |
|
|
27
|
+
| client, sdk, request, fetch, provider, api key, endpoint, response | API Client / Third-Party Integration |
|
|
28
|
+
| date, time, expiry, expiration, ttl, schedule, window, timezone | Date / Time / Expiration |
|
|
29
|
+
|
|
30
|
+
When names and behavior disagree, trust behavior and dependencies over names. For example, `createCheckoutSession()` is payment-related even if it lives in a controller module.
|
|
31
|
+
|
|
32
|
+
## Universal Boundary Matrix
|
|
33
|
+
|
|
34
|
+
Apply these categories to every public function/class method before adding service-specific cases:
|
|
35
|
+
|
|
36
|
+
- **Valid input**: typical valid input, minimal valid input, and complex valid input when supported.
|
|
37
|
+
- **Empty input**: `null` / `undefined` / `None`, empty string, empty array/object, whitespace-only string.
|
|
38
|
+
- **Numeric boundaries**: zero, one, minimum allowed value, maximum allowed value, just below/above limits.
|
|
39
|
+
- **Collection boundaries**: zero items, one item, many items, duplicate items, first/last element behavior.
|
|
40
|
+
- **Type and format errors**: wrong type, malformed string, unsupported enum, missing required parameter.
|
|
41
|
+
- **Branch paths**: each `if/else`, `switch/case/default`, ternary side, and loop path with zero/one/many iterations.
|
|
42
|
+
- **State and side effects**: before/after state, writes, emitted events, dependency method calls, call count/order/arguments.
|
|
43
|
+
- **Dependency failures**: mocked database errors, network timeouts, storage failures, provider errors, clock/randomness behavior.
|
|
44
|
+
|
|
45
|
+
## Service-Specific Boundary Cases
|
|
46
|
+
|
|
47
|
+
### Auth / Session / Token Services
|
|
48
|
+
|
|
49
|
+
Generate applicable cases for:
|
|
50
|
+
|
|
51
|
+
- Missing identifier, missing password, empty credentials, malformed email/username.
|
|
52
|
+
- Identifier normalization: uppercase/lowercase email, leading/trailing whitespace, Unicode usernames when supported.
|
|
53
|
+
- User not found, wrong password, unverified account, disabled account, locked account.
|
|
54
|
+
- Failed login count just below/at/above lock threshold.
|
|
55
|
+
- Successful login creates exactly one session/token with expected expiry and persisted state.
|
|
56
|
+
- Token missing, malformed, invalid signature, wrong algorithm, expired, not-yet-valid, revoked.
|
|
57
|
+
- Refresh token rotation: old refresh token reuse, missing refresh token, expired refresh token, revoked refresh token.
|
|
58
|
+
- Logout idempotency: logout with valid token, already logged-out token, missing token.
|
|
59
|
+
- OAuth/callback flows: missing code, missing state, state mismatch, provider error, provider returns incomplete profile.
|
|
60
|
+
- Dependency failures: user store error, password hasher error, token signer/verifier error, clock skew.
|
|
61
|
+
|
|
62
|
+
### Authorization / Permission / Entitlement Services
|
|
63
|
+
|
|
64
|
+
Generate applicable cases for:
|
|
65
|
+
|
|
66
|
+
- Missing principal, anonymous principal, principal without roles/permissions.
|
|
67
|
+
- Default-deny behavior when no policy matches.
|
|
68
|
+
- Role hierarchy: basic role, elevated role, admin override, deny rule precedence.
|
|
69
|
+
- Resource ownership: owner, non-owner, tenant mismatch, organization mismatch.
|
|
70
|
+
- Entitlement states: active, expired, canceled, trial, disabled feature, missing plan.
|
|
71
|
+
- Quota boundaries: usage below limit, exactly at limit, one over limit, reset window boundary.
|
|
72
|
+
- Duplicate or conflicting permissions.
|
|
73
|
+
- Policy conditions with missing attributes, malformed attributes, unknown action/resource.
|
|
74
|
+
- Dependency failures: policy store error, entitlement lookup error, quota service timeout.
|
|
75
|
+
|
|
76
|
+
### Payment / Wallet / Billing / Refund Services
|
|
77
|
+
|
|
78
|
+
Generate applicable cases for:
|
|
79
|
+
|
|
80
|
+
- Amount zero, negative amount, minimum billable unit, maximum allowed amount, just above maximum.
|
|
81
|
+
- Currency precision: too many decimal places, integer minor units, rounding at half-unit boundaries.
|
|
82
|
+
- Balance boundaries: balance exactly equals debit amount, balance one minor unit below amount, zero balance.
|
|
83
|
+
- Currency mismatch between wallet, invoice, and payment request.
|
|
84
|
+
- Idempotency: missing key, duplicate key with same payload, duplicate key with different payload.
|
|
85
|
+
- Transaction states: pending, succeeded, failed, canceled, already paid, already refunded.
|
|
86
|
+
- Refund boundaries: zero refund, partial refund, full refund, cumulative refunds equal original amount, cumulative refunds exceed original amount.
|
|
87
|
+
- Concurrent debit/refund attempts against the same account or transaction.
|
|
88
|
+
- Subscription/billing cycles: trial start/end, expired subscription, canceled subscription, renewal at boundary time.
|
|
89
|
+
- Provider failures: timeout, 4xx/5xx, malformed response, duplicate provider event, out-of-order webhook.
|
|
90
|
+
- Side effects: ledger entry count, balance mutation, webhook/event emission, provider call arguments.
|
|
91
|
+
|
|
92
|
+
### CRUD / Repository / Database Services
|
|
93
|
+
|
|
94
|
+
Generate applicable cases for:
|
|
95
|
+
|
|
96
|
+
- Create with missing required fields, nullable fields set to `null`, optional fields omitted.
|
|
97
|
+
- Duplicate unique key, generated ID collision, invalid foreign key, unknown enum value.
|
|
98
|
+
- Read/update/delete with nonexistent ID, malformed ID, deleted/soft-deleted ID.
|
|
99
|
+
- Partial update semantics: omitted field vs `undefined` vs `null`, empty patch object.
|
|
100
|
+
- Optimistic locking: expected version, stale version, missing version.
|
|
101
|
+
- Soft delete behavior: excluded by default, included only when requested, double delete idempotency.
|
|
102
|
+
- Transaction behavior: rollback when one write fails, no partial side effects after failure.
|
|
103
|
+
- Database dependency errors: connection failure, constraint violation, timeout.
|
|
104
|
+
- Repository side effects: correct query arguments, write count, returned entity shape.
|
|
105
|
+
|
|
106
|
+
### Search / List / Pagination / Sorting Services
|
|
107
|
+
|
|
108
|
+
Generate applicable cases for:
|
|
109
|
+
|
|
110
|
+
- Empty query, whitespace query, special characters, Unicode query, injection-like strings treated as data.
|
|
111
|
+
- No results, one result, many results, duplicate ranking/sort values.
|
|
112
|
+
- Page/offset pagination: page 0, page 1, last page, beyond last page, negative page/offset.
|
|
113
|
+
- Cursor pagination: missing cursor, malformed cursor, expired cursor, cursor at final item.
|
|
114
|
+
- Limit boundaries: omitted limit, limit 0, limit 1, maximum limit, maximum + 1.
|
|
115
|
+
- Sorting: default sort, invalid sort field, invalid direction, stable ordering with ties.
|
|
116
|
+
- Filters: empty filter set, unknown filter, conflicting filters, inclusive/exclusive date ranges.
|
|
117
|
+
- Total count and hasNext/hasPrevious flags at page boundaries.
|
|
118
|
+
- Dependency failures: search index unavailable, database query error, stale index response.
|
|
119
|
+
|
|
120
|
+
### Validation / Parser / Normalizer Services
|
|
121
|
+
|
|
122
|
+
Generate applicable cases for:
|
|
123
|
+
|
|
124
|
+
- Missing input, `null` / `undefined` / `None`, empty string, whitespace-only string.
|
|
125
|
+
- Minimum and maximum length; just below/above configured length boundaries.
|
|
126
|
+
- Special characters, Unicode, emoji, newline/control characters, normalization-sensitive characters.
|
|
127
|
+
- Wrong type, mixed-type arrays, numeric strings vs numbers, booleans represented as strings.
|
|
128
|
+
- Unknown fields in strict mode, extra fields in permissive mode, duplicate keys/items.
|
|
129
|
+
- Invalid formats: email, URL, date, UUID, JSON, CSV, phone number, currency.
|
|
130
|
+
- Normalization idempotency: applying the normalizer twice yields the same result.
|
|
131
|
+
- Error shape: path/field name, code, message, and aggregation of multiple errors.
|
|
132
|
+
- Parser failures: malformed payload, truncated payload, unsupported version/schema.
|
|
133
|
+
|
|
134
|
+
### File Upload / Storage Services
|
|
135
|
+
|
|
136
|
+
Generate applicable cases for:
|
|
137
|
+
|
|
138
|
+
- Zero-byte file, one-byte file, just below max size, exactly max size, just above max size.
|
|
139
|
+
- MIME/type mismatch between content, extension, and declared header.
|
|
140
|
+
- Unsupported file type, missing extension, uppercase extension, compound extension.
|
|
141
|
+
- Filename boundaries: empty name, very long name, Unicode name, duplicate name, path traversal characters.
|
|
142
|
+
- Storage key collisions and deterministic key generation.
|
|
143
|
+
- Checksum/hash mismatch, corrupted stream, interrupted upload, storage write failure.
|
|
144
|
+
- Image/media metadata boundaries: dimensions too small/large, unsupported codec, malformed metadata.
|
|
145
|
+
- Delete/read behavior for missing object, already-deleted object, permission-denied object.
|
|
146
|
+
- Side effects: storage provider call arguments, metadata record creation, cleanup on failure.
|
|
147
|
+
|
|
148
|
+
### Notification / Email / Webhook Services
|
|
149
|
+
|
|
150
|
+
Generate applicable cases for:
|
|
151
|
+
|
|
152
|
+
- Missing recipient, invalid email/phone/URL, empty recipient list, duplicate recipients.
|
|
153
|
+
- Recipient preferences: unsubscribed, disabled channel, quiet hours, blocked user.
|
|
154
|
+
- Template variables: missing required variable, extra variable, `null` variable, special characters/HTML escaping.
|
|
155
|
+
- Provider selection: unsupported channel, fallback provider, disabled provider.
|
|
156
|
+
- Deduplication: duplicate notification key, repeated webhook event, retry with same id.
|
|
157
|
+
- Provider responses: success, rate limit, timeout, 4xx/5xx, malformed response, partial multi-recipient failure.
|
|
158
|
+
- Webhook security: missing signature, invalid signature, timestamp outside tolerance, replayed event.
|
|
159
|
+
- Side effects: event status persisted, retry scheduled or suppressed, provider called with expected payload.
|
|
160
|
+
|
|
161
|
+
### Job / Queue / Scheduler Services
|
|
162
|
+
|
|
163
|
+
Generate applicable cases for:
|
|
164
|
+
|
|
165
|
+
- Missing payload, empty payload, malformed payload, unsupported job type/version.
|
|
166
|
+
- Duplicate job ID, idempotent processing of already-completed job, requeue behavior.
|
|
167
|
+
- Retry boundaries: first failure, retry count just below max, at max, over max, poison/dead-letter path.
|
|
168
|
+
- Backoff calculation: zero delay, minimum delay, maximum delay, jitter bounds when deterministic/mocked.
|
|
169
|
+
- Schedule boundaries: run in past, run now, run in future, invalid cron, daylight-saving transition.
|
|
170
|
+
- Concurrency: two workers claim same job, lock acquisition failure, stale lock recovery.
|
|
171
|
+
- Cancellation: before start, during processing, after completion.
|
|
172
|
+
- Side effects: ack/nack calls, status transitions, retry scheduling, emitted events.
|
|
173
|
+
|
|
174
|
+
### Cache / Rate Limit / Idempotency Services
|
|
175
|
+
|
|
176
|
+
Generate applicable cases for:
|
|
177
|
+
|
|
178
|
+
- Cache miss, hit, stale hit, expired entry, invalidation, key collision.
|
|
179
|
+
- TTL boundaries: zero TTL, negative TTL, one unit TTL, exact expiry instant, just before/after expiry.
|
|
180
|
+
- Serialization/deserialization failure, corrupted cached value, unsupported value type.
|
|
181
|
+
- Cache stampede: concurrent misses for the same key should not duplicate expensive work when guarded.
|
|
182
|
+
- Rate limit boundaries: count below limit, exactly at limit, one above limit, window rollover.
|
|
183
|
+
- Missing actor key: anonymous user, missing IP, shared tenant/global scope.
|
|
184
|
+
- Idempotency key: missing, malformed, reused with same payload, reused with different payload, expired record.
|
|
185
|
+
- Lock behavior: lock unavailable, lock timeout, release on success, release on failure.
|
|
186
|
+
- Backing store failures: Redis/cache down, slow response, partial write.
|
|
187
|
+
|
|
188
|
+
### API Client / Third-Party Integration Services
|
|
189
|
+
|
|
190
|
+
Generate applicable cases for:
|
|
191
|
+
|
|
192
|
+
- Missing base URL, missing API key, malformed configuration, unsupported region/environment.
|
|
193
|
+
- Request building: query encoding, header inclusion, body serialization, path parameter escaping.
|
|
194
|
+
- Response handling: 200 with valid body, 204/no body, malformed JSON, missing required field, unknown extra field.
|
|
195
|
+
- Error responses: 400, 401/403, 404, 409, 429, 500/503; retryable vs non-retryable classification.
|
|
196
|
+
- Timeout, network error, DNS/connect failure, aborted request.
|
|
197
|
+
- Retry boundaries: zero retries, one retry then success, max retries exhausted, backoff capped.
|
|
198
|
+
- Pagination: empty page, last page, next token missing/malformed, duplicate page token.
|
|
199
|
+
- Auth refresh/signing: expired access token, refresh failure, invalid signature, clock skew.
|
|
200
|
+
- Circuit breaker or fallback behavior when present.
|
|
201
|
+
|
|
202
|
+
### Date / Time / Expiration Services
|
|
203
|
+
|
|
204
|
+
Generate applicable cases for:
|
|
205
|
+
|
|
206
|
+
- Exact boundary: `now == startsAt`, `now == expiresAt`, one millisecond/second before and after.
|
|
207
|
+
- Inclusive vs exclusive interval ends according to the contract.
|
|
208
|
+
- Start after end, zero-length interval, negative duration, missing timezone.
|
|
209
|
+
- Time zones: UTC vs local time, DST jump forward/back, leap day, month end, year end.
|
|
210
|
+
- Clock skew tolerance for tokens, webhooks, scheduled jobs, and signed requests.
|
|
211
|
+
- Recurring schedules: first occurrence, last occurrence, skipped occurrence, invalid cron/expression.
|
|
212
|
+
- TTL/window calculations: zero TTL, negative TTL, max TTL, rollover between windows.
|
|
213
|
+
|
|
214
|
+
## When Multiple Service Types Apply
|
|
215
|
+
|
|
216
|
+
Combine the relevant sections and remove duplicate cases. Prioritize tests that exercise business invariants over tests that only repeat generic invalid input handling. For example, a wallet debit function should cover payment amount boundaries, idempotency replay, and date/expiration behavior if it also accepts an expiring authorization.
|
|
217
|
+
|
|
218
|
+
## N/A Rules
|
|
219
|
+
|
|
220
|
+
Mark a category `N/A` when the unit has no corresponding input, state, or dependency. Include a short reason:
|
|
221
|
+
|
|
222
|
+
- `N/A — no external provider dependency`
|
|
223
|
+
- `N/A — function is pure and has no stateful side effects`
|
|
224
|
+
- `N/A — pagination is handled by caller, not this unit`
|
|
225
|
+
- `N/A — concurrency safety belongs to integration test because unit has no shared mutable state`
|