docs(phase-22): add validation strategy
This commit is contained in:
parent
7072190629
commit
9164dc6177
1 changed files with 84 additions and 0 deletions
|
|
@ -0,0 +1,84 @@
|
|||
---
|
||||
phase: 22
|
||||
slug: approval-ui-livelink-addressable-campaign-review-and-approve
|
||||
status: draft
|
||||
nyquist_compliant: true
|
||||
wave_0_complete: false
|
||||
created: 2026-07-16
|
||||
---
|
||||
|
||||
# Phase 22 — Validation Strategy
|
||||
|
||||
> Per-phase validation contract for feedback sampling during execution.
|
||||
|
||||
---
|
||||
|
||||
## Test Infrastructure
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| **Framework** | vitest 4.1.5 |
|
||||
| **Config file** | `/opt/stacks/pulse/vitest.config.ts` |
|
||||
| **Quick run command** | `npm test -- <specific new lib/services test file>` |
|
||||
| **Full suite command** | `npm test` |
|
||||
| **Estimated runtime** | ~30 seconds |
|
||||
|
||||
**Confirmed constraint:** `vitest.config.ts`'s `test.include` is `['lib/**/*.test.ts']` only — it does NOT include `app/**` or `components/**`. React page/component code and Next.js API route handlers in this phase have **no automated test coverage under the current config**, consistent with CLAUDE.md's stated safety net (`npx tsc --noEmit --pretty`) for untested areas. Any genuinely new *pure logic* this phase introduces should be extracted into a `lib/services/*.ts` file specifically so it can be unit-tested; UI composition and route wiring fall back to type-check as the safety net.
|
||||
|
||||
---
|
||||
|
||||
## Sampling Rate
|
||||
|
||||
- **After every task commit:** `npx tsc --noEmit --pretty` + `npm test -- <newly-added lib/services test file>` if one exists for that task
|
||||
- **After every plan wave:** `npm test` (full suite) + `npx tsc --noEmit --pretty`
|
||||
- **Before `/gsd:verify-work`:** Full suite must be green + manual click-through of both new pages (list page + ticket-scoped review page) in all four states: full-campaign, D-07 not-yet-triaged, D-08 ungrouped-report, load-error
|
||||
- **Max feedback latency:** ~30 seconds (full suite)
|
||||
|
||||
---
|
||||
|
||||
## Per-Task Verification Map
|
||||
|
||||
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|
||||
|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------|
|
||||
| TBD-resolver | TBD | TBD | REVIEW-01 | V5 Input Validation | `ticket_id` validated `Number.isFinite()` matching `analyze/route.ts` idiom; returns correct `{found, reportId, campaignId}` shape for no-report / ungrouped-report / grouped-campaign | unit | `npx vitest run lib/services/phishing-ticket-resolver.test.ts` | ❌ Wave 0 — extract resolver SQL into testable `lib/services/phishing-ticket-resolver.ts` | ⬜ pending |
|
||||
| TBD-defaults | TBD | TBD | REVIEW-04 | — | Default-param derivation table (7 action types → client-side default params) matches `ApproveActionInput` shape exactly | unit | `npx vitest run lib/services/remediation-default-params.test.ts` | ❌ Wave 0 — extract UI-SPEC's Action Area default-param logic into a pure function | ⬜ pending |
|
||||
| TBD-timeline | TBD | TBD | REVIEW-02 | — | Timeline merge/sort (reports + classifications + audit_events, chronological) — only if server-merged | unit | `npx vitest run lib/services/phishing-timeline.test.ts` | ❌ Wave 0 — only if planner chooses server-merge approach | ⬜ pending |
|
||||
| TBD-page | TBD | TBD | REVIEW-03, REVIEW-05, REVIEW-06 | V4 Access Control, Tampering (XSS) | Page rendering, action button gating/disabling per `hasPermission()`, evidence display (no `dangerouslySetInnerHTML`, URLs inert-text-only per D-09) | manual | — | N/A — no `app/**`/`components/**` test infra | ⬜ pending |
|
||||
|
||||
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
|
||||
|
||||
*Task IDs are placeholders (TBD-*) pending the planner's actual plan/task numbering — the planner must populate this table's Task ID / Plan / Wave columns to match the real PLAN.md files it produces.*
|
||||
|
||||
---
|
||||
|
||||
## Wave 0 Requirements
|
||||
|
||||
- [ ] `lib/services/phishing-ticket-resolver.ts` + `lib/services/phishing-ticket-resolver.test.ts` — ticket→campaign resolution as a testable pure function (REVIEW-01), not inline route logic
|
||||
- [ ] `lib/services/remediation-default-params.ts` + `.test.ts` — 7-action-type default-param derivation table extracted from UI-SPEC's Action Area spec (REVIEW-04), not inline component logic
|
||||
- [ ] (Conditional) `lib/services/phishing-timeline.ts` + `.test.ts` — only if the planner chooses to server-merge the timeline (REVIEW-02) rather than merge client-side
|
||||
- [ ] No framework install needed — vitest already configured and passing for the rest of the codebase
|
||||
|
||||
---
|
||||
|
||||
## Manual-Only Verifications
|
||||
|
||||
| Behavior | Requirement | Why Manual | Test Instructions |
|
||||
|----------|-------------|------------|-------------------|
|
||||
| Ticket-scoped review page renders timeline, evidence, classification correctly across all campaign states | REVIEW-02, REVIEW-03, REVIEW-04 | No `app/**`/`components/**` test infra (vitest.config.ts excludes these paths) | Click through `/phishing/tickets/{ticketId}` for: a fully-classified campaign, a D-07 not-yet-triaged ticket, a D-08 ungrouped report, and an invalid/missing ticket ID |
|
||||
| Approve/remediate/mark-false-positive buttons call correct APIs and refetch-render (D-04) | REVIEW-05 | Same — no component test infra | Approve one action, confirm page refetches and shows updated state; repeat for remediate and mark-false-positive; confirm buttons disable post-resolution (D-05) with tooltip |
|
||||
| Approve/remediate actions disabled/hidden for a non-privileged role, matching server-side `requirePermission` exactly | REVIEW-06 | Same — no component test infra; also requires a second test-role session | Sign in as a `user`-role account (no `phishing:approve`/`remediate`), confirm buttons are disabled/hidden and a direct API call still 403s |
|
||||
| Extracted URLs render as inert copy-only text, never clickable (D-09) | REVIEW-03 | Visual/DOM inspection, not unit-testable without component infra | Inspect rendered evidence section — confirm no `<a href>` wraps any indicator URL, confirm copy-to-clipboard affordance works |
|
||||
| Blast-radius `unavailable` state renders explicitly when Mimecast isn't configured | REVIEW-03 | Requires toggling integration config, not a pure-function concern | With `MIMECAST_*` env unset/disabled, load a campaign's review page and confirm an explicit "unavailable" state (not a blank/error) |
|
||||
|
||||
---
|
||||
|
||||
## Validation Sign-Off
|
||||
|
||||
- [ ] All tasks have automated verify or Wave 0 dependencies
|
||||
- [ ] Sampling continuity: no 3 consecutive tasks without automated verify
|
||||
- [ ] Wave 0 covers all MISSING references
|
||||
- [ ] No watch-mode flags
|
||||
- [ ] Feedback latency < 30s
|
||||
- [x] `nyquist_compliant: true` set in frontmatter
|
||||
|
||||
**Approval:** pending
|
||||
Loading…
Add table
Add a link
Reference in a new issue