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.
Files changed (39) hide show
  1. package/CHANGELOG.md +130 -1
  2. package/README.md +64 -0
  3. package/package.json +1 -1
  4. package/src/method-skills/1-analysis/wize-document-project/workflow.md +188 -20
  5. package/src/method-skills/1-analysis/wize-prfaq/workflow.md +150 -11
  6. package/src/method-skills/1-analysis/wize-product-brief/workflow.md +90 -19
  7. package/src/method-skills/1-analysis/wize-refresh-knowledge/workflow.md +127 -0
  8. package/src/method-skills/1-analysis/wize-research/workflow.md +101 -9
  9. package/src/method-skills/1-analysis/wize-trigger-map/workflow.md +80 -16
  10. package/src/method-skills/2-plan-workflows/wize-create-prd/workflow.md +132 -23
  11. package/src/method-skills/2-plan-workflows/wize-ux-design/workflow.md +132 -28
  12. package/src/method-skills/2-plan-workflows/wize-ux-scenarios/workflow.md +91 -15
  13. package/src/method-skills/2-plan-workflows/wize-validate-prd/workflow.md +106 -12
  14. package/src/method-skills/3-solutioning/wize-check-implementation-readiness/workflow.md +101 -11
  15. package/src/method-skills/3-solutioning/wize-create-architecture/workflow.md +197 -29
  16. package/src/method-skills/3-solutioning/wize-create-epics-and-stories/workflow.md +127 -12
  17. package/src/method-skills/3-solutioning/wize-design-system/workflow.md +182 -22
  18. package/src/method-skills/3-solutioning/wize-nfr-principles/workflow.md +142 -16
  19. package/src/method-skills/3-solutioning/wize-tech-vision/workflow.md +127 -21
  20. package/src/method-skills/4-implementation/wize-code-review/workflow.md +105 -10
  21. package/src/method-skills/4-implementation/wize-create-story/workflow.md +131 -10
  22. package/src/method-skills/4-implementation/wize-dev-story/workflow.md +140 -17
  23. package/src/method-skills/4-implementation/wize-quick-dev/workflow.md +121 -18
  24. package/src/method-skills/4-implementation/wize-retrospective/workflow.md +112 -10
  25. package/src/method-skills/4-implementation/wize-sprint-planning/workflow.md +85 -10
  26. package/src/method-skills/4-implementation/wize-sprint-status/workflow.md +96 -11
  27. package/src/orchestrator-skills/wize-help/skill.md +25 -1
  28. package/src/tea-skills/wize-tea-design/workflow.md +104 -13
  29. package/src/tea-skills/wize-tea-gate/workflow.md +115 -25
  30. package/src/tea-skills/wize-tea-nfr/workflow.md +104 -14
  31. package/src/tea-skills/wize-tea-review/workflow.md +120 -13
  32. package/src/tea-skills/wize-tea-risk/workflow.md +99 -10
  33. package/src/tea-skills/wize-tea-trace/workflow.md +83 -12
  34. package/tools/installer/baseline.js +128 -0
  35. package/tools/installer/commands/agent.js +197 -0
  36. package/tools/installer/commands/sync.js +45 -0
  37. package/tools/installer/commands/update.js +172 -0
  38. package/tools/installer/version-check.js +117 -0
  39. 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: stub
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
- - `.wize/planning/nfr-principles.md`
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
- ## YAML frontmatter
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: PASS | CONCERNS | FAIL | WAIVED
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: stub
7
+ status: ready
8
8
  ---
9
9
 
10
10
  # TEA — Story Review
11
11
 
12
- **Goal.** Structured story review (separate from Shuri's `wize-code-review`).
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
- - Story file (ACs)
16
- - Test results
17
- - Trace doc
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
- ## YAML frontmatter
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 | CONCERNS | FAIL
78
+ story_id: E01-S03
79
+ status: PASS
28
80
  ac_check:
29
- - id: AC-1
30
- met: true|partial|false
31
- evidence:
32
- findings: [...]
33
- recommendations: [...]
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: stub
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: ISO-8601
63
+ created_at: 2026-06-11T12:00:00Z
28
64
  findings:
29
65
  - id: R-1
30
- area:
31
- probability: low | medium | high
32
- impact: low | medium | high
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
- Narrative summary; the structured data is the YAML.
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: stub
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
- - Story file (ACs)
16
- - Test files produced by Shuri
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
- ## YAML frontmatter
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 | CONCERNS | FAIL
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
- - path/to/test.spec.ts::case-name
31
- status: covered | partial | missing
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
- For any `missing` or `partial`, propose what to write.
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
+ };