workflow.security_asvs_level was display-only — the planner hardcoded 'mitigate if ASVS L1 requires it' and the auditor only echoed the level, so L2/L3 behaved identically to L1. - New reference gsd-core/references/security-asvs-levels.md defines L1 (opportunistic), L2 (standard), L3 (comprehensive) for both planner threat disposition and auditor verification depth (higher = superset). - planner: disposition now scales with the configured ASVS level (no hardcoded L1) + @-pointer to the reference. - auditor: verification depth scales with asvs_level (L1 grep-presence, L2 boundary/vector check, L3 end-to-end trace + bypass check). - planning-config.md + INVENTORY updated; planner kept under its 48K cap by extracting the goal-backward worked example to planner-guidance.md. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -184,3 +184,69 @@ Execute: `/gsd:execute-phase {phase} --gaps-only`
|
||||
## Checkpoint Reached / Revision Complete
|
||||
|
||||
Follow templates in checkpoints and revision_mode sections respectively.
|
||||
|
||||
---
|
||||
|
||||
## Goal-Backward Worked Example
|
||||
|
||||
### Step 2: Derive Observable Truths
|
||||
|
||||
For "working chat interface":
|
||||
- User can see existing messages
|
||||
- User can type a new message
|
||||
- User can send the message
|
||||
- Sent message appears in the list
|
||||
- Messages persist across page refresh
|
||||
|
||||
**Test:** Each truth verifiable by a human using the application.
|
||||
|
||||
### Step 3: Derive Required Artifacts
|
||||
|
||||
"User can see existing messages" requires:
|
||||
- Message list component (renders Message[])
|
||||
- Messages state (loaded from somewhere)
|
||||
- API route or data source (provides messages)
|
||||
- Message type definition (shapes the data)
|
||||
|
||||
**Test:** Each artifact = a specific file or database object.
|
||||
|
||||
### Step 4: Derive Required Wiring
|
||||
|
||||
Message list component wiring:
|
||||
- Imports Message type (not using `any`)
|
||||
- Receives messages prop or fetches from API
|
||||
- Maps over messages to render (not hardcoded)
|
||||
- Handles empty state (not just crashes)
|
||||
|
||||
### Step 5: Identify Key Links
|
||||
|
||||
"Where is this most likely to break?" Key links = critical connections where breakage causes cascading failures.
|
||||
|
||||
### Must-Haves Output Format
|
||||
|
||||
```yaml
|
||||
must_haves:
|
||||
truths:
|
||||
- "User can see existing messages"
|
||||
- "User can send a message"
|
||||
- "Messages persist across refresh"
|
||||
artifacts:
|
||||
- path: "src/components/Chat.tsx"
|
||||
provides: "Message list rendering"
|
||||
min_lines: 30
|
||||
- path: "src/app/api/chat/route.ts"
|
||||
provides: "Message CRUD operations"
|
||||
exports: ["GET", "POST"]
|
||||
- path: "prisma/schema.prisma"
|
||||
provides: "Message model"
|
||||
contains: "model Message"
|
||||
key_links:
|
||||
- from: "src/components/Chat.tsx"
|
||||
to: "src/app/api/chat/route.ts"
|
||||
via: "fetch in useEffect — calls /api/chat endpoint"
|
||||
pattern: "fetch.*api/chat"
|
||||
- from: "src/app/api/chat/route.ts"
|
||||
to: "prisma/schema.prisma"
|
||||
via: "database query via prisma.message"
|
||||
pattern: "prisma\\.message\\.(find|create)"
|
||||
```
|
||||
|
||||
@@ -275,7 +275,7 @@ Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research":
|
||||
| `workflow.code_review_depth` | string | `"standard"` | `"light"`, `"standard"`, `"deep"` | Depth level for code review analysis in the ship workflow |
|
||||
| `workflow._auto_chain_active` | boolean | `false` | `true`, `false` | Internal: tracks whether autonomous chaining is active |
|
||||
| `workflow.security_enforcement` | boolean | `true` | `true`, `false` | Enable threat-model-anchored security verification via `/gsd:secure-phase`. When `false`, security checks are skipped entirely |
|
||||
| `workflow.security_asvs_level` | number | `1` | `1`, `2`, `3` | OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive |
|
||||
| `workflow.security_asvs_level` | number | `1` | `1`, `2`, `3` | OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive. Scales both planner threat-disposition rigor (which threats must be mitigated vs. accepted) and auditor verification depth (grep-level → boundary-placement check → full data-flow trace). See `gsd-core/references/security-asvs-levels.md`. |
|
||||
| `workflow.security_block_on` | string | `"high"` | `"high"`, `"medium"`, `"low"` | Minimum severity that blocks phase advancement |
|
||||
| `workflow.post_planning_gaps` | boolean | `true` | `true`, `false` | Post-planning gap report (#2493). After plans are generated, scans REQUIREMENTS.md and CONTEXT.md `<decisions>` against all PLAN.md files and emits a unified `Source \| Item \| Status` table. Non-blocking. Set to `false` to skip Step 13e of plan-phase. _Alias:_ `post_planning_gaps` is the flat-key form used in `CONFIG_DEFAULTS`; `workflow.post_planning_gaps` is the canonical namespaced form. |
|
||||
|
||||
|
||||
27
gsd-core/references/security-asvs-levels.md
Normal file
27
gsd-core/references/security-asvs-levels.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Security ASVS Levels
|
||||
|
||||
GSD threat modeling maps OWASP ASVS levels to planner disposition rigor and auditor verification depth. Higher levels are supersets of lower — L3 includes all L2 and L1 requirements.
|
||||
|
||||
## L1 — Opportunistic (default)
|
||||
|
||||
**Scope:** Cover threats on primary trust boundaries and high-impact components.
|
||||
|
||||
**Planner disposition:** `mitigate` critical/high-severity threats. `mitigate` medium-severity threats if they occur on a primary trust boundary; otherwise `accept` with documented rationale explaining the specific risk tolerance. `accept` low-risk threats with a rationale statement. `transfer` when threat is third-party responsibility.
|
||||
|
||||
**Auditor verification depth:** Verify each declared mitigation is PRESENT in the cited file (grep-level check — find the pattern, confirm the call exists).
|
||||
|
||||
## L2 — Standard
|
||||
|
||||
**Scope:** Map ALL applicable STRIDE categories for every in-scope component.
|
||||
|
||||
**Planner disposition:** `mitigate` medium-severity-and-above threats. Every `accept` MUST have explicit documented rationale explaining why the risk is tolerable for this specific context.
|
||||
|
||||
**Auditor verification depth:** Verify the mitigation ACTUALLY ADDRESSES the threat vector (not just that some pattern is present) and is placed at the correct trust boundary. A login check in the wrong layer does not close the threat.
|
||||
|
||||
## L3 — Comprehensive
|
||||
|
||||
**Scope:** Exhaustive STRIDE × all components; defense-in-depth for critical threats.
|
||||
|
||||
**Planner disposition:** `mitigate` all threats except those explicitly accepted with documented sign-off. Defense-in-depth layers required for critical threats (multiple independent controls).
|
||||
|
||||
**Auditor verification depth:** Deep verification — trace data flow end-to-end, check edge cases and ordering, confirm the mitigation cannot be bypassed via alternate code paths or parameter manipulation.
|
||||
@@ -77,7 +77,8 @@ Classify each threat:
|
||||
Build: `{ threat_id, category, component, disposition, status, evidence }`
|
||||
|
||||
**Short-circuit rule:**
|
||||
- If `threats_open: 0 AND register_authored_at_plan_time: true` → skip to Step 6 directly. All plan-time threats are verified CLOSED.
|
||||
- If `threats_open: 0 AND register_authored_at_plan_time: true AND asvs_level == 1` → skip to Step 6 directly. All plan-time threats are verified CLOSED at L1 grep-depth; no deeper verification required.
|
||||
- If `threats_open: 0 AND register_authored_at_plan_time: true AND asvs_level >= 2` → **do NOT skip**. The preliminary threat classification is grep-level (L1 depth) and is insufficient for L2/L3. Proceed to Step 5 (spawn the auditor) so that L2 boundary-placement checks and L3 end-to-end trace checks are performed. Skipping the auditor here would defeat ASVS level scaling for "clean" phases.
|
||||
- If `threats_open: 0 AND register_authored_at_plan_time: false` → **do NOT skip**. Empty-by-no-planning must not rubber-stamp a clean SECURITY.md. Proceed to Step 5 in **retroactive-STRIDE mode** — the auditor builds a register from implementation files first, then verifies mitigations.
|
||||
- If `threats_open > 0` → proceed to Step 4 (present threat plan to user).
|
||||
|
||||
@@ -177,7 +178,8 @@ Display `/clear` reminder.
|
||||
- [ ] Input state detected (A/B/C) — state C exits cleanly
|
||||
- [ ] PLAN.md threat model parsed, register built
|
||||
- [ ] SUMMARY.md threat flags incorporated
|
||||
- [ ] threats_open: 0 AND register_authored_at_plan_time: true → skip directly to Step 6
|
||||
- [ ] threats_open: 0 AND register_authored_at_plan_time: true AND asvs_level == 1 → skip directly to Step 6 (L1 grep-depth sufficient)
|
||||
- [ ] threats_open: 0 AND register_authored_at_plan_time: true AND asvs_level >= 2 → do NOT skip; auditor spawned for L2/L3 deep verification
|
||||
- [ ] threats_open: 0 AND register_authored_at_plan_time: false → retroactive-STRIDE mode (Step 5), not skipped
|
||||
- [ ] User gate with threat table presented
|
||||
- [ ] Auditor spawned with complete context
|
||||
|
||||
Reference in New Issue
Block a user