@hegemonart/get-design-done 1.28.0 → 1.28.6
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +134 -0
- package/SKILL.md +1 -1
- package/hooks/gdd-decision-injector.js +149 -3
- package/package.json +1 -1
- package/reference/adr-format.md +96 -0
- package/reference/architecture-vocabulary.md +102 -0
- package/reference/context-md-format.md +106 -0
- package/reference/heuristics.md +84 -0
- package/reference/registry.json +29 -1
- package/reference/registry.schema.json +1 -1
- package/reference/shared-preamble.md +78 -6
- package/reference/skill-authoring-contract.md +159 -0
- package/scripts/validate-skill-length.cjs +283 -0
- package/skills/add-backlog/SKILL.md +1 -0
- package/skills/analyze-dependencies/SKILL.md +33 -122
- package/skills/apply-reflections/SKILL.md +1 -40
- package/skills/apply-reflections/apply-reflections-procedure.md +68 -0
- package/skills/audit/SKILL.md +3 -1
- package/skills/bandit-status/SKILL.md +31 -66
- package/skills/benchmark/SKILL.md +15 -55
- package/skills/brief/SKILL.md +12 -1
- package/skills/cache-manager/SKILL.md +3 -57
- package/skills/cache-manager/cache-policy.md +126 -0
- package/skills/check-update/SKILL.md +38 -75
- package/skills/compare/SKILL.md +29 -269
- package/skills/compare/compare-rubric.md +171 -0
- package/skills/complete-cycle/SKILL.md +1 -1
- package/skills/connections/SKILL.md +21 -427
- package/skills/connections/connections-onboarding.md +417 -0
- package/skills/continue/SKILL.md +1 -0
- package/skills/darkmode/SKILL.md +32 -287
- package/skills/darkmode/darkmode-audit-procedure.md +258 -0
- package/skills/debug/SKILL.md +11 -8
- package/skills/debug/debug-feedback-loops.md +119 -0
- package/skills/design/SKILL.md +27 -245
- package/skills/design/design-procedure.md +304 -0
- package/skills/discover/SKILL.md +26 -133
- package/skills/discover/discover-procedure.md +204 -0
- package/skills/discuss/SKILL.md +18 -2
- package/skills/explore/SKILL.md +40 -205
- package/skills/explore/explore-procedure.md +267 -0
- package/skills/fast/SKILL.md +1 -0
- package/skills/figma-write/SKILL.md +2 -2
- package/skills/health/SKILL.md +11 -33
- package/skills/health/health-mcp-detection.md +44 -0
- package/skills/health/health-skill-length-report.md +69 -0
- package/skills/help/SKILL.md +1 -0
- package/skills/list-assumptions/SKILL.md +1 -0
- package/skills/map/SKILL.md +8 -31
- package/skills/new-cycle/SKILL.md +3 -1
- package/skills/new-cycle/milestone-completeness-rubric.md +87 -0
- package/skills/next/SKILL.md +1 -0
- package/skills/note/SKILL.md +1 -0
- package/skills/optimize/SKILL.md +21 -44
- package/skills/pause/SKILL.md +1 -0
- package/skills/peer-cli-add/SKILL.md +26 -108
- package/skills/peer-cli-add/peer-cli-protocol.md +161 -0
- package/skills/peer-cli-customize/SKILL.md +22 -42
- package/skills/peers/SKILL.md +33 -57
- package/skills/plan/SKILL.md +33 -220
- package/skills/plan/plan-procedure.md +278 -0
- package/skills/plant-seed/SKILL.md +1 -0
- package/skills/pr-branch/SKILL.md +1 -0
- package/skills/progress/SKILL.md +1 -7
- package/skills/quality-gate/SKILL.md +34 -166
- package/skills/quality-gate/threat-modeling.md +101 -0
- package/skills/quick/SKILL.md +1 -0
- package/skills/reapply-patches/SKILL.md +1 -0
- package/skills/recall/SKILL.md +1 -0
- package/skills/resume/SKILL.md +1 -0
- package/skills/review-backlog/SKILL.md +1 -0
- package/skills/router/SKILL.md +3 -59
- package/skills/router/router-rules.md +84 -0
- package/skills/scan/SKILL.md +36 -675
- package/skills/scan/scan-procedure.md +731 -0
- package/skills/settings/SKILL.md +1 -0
- package/skills/ship/SKILL.md +1 -0
- package/skills/sketch/SKILL.md +1 -1
- package/skills/sketch-wrap-up/SKILL.md +13 -54
- package/skills/spike/SKILL.md +1 -1
- package/skills/spike-wrap-up/SKILL.md +12 -46
- package/skills/start/SKILL.md +13 -112
- package/skills/start/start-procedure.md +115 -0
- package/skills/stats/SKILL.md +1 -0
- package/skills/style/SKILL.md +18 -140
- package/skills/style/style-doc-procedure.md +150 -0
- package/skills/synthesize/SKILL.md +1 -0
- package/skills/timeline/SKILL.md +1 -0
- package/skills/todo/SKILL.md +1 -0
- package/skills/turn-closeout/SKILL.md +36 -56
- package/skills/undo/SKILL.md +1 -0
- package/skills/update/SKILL.md +1 -0
- package/skills/verify/SKILL.md +42 -457
- package/skills/verify/verify-procedure.md +512 -0
- package/skills/warm-cache/SKILL.md +3 -35
- package/skills/zoom-out/SKILL.md +26 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: threat-modeling
|
|
3
|
+
type: heuristic
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
phase: 28.5
|
|
6
|
+
tags: [threat-modeling, stride, audit, security, trust-boundary, disposition]
|
|
7
|
+
last_updated: 2026-05-18
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Threat Modeling
|
|
11
|
+
|
|
12
|
+
Audit-side STRIDE / threat-modeling reference. Centralizes the categories, trust-boundary
|
|
13
|
+
identification heuristics, and disposition framework (mitigate / accept / transfer) so
|
|
14
|
+
consumer skills can cross-link rather than inline. Extracted as part of Phase 28.5 from
|
|
15
|
+
inline content in `skills/quality-gate/SKILL.md` (the four-tier classification) and the
|
|
16
|
+
shared verifier / audit family. See `./audit-scoring.md` for the design-side scoring
|
|
17
|
+
framework, which uses STRIDE as one of its lenses.
|
|
18
|
+
|
|
19
|
+
## When to use
|
|
20
|
+
|
|
21
|
+
Apply STRIDE during:
|
|
22
|
+
|
|
23
|
+
- **Verify entry** (Stage 5) when the changeset touches a trust boundary (auth, ingress,
|
|
24
|
+
deserialization, subprocess spawn).
|
|
25
|
+
- **Audit pillar runs** when a heuristic flags potential security surface.
|
|
26
|
+
- **Plan-phase risk-register population** when the plan touches user input, network
|
|
27
|
+
endpoints, file IO from user paths, or persisted state.
|
|
28
|
+
- **Threat register on plans that ship new endpoints** — assign one of {mitigate, accept,
|
|
29
|
+
transfer} to every identified threat before the plan ships.
|
|
30
|
+
|
|
31
|
+
## STRIDE categories
|
|
32
|
+
|
|
33
|
+
| Letter | Threat | Audit lens |
|
|
34
|
+
|--------|-------------------------|----------------------------------------------------|
|
|
35
|
+
| S | Spoofing | Auth surfaces — login, session, token issuance |
|
|
36
|
+
| T | Tampering | Data integrity — write paths, persisted state |
|
|
37
|
+
| R | Repudiation | Audit trails / logging — proof of action |
|
|
38
|
+
| I | Information Disclosure | PII / secret leakage — logs, errors, side channels |
|
|
39
|
+
| D | Denial of Service | Resource exhaustion — unbounded loops, large reads |
|
|
40
|
+
| E | Elevation of Privilege | AuthZ bypass — role checks, capability tokens |
|
|
41
|
+
|
|
42
|
+
## Trust boundaries
|
|
43
|
+
|
|
44
|
+
A trust boundary is a point where untrusted input crosses into trusted code. Identify
|
|
45
|
+
trust boundaries before applying STRIDE — each boundary is one analysis sweep.
|
|
46
|
+
|
|
47
|
+
Identification heuristics:
|
|
48
|
+
|
|
49
|
+
- **Network ingress** — HTTP, gRPC, WebSocket, MCP transport, any TCP/UDP listen socket.
|
|
50
|
+
- **File reads from user-writable paths** — uploads, `$HOME` configs, user-supplied paths
|
|
51
|
+
from CLI args, drag-drop.
|
|
52
|
+
- **Subprocess spawns with user-supplied args** — `exec`/`spawn` where any argv element
|
|
53
|
+
is reachable from user input (URL params, env vars, config keys).
|
|
54
|
+
- **Deserialization of persisted format** — JSON, YAML, MsgPack, Protobuf, custom
|
|
55
|
+
formats. The deserializer is the boundary, regardless of where the bytes came from.
|
|
56
|
+
- **Third-party SDK callouts** — when gdd hands data to a peer-CLI, the data leaves the
|
|
57
|
+
trust boundary; treat the return path as untrusted on re-entry.
|
|
58
|
+
|
|
59
|
+
## Disposition framework
|
|
60
|
+
|
|
61
|
+
Every identified threat MUST carry a disposition before the plan ships. Three values:
|
|
62
|
+
|
|
63
|
+
| Disposition | When to use |
|
|
64
|
+
|-------------|------------------------------------------------------------------------------|
|
|
65
|
+
| Mitigate | Threat has both impact and likelihood; ASVS L1 requires the control. Build |
|
|
66
|
+
| | the control as part of the plan; cite the test that proves it. |
|
|
67
|
+
| Accept | Low impact AND low likelihood. Documented rationale in the threat register; |
|
|
68
|
+
| | no code change required. Re-visit if the threat-surface scope grows. |
|
|
69
|
+
| Transfer | Third-party owns the control surface (e.g., the OS, the runtime, a peer's |
|
|
70
|
+
| | sandbox). Document the boundary; do not re-implement the control. |
|
|
71
|
+
|
|
72
|
+
Mitigations on Plan tasks are correctness requirements — the executor applies Rule 2
|
|
73
|
+
(missing critical functionality) if a mitigation disposition is present but the
|
|
74
|
+
implementation lacks the control.
|
|
75
|
+
|
|
76
|
+
## Threat register schema
|
|
77
|
+
|
|
78
|
+
When a plan carries a `<threat_model>` block in its frontmatter, each entry follows:
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
- id: T-01
|
|
82
|
+
category: spoofing # S, T, R, I, D, or E
|
|
83
|
+
surface: auth/login # path or component the threat hits
|
|
84
|
+
description: "<one-line description>"
|
|
85
|
+
disposition: mitigate # mitigate, accept, or transfer
|
|
86
|
+
control: "rate-limit + ASVS V2.2.1 password policy" # required when mitigate
|
|
87
|
+
rationale: "<why accept/transfer>" # required when accept/transfer
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Multiple threats per plan are normal. The disposition column is the load-bearing field —
|
|
91
|
+
the executor scans it; the verifier scans it.
|
|
92
|
+
|
|
93
|
+
## Cross-references
|
|
94
|
+
|
|
95
|
+
- `./audit-scoring.md` — design-side audit-scoring rubric; STRIDE is one of its lenses.
|
|
96
|
+
- `./anti-patterns.md` — concrete anti-patterns mapped to STRIDE categories where
|
|
97
|
+
applicable (e.g., `eval`-on-user-input → Tampering + EoP).
|
|
98
|
+
- `./accessibility.md` — accessibility is the orthogonal lens; threat-modeling does not
|
|
99
|
+
cover it.
|
|
100
|
+
- ASVS (OWASP Application Security Verification Standard) — external authority for the
|
|
101
|
+
control catalog. Cited in plan threat-registers as `ASVS V<chapter>.<section>`.
|
package/skills/quick/SKILL.md
CHANGED
|
@@ -3,6 +3,7 @@ name: gdd-quick
|
|
|
3
3
|
description: "Run the pipeline with optional agents skipped for speed. Skips: phase-researcher, design-assumptions-analyzer, design-integration-checker. Keeps: planner, executor, verifier, auditor."
|
|
4
4
|
argument-hint: "[--skip <agent-name>] [stage]"
|
|
5
5
|
tools: Read, Task
|
|
6
|
+
disable-model-invocation: true
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
# /gdd:quick
|
|
@@ -3,6 +3,7 @@ name: gdd-reapply-patches
|
|
|
3
3
|
description: "Reapply user modifications to reference/ files after a plugin update. Detects customizations via git diff against pristine baseline."
|
|
4
4
|
argument-hint: "[--dry-run]"
|
|
5
5
|
tools: Read, Write, Bash
|
|
6
|
+
disable-model-invocation: true
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
# gdd-reapply-patches
|
package/skills/recall/SKILL.md
CHANGED
package/skills/resume/SKILL.md
CHANGED
|
@@ -3,6 +3,7 @@ name: gdd-resume
|
|
|
3
3
|
description: "Restore session context from a numbered checkpoint. Lists available checkpoints when no argument given."
|
|
4
4
|
argument-hint: "[<N>]"
|
|
5
5
|
tools: Read, Write, Bash, Glob, AskUserQuestion, mcp__gdd_state__get, mcp__gdd_state__set_status, mcp__gdd_state__resolve_blocker, mcp__gdd_state__checkpoint, mcp__gdd_status, mcp__gdd_phase_current, mcp__gdd_plans_list, mcp__gdd_decisions_list
|
|
6
|
+
disable-model-invocation: true
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
@reference/retrieval-contract.md
|
package/skills/router/SKILL.md
CHANGED
|
@@ -53,71 +53,15 @@ Existing consumers reading any subset of the older fields keep working unchanged
|
|
|
53
53
|
|
|
54
54
|
## Path Selection Heuristic
|
|
55
55
|
|
|
56
|
-
The router emits
|
|
57
|
-
|
|
58
|
-
| complexity_class | path | Behavior |
|
|
59
|
-
|------------------|------|----------|
|
|
60
|
-
| `S` | `fast` (short-circuited) | Skip router itself, skip cache-manager, skip telemetry write. Deterministic no-op decision. |
|
|
61
|
-
| `M` | `fast` | Single Haiku + no checkers. |
|
|
62
|
-
| `L` | `quick` | Sonnet mappers + Haiku verify. |
|
|
63
|
-
| `XL` | `full` | Opus planners + full quality gates. Recommends worktree-isolation default + mandatory inter-stage checkpoint + reflector auto-spawn. |
|
|
64
|
-
|
|
65
|
-
Bucket assignment:
|
|
66
|
-
|
|
67
|
-
| Signal | complexity_class | path |
|
|
68
|
-
|--------|------------------|------|
|
|
69
|
-
| Command is `/gdd:help`, `/gdd:stats`, `/gdd:note`, `/gdd:health`, single-Haiku skill | `S` | `fast` (short-circuited — see below) |
|
|
70
|
-
| Command is `/gdd:scan`, `/gdd:brief`, `/gdd:sketch`, `/gdd:spike`, `/gdd:fast` | `M` | `fast` |
|
|
71
|
-
| Command spawns exactly one agent (no orchestration), not in S list | `M` | `fast` |
|
|
72
|
-
| Command is `/gdd:explore`, `/gdd:discover`, standalone `/gdd:verify`, standalone `/gdd:plan` | `L` | `quick` |
|
|
73
|
-
| Command spawns parallel mappers but no planners/auditors (`/gdd:discover` in `--auto` mode) | `L` | `quick` |
|
|
74
|
-
| Command is `/gdd:next`, `/gdd:do`, `/gdd:autonomous`, end-to-end Brief→Verify, anything spawning planners + auditors + verifiers in series | `XL` | `full` |
|
|
75
|
-
| Command spawns planners, auditors, verifiers, or integration-checkers (`/gdd:plan`, `/gdd:verify`, `/gdd:audit`) and is not standalone | `XL` | `full` |
|
|
76
|
-
| `--dry-run` flag present on any command | downgrade one tier (XL→L→M→S; `path` follows the mapping table) |
|
|
77
|
-
|
|
78
|
-
### S-class short-circuit
|
|
79
|
-
|
|
80
|
-
When `complexity_class` would be `S`, the router itself **does not run** for that invocation — the deterministic skip list is encoded in the `/gdd:*` SKILL.md entry of the matching command. The budget-enforcer hook treats "no router decision payload + matching command name" as the S-class signal and skips enforcement entirely (no telemetry row, no cache lookup, no event emission). When the router *is* invoked explicitly (e.g., debugging) it still emits `complexity_class: "S"` in the JSON for observability, but the runtime path is the no-op.
|
|
56
|
+
The router emits `path` (3-tier: `fast|quick|full`, legacy enum, stable for back-compat) AND `complexity_class` (4-tier: `S|M|L|XL`, Phase 25 / D-04 additive). Full mapping table, bucket-assignment signal list, `--dry-run` downgrade rule, and the S-class short-circuit semantics live in `./router-rules.md#path-selection-heuristic`. The S-class short-circuit is load-bearing: when `complexity_class` would be `S`, the router does not run; the deterministic skip list lives in the `/gdd:*` SKILL.md entry, and the budget-enforcer hook treats "no payload + matching command name" as the S signal.
|
|
81
57
|
|
|
82
58
|
## Cost Estimation Algorithm
|
|
83
59
|
|
|
84
|
-
|
|
85
|
-
total = 0
|
|
86
|
-
for each agent in planned spawn graph:
|
|
87
|
-
tier = resolve_tier(agent) # budget.json tier_overrides > agent frontmatter default-tier
|
|
88
|
-
(in_tok, out_tok) = token_range_from_size_budget(agent.size_budget) # from reference/model-prices.md
|
|
89
|
-
(in_rate, out_rate) = price_from_tier(tier)
|
|
90
|
-
total += (in_tok / 1e6) * in_rate + (out_tok / 1e6) * out_rate
|
|
91
|
-
return total
|
|
92
|
-
```
|
|
60
|
+
Standard cost-estimation pseudocode (sum over planned spawn graph; per-agent `(in_tok / 1e6) * in_rate + (out_tok / 1e6) * out_rate` using `./reference/model-prices.md`) lives in `./router-rules.md#cost-estimation-algorithm`.
|
|
93
61
|
|
|
94
62
|
## Runtime-aware model resolution
|
|
95
63
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
Computation contract (per D-07):
|
|
99
|
-
|
|
100
|
-
```
|
|
101
|
-
runtime = runtimeDetect.detect() ?? 'claude'
|
|
102
|
-
for each agent in planned spawn graph:
|
|
103
|
-
tier = resolve_tier(agent) # same merge as model_tier_overrides
|
|
104
|
-
resolved_models[agent] = tierResolver.resolve(runtime, tier)
|
|
105
|
-
# → concrete model string OR null
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
Implementation surfaces (Phase 26 / Wave A):
|
|
109
|
-
|
|
110
|
-
- `scripts/lib/runtime-detect.cjs` — `detect() → runtime-id | null`. Reads the same `*_CONFIG_DIR` / `*_HOME` env-vars Phase 24's installer uses (single source of truth in `scripts/lib/install/runtimes.cjs`). Returns `null` when no recognized runtime env-var is set; the router falls back to `'claude'` so the resolver always has a runtime ID to work with.
|
|
111
|
-
- `scripts/lib/tier-resolver.cjs` — `resolve(runtime, tier, opts?) → model | null`. Translates `opus|sonnet|haiku` to the concrete model the runtime understands using the `reference/runtime-models.md` mapping (Phase 26 / Wave A). Fallback chain (D-04): runtime-specific entry → `claude` row default with `tier_resolution_fallback` event → `null` with `tier_resolution_failed` event. Never throws; `null` is a valid output the consumer must handle.
|
|
112
|
-
|
|
113
|
-
Per-agent emission rules:
|
|
114
|
-
|
|
115
|
-
- One key per agent in the planned spawn graph (same key set the cost-estimation loop iterates over). Keys MUST match agent names exactly so consumers can join `resolved_models` against `model_tier_overrides` and the spawn graph by name.
|
|
116
|
-
- Value is the concrete model string returned by `tier-resolver.resolve(runtime, tier)`.
|
|
117
|
-
- When the resolver returns `null` (missing tier-map row, missing tier, garbage input), the value is JSON `null` — NOT omitted, NOT the empty string. Consumers (budget-enforcer, telemetry) MUST handle `null`: typically by skipping the cost row for that spawn and emitting their own diagnostic event, never by crashing.
|
|
118
|
-
- When `complexity_class` is `S` and the router itself short-circuits (see **S-class short-circuit** above), no payload is emitted at all and `resolved_models` does not exist for that invocation — the budget-enforcer's "no router decision payload" branch already handles this case.
|
|
119
|
-
|
|
120
|
-
Back-compat assertion: a router invocation in a Claude runtime (or any environment where `runtime-detect.detect()` returns `null` and the router falls back to `'claude'`) produces `resolved_models` values that are the canonical Anthropic model IDs (`claude-opus-4-7`, `claude-sonnet-4-6`, `claude-haiku-4-5`) for the corresponding tiers. Pre-Phase-26 consumers that ignore `resolved_models` see the same `model_tier_overrides` they always saw (Plan 26-09 owns the runtime fixture diff that asserts this).
|
|
64
|
+
Computation contract for `resolved_models`, implementation surfaces (`scripts/lib/runtime-detect.cjs` + `scripts/lib/tier-resolver.cjs`), per-agent emission rules (including the JSON-`null` contract), and the Claude-runtime back-compat assertion live in `./router-rules.md#runtime-aware-model-resolution`. Top-line: `model_tier_overrides` keeps its `opus|sonnet|haiku` enum for back-compat; `resolved_models` runs the per-runtime translation additively on top.
|
|
121
65
|
|
|
122
66
|
## Cache-Hit Detection
|
|
123
67
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: router-rules
|
|
3
|
+
type: heuristic
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
phase: 28.5
|
|
6
|
+
tags: [router, path-selection, complexity-class, model-tier, runtime-resolution, cost-estimation]
|
|
7
|
+
last_updated: 2026-05-18
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Router Path-Selection + Runtime Resolution Rules
|
|
11
|
+
|
|
12
|
+
Extracted from `skills/router/SKILL.md` per Phase 28.5 D-10 (extract-then-link, never delete
|
|
13
|
+
content). The router SKILL keeps its invocation contract, output schema versioning table,
|
|
14
|
+
integration point, and failure modes. The path-selection heuristic tables, the cost
|
|
15
|
+
estimation algorithm, and the runtime-aware model resolution computation contract live
|
|
16
|
+
here so the SKILL stays under the 100-line cap.
|
|
17
|
+
|
|
18
|
+
## Path Selection Heuristic
|
|
19
|
+
|
|
20
|
+
The router emits both `path` (legacy 3-tier enum) and `complexity_class` (Phase 25 4-tier enum). The canonical mapping is:
|
|
21
|
+
|
|
22
|
+
| complexity_class | path | Behavior |
|
|
23
|
+
|------------------|------|----------|
|
|
24
|
+
| `S` | `fast` (short-circuited) | Skip router itself, skip cache-manager, skip telemetry write. Deterministic no-op decision. |
|
|
25
|
+
| `M` | `fast` | Single Haiku + no checkers. |
|
|
26
|
+
| `L` | `quick` | Sonnet mappers + Haiku verify. |
|
|
27
|
+
| `XL` | `full` | Opus planners + full quality gates. Recommends worktree-isolation default + mandatory inter-stage checkpoint + reflector auto-spawn. |
|
|
28
|
+
|
|
29
|
+
Bucket assignment:
|
|
30
|
+
|
|
31
|
+
| Signal | complexity_class | path |
|
|
32
|
+
|--------|------------------|------|
|
|
33
|
+
| Command is `/gdd:help`, `/gdd:stats`, `/gdd:note`, `/gdd:health`, single-Haiku skill | `S` | `fast` (short-circuited — see below) |
|
|
34
|
+
| Command is `/gdd:scan`, `/gdd:brief`, `/gdd:sketch`, `/gdd:spike`, `/gdd:fast` | `M` | `fast` |
|
|
35
|
+
| Command spawns exactly one agent (no orchestration), not in S list | `M` | `fast` |
|
|
36
|
+
| Command is `/gdd:explore`, `/gdd:discover`, standalone `/gdd:verify`, standalone `/gdd:plan` | `L` | `quick` |
|
|
37
|
+
| Command spawns parallel mappers but no planners/auditors (`/gdd:discover` in `--auto` mode) | `L` | `quick` |
|
|
38
|
+
| Command is `/gdd:next`, `/gdd:do`, `/gdd:autonomous`, end-to-end Brief→Verify, anything spawning planners + auditors + verifiers in series | `XL` | `full` |
|
|
39
|
+
| Command spawns planners, auditors, verifiers, or integration-checkers (`/gdd:plan`, `/gdd:verify`, `/gdd:audit`) and is not standalone | `XL` | `full` |
|
|
40
|
+
| `--dry-run` flag present on any command | downgrade one tier (XL→L→M→S; `path` follows the mapping table) |
|
|
41
|
+
|
|
42
|
+
### S-class short-circuit
|
|
43
|
+
|
|
44
|
+
When `complexity_class` would be `S`, the router itself **does not run** for that invocation — the deterministic skip list is encoded in the `/gdd:*` SKILL.md entry of the matching command. The budget-enforcer hook treats "no router decision payload + matching command name" as the S-class signal and skips enforcement entirely (no telemetry row, no cache lookup, no event emission). When the router *is* invoked explicitly (e.g., debugging) it still emits `complexity_class: "S"` in the JSON for observability, but the runtime path is the no-op.
|
|
45
|
+
|
|
46
|
+
## Cost Estimation Algorithm
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
total = 0
|
|
50
|
+
for each agent in planned spawn graph:
|
|
51
|
+
tier = resolve_tier(agent) # budget.json tier_overrides > agent frontmatter default-tier
|
|
52
|
+
(in_tok, out_tok) = token_range_from_size_budget(agent.size_budget) # from reference/model-prices.md
|
|
53
|
+
(in_rate, out_rate) = price_from_tier(tier)
|
|
54
|
+
total += (in_tok / 1e6) * in_rate + (out_tok / 1e6) * out_rate
|
|
55
|
+
return total
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Runtime-aware model resolution
|
|
59
|
+
|
|
60
|
+
The router emits `resolved_models` alongside `model_tier_overrides` so downstream consumers (budget-enforcer cost computation, Phase 22 cost telemetry, Phase 23.5 bandit posterior store) can read the **concrete model ID** for the active runtime without re-deriving it from the tier name. The resolution is per-agent and additive — `model_tier_overrides` keeps its `opus|sonnet|haiku` enum for back-compat across all 14 runtimes, and `resolved_models` runs the runtime-specific translation on top of it.
|
|
61
|
+
|
|
62
|
+
Computation contract (per D-07):
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
runtime = runtimeDetect.detect() ?? 'claude'
|
|
66
|
+
for each agent in planned spawn graph:
|
|
67
|
+
tier = resolve_tier(agent) # same merge as model_tier_overrides
|
|
68
|
+
resolved_models[agent] = tierResolver.resolve(runtime, tier)
|
|
69
|
+
# → concrete model string OR null
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Implementation surfaces (Phase 26 / Wave A):
|
|
73
|
+
|
|
74
|
+
- `scripts/lib/runtime-detect.cjs` — `detect() → runtime-id | null`. Reads the same `*_CONFIG_DIR` / `*_HOME` env-vars Phase 24's installer uses (single source of truth in `scripts/lib/install/runtimes.cjs`). Returns `null` when no recognized runtime env-var is set; the router falls back to `'claude'` so the resolver always has a runtime ID to work with.
|
|
75
|
+
- `scripts/lib/tier-resolver.cjs` — `resolve(runtime, tier, opts?) → model | null`. Translates `opus|sonnet|haiku` to the concrete model the runtime understands using the `./runtime-models.md` mapping (Phase 26 / Wave A). Fallback chain (D-04): runtime-specific entry → `claude` row default with `tier_resolution_fallback` event → `null` with `tier_resolution_failed` event. Never throws; `null` is a valid output the consumer must handle.
|
|
76
|
+
|
|
77
|
+
Per-agent emission rules:
|
|
78
|
+
|
|
79
|
+
- One key per agent in the planned spawn graph (same key set the cost-estimation loop iterates over). Keys MUST match agent names exactly so consumers can join `resolved_models` against `model_tier_overrides` and the spawn graph by name.
|
|
80
|
+
- Value is the concrete model string returned by `tier-resolver.resolve(runtime, tier)`.
|
|
81
|
+
- When the resolver returns `null` (missing tier-map row, missing tier, garbage input), the value is JSON `null` — NOT omitted, NOT the empty string. Consumers (budget-enforcer, telemetry) MUST handle `null`: typically by skipping the cost row for that spawn and emitting their own diagnostic event, never by crashing.
|
|
82
|
+
- When `complexity_class` is `S` and the router itself short-circuits (see **S-class short-circuit** above), no payload is emitted at all and `resolved_models` does not exist for that invocation — the budget-enforcer's "no router decision payload" branch already handles this case.
|
|
83
|
+
|
|
84
|
+
Back-compat assertion: a router invocation in a Claude runtime (or any environment where `runtime-detect.detect()` returns `null` and the router falls back to `'claude'`) produces `resolved_models` values that are the canonical Anthropic model IDs (`claude-opus-4-7`, `claude-sonnet-4-6`, `claude-haiku-4-5`) for the corresponding tiers. Pre-Phase-26 consumers that ignore `resolved_models` see the same `model_tier_overrides` they always saw (Plan 26-09 owns the runtime fixture diff that asserts this).
|