@hegemonart/get-design-done 1.59.3 → 1.59.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +61 -0
- package/SKILL.md +2 -0
- package/figma-plugin/README.md +61 -0
- package/figma-plugin/code.ts +36 -0
- package/figma-plugin/manifest.json +12 -0
- package/figma-plugin/package-lock.json +35 -0
- package/figma-plugin/package.json +12 -0
- package/figma-plugin/src/export-variables.ts +144 -0
- package/figma-plugin/src/payload-schema.ts +250 -0
- package/figma-plugin/tsconfig.json +16 -0
- package/figma-plugin/ui.html +44 -0
- package/hooks/budget-enforcer.ts +134 -7
- package/hooks/gdd-intel-trigger.js +3 -3
- package/package.json +6 -1
- package/reference/DEPRECATIONS.md +3 -3
- package/reference/live-mode-integration.md +1 -1
- package/reference/registry.json +1 -1
- package/reference/runtime-models.md +15 -15
- package/reference/schemas/generated.d.ts +4 -0
- package/reference/schemas/runtime-models.schema.json +5 -0
- package/reference/skill-metadata.md +4 -4
- package/reference/skill-placeholders.md +2 -2
- package/scripts/build-skills.cjs +146 -0
- package/scripts/generate-skill-frontmatter.cjs +243 -0
- package/scripts/lib/bandit-router/integration.cjs +38 -0
- package/scripts/lib/install/installer.cjs +133 -1
- package/scripts/lib/manifest/scaffolder.cjs +1 -1
- package/scripts/lib/manifest/schemas/skills.schema.json +1 -1
- package/scripts/lib/manifest/skills.json +1 -1
- package/scripts/lib/new-addendum.cjs +1 -1
- package/scripts/skill-templates/README.md +90 -0
- package/scripts/skill-templates/add-backlog/SKILL.md +48 -0
- package/scripts/skill-templates/analyze-dependencies/SKILL.md +95 -0
- package/scripts/skill-templates/apply-reflections/SKILL.md +109 -0
- package/scripts/skill-templates/apply-reflections/apply-reflections-procedure.md +170 -0
- package/scripts/skill-templates/audit/SKILL.md +79 -0
- package/scripts/skill-templates/bandit-reset/SKILL.md +91 -0
- package/scripts/skill-templates/bandit-status/SKILL.md +94 -0
- package/scripts/skill-templates/benchmark/SKILL.md +65 -0
- package/scripts/skill-templates/bootstrap-ds/SKILL.md +43 -0
- package/scripts/skill-templates/brief/SKILL.md +145 -0
- package/scripts/skill-templates/budget/SKILL.md +45 -0
- package/scripts/skill-templates/cache-manager/SKILL.md +66 -0
- package/scripts/skill-templates/cache-manager/cache-policy.md +126 -0
- package/scripts/skill-templates/check-update/SKILL.md +98 -0
- package/scripts/skill-templates/compare/SKILL.md +82 -0
- package/scripts/skill-templates/compare/compare-rubric.md +171 -0
- package/scripts/skill-templates/complete-cycle/SKILL.md +81 -0
- package/scripts/skill-templates/connections/SKILL.md +71 -0
- package/scripts/skill-templates/connections/connections-onboarding.md +608 -0
- package/scripts/skill-templates/context/SKILL.md +137 -0
- package/scripts/skill-templates/continue/SKILL.md +24 -0
- package/scripts/skill-templates/darkmode/SKILL.md +76 -0
- package/scripts/skill-templates/darkmode/darkmode-audit-procedure.md +258 -0
- package/scripts/skill-templates/debug/SKILL.md +41 -0
- package/scripts/skill-templates/debug/debug-feedback-loops.md +119 -0
- package/scripts/skill-templates/design/SKILL.md +118 -0
- package/scripts/skill-templates/design/design-procedure.md +304 -0
- package/scripts/skill-templates/discuss/SKILL.md +96 -0
- package/scripts/skill-templates/do/SKILL.md +45 -0
- package/scripts/skill-templates/explore/SKILL.md +118 -0
- package/scripts/skill-templates/explore/explore-procedure.md +267 -0
- package/scripts/skill-templates/export/SKILL.md +30 -0
- package/scripts/skill-templates/extract-learnings/SKILL.md +114 -0
- package/scripts/skill-templates/fast/SKILL.md +91 -0
- package/scripts/skill-templates/figma-extract/SKILL.md +64 -0
- package/scripts/skill-templates/figma-write/SKILL.md +50 -0
- package/scripts/skill-templates/graphify/SKILL.md +49 -0
- package/scripts/skill-templates/health/SKILL.md +99 -0
- package/scripts/skill-templates/health/health-mcp-detection.md +44 -0
- package/scripts/skill-templates/health/health-skill-length-report.md +69 -0
- package/scripts/skill-templates/help/SKILL.md +60 -0
- package/scripts/skill-templates/instinct/SKILL.md +111 -0
- package/scripts/skill-templates/list-assumptions/SKILL.md +61 -0
- package/scripts/skill-templates/list-pins/SKILL.md +27 -0
- package/scripts/skill-templates/live/SKILL.md +98 -0
- package/scripts/skill-templates/locale/SKILL.md +51 -0
- package/scripts/skill-templates/map/SKILL.md +89 -0
- package/scripts/skill-templates/migrate/SKILL.md +70 -0
- package/scripts/skill-templates/migrate-context/SKILL.md +123 -0
- package/scripts/skill-templates/new-addendum/SKILL.md +81 -0
- package/scripts/skill-templates/new-cycle/SKILL.md +37 -0
- package/scripts/skill-templates/new-project/SKILL.md +53 -0
- package/scripts/skill-templates/new-skill/SKILL.md +90 -0
- package/scripts/skill-templates/next/SKILL.md +68 -0
- package/scripts/skill-templates/note/SKILL.md +48 -0
- package/scripts/skill-templates/openrouter-status/SKILL.md +86 -0
- package/scripts/skill-templates/optimize/SKILL.md +97 -0
- package/scripts/skill-templates/override/SKILL.md +86 -0
- package/scripts/skill-templates/paper-write/SKILL.md +54 -0
- package/scripts/skill-templates/pause/SKILL.md +77 -0
- package/scripts/skill-templates/peer-cli-add/SKILL.md +88 -0
- package/scripts/skill-templates/peer-cli-add/peer-cli-protocol.md +161 -0
- package/scripts/skill-templates/peer-cli-customize/SKILL.md +89 -0
- package/scripts/skill-templates/peers/SKILL.md +96 -0
- package/scripts/skill-templates/pencil-write/SKILL.md +54 -0
- package/scripts/skill-templates/pin/SKILL.md +37 -0
- package/scripts/skill-templates/plan/SKILL.md +105 -0
- package/scripts/skill-templates/plan/plan-procedure.md +278 -0
- package/scripts/skill-templates/plant-seed/SKILL.md +48 -0
- package/scripts/skill-templates/pr-branch/SKILL.md +32 -0
- package/scripts/skill-templates/progress/SKILL.md +107 -0
- package/scripts/skill-templates/quality-gate/SKILL.md +90 -0
- package/scripts/skill-templates/quality-gate/threat-modeling.md +101 -0
- package/scripts/skill-templates/quick/SKILL.md +44 -0
- package/scripts/skill-templates/reapply-patches/SKILL.md +32 -0
- package/scripts/skill-templates/recall/SKILL.md +75 -0
- package/scripts/skill-templates/reflect/SKILL.md +85 -0
- package/scripts/skill-templates/reflect/procedures/capability-gap-scan.md +119 -0
- package/scripts/skill-templates/report-issue/SKILL.md +53 -0
- package/scripts/skill-templates/report-issue/report-issue-procedure.md +119 -0
- package/scripts/skill-templates/resume/SKILL.md +93 -0
- package/scripts/skill-templates/review-backlog/SKILL.md +46 -0
- package/scripts/skill-templates/review-decisions/SKILL.md +42 -0
- package/scripts/skill-templates/roi/SKILL.md +54 -0
- package/scripts/skill-templates/rollout-status/SKILL.md +35 -0
- package/scripts/skill-templates/router/SKILL.md +89 -0
- package/scripts/skill-templates/router/capability-gap-emitter.md +65 -0
- package/scripts/skill-templates/router/router-pick-emitter.md +78 -0
- package/scripts/skill-templates/router/router-rules.md +84 -0
- package/scripts/skill-templates/settings/SKILL.md +87 -0
- package/scripts/skill-templates/ship/SKILL.md +48 -0
- package/scripts/skill-templates/sketch/SKILL.md +78 -0
- package/scripts/skill-templates/sketch-wrap-up/SKILL.md +92 -0
- package/scripts/skill-templates/skill-manifest/SKILL.md +79 -0
- package/scripts/skill-templates/spike/SKILL.md +67 -0
- package/scripts/skill-templates/spike-wrap-up/SKILL.md +86 -0
- package/scripts/skill-templates/start/SKILL.md +67 -0
- package/scripts/skill-templates/start/start-procedure.md +115 -0
- package/scripts/skill-templates/state/SKILL.md +106 -0
- package/scripts/skill-templates/stats/SKILL.md +51 -0
- package/scripts/skill-templates/style/SKILL.md +71 -0
- package/scripts/skill-templates/style/style-doc-procedure.md +150 -0
- package/scripts/skill-templates/synthesize/SKILL.md +94 -0
- package/scripts/skill-templates/timeline/SKILL.md +66 -0
- package/scripts/skill-templates/todo/SKILL.md +64 -0
- package/scripts/skill-templates/turn-closeout/SKILL.md +95 -0
- package/scripts/skill-templates/undo/SKILL.md +31 -0
- package/scripts/skill-templates/unlock-decision/SKILL.md +54 -0
- package/scripts/skill-templates/unpin/SKILL.md +31 -0
- package/scripts/skill-templates/update/SKILL.md +56 -0
- package/scripts/skill-templates/using-gdd/SKILL.md +78 -0
- package/scripts/skill-templates/verify/SKILL.md +113 -0
- package/scripts/skill-templates/verify/verify-procedure.md +511 -0
- package/scripts/skill-templates/warm-cache/SKILL.md +81 -0
- package/scripts/skill-templates/watch-authorities/SKILL.md +82 -0
- package/scripts/skill-templates/zoom-out/SKILL.md +26 -0
- package/sdk/cli/commands/build.ts +2 -2
- package/sdk/cli/index.js +2 -2
- package/sdk/cli/index.ts +1 -1
- package/skills/README.md +22 -14
- package/skills/help/SKILL.md +28 -55
- package/skills/new-skill/SKILL.md +5 -5
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-bandit-reset
|
|
3
|
+
description: "Confirm-then-reset the per-(agent, bin, delegate) bandit posterior - backs up .design/telemetry/posterior.json to posterior.json.bak, then clears it to a fresh empty envelope. Mutation companion to read-only bandit-status. Use when the posterior is corrupted/unparseable, after a major agent/skill roster change invalidates accumulated arms, or when you deliberately want to rebootstrap adaptive routing from informed priors."
|
|
4
|
+
argument-hint: "[--yes to skip the confirmation prompt]"
|
|
5
|
+
tools: Read, Write, Bash, AskUserQuestion
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# gdd-bandit-reset
|
|
10
|
+
|
|
11
|
+
## Role
|
|
12
|
+
|
|
13
|
+
You are a deterministic, destructive maintenance skill. You are the ONLY skill that clears the bandit posterior - the mutation companion to read-only `{{command_prefix}}bandit-status`. You read the posterior path declared by `scripts/lib/bandit-router.cjs`'s `DEFAULT_POSTERIOR_PATH` (`.design/telemetry/posterior.json`), REQUIRE explicit confirmation, back the file up to `posterior.json.bak`, then overwrite it with a fresh empty envelope so the next bandit pull rebootstraps from informed priors. See `./reference/bandit-integration.md` for setup, interpretation, and convergence guidance.
|
|
14
|
+
|
|
15
|
+
## Invocation Contract
|
|
16
|
+
|
|
17
|
+
- **Input**: optional `--yes` to skip the interactive confirmation (for non-interactive/automated runs).
|
|
18
|
+
- **Output**: a Markdown reset receipt to stdout (backup path + arms cleared + envelope written).
|
|
19
|
+
|
|
20
|
+
## Procedure
|
|
21
|
+
|
|
22
|
+
### 1. Locate the posterior file
|
|
23
|
+
|
|
24
|
+
Read `.design/telemetry/posterior.json` (path declared by `scripts/lib/bandit-router.cjs`'s `DEFAULT_POSTERIOR_PATH` - never hardcode a different path). Missing → nothing to reset; emit and skip to Section 5 (Record):
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
## Bandit Posterior Reset
|
|
28
|
+
|
|
29
|
+
No posterior file found at `.design/telemetry/posterior.json` — nothing to reset.
|
|
30
|
+
|
|
31
|
+
The next bandit pull with `adaptive_mode: full` will bootstrap a fresh posterior from informed priors. See `reference/bandit-integration.md`.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If present, count the arms (`arms.length`, treating a missing/non-array `arms` as `0`) so the confirmation and receipt can report what will be cleared. A corrupted/unparseable file is still resettable - report `arms: unknown (file unparseable)` and continue.
|
|
35
|
+
|
|
36
|
+
### 2. Require explicit confirmation
|
|
37
|
+
|
|
38
|
+
This is a DESTRUCTIVE operation. Do NOT proceed without confirmation.
|
|
39
|
+
|
|
40
|
+
- If `--yes` was passed, skip straight to Section 3.
|
|
41
|
+
- Otherwise, prompt via AskUserQuestion: "Reset the bandit posterior at `.design/telemetry/posterior.json`? This clears <N> learned arms. A backup will be written to `posterior.json.bak` first." with options **Reset** and **Cancel**.
|
|
42
|
+
- On **Cancel** (or any non-affirmative answer), abort WITHOUT touching either the posterior or the backup, and emit:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
## Bandit Posterior Reset — Cancelled
|
|
46
|
+
|
|
47
|
+
No changes made. The posterior at `.design/telemetry/posterior.json` is untouched (<N> arms).
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then skip to Section 5 (Record) with `reset: false`.
|
|
51
|
+
|
|
52
|
+
### 3. Back up the current posterior
|
|
53
|
+
|
|
54
|
+
Copy the live posterior to `.design/telemetry/posterior.json.bak` (sibling backup) BEFORE clearing it, so the previous state is always recoverable. Overwrite any existing `.bak` from a prior reset. If the backup write fails, ABORT before clearing; never clear without a successful backup.
|
|
55
|
+
|
|
56
|
+
### 4. Clear to a fresh empty envelope
|
|
57
|
+
|
|
58
|
+
Overwrite `.design/telemetry/posterior.json` with a fresh empty envelope matching `scripts/lib/bandit-router.cjs`'s `loadPosterior()` shape (`SCHEMA_VERSION` = `1.0.0`, current ISO `generated_at`, empty `arms`):
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"schema_version": "1.0.0",
|
|
63
|
+
"generated_at": "<ISO>",
|
|
64
|
+
"arms": []
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Write atomically where possible (`.tmp` + rename, mirroring `savePosterior()`). Then emit the receipt:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
## Bandit Posterior Reset
|
|
72
|
+
|
|
73
|
+
Posterior cleared. The next bandit pull with `adaptive_mode: full` will rebootstrap from informed priors.
|
|
74
|
+
|
|
75
|
+
- Backup: `.design/telemetry/posterior.json.bak`
|
|
76
|
+
- Arms cleared: <N>
|
|
77
|
+
- Fresh envelope: `.design/telemetry/posterior.json` (schema_version 1.0.0, 0 arms)
|
|
78
|
+
|
|
79
|
+
Restore the previous state with: `cp .design/telemetry/posterior.json.bak .design/telemetry/posterior.json`
|
|
80
|
+
Verify the cleared state with `{{command_prefix}}bandit-status`. See `reference/bandit-integration.md`.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 5. Record
|
|
84
|
+
|
|
85
|
+
Append one JSONL line to `.design/skill-records.jsonl`: `{"skill":"gdd-bandit-reset","ts":"<ISO>","reset":<bool>,"arms_cleared":<count>,"backup_written":<bool>}`. The skill mutates ONLY the posterior (+ its `.bak`) and appends to skill-records.jsonl (telemetry); it touches no other state.
|
|
86
|
+
|
|
87
|
+
## Cross-references
|
|
88
|
+
|
|
89
|
+
- `{{command_prefix}}bandit-status` - read-only companion; inspect the posterior before/after a reset.
|
|
90
|
+
- `./reference/bandit-integration.md` - operator guide; interpretation patterns and when a reset is warranted.
|
|
91
|
+
- `scripts/lib/bandit-router.cjs` - posterior shape, `DEFAULT_POSTERIOR_PATH`, `SCHEMA_VERSION`, `loadPosterior()`, `savePosterior()`, `reset()`.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-bandit-status
|
|
3
|
+
description: "Surface read-only per-(agent, bin, delegate) bandit posterior snapshot - alpha/beta/mean/stddev/count/last-used per arm. Phase 27.5 (v1.27.5) diagnostic. Use when investigating 'why did the bandit pick tier X for agent Y?' or when verifying posterior convergence after enabling adaptive_mode: full."
|
|
4
|
+
argument-hint: ""
|
|
5
|
+
tools: Read, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# gdd-bandit-status
|
|
9
|
+
|
|
10
|
+
## Role
|
|
11
|
+
|
|
12
|
+
You are a deterministic, read-only diagnostic skill. You do not spawn agents and do not modify the posterior. You read `.design/telemetry/posterior.json` (path declared by `scripts/lib/bandit-router.cjs`'s `DEFAULT_POSTERIOR_PATH`), aggregate per-`(agent, bin, delegate, tier)` arm state, and emit a single Markdown table. Read-only per Phase 27.5 D-11 - to reset, use `{{command_prefix}}bandit-reset` (Phase 23.5). See `./reference/bandit-integration.md` for setup, interpretation, and convergence guidance.
|
|
13
|
+
|
|
14
|
+
## Invocation Contract
|
|
15
|
+
|
|
16
|
+
- **Input**: none.
|
|
17
|
+
- **Output**: a Markdown bandit-status table to stdout. The table is the entire output.
|
|
18
|
+
|
|
19
|
+
## Procedure
|
|
20
|
+
|
|
21
|
+
### 1. Locate the posterior file
|
|
22
|
+
|
|
23
|
+
Read `.design/telemetry/posterior.json`. Missing → emit empty-state message:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
## Bandit Posterior Snapshot
|
|
27
|
+
|
|
28
|
+
No posterior data yet — run a few pipeline cycles with `adaptive_mode: full` first.
|
|
29
|
+
|
|
30
|
+
No posterior data found at `.design/telemetry/posterior.json`.
|
|
31
|
+
|
|
32
|
+
Possible reasons:
|
|
33
|
+
- `adaptive_mode` is `static` or `hedge` (bandit silent — see `.design/budget.json`).
|
|
34
|
+
- No spawns have fired since Phase 27.5 wiring landed.
|
|
35
|
+
- Posterior was cleared via `{{command_prefix}}bandit-reset`.
|
|
36
|
+
|
|
37
|
+
See `reference/bandit-integration.md` for setup guidance.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Skip to Section 4 (Record). Parse failure (truncated/corrupted) → emit `Posterior file exists but is unparseable. Run {{command_prefix}}bandit-reset to start fresh, or restore from a backup.`
|
|
41
|
+
|
|
42
|
+
### 2. Parse the posterior
|
|
43
|
+
|
|
44
|
+
Schema:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"schema_version": "1.0.0",
|
|
49
|
+
"generated_at": "<ISO>",
|
|
50
|
+
"arms": [{ "agent": "...", "bin": "...", "tier": "...", "delegate": "...", "alpha": N, "beta": N, "last_used": "...", "count": N }]
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The `delegate` field is optional - absent = Phase 23.5 legacy slice (rendered as `-` in the table).
|
|
55
|
+
|
|
56
|
+
### 3. Render the table
|
|
57
|
+
|
|
58
|
+
Compute per arm: `mean = alpha / (alpha + beta)` (3 decimals), `stddev = sqrt(alpha*beta / ((alpha+beta)^2 * (alpha+beta+1)))` (3 decimals).
|
|
59
|
+
|
|
60
|
+
Sort by `(agent ASC, bin ASC, delegate ASC where '-' first, tier ASC opus<sonnet<haiku, last_used DESC)`. Group by agent for readability.
|
|
61
|
+
|
|
62
|
+
Emit:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
## Bandit Posterior Snapshot
|
|
66
|
+
|
|
67
|
+
Per-(agent, bin, delegate, tier) posterior state. Read-only — to reset use `{{command_prefix}}bandit-reset` (Phase 23.5).
|
|
68
|
+
|
|
69
|
+
Posterior file: `.design/telemetry/posterior.json` (last updated: <generated_at>)
|
|
70
|
+
Total arms: <count>
|
|
71
|
+
|
|
72
|
+
| Agent | Bin | Delegate | Tier | Alpha | Beta | Mean | Stddev | Count | Last Used |
|
|
73
|
+
|-------|-----|----------|------|-------|------|------|--------|-------|-----------|
|
|
74
|
+
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
|
|
75
|
+
|
|
76
|
+
> Mean = alpha / (alpha + beta). Stddev = sqrt(alpha*beta / ((alpha+beta)^2 * (alpha+beta+1))).
|
|
77
|
+
> Delegate '-' = Phase 23.5 legacy slice (equivalent to 'none').
|
|
78
|
+
> See `reference/bandit-integration.md` for interpretation.
|
|
79
|
+
> Read-only — use `{{command_prefix}}bandit-reset` to clear posterior state.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Precision: alpha/beta 2 decimals; mean/stddev 3 decimals; count integer; `last_used` truncated to minute (`YYYY-MM-DDTHH:MM`); null `last_used` renders `-`.
|
|
83
|
+
|
|
84
|
+
After the table, surface a per-`(agent, bin)` best-arm summary: for each unique pair, identify highest-mean arm (tie-broken by `count` DESC) - answers "why did the bandit pick tier X?" at a glance.
|
|
85
|
+
|
|
86
|
+
### 4. Record
|
|
87
|
+
|
|
88
|
+
Append one JSONL line to `.design/skill-records.jsonl`: `{"skill":"gdd-bandit-status","ts":"<ISO>","arms_seen":<count>,"posterior_present":<bool>}`. Skill writes ONLY to skill-records.jsonl (telemetry); never touches the posterior.
|
|
89
|
+
|
|
90
|
+
## Cross-references
|
|
91
|
+
|
|
92
|
+
- `./reference/bandit-integration.md` - operator guide; interpretation patterns.
|
|
93
|
+
- `scripts/lib/bandit-router.cjs` (Phase 23.5) - posterior shape, `DEFAULT_POSTERIOR_PATH`, `loadPosterior()`.
|
|
94
|
+
- `scripts/lib/bandit-router/integration.cjs` (27.5-01), `hooks/budget-enforcer.ts` (27.5-02), `scripts/lib/session-runner/index.ts` (27.5-03), `scripts/lib/bandit-arbitrage.cjs` (27.5-04), `{{command_prefix}}bandit-reset` (Phase 23.5) - only surface that mutates the posterior.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-benchmark
|
|
3
|
+
description: "Harvest and synthesize per-component design benchmarks from 18 design systems and produce canonical component specs at `reference/components/<name>.md`. Use when adding a new component spec, running a benchmark wave, listing corpus coverage, or refreshing a spec after a design-system version bump."
|
|
4
|
+
argument-hint: "<component> | --wave <N> | --list | --refresh <component>"
|
|
5
|
+
tools: Read, Write, Bash, Grep, Glob, Task, WebFetch
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# {{command_prefix}}benchmark
|
|
9
|
+
|
|
10
|
+
Harvest per-component design knowledge from 18 design systems and synthesize canonical
|
|
11
|
+
specs at `reference/components/<name>.md`. The 18-source corpus + fallback chain lives in
|
|
12
|
+
`../../connections/design-corpora.md`. Per-skill output discipline + completion-marker
|
|
13
|
+
conventions are at `../../reference/shared-preamble.md#output-contract-reminders`.
|
|
14
|
+
|
|
15
|
+
## Invocation Modes
|
|
16
|
+
|
|
17
|
+
| Invocation | Action |
|
|
18
|
+
|------------|--------|
|
|
19
|
+
| `{{command_prefix}}benchmark <component>` | Harvest + synthesize a single component |
|
|
20
|
+
| `{{command_prefix}}benchmark --wave <N>` | Run a full wave (1 = Inputs, 2 = Containers, etc.) |
|
|
21
|
+
| `{{command_prefix}}benchmark --list` | Show corpus coverage - which specs exist, which are pending |
|
|
22
|
+
| `{{command_prefix}}benchmark --refresh <component>` | Re-harvest a spec (for design-system version bumps) |
|
|
23
|
+
|
|
24
|
+
## Single-Component Flow (`{{command_prefix}}benchmark <component>`)
|
|
25
|
+
|
|
26
|
+
1. **Check if spec exists** - `Glob("reference/components/<component>.md")`. If found and `--refresh` was not passed, confirm before overwriting.
|
|
27
|
+
|
|
28
|
+
2. **Harvest** - spawn `component-benchmark-harvester` with required-reading `@connections/design-corpora.md`, target component, raw-output path `.planning/benchmarks/raw/<component>.md`, and a salvage hint to `.planning/research/impeccable-salvage/`. Acceptance: raw harvest exists with ≥4 source sections.
|
|
29
|
+
|
|
30
|
+
3. **Synthesize** - spawn `component-benchmark-synthesizer` with required-reading `@.planning/benchmarks/raw/<component>.md`, `@reference/components/TEMPLATE.md`, `@reference/anti-patterns.md`. Output: `reference/components/<component>.md`. Also update `reference/components/README.md` (add entry in correct category). Acceptance: spec ≤350 lines, cites ≥4 systems, follows `TEMPLATE.md` sections, has a WAI-ARIA keyboard contract + a failing-example block.
|
|
31
|
+
|
|
32
|
+
4. **Report** - print spec path, line count, systems cited.
|
|
33
|
+
|
|
34
|
+
## Wave Mode (`{{command_prefix}}benchmark --wave <N>`)
|
|
35
|
+
|
|
36
|
+
Read the wave definition from `reference/components/README.md` and run each component sequentially (not parallel - each harvest is network-bound and the raw files are large).
|
|
37
|
+
|
|
38
|
+
| Wave | Components |
|
|
39
|
+
|------|-----------|
|
|
40
|
+
| 1 | button, input, select-combobox, checkbox, radio, switch, link, label |
|
|
41
|
+
| 2 | card, modal-dialog, drawer, popover, tooltip, accordion, tabs |
|
|
42
|
+
|
|
43
|
+
Print progress per component: `[N/total] harvesting <component>…`
|
|
44
|
+
|
|
45
|
+
## List Mode (`{{command_prefix}}benchmark --list`)
|
|
46
|
+
|
|
47
|
+
Read `reference/components/README.md` and diff against `reference/components/*.md` files. Print a table with columns: Component, Status, Wave, Lines.
|
|
48
|
+
|
|
49
|
+
## Refresh Mode (`{{command_prefix}}benchmark --refresh <component>`)
|
|
50
|
+
|
|
51
|
+
Same as single-component flow but skips the "already exists" guard. Use when a design system ships a breaking update to a component's spec.
|
|
52
|
+
|
|
53
|
+
## Source List
|
|
54
|
+
|
|
55
|
+
`../../connections/design-corpora.md` - 18 design systems with canonical URLs, licensing, and fallback chain (canonical → archive.org → Refero MCP → Pinterest MCP).
|
|
56
|
+
|
|
57
|
+
## Output Artifacts
|
|
58
|
+
|
|
59
|
+
| Artifact | Purpose |
|
|
60
|
+
|----------|---------|
|
|
61
|
+
| `.planning/benchmarks/raw/<component>.md` | Raw multi-source harvest (input only) |
|
|
62
|
+
| `reference/components/<component>.md` | Canonical spec (distributed with plugin) |
|
|
63
|
+
| `reference/components/README.md` | Corpus index (updated by synthesizer) |
|
|
64
|
+
|
|
65
|
+
## BENCHMARK COMPLETE
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-bootstrap-ds
|
|
3
|
+
description: "Bootstraps a design system for a GREENFIELD project that has none - no Figma, no tokens, no component library. Takes a brand input (primary color + optional secondary + tone tags + target framework) and emits a coherent OKLCH token system (color tints, modular type scale, 4pt/8pt spacing, radius + motion defaults) in 3 variants to pick from, then scaffolds proof components (button/input/card). Use at the start of a brand-new project, or when {{command_prefix}}explore finds no existing design system. Never invents a brand; never overwrites an existing DS."
|
|
4
|
+
argument-hint: "[--primary <color>] [--secondary <color>] [--tone <tags>] [--framework web|native-ios|native-android|flutter]"
|
|
5
|
+
user-invocable: true
|
|
6
|
+
tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, Task
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# {{command_prefix}}bootstrap-ds
|
|
10
|
+
|
|
11
|
+
Greenfield design-system bootstrap. Closes the gap that GDD's `design-context-builder` assumes a design system already exists (in code or Figma) - a brand-new project has none. This skill is the **front door**: it collects a brand input and hands it to `agents/ds-generator.md`, which emits the token system + proof components per `reference/ds-bootstrap-rubric.md` (deterministic math in `scripts/lib/ds/token-scale.cjs`).
|
|
12
|
+
|
|
13
|
+
## When to use
|
|
14
|
+
|
|
15
|
+
- At the start of a brand-new project (no `tailwind.config`, no token file, no DS).
|
|
16
|
+
- When `{{command_prefix}}discover` / `design-context-builder` reports **no existing design system** and the user opts to bootstrap one.
|
|
17
|
+
|
|
18
|
+
If a design system **already exists**, do NOT run this - defer to `design-context-builder` (it maps the existing one). State that and stop.
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
1. **Collect the brand input.** From flags, or via `AskUserQuestion` for anything missing:
|
|
23
|
+
- **primary** (required) - the brand color (hex / rgb / `oklch()`).
|
|
24
|
+
- **secondary** (optional) - a second brand color (emitted only if supplied - the rubric's ≤2-brand-colors rule).
|
|
25
|
+
- **tone tags** (optional) - `calm` / `corporate` / `editorial` / `playful` / `bold` (maps to the type ratio + chroma treatment).
|
|
26
|
+
- **target framework** (optional) - `web` (default) / `native-ios` / `native-android` / `flutter`. Detect from the project if absent (Phase 34 routing).
|
|
27
|
+
2. **Delegate to `ds-generator`** (via `Task`): it resolves the primary to OKLCH, runs `token-scale.cjs` for **3 variants** (conservative / balanced / bold), and presents them.
|
|
28
|
+
3. **Pick a variant.** Surface the 3 variants (primary `500`, type ratio, spacing baseline, radius, feel); the user picks ONE.
|
|
29
|
+
4. **Emit + scaffold (proposal → confirm).** `ds-generator` emits the chosen token set (role-named CSS custom properties + the framework mapping) and scaffolds **button / input / card** as a coherence proof. Nothing is written to `src/` without confirmation.
|
|
30
|
+
|
|
31
|
+
## Do Not
|
|
32
|
+
|
|
33
|
+
- Do not invent a brand (no logomark, no typeface choice, no third brand color) - emit a token *system*, not an identity.
|
|
34
|
+
- Do not overwrite an existing design system - defer to `design-context-builder`.
|
|
35
|
+
- Do not add a color-conversion dependency - `token-scale.cjs` emits native CSS `oklch()`.
|
|
36
|
+
|
|
37
|
+
## Output
|
|
38
|
+
|
|
39
|
+
End with:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
## BOOTSTRAP-DS COMPLETE
|
|
43
|
+
```
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-brief
|
|
3
|
+
description: "Stage 1 of 5 design intake that captures problem statement, audience, constraints, success metrics, and scope into .design/BRIEF.md, and bootstraps .design/STATE.md if missing. Use when starting a new design cycle and before {{command_prefix}}explore. Activates for requests involving capturing a problem statement, defining audience and constraints, or starting a new design brief."
|
|
4
|
+
argument-hint: "[--re-brief to redo intake on existing project]"
|
|
5
|
+
tools: Read, Write, AskUserQuestion, mcp__gdd_state__frontmatter_update, mcp__gdd_state__set_status, mcp__gdd_state__update_progress, mcp__gdd_state__get
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Get Design Done - Brief
|
|
9
|
+
|
|
10
|
+
**Role:** You are the Brief stage. Stage 1 of 5 in the get-design-done pipeline.
|
|
11
|
+
|
|
12
|
+
**Purpose:** Capture the design problem before any scanning or exploration. Produces `.design/BRIEF.md`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Step 1 - Check for existing BRIEF.md
|
|
17
|
+
|
|
18
|
+
1. Read `.design/BRIEF.md` if it exists.
|
|
19
|
+
2. Parse it into sections: Problem, Audience, Constraints, Success Metrics, Scope.
|
|
20
|
+
3. Note which sections are already answered (non-empty).
|
|
21
|
+
4. If `--re-brief` flag is passed, ignore existing answers and ask all five questions.
|
|
22
|
+
5. Otherwise, only ask questions for unanswered sections.
|
|
23
|
+
|
|
24
|
+
## Step 2 - Interview
|
|
25
|
+
|
|
26
|
+
Ask the following one at a time using `AskUserQuestion`, only for unanswered sections:
|
|
27
|
+
|
|
28
|
+
1. **Problem** - "What design problem are we solving? (user-facing outcome)"
|
|
29
|
+
2. **Audience** - "Who is the primary audience? (role, device, context)"
|
|
30
|
+
3. **Constraints** - "What constraints apply? (tech stack, brand, time, a11y requirements)"
|
|
31
|
+
4. **Success Metrics** - "How will we measure success? (specific metrics or outcomes)"
|
|
32
|
+
5. **Scope** - "What is in/out of scope for this cycle?"
|
|
33
|
+
|
|
34
|
+
Do not proceed to the next question until the current one is answered.
|
|
35
|
+
|
|
36
|
+
## Step 3 - Write .design/BRIEF.md
|
|
37
|
+
|
|
38
|
+
Write the brief with these sections, preserving any pre-existing answers:
|
|
39
|
+
|
|
40
|
+
```markdown
|
|
41
|
+
# Design Brief — <project name>
|
|
42
|
+
|
|
43
|
+
## Problem
|
|
44
|
+
<answer>
|
|
45
|
+
|
|
46
|
+
## Audience
|
|
47
|
+
<answer>
|
|
48
|
+
|
|
49
|
+
## Constraints
|
|
50
|
+
<answer>
|
|
51
|
+
|
|
52
|
+
## Success Metrics
|
|
53
|
+
<answer>
|
|
54
|
+
|
|
55
|
+
## Scope
|
|
56
|
+
<answer>
|
|
57
|
+
|
|
58
|
+
<prior-research>
|
|
59
|
+
<!-- Phase 38: populated by agents/user-research-synthesizer.md from UserTesting/Maze/Hotjar
|
|
60
|
+
(pseudonymized) — ranked findings {finding · frequency · severity}. Empty on a fresh brief;
|
|
61
|
+
the verify stage cross-checks each finding (addressed or explicitly deferred). -->
|
|
62
|
+
</prior-research>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Leave the `<prior-research>` block empty on a greenfield brief - it is filled by `{{command_prefix}}research-sync` (the `user-research-synthesizer`) when a research source is connected, and re-checked at verify. See `reference/design-variants.md` for the outcome loop.
|
|
66
|
+
|
|
67
|
+
## Step 4 - Bootstrap STATE.md (if missing)
|
|
68
|
+
|
|
69
|
+
<!-- BOOTSTRAP EXCEPTION: STATE.md does not exist yet — MCP tools require it to exist. Direct Write is intentional. All subsequent mutations use MCP. -->
|
|
70
|
+
|
|
71
|
+
If `.design/STATE.md` does not exist, copy the template block from `reference/STATE-TEMPLATE.md` (between `==== BEGIN TEMPLATE ====` and `==== END TEMPLATE ====`) to `.design/STATE.md` via `Write`. Leave the `<ISO 8601 timestamp>` placeholders in-place - Step 5 stamps them via MCP. If STATE.md already exists, skip to Step 5.
|
|
72
|
+
|
|
73
|
+
## Step 5 - Commit STATE.md initialization
|
|
74
|
+
|
|
75
|
+
With `.design/STATE.md` seeded from the template:
|
|
76
|
+
|
|
77
|
+
1. Stamp timestamps + cycle id: call `mcp__gdd_state__frontmatter_update` with `patch: { started_at: <ISO>, last_checkpoint: <ISO>, cycle: <cycle-id> }`.
|
|
78
|
+
2. Mark brief progress: call `mcp__gdd_state__update_progress` with `task_progress: "5/5"`, `status: "brief_complete"`.
|
|
79
|
+
3. Set handoff status: call `mcp__gdd_state__set_status` with `status: "brief_complete"`.
|
|
80
|
+
|
|
81
|
+
Do NOT call `mcp__gdd_state__transition_stage` from brief - explore calls it on entry, keeping the transition atomic with the stage that owns the new state.
|
|
82
|
+
|
|
83
|
+
## Step 6 - Inline glossary (CONTEXT.md) + ADR pointer
|
|
84
|
+
|
|
85
|
+
When a fuzzy phrase is resolved or a new domain concept is named during the briefing
|
|
86
|
+
interview: write to `./CONTEXT.md` IMMEDIATELY per `./../../reference/context-md-format.md`
|
|
87
|
+
(H2 heading + body; lazy-create on first term; no batching). Glossary entries compound
|
|
88
|
+
across cycles - token savings + naming consistency.
|
|
89
|
+
|
|
90
|
+
Project-shaping decisions surfaced in briefing can be promoted to an ADR - see
|
|
91
|
+
`./../../reference/adr-format.md` for the 3-criteria gate (hard-to-reverse AND
|
|
92
|
+
surprising-without-context AND real-tradeoff). Routine choices stay in STATE.md.
|
|
93
|
+
|
|
94
|
+
## After Writing
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
━━━ Brief complete ━━━
|
|
98
|
+
Saved: .design/BRIEF.md
|
|
99
|
+
Next: @get-design-done explore
|
|
100
|
+
━━━━━━━━━━━━━━━━━━━━━━━
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Spec self-review (before transition)
|
|
104
|
+
|
|
105
|
+
Run this final spec-quality pass over `.design/BRIEF.md` before the brief→explore transition:
|
|
106
|
+
- Placeholder scan: no TBD / TODO / `<placeholder>` / lorem left in the artifact.
|
|
107
|
+
- Internal consistency: sections don't contradict each other.
|
|
108
|
+
- Scope check: nothing in the artifact exceeds (or silently drops) the agreed scope.
|
|
109
|
+
- Ambiguity check: every requirement/decision is specific enough to act on without a follow-up question.
|
|
110
|
+
|
|
111
|
+
## Optional brief audit (non-blocking)
|
|
112
|
+
|
|
113
|
+
Before the gate, you MAY spawn `agents/brief-auditor.md` via `Task` to grade the brief against the five
|
|
114
|
+
brief anti-patterns (vague verbs, missing audience, immeasurable success criteria, scope creep, missing
|
|
115
|
+
anti-goals). The auditor reads `.design/BRIEF.md` plus `reference/brief-quality-rubric.md` and writes
|
|
116
|
+
advisory findings to `.design/BRIEF-AUDIT.md`. This step is advisory and MUST NOT block the brief to
|
|
117
|
+
explore transition.
|
|
118
|
+
|
|
119
|
+
If the auditor reports one or more fired anti-patterns, surface a single-line pointer to the user:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Brief audit flagged N issue(s) - run {{command_prefix}}discuss brief to refine, or proceed to explore.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The user decides. Proceeding to explore with a flagged brief is allowed; the pointer is a nudge, not a gate.
|
|
126
|
+
If the auditor reports no fired anti-patterns, or you skip the audit, continue to the gate unchanged.
|
|
127
|
+
|
|
128
|
+
<HARD-GATE>
|
|
129
|
+
Do NOT transition to explore (or invoke `{{command_prefix}}explore`) until the brief artifact (default `.design/BRIEF.md`) is committed AND the user has approved it. If this project uses a custom `.design` location, read the artifact path from `.design/STATE.md` rather than assuming the default.
|
|
130
|
+
</HARD-GATE>
|
|
131
|
+
|
|
132
|
+
## Rationalizations - Thought to Reality
|
|
133
|
+
|
|
134
|
+
The excuses an agent invents to skip or shortcut the brief, and what each one actually costs the cycle:
|
|
135
|
+
|
|
136
|
+
| Thought | Reality |
|
|
137
|
+
|---------|---------|
|
|
138
|
+
| "This brief is too simple to need a problem statement." | Skip the brief = guess at requirements, then redesign mid-design when the real problem surfaces. |
|
|
139
|
+
| "The user told me what to build, I can skip the interview." | Unasked constraints (a11y, brand, stack) become rework - the five questions exist because each one has blown a past cycle. |
|
|
140
|
+
| "I'll capture success metrics later in verify." | Verify has nothing to check against; an un-metricked brief produces an un-verifiable cycle. |
|
|
141
|
+
| "Scope is obvious, I don't need an in/out line." | Undeclared scope is scope creep waiting to happen - the explore scan widens to fill the vacuum. |
|
|
142
|
+
| "I can answer all five questions for the user from context." | AskUserQuestion one-at-a-time exists because batched/assumed answers smuggle in wrong premises that compound downstream. |
|
|
143
|
+
| "STATE.md bootstrap can wait." | Every later MCP mutation requires STATE.md to exist; skipping the bootstrap hard-blocks explore on entry. |
|
|
144
|
+
|
|
145
|
+
## BRIEF COMPLETE
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-budget
|
|
3
|
+
description: "Forecasts GDD design-cycle spend before the bill arrives. Reads .design/telemetry/costs.jsonl (cost per cycle) + .design/budget.json (the project_cap), runs the pure cost-forecast model via agents/cost-forecaster.md, and projects the next N cycles - surfacing 'at the current rate you'll hit your $X project cap in Y cycles.' Supports --scenario best|typical|worst and --cycles N. Read-only - it forecasts and warns; it never spends, edits budget.json, or halts (the budget-enforcer hook halts). Use to sanity-check spend trajectory before a long run."
|
|
4
|
+
argument-hint: "[--cycles N] [--scenario best|typical|worst]"
|
|
5
|
+
user-invocable: true
|
|
6
|
+
tools: Read, Bash, Grep, Glob, ToolSearch, Task
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# {{command_prefix}}budget
|
|
10
|
+
|
|
11
|
+
Closes the long-horizon cost gap: Phase 10.1 per-task caps + Phase 26 per-runtime telemetry track
|
|
12
|
+
*cost*, but nothing **forecasts** it. This skill projects the next N cycles of spend and tells you how
|
|
13
|
+
many cycles you have before you hit your `project_cap`. **Read-only** - it forecasts and warns; it
|
|
14
|
+
never spends, never edits `budget.json`, and never halts (the Phase 25 budget-enforcer hook is the
|
|
15
|
+
only thing that blocks a spawn). Contract: `../../reference/cost-governance.md`.
|
|
16
|
+
|
|
17
|
+
## Invocation
|
|
18
|
+
|
|
19
|
+
| Command | Behavior |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `{{command_prefix}}budget` | Typical-scenario forecast over the next 5 cycles + cycles-to-cap. |
|
|
22
|
+
| `{{command_prefix}}budget --cycles N` | Forecast over the next N cycles. |
|
|
23
|
+
| `{{command_prefix}}budget --scenario best\|typical\|worst` | Pick the projection rate (best / steady / worst). |
|
|
24
|
+
|
|
25
|
+
## Steps
|
|
26
|
+
|
|
27
|
+
1. **Check telemetry exists.** No `.design/telemetry/costs.jsonl` (or zero rows) → print
|
|
28
|
+
`budget: no cost telemetry yet — run a cycle first.` and exit.
|
|
29
|
+
2. **Delegate to `cost-forecaster`** (via `Task`): it groups `est_cost_usd` by `cycle`, runs the pure
|
|
30
|
+
`scripts/lib/budget/cost-forecast.cjs` model for the requested `--scenario`/`--cycles`, reads
|
|
31
|
+
`project_cap_usd` from `.design/budget.json`, and computes cycles-to-cap.
|
|
32
|
+
3. **Render.** Show: the scenario + its per-cycle rate, the best↔worst band, the projected total over
|
|
33
|
+
N cycles, and - when `project_cap_usd > 0` - **"at the `<scenario>` rate (~$X/cycle) you'll reach
|
|
34
|
+
your $`<cap>` project cap in `<Y>` cycles"** (or "not at this rate" when the trend is flat/down).
|
|
35
|
+
When no cap is set, show the trajectory and note that `project_cap_usd` is unset (so the hook won't
|
|
36
|
+
halt).
|
|
37
|
+
4. **Do not act.** Never raise/lower the cap, never spend - GDD forecasts; the human sets the budget.
|
|
38
|
+
|
|
39
|
+
## Output
|
|
40
|
+
|
|
41
|
+
End with:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
## BUDGET COMPLETE
|
|
45
|
+
```
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-cache-manager
|
|
3
|
+
description: "Maintains .design/cache-manifest.json for Layer B explicit cache per D-08. Computes deterministic SHA-256 input-hash from (agent-path + sorted-input-file-paths + input-content-hashes). On spawn: lookup key → return cached blob if within TTL, else miss. On completion: write result + TTL. Consulted by hooks/budget-enforcer.ts before every Agent spawn."
|
|
4
|
+
user-invocable: false
|
|
5
|
+
tools: Read, Bash, Write
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# gdd-cache-manager
|
|
10
|
+
|
|
11
|
+
## Role
|
|
12
|
+
|
|
13
|
+
You are the deterministic cache-key computer and cache-manifest writer for the optimization layer. You do not spawn agents, and you do not make model calls. You read agent paths, input file paths, and input file contents; you compute a stable SHA-256 key; you look that key up in `.design/cache-manifest.json`; you return a hit (cached result + `cache_hit: true`) or a miss. On spawn completion, the orchestrator calls you again to persist the result. You are Layer B of the two-layer cache (D-08). Layer A - Anthropic's 5-min prompt cache - is not owned by you; it's owned by the shared-preamble ordering convention in `agents/README.md`.
|
|
14
|
+
|
|
15
|
+
## Invocation Contract
|
|
16
|
+
|
|
17
|
+
### Phase 1: compute-key
|
|
18
|
+
|
|
19
|
+
- **Input**: `{agent_path: string, input_file_paths: string[]}` - `agent_path` is the absolute or repo-relative path to the `agents/<name>.md` file; `input_file_paths` is the sorted-unique list of files the agent will read.
|
|
20
|
+
- **Output**: `{input_hash: string}` - 64-character lowercase SHA-256 hex.
|
|
21
|
+
- **Algorithm**: canonicalize inputs, concat with newline separators, SHA-256 (see Deterministic Input-Hash Algorithm below).
|
|
22
|
+
|
|
23
|
+
### Phase 2: lookup
|
|
24
|
+
|
|
25
|
+
- **Input**: `{input_hash: string}`
|
|
26
|
+
- **Output**: `{hit: true, result: string, expires_at: string} | {hit: false}`
|
|
27
|
+
- Reads `.design/cache-manifest.json`. If key absent → miss. If present and `Date.now() >= entry.expires_at` → miss (lazy cleanup: caller may evict but is not required to). Else → hit with `entry.result`.
|
|
28
|
+
|
|
29
|
+
### Phase 3: short-circuit-or-miss
|
|
30
|
+
|
|
31
|
+
- On hit: orchestrator short-circuits the spawn. Budget-enforcer hook (Plan 10.1-01) emits `SkippedCached` telemetry with `tokens_in: 0, tokens_out: 0, cache_hit: true, est_cost_usd: 0` (writer lands in Plan 10.1-05). Returns cached `result` as the tool output.
|
|
32
|
+
- On miss: orchestrator proceeds with real spawn. Cache-manager is not involved until Phase 4.
|
|
33
|
+
|
|
34
|
+
### Phase 4: write-result-on-completion
|
|
35
|
+
|
|
36
|
+
- **Input**: `{input_hash: string, agent: string, result: string, ttl_seconds: number}` - `ttl_seconds` defaults to `.design/budget.json.cache_ttl_seconds` (3600 if budget.json absent).
|
|
37
|
+
- **Behavior**: open `.design/cache-manifest.json` (create if missing), set key `input_hash` → `{agent, result, written_at, ttl_seconds, expires_at}`, write file. `written_at` is `new Date().toISOString()`. `expires_at` is `written_at + ttl_seconds` as ISO.
|
|
38
|
+
|
|
39
|
+
## Deterministic Input-Hash Algorithm
|
|
40
|
+
|
|
41
|
+
The canonical reference implementation (single source of truth; `hooks/budget-enforcer.ts` imports the same primitive via a shared helper) lives in `./cache-policy.md#deterministic-input-hash-algorithm-layer-b` - it documents the JS implementation, the maintainer notes (sorted-unique paths, MISSING-file sentinel, agent-path bust behavior), the manifest shape, and TTL semantics in one place. Conform to the algorithm exactly so the hook and any orchestrator agree byte-for-byte.
|
|
42
|
+
|
|
43
|
+
## Integration Points
|
|
44
|
+
|
|
45
|
+
- **`hooks/budget-enforcer.ts`** (Plan 10.1-01) reads the manifest on every Agent spawn. The hook already calls `cacheLookup(agent, inputHash)` against `.design/cache-manifest.json`. This skill is the authority on how `inputHash` is computed so the hook and any orchestrator agree byte-for-byte.
|
|
46
|
+
- **Orchestrators** (e.g., `skills/map/`, `skills/discover/`, `skills/plan/`) invoke Phase 1 (compute-key) + Phase 4 (write-result-on-completion) around each Agent spawn they launch. Phase 2 + Phase 3 are executed by the hook.
|
|
47
|
+
- **Warm-cache command** (`skills/warm-cache/SKILL.md`, Task 02) does not touch Layer B - it only primes Anthropic's 5-min prompt cache (Layer A). Do not confuse the two.
|
|
48
|
+
|
|
49
|
+
## Failure Modes
|
|
50
|
+
|
|
51
|
+
- `.design/cache-manifest.json` missing or malformed → treat every lookup as miss; orchestrator proceeds with full spawn. Do not throw.
|
|
52
|
+
- File system write fails on Phase 4 → log to stderr, do not throw (the spawn already completed successfully; losing a cache write is a performance regression, not a correctness bug).
|
|
53
|
+
- `agent_path` file missing → compute hash anyway using the provided string; cache entries for a deleted agent simply never hit again.
|
|
54
|
+
|
|
55
|
+
## Non-Goals
|
|
56
|
+
|
|
57
|
+
Per D-09:
|
|
58
|
+
|
|
59
|
+
- No semantic / graph-based lookup. Manifest is a dumb KV store keyed by content hash.
|
|
60
|
+
- No cross-project cache sharing. Manifest lives at `.design/cache-manifest.json`, scoped per repo.
|
|
61
|
+
- No eviction beyond lazy expiry on read. A `{{command_prefix}}cache-prune` command is a Phase 11 reflector candidate, not 10.1 scope.
|
|
62
|
+
- No hash-algorithm tuning. SHA-256 is fixed; if a future phase wants BLAKE3, bump the manifest schema version (not relevant in v1).
|
|
63
|
+
|
|
64
|
+
## TTL Semantics
|
|
65
|
+
|
|
66
|
+
Default `ttl_seconds` = `.design/budget.json.cache_ttl_seconds` = 3600s (1 hour) per D-10. `expires_at` is computed at write time and stored; readers do not recompute. Stale entries are lazily cleaned on read (no eager reaper in v1). Full TTL discussion: `./cache-policy.md#ttl-semantics-layer-b`.
|