wize-dev-kit 0.1.5 → 0.2.5
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/CHANGELOG.md +130 -1
- package/README.md +64 -0
- package/package.json +1 -1
- package/src/method-skills/1-analysis/wize-document-project/workflow.md +188 -20
- package/src/method-skills/1-analysis/wize-prfaq/workflow.md +150 -11
- package/src/method-skills/1-analysis/wize-product-brief/workflow.md +90 -19
- package/src/method-skills/1-analysis/wize-refresh-knowledge/workflow.md +127 -0
- package/src/method-skills/1-analysis/wize-research/workflow.md +101 -9
- package/src/method-skills/1-analysis/wize-trigger-map/workflow.md +80 -16
- package/src/method-skills/2-plan-workflows/wize-create-prd/workflow.md +132 -23
- package/src/method-skills/2-plan-workflows/wize-ux-design/workflow.md +132 -28
- package/src/method-skills/2-plan-workflows/wize-ux-scenarios/workflow.md +91 -15
- package/src/method-skills/2-plan-workflows/wize-validate-prd/workflow.md +106 -12
- package/src/method-skills/3-solutioning/wize-check-implementation-readiness/workflow.md +101 -11
- package/src/method-skills/3-solutioning/wize-create-architecture/workflow.md +197 -29
- package/src/method-skills/3-solutioning/wize-create-epics-and-stories/workflow.md +127 -12
- package/src/method-skills/3-solutioning/wize-design-system/workflow.md +182 -22
- package/src/method-skills/3-solutioning/wize-nfr-principles/workflow.md +142 -16
- package/src/method-skills/3-solutioning/wize-tech-vision/workflow.md +127 -21
- package/src/method-skills/4-implementation/wize-code-review/workflow.md +105 -10
- package/src/method-skills/4-implementation/wize-create-story/workflow.md +131 -10
- package/src/method-skills/4-implementation/wize-dev-story/workflow.md +140 -17
- package/src/method-skills/4-implementation/wize-quick-dev/workflow.md +121 -18
- package/src/method-skills/4-implementation/wize-retrospective/workflow.md +112 -10
- package/src/method-skills/4-implementation/wize-sprint-planning/workflow.md +85 -10
- package/src/method-skills/4-implementation/wize-sprint-status/workflow.md +96 -11
- package/src/orchestrator-skills/wize-help/skill.md +25 -1
- package/src/tea-skills/wize-tea-design/workflow.md +104 -13
- package/src/tea-skills/wize-tea-gate/workflow.md +115 -25
- package/src/tea-skills/wize-tea-nfr/workflow.md +104 -14
- package/src/tea-skills/wize-tea-review/workflow.md +120 -13
- package/src/tea-skills/wize-tea-risk/workflow.md +99 -10
- package/src/tea-skills/wize-tea-trace/workflow.md +83 -12
- package/tools/installer/baseline.js +128 -0
- package/tools/installer/commands/agent.js +197 -0
- package/tools/installer/commands/sync.js +45 -0
- package/tools/installer/commands/update.js +172 -0
- package/tools/installer/version-check.js +117 -0
- package/tools/installer/wize-cli.js +98 -11
|
@@ -4,34 +4,124 @@ name: TEA NFR Assessment
|
|
|
4
4
|
gate: nfr
|
|
5
5
|
owner: wize-agent-test-architect # Hawkeye
|
|
6
6
|
when: pre-merge-per-epic
|
|
7
|
-
status:
|
|
7
|
+
status: ready
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# TEA — NFR Assessment
|
|
11
11
|
|
|
12
|
-
**Goal.** Verify the epic meets Fury's NFR principles: performance, security, reliability, maintainability, accessibility, cost.
|
|
12
|
+
**Goal.** Verify that the **epic** as a whole meets Fury's NFR principles: performance, security, reliability, maintainability, accessibility, cost. Story-level gates miss NFRs that emerge only at integration; this gate catches them.
|
|
13
|
+
|
|
14
|
+
Hawkeye drives. Tony reviews perf + security findings. Fury escalates if a non-negotiable is at risk. Runs **per epic**, just before any of its stories merges.
|
|
13
15
|
|
|
14
16
|
## Inputs
|
|
15
|
-
|
|
17
|
+
|
|
18
|
+
- `.wize/planning/nfr-principles.md` (Fury's targets)
|
|
16
19
|
- Code from all stories in the epic
|
|
17
|
-
- Telemetry/benchmark output
|
|
20
|
+
- Telemetry / benchmark output (lighthouse, web-vitals, macrobenchmark, Sentry perf)
|
|
21
|
+
- Overlay perf playbooks: `web-perf-budgets.md`, `mobile-perf-budgets.md`
|
|
18
22
|
|
|
19
23
|
## Output
|
|
24
|
+
|
|
20
25
|
- `.wize/implementation/tea/nfr/{epic}.md`
|
|
21
26
|
|
|
22
|
-
##
|
|
27
|
+
## Steps
|
|
28
|
+
|
|
29
|
+
### 1. For each category, run the verifier
|
|
30
|
+
|
|
31
|
+
| Category | Verifier (typical) |
|
|
32
|
+
|---|---|
|
|
33
|
+
| Performance | lighthouse-ci against epic-scope routes; web-vitals beacon delta |
|
|
34
|
+
| Security | `npm audit --omit=dev`; manual OWASP Top 10 walk; secret scan |
|
|
35
|
+
| Reliability | injected-failure tests (`@chaos` tag); retry policy review; idempotency check |
|
|
36
|
+
| Maintainability | coverage delta; cyclomatic complexity delta; lint baseline |
|
|
37
|
+
| Accessibility | axe on every epic-scope route; keyboard walk on critical flows |
|
|
38
|
+
| Cost | cost dashboard delta in the epic window |
|
|
39
|
+
|
|
40
|
+
### 2. Score each
|
|
41
|
+
|
|
42
|
+
For each category: `PASS` (meets non-negotiable) / `CONCERNS` (within stretch range; below non-negotiable on a measurable item with mitigation plan) / `FAIL` (non-negotiable missed; no plan) / `WAIVED` (with documented reason + sign-off).
|
|
43
|
+
|
|
44
|
+
### 3. Findings (one per slip)
|
|
45
|
+
|
|
46
|
+
If anything failed or concerned, write the finding: what we measured, what was expected, why the slip, what the next step is.
|
|
47
|
+
|
|
48
|
+
### 4. Hand off
|
|
49
|
+
|
|
50
|
+
`PASS` → epic can merge. `CONCERNS` (advisory) → flag in PR description. `FAIL` (enforcing) → blocks merge.
|
|
51
|
+
|
|
52
|
+
## YAML frontmatter (canonical)
|
|
53
|
+
|
|
23
54
|
```yaml
|
|
24
55
|
---
|
|
25
56
|
gate: nfr
|
|
26
|
-
epic:
|
|
27
|
-
status:
|
|
57
|
+
epic: 01-onboarding
|
|
58
|
+
status: CONCERNS
|
|
28
59
|
scores:
|
|
29
|
-
performance:
|
|
30
|
-
security:
|
|
31
|
-
reliability:
|
|
32
|
-
maintainability:
|
|
33
|
-
accessibility:
|
|
34
|
-
cost:
|
|
35
|
-
findings:
|
|
60
|
+
performance: PASS
|
|
61
|
+
security: PASS
|
|
62
|
+
reliability: CONCERNS
|
|
63
|
+
maintainability: PASS
|
|
64
|
+
accessibility: PASS
|
|
65
|
+
cost: PASS
|
|
66
|
+
findings:
|
|
67
|
+
- id: NFR-01-1
|
|
68
|
+
category: reliability
|
|
69
|
+
severity: medium
|
|
70
|
+
summary: "Outbox retry interval too aggressive for Resend's documented backoff."
|
|
71
|
+
expected: "Exponential 30s/2m/10m; we set 5s/15s/45s."
|
|
72
|
+
actual: "Spike in Resend 429s during integration test."
|
|
73
|
+
recommendation: "Update retry policy in `lib/email/outbox.ts`; capture with `outbox-retry.spec.ts`."
|
|
74
|
+
owner: shuri
|
|
75
|
+
blocking: false
|
|
76
|
+
created_at: 2026-06-11T18:00:00Z
|
|
36
77
|
---
|
|
37
78
|
```
|
|
79
|
+
|
|
80
|
+
## Body of `nfr/{epic}.md`
|
|
81
|
+
|
|
82
|
+
```markdown
|
|
83
|
+
## Summary
|
|
84
|
+
Epic 01 (onboarding) at gate. Performance and a11y pass non-negotiables; reliability has one mid-severity concern around outbox backoff.
|
|
85
|
+
|
|
86
|
+
## Per category
|
|
87
|
+
|
|
88
|
+
### Performance — PASS
|
|
89
|
+
- LCP (signup): 1.45s p75 (target ≤ 2.5s).
|
|
90
|
+
- INP (signup): 90ms p75 (target ≤ 200ms).
|
|
91
|
+
- CLS (signup): 0.03 (target ≤ 0.1).
|
|
92
|
+
- LCP (onboarding): 1.7s p75.
|
|
93
|
+
|
|
94
|
+
### Security — PASS
|
|
95
|
+
- `npm audit` clean (dev advisories noted in `.audit-ignore.md`).
|
|
96
|
+
- OWASP Top 10 walk: no findings.
|
|
97
|
+
- RLS verified on `users`, `teams`, `memberships`.
|
|
98
|
+
|
|
99
|
+
### Reliability — CONCERNS
|
|
100
|
+
- See NFR-01-1.
|
|
101
|
+
|
|
102
|
+
### Maintainability — PASS
|
|
103
|
+
- Coverage 84% on logic modules in this epic.
|
|
104
|
+
- No file > 300 LOC introduced.
|
|
105
|
+
|
|
106
|
+
### Accessibility — PASS
|
|
107
|
+
- axe clean on `/signup`, `/signup/error`, `/onboarding`, `/onboarding/invite-sent`.
|
|
108
|
+
- Keyboard walk: focus order matches visual; modal traps + restores.
|
|
109
|
+
|
|
110
|
+
### Cost — PASS
|
|
111
|
+
- No cost dashboard change beyond expected (account creation; mailer spend within budget).
|
|
112
|
+
|
|
113
|
+
## Action items
|
|
114
|
+
- Shuri: PR-XXX fixes NFR-01-1. Re-run NFR after merge.
|
|
115
|
+
- Hawkeye: re-baseline web-vitals after epic ships to prod.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Anti-patterns Hawkeye rejects
|
|
119
|
+
|
|
120
|
+
- **Self-reported "looks fine" with no verifier output.** Attach the artifact.
|
|
121
|
+
- **Concerns left for "later."** Either an action item with owner+deadline or it's not a concern.
|
|
122
|
+
- **Waived without sign-off.** WAIVED needs `waived_by: NAME` + reason.
|
|
123
|
+
- **NFR run on stage with synthetic data.** Use realistic distributions whenever possible.
|
|
124
|
+
|
|
125
|
+
## Hand-off
|
|
126
|
+
|
|
127
|
+
> NFR gate for Epic 01: **CONCERNS**. PR can proceed if the reliability finding (NFR-01-1) is committed to be addressed in the next sprint. Otherwise hold the merge.
|
|
@@ -4,32 +4,139 @@ name: TEA Story Review
|
|
|
4
4
|
gate: review
|
|
5
5
|
owner: wize-agent-test-architect # Hawkeye
|
|
6
6
|
when: story-end
|
|
7
|
-
status:
|
|
7
|
+
status: ready
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# TEA — Story Review
|
|
11
11
|
|
|
12
|
-
**Goal.**
|
|
12
|
+
**Goal.** A structured review of one story before its gate decision. Distinct from Shuri's `wize-code-review` (which audits code health). This one audits **AC fulfillment, test discipline, and risk-spot coverage**.
|
|
13
|
+
|
|
14
|
+
Hawkeye drives. Runs at story end, right before `tea-gate`.
|
|
13
15
|
|
|
14
16
|
## Inputs
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
17
|
+
|
|
18
|
+
- Story file (the AC list, out-of-scope, notes).
|
|
19
|
+
- `tea-design.md` + `tea-trace.md`.
|
|
20
|
+
- Test run results (PR CI).
|
|
21
|
+
- Code diff (the PR).
|
|
18
22
|
|
|
19
23
|
## Output
|
|
24
|
+
|
|
20
25
|
- `.wize/implementation/tea/{epic}/{story}/review.md`
|
|
21
26
|
|
|
22
|
-
##
|
|
27
|
+
## Steps
|
|
28
|
+
|
|
29
|
+
### 1. AC check (per AC)
|
|
30
|
+
|
|
31
|
+
For each AC, observe the actual behavior on a staging or local build and decide: `met` / `partial` / `not-met`. Use the recorded video/screenshot when CI captured one (Playwright `screenshot: only-on-failure` or always for review tag).
|
|
32
|
+
|
|
33
|
+
### 2. Test discipline
|
|
34
|
+
|
|
35
|
+
Walk:
|
|
36
|
+
- Are `tea-design.md`'s declared tests present in code?
|
|
37
|
+
- Is every assertion meaningful (not just `expect(true).toBe(true)`)?
|
|
38
|
+
- Are selectors stable (role/label/testid) rather than brittle (CSS classes)?
|
|
39
|
+
- Are mocks at the network boundary (MSW) rather than in the unit under test?
|
|
40
|
+
- Are there `test.skip` or `test.only` left in?
|
|
41
|
+
|
|
42
|
+
### 3. Risk-spot coverage
|
|
43
|
+
|
|
44
|
+
If the story touches any `R-x` from the risk profile, walk the mitigation contract and confirm it's met.
|
|
45
|
+
|
|
46
|
+
### 4. Story scope discipline
|
|
47
|
+
|
|
48
|
+
Did the story stay within its declared scope? Any out-of-scope item that crept in is flagged in the review (and either moved to a new story or backed out).
|
|
49
|
+
|
|
50
|
+
### 5. Knowledge update check
|
|
51
|
+
|
|
52
|
+
Did this story touch any of the 5 `document-project` axes (architecture / conventions / risk-spots / dependencies / overview)? If yes, walk the PR diff and confirm the corresponding `.wize/knowledge/document-project/*.md` got 1–3 new lines this commit.
|
|
53
|
+
|
|
54
|
+
Decision:
|
|
55
|
+
- **Touched + updated** → record as PASS, no finding.
|
|
56
|
+
- **Touched + NOT updated** → record finding `KN-NN` (severity `medium`); recommendation: `gate CONCERNS` (advisory mode) or `gate FAIL` (enforcing).
|
|
57
|
+
- **Not touched** → write `knowledge: n/a` in the body, move on.
|
|
58
|
+
|
|
59
|
+
This is what keeps the brownfield baseline alive instead of stale. Without it, `document-project` is honest in week 1 and obsolete in week 24.
|
|
60
|
+
|
|
61
|
+
### 6. Findings
|
|
62
|
+
|
|
63
|
+
For each issue, write: severity (`low / medium / high`), what, why it matters, what to do.
|
|
64
|
+
|
|
65
|
+
### 7. Recommend gate outcome
|
|
66
|
+
|
|
67
|
+
Review doesn't *make* the gate decision (that's `tea-gate`); it recommends. Possible recommendations:
|
|
68
|
+
- `gate PASS`
|
|
69
|
+
- `gate CONCERNS` with N findings
|
|
70
|
+
- `gate FAIL` (only if a non-negotiable AC is `not-met`)
|
|
71
|
+
- `gate WAIVED` (only with documented reason + senior signoff)
|
|
72
|
+
|
|
73
|
+
## YAML frontmatter (canonical)
|
|
74
|
+
|
|
23
75
|
```yaml
|
|
24
76
|
---
|
|
25
77
|
gate: review
|
|
26
|
-
story_id:
|
|
27
|
-
status: PASS
|
|
78
|
+
story_id: E01-S03
|
|
79
|
+
status: PASS
|
|
28
80
|
ac_check:
|
|
29
|
-
- id: AC-1
|
|
30
|
-
met: true
|
|
31
|
-
evidence:
|
|
32
|
-
|
|
33
|
-
|
|
81
|
+
- id: AC-02-1
|
|
82
|
+
met: true
|
|
83
|
+
evidence: "e2e/onboarding/invite.spec.ts::happy path passed on PR-#412; recording in CI artifact #412-1"
|
|
84
|
+
- id: AC-02-2
|
|
85
|
+
met: true
|
|
86
|
+
evidence: "InviteForm.spec.tsx::error region announces"
|
|
87
|
+
knowledge_axes_touched: [conventions, risk-spots]
|
|
88
|
+
knowledge_axes_updated: [conventions, risk-spots] # leave empty array if axes touched but no update happened
|
|
89
|
+
findings:
|
|
90
|
+
- id: REV-01
|
|
91
|
+
severity: low
|
|
92
|
+
summary: "Empty-state copy slightly differs from Mantis' spec."
|
|
93
|
+
recommendation: "Update `<EmptyTeamPanel>` heading to 'Invite your first teammate'."
|
|
94
|
+
owner: shuri
|
|
95
|
+
blocking: false
|
|
96
|
+
risk_links: [R-1]
|
|
97
|
+
recommendation: gate-PASS
|
|
98
|
+
created_at: 2026-06-11T20:00:00Z
|
|
34
99
|
---
|
|
35
100
|
```
|
|
101
|
+
|
|
102
|
+
## Body of `review.md`
|
|
103
|
+
|
|
104
|
+
```markdown
|
|
105
|
+
## Per-AC
|
|
106
|
+
|
|
107
|
+
### AC-02-1 — met
|
|
108
|
+
Evidence: E2E `e2e/onboarding/invite.spec.ts::happy path` passed locally + CI run #412. Banner appears 720ms after click (well within 1s NFR).
|
|
109
|
+
|
|
110
|
+
### AC-02-2 — met
|
|
111
|
+
Evidence: Unit + component test both pass. Manually walked screen-reader output — VoiceOver announces "Email — error — Enter a valid email." correctly.
|
|
112
|
+
|
|
113
|
+
## Test discipline
|
|
114
|
+
- All declared tests present.
|
|
115
|
+
- `data-testid` discipline solid (invite-form, invite-email, invite-cta, invite-sent-banner).
|
|
116
|
+
- No `test.skip` / `.only`.
|
|
117
|
+
- One snapshot test — small enough to be useful; not a tree snapshot.
|
|
118
|
+
|
|
119
|
+
## Risk coverage
|
|
120
|
+
- R-1 (mailer): integration test covers the right path; happy path E2E confirms end-to-end. PASS.
|
|
121
|
+
|
|
122
|
+
## Scope discipline
|
|
123
|
+
- Two minor copy tweaks crept in (out-of-spec; logged as REV-01).
|
|
124
|
+
|
|
125
|
+
## Findings
|
|
126
|
+
- REV-01 (low): empty-state copy.
|
|
127
|
+
|
|
128
|
+
## Recommendation
|
|
129
|
+
Recommend `gate PASS` with one low-severity finding to fix in a follow-up.
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Anti-patterns Hawkeye rejects
|
|
133
|
+
|
|
134
|
+
- **Review without walking the code.** Reading the test names isn't review.
|
|
135
|
+
- **AC marked "met" without observed evidence.** Tests passing + screenshot/recording, please.
|
|
136
|
+
- **Findings without owners.** Same as everywhere else in the kit.
|
|
137
|
+
- **Recommending PASS when an AC is `partial`.** No.
|
|
138
|
+
- **Recommending PASS when a non-negotiable NFR slipped.** That's a gate FAIL.
|
|
139
|
+
|
|
140
|
+
## Hand-off
|
|
141
|
+
|
|
142
|
+
> Review for E01-S03 at `.wize/implementation/tea/E01-S03/review.md`. All ACs `met`, one low-severity copy finding. Recommending `gate PASS`. Final at `wize-tea-gate`.
|
|
@@ -4,36 +4,125 @@ name: TEA Risk Profile
|
|
|
4
4
|
gate: risk
|
|
5
5
|
owner: wize-agent-test-architect # Hawkeye
|
|
6
6
|
when: once-after-architecture
|
|
7
|
-
status:
|
|
7
|
+
status: ready
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# TEA — Risk Profile
|
|
11
11
|
|
|
12
|
-
**Goal.** Build the probability × impact matrix that prioritizes the rest of TEA's work.
|
|
12
|
+
**Goal.** Build the **probability × impact** matrix that prioritizes the rest of TEA's work. Areas in `HIGH` get deep test design; areas in `LOW` get smoke. Without a risk profile, every story is tested the same — wasteful, and unsafe.
|
|
13
|
+
|
|
14
|
+
Hawkeye drives. Tony co-signs. Runs **once**, right after architecture is signed off; revisit only on significant scope or architecture changes.
|
|
13
15
|
|
|
14
16
|
## Inputs
|
|
17
|
+
|
|
15
18
|
- `.wize/solutioning/architecture.md`
|
|
16
19
|
- `.wize/solutioning/epics/`
|
|
20
|
+
- `.wize/planning/nfr-principles.md`
|
|
21
|
+
- `.wize/knowledge/document-project/risk-spots.md` (brownfield)
|
|
17
22
|
|
|
18
23
|
## Output
|
|
24
|
+
|
|
19
25
|
- `.wize/implementation/tea/risk-profile.md`
|
|
20
26
|
|
|
27
|
+
## Steps
|
|
28
|
+
|
|
29
|
+
### 1. List candidate hot spots
|
|
30
|
+
|
|
31
|
+
For every architectural component + every epic, ask: *"If this misbehaves, what hurts?"*. Write candidates without filtering.
|
|
32
|
+
|
|
33
|
+
### 2. Score each
|
|
34
|
+
|
|
35
|
+
| Axis | Levels |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Probability | `low` (would be a surprise), `medium` (could happen), `high` (likely without explicit work) |
|
|
38
|
+
| Impact | `low` (cosmetic / opex), `medium` (user friction / revenue dent), `high` (data loss / outage / regulatory) |
|
|
39
|
+
|
|
40
|
+
Composite score:
|
|
41
|
+
- `low × low` = LOW
|
|
42
|
+
- `low × medium`, `medium × low`, `medium × medium` = MEDIUM
|
|
43
|
+
- anything touching `high` = HIGH
|
|
44
|
+
|
|
45
|
+
### 3. For each finding, write the mitigation contract
|
|
46
|
+
|
|
47
|
+
Per row:
|
|
48
|
+
- **What test makes us confident?** Unit / integration / E2E / NFR / manual.
|
|
49
|
+
- **Who owns the mitigation?** Shuri / Tony / external service.
|
|
50
|
+
- **When is it verified?** Story-level / epic-level / pre-launch.
|
|
51
|
+
|
|
52
|
+
### 4. Hand off
|
|
53
|
+
|
|
54
|
+
Hawkeye uses this in every `tea-design.md`. Tony respects it when picking ADR options.
|
|
55
|
+
|
|
21
56
|
## YAML frontmatter (canonical)
|
|
57
|
+
|
|
22
58
|
```yaml
|
|
23
59
|
---
|
|
24
60
|
gate: risk
|
|
25
61
|
status: PASS | CONCERNS | FAIL | WAIVED
|
|
26
62
|
score: 0-100
|
|
27
|
-
created_at:
|
|
63
|
+
created_at: 2026-06-11T12:00:00Z
|
|
28
64
|
findings:
|
|
29
65
|
- id: R-1
|
|
30
|
-
area:
|
|
31
|
-
probability:
|
|
32
|
-
impact:
|
|
33
|
-
rationale:
|
|
34
|
-
mitigation:
|
|
66
|
+
area: "Outbox / mailer"
|
|
67
|
+
probability: high
|
|
68
|
+
impact: medium
|
|
69
|
+
rationale: "Sign-up flow depends on email delivery; first impression failure is high-cost."
|
|
70
|
+
mitigation: "Integration test against Resend sandbox; outbox retry with backoff; on-call alert on delivery failure rate > 5%."
|
|
71
|
+
owner: shuri + tony
|
|
72
|
+
verified_when: story E01-S04 + NFR per epic
|
|
73
|
+
- id: R-2
|
|
74
|
+
area: "Database migrations under load"
|
|
75
|
+
probability: medium
|
|
76
|
+
impact: high
|
|
77
|
+
rationale: "Future migrations must be rolled out without lock contention."
|
|
78
|
+
mitigation: "Online schema changes; canary on staging with synthetic load; ADR-006 process."
|
|
79
|
+
owner: tony
|
|
80
|
+
verified_when: pre-launch
|
|
81
|
+
- id: R-3
|
|
82
|
+
area: "Auth: token refresh during long-running tabs"
|
|
83
|
+
probability: medium
|
|
84
|
+
impact: medium
|
|
85
|
+
rationale: "Cookie refresh race in RSC + edge can sign user out unexpectedly."
|
|
86
|
+
mitigation: "E2E covering > 1h tab; refresh strategy ADR-008; on-call alert on `auth_session_expired_unexpected`."
|
|
87
|
+
owner: shuri
|
|
88
|
+
verified_when: story E04-S02 + post-launch monitoring
|
|
35
89
|
---
|
|
36
90
|
```
|
|
37
91
|
|
|
38
|
-
## Body
|
|
39
|
-
|
|
92
|
+
## Body of `risk-profile.md`
|
|
93
|
+
|
|
94
|
+
The narrative explains the matrix; the YAML is the structured truth. Hawkeye writes 1–2 lines per finding explaining the *why*.
|
|
95
|
+
|
|
96
|
+
```markdown
|
|
97
|
+
## Matrix
|
|
98
|
+
|
|
99
|
+
| | Impact LOW | Impact MEDIUM | Impact HIGH |
|
|
100
|
+
|---|---|---|---|
|
|
101
|
+
| **Prob HIGH** | R-7 | R-1 | R-2 |
|
|
102
|
+
| **Prob MEDIUM** | R-4 | R-3 | R-5 |
|
|
103
|
+
| **Prob LOW** | — | R-6 | — |
|
|
104
|
+
|
|
105
|
+
## Top-3 (drive test design)
|
|
106
|
+
|
|
107
|
+
1. **R-2** — Database migrations under load. Pre-launch verification mandatory.
|
|
108
|
+
2. **R-1** — Outbox/mailer. Story E01-S04 covers; epic NFR re-verifies.
|
|
109
|
+
3. **R-5** — Payment idempotency. Story E03-S02 covers.
|
|
110
|
+
|
|
111
|
+
## What this means for `tea-design.md`
|
|
112
|
+
|
|
113
|
+
- E01-S04 (mailer): 1 unit (retry policy), 1 integration (Resend sandbox), 1 E2E (sign-up arrives within 5min).
|
|
114
|
+
- E03-S02 (payments): 2 integration (Stripe idempotency keys), 1 E2E (double-click guard).
|
|
115
|
+
- Other stories follow the default 70/20/10 split.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Anti-patterns Hawkeye rejects
|
|
119
|
+
|
|
120
|
+
- **Findings without mitigation.** A finding without a contract is a wish.
|
|
121
|
+
- **Mitigation owned by "the team."** Name a persona/human.
|
|
122
|
+
- **HIGH impact, MEDIUM probability, no NFR re-check.** Wire it into epic NFR gate.
|
|
123
|
+
- **Cosmetic risks scored HIGH.** Calibration. Reserve HIGH for data, outage, regulatory.
|
|
124
|
+
- **Risk profile rewritten per sprint.** Run once; revise on real architecture changes.
|
|
125
|
+
|
|
126
|
+
## Hand-off
|
|
127
|
+
|
|
128
|
+
> Risk profile at `.wize/implementation/tea/risk-profile.md`. Top-3 drive deep `tea-design.md` for E01-S04, E03-S02, plus pre-launch migration drill. Default 70/20/10 split for the rest.
|
|
@@ -4,33 +4,104 @@ name: TEA Traceability
|
|
|
4
4
|
gate: trace
|
|
5
5
|
owner: wize-agent-test-architect # Hawkeye
|
|
6
6
|
when: during-or-after-implementation
|
|
7
|
-
status:
|
|
7
|
+
status: ready
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# TEA — Traceability
|
|
11
11
|
|
|
12
|
-
**Goal.** Map every Acceptance Criterion to one or more concrete tests in the repo.
|
|
12
|
+
**Goal.** Map every Acceptance Criterion to **one or more concrete tests in the repo**. Reports honest coverage: `covered`, `partial`, `missing`. A story with `missing` rows cannot pass gate.
|
|
13
|
+
|
|
14
|
+
Hawkeye drives. Runs while Shuri implements (or right after PR open).
|
|
13
15
|
|
|
14
16
|
## Inputs
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
+
|
|
18
|
+
- Story file (the AC list).
|
|
19
|
+
- `tea-design.md` (the test contract).
|
|
20
|
+
- Repo (the actual test files).
|
|
17
21
|
|
|
18
22
|
## Output
|
|
23
|
+
|
|
19
24
|
- `.wize/implementation/tea/{epic}/{story}/trace.md`
|
|
20
25
|
|
|
21
|
-
##
|
|
26
|
+
## Steps
|
|
27
|
+
|
|
28
|
+
### 1. Walk every AC
|
|
29
|
+
|
|
30
|
+
For each AC ID:
|
|
31
|
+
- Find the test(s) that exercise it.
|
|
32
|
+
- Reference the file + test name precisely.
|
|
33
|
+
- Decide status: `covered` (every assertion of the AC has a test) / `partial` (some assertions only) / `missing` (no test).
|
|
34
|
+
|
|
35
|
+
### 2. Compute coverage score
|
|
36
|
+
|
|
37
|
+
- `covered_count / total_acs`.
|
|
38
|
+
- Reported but doesn't drive gate alone; the **per-AC status** drives gate.
|
|
39
|
+
|
|
40
|
+
### 3. Flag holes
|
|
41
|
+
|
|
42
|
+
For every `partial` / `missing`, write what's needed in one line. Hawkeye proposes the test; Shuri writes it.
|
|
43
|
+
|
|
44
|
+
### 4. Hand off
|
|
45
|
+
|
|
46
|
+
If everything is `covered`, status `PASS`. Otherwise `CONCERNS` (advisory) or `FAIL` (enforcing) until holes are closed.
|
|
47
|
+
|
|
48
|
+
## YAML frontmatter (canonical)
|
|
49
|
+
|
|
22
50
|
```yaml
|
|
23
51
|
---
|
|
24
52
|
gate: trace
|
|
25
|
-
story_id:
|
|
26
|
-
status: PASS
|
|
53
|
+
story_id: E01-S03
|
|
54
|
+
status: PASS
|
|
27
55
|
coverage:
|
|
28
|
-
- ac_id: AC-1
|
|
56
|
+
- ac_id: AC-02-1
|
|
57
|
+
status: covered
|
|
29
58
|
tests:
|
|
30
|
-
-
|
|
31
|
-
|
|
59
|
+
- "src/onboarding/invite/__tests__/validateInviteEmail.spec.ts::valid email"
|
|
60
|
+
- "src/onboarding/invite/__tests__/inviteTeammate.spec.ts::calls mailer with right args"
|
|
61
|
+
- "e2e/onboarding/invite.spec.ts::happy path on Playwright @chromium"
|
|
62
|
+
- ac_id: AC-02-2
|
|
63
|
+
status: covered
|
|
64
|
+
tests:
|
|
65
|
+
- "src/onboarding/invite/__tests__/validateInviteEmail.spec.ts::invalid email rules"
|
|
66
|
+
- "src/onboarding/invite/__tests__/InviteForm.spec.tsx::error region announces"
|
|
67
|
+
created_at: 2026-06-11T15:30:00Z
|
|
32
68
|
---
|
|
33
69
|
```
|
|
34
70
|
|
|
35
|
-
## Body
|
|
36
|
-
|
|
71
|
+
## Body of `trace.md`
|
|
72
|
+
|
|
73
|
+
```markdown
|
|
74
|
+
## Per-AC
|
|
75
|
+
|
|
76
|
+
### AC-02-1 — covered
|
|
77
|
+
Tests:
|
|
78
|
+
- `validateInviteEmail.spec.ts::valid email`
|
|
79
|
+
- `inviteTeammate.spec.ts::calls mailer with right args`
|
|
80
|
+
- `e2e/onboarding/invite.spec.ts::happy path`
|
|
81
|
+
|
|
82
|
+
### AC-02-2 — covered
|
|
83
|
+
Tests:
|
|
84
|
+
- `validateInviteEmail.spec.ts::invalid email rules`
|
|
85
|
+
- `InviteForm.spec.tsx::error region announces`
|
|
86
|
+
|
|
87
|
+
## Edges (from `design.md`)
|
|
88
|
+
|
|
89
|
+
- E1 (empty) — covered (validateInviteEmail.spec.ts::empty).
|
|
90
|
+
- E3 (idempotency) — **partial**. Integration test exists but doesn't assert second insert is no-op. Propose: assert `db.invites.count({ email, team_id })` = 1 after two calls.
|
|
91
|
+
- E4 (offline) — **missing**. Propose: Playwright `context.setOffline(true)` before click; assert offline banner.
|
|
92
|
+
|
|
93
|
+
## Action items
|
|
94
|
+
- Shuri: add the missing offline E2E (or split into next story; flag in `review.md` then).
|
|
95
|
+
- Hawkeye: re-run trace once PR has the new tests.
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Anti-patterns Hawkeye rejects
|
|
99
|
+
|
|
100
|
+
- **Trace by file count, not per-AC.** "We have 24 tests" tells you nothing. Per AC, please.
|
|
101
|
+
- **Counting passing CI as trace.** CI passes when a test exists; trace cares whether the test exercises the AC.
|
|
102
|
+
- **`partial` left unflagged.** Either close or list as a known-open with story link.
|
|
103
|
+
- **Re-naming tests after trace.** The trace breaks; Shuri renames in agreement with Hawkeye or doesn't rename.
|
|
104
|
+
|
|
105
|
+
## Hand-off
|
|
106
|
+
|
|
107
|
+
> Trace for E01-S03 at `.wize/implementation/tea/E01-S03/trace.md`. All ACs `covered`. Two edges still open (E3, E4); proposing follow-up. Ready for `tea-review`.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Brownfield baseline runner — detects AI harness CLIs available on PATH and,
|
|
2
|
+
// when authorized, executes `/wize-document-project` headlessly to populate
|
|
3
|
+
// .wize/knowledge/document-project/. Falls back to printed instructions when
|
|
4
|
+
// no harness is present or the user opts out.
|
|
5
|
+
//
|
|
6
|
+
// Harness priority is:
|
|
7
|
+
// 1. user's selected IDE targets (from .wize/config/project.toml), highest first
|
|
8
|
+
// 2. claude > codex > opencode (universal fallback)
|
|
9
|
+
//
|
|
10
|
+
// Set WIZE_SKIP_BASELINE=1 in the environment to disable any execution (the
|
|
11
|
+
// install still suggests the next step). Useful for CI and unattended setups.
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const fs = require('node:fs');
|
|
16
|
+
const path = require('node:path');
|
|
17
|
+
const { spawnSync } = require('node:child_process');
|
|
18
|
+
|
|
19
|
+
// Harness registry — for each supported CLI we know:
|
|
20
|
+
// binary : the executable name to find on PATH
|
|
21
|
+
// ideCode : the matching `ide_targets` code in project.toml (so we can prioritize)
|
|
22
|
+
// buildCmd: returns the spawnSync args (binary + arg list) for a headless run
|
|
23
|
+
const HARNESSES = [
|
|
24
|
+
{
|
|
25
|
+
code: 'claude-code',
|
|
26
|
+
binary: 'claude',
|
|
27
|
+
buildCmd: (prompt) => ({ cmd: 'claude', args: ['-p', prompt] })
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
code: 'codex',
|
|
31
|
+
binary: 'codex',
|
|
32
|
+
buildCmd: (prompt) => ({ cmd: 'codex', args: ['exec', '--', prompt] })
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
code: 'opencode',
|
|
36
|
+
binary: 'opencode',
|
|
37
|
+
buildCmd: (prompt) => ({ cmd: 'opencode', args: ['run', prompt] })
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
function whichSync(bin) {
|
|
42
|
+
// Manual PATH walk — more predictable than shelling out to `which`/`where`,
|
|
43
|
+
// honors PATH overrides set by callers (and our tests), and stays portable.
|
|
44
|
+
const PATH = process.env.PATH || '';
|
|
45
|
+
const sep = process.platform === 'win32' ? ';' : ':';
|
|
46
|
+
const exts = process.platform === 'win32'
|
|
47
|
+
? (process.env.PATHEXT || '.EXE;.CMD;.BAT').split(';')
|
|
48
|
+
: [''];
|
|
49
|
+
for (const dir of PATH.split(sep).filter(Boolean)) {
|
|
50
|
+
for (const ext of exts) {
|
|
51
|
+
const candidate = path.join(dir, bin + ext);
|
|
52
|
+
try {
|
|
53
|
+
const st = fs.statSync(candidate);
|
|
54
|
+
if (st.isFile() && (process.platform === 'win32' || (st.mode & 0o111))) {
|
|
55
|
+
return candidate;
|
|
56
|
+
}
|
|
57
|
+
} catch (_) { /* not here, keep looking */ }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Returns an ordered list of harnesses present on PATH. When `preferIde`
|
|
64
|
+
// includes a harness's `code`, it floats to the top of the result.
|
|
65
|
+
function detectHarnessCli({ preferIde = [] } = {}) {
|
|
66
|
+
const found = [];
|
|
67
|
+
for (const h of HARNESSES) {
|
|
68
|
+
const p = whichSync(h.binary);
|
|
69
|
+
if (p) found.push({ ...h, path: p });
|
|
70
|
+
}
|
|
71
|
+
// Float preferred IDE targets to the top, keep relative order otherwise.
|
|
72
|
+
return found.sort((a, b) => {
|
|
73
|
+
const ai = preferIde.indexOf(a.code);
|
|
74
|
+
const bi = preferIde.indexOf(b.code);
|
|
75
|
+
if (ai === -1 && bi === -1) return 0;
|
|
76
|
+
if (ai === -1) return 1;
|
|
77
|
+
if (bi === -1) return -1;
|
|
78
|
+
return ai - bi;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Run the harness headless with the document-project prompt. Returns
|
|
83
|
+
// { ok: boolean, exitCode, stdout, stderr }.
|
|
84
|
+
function runHeadlessBaseline({ harness, projectRoot, prompt, log = console.log }) {
|
|
85
|
+
if (process.env.WIZE_SKIP_BASELINE === '1') {
|
|
86
|
+
log('WIZE_SKIP_BASELINE=1 — not running the baseline; you can do it later in your IDE.');
|
|
87
|
+
return { ok: false, skipped: true };
|
|
88
|
+
}
|
|
89
|
+
const { cmd, args } = harness.buildCmd(prompt);
|
|
90
|
+
log(`Running ${cmd} ${args.map(a => /\s/.test(a) ? '"' + a + '"' : a).join(' ')}\n`);
|
|
91
|
+
const r = spawnSync(cmd, args, { cwd: projectRoot, stdio: 'inherit' });
|
|
92
|
+
return { ok: r.status === 0, exitCode: r.status, signal: r.signal };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function manualInstructions(harness) {
|
|
96
|
+
if (!harness) {
|
|
97
|
+
return [
|
|
98
|
+
'',
|
|
99
|
+
'No AI harness CLI was detected on PATH (claude / codex / opencode).',
|
|
100
|
+
'Open your IDE in this repo and run:',
|
|
101
|
+
' /wize-document-project',
|
|
102
|
+
''
|
|
103
|
+
].join('\n');
|
|
104
|
+
}
|
|
105
|
+
const { cmd, args } = harness.buildCmd('/wize-document-project');
|
|
106
|
+
const shown = `${cmd} ${args.map(a => /\s/.test(a) ? '"' + a + '"' : a).join(' ')}`;
|
|
107
|
+
return [
|
|
108
|
+
'',
|
|
109
|
+
`Skipping the headless run. When you're ready, run from this folder:`,
|
|
110
|
+
` ${shown}`,
|
|
111
|
+
'',
|
|
112
|
+
`Or open your IDE and type: /wize-document-project`,
|
|
113
|
+
''
|
|
114
|
+
].join('\n');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function defaultPrompt() {
|
|
118
|
+
return 'Activate the wize-document-project skill and execute it on this repository. Follow the steps in .claude/skills/wize-document-project/SKILL.md (or the equivalent path for your IDE). Output the baseline docs under .wize/knowledge/document-project/.';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = {
|
|
122
|
+
HARNESSES,
|
|
123
|
+
whichSync,
|
|
124
|
+
detectHarnessCli,
|
|
125
|
+
runHeadlessBaseline,
|
|
126
|
+
manualInstructions,
|
|
127
|
+
defaultPrompt
|
|
128
|
+
};
|