@hegemonart/get-design-done 1.55.0 → 1.57.0
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 +90 -0
- package/README.md +6 -0
- package/SKILL.md +2 -0
- package/agents/design-fixer.md +16 -0
- package/dist/claude-code/.claude/skills/override/SKILL.md +86 -0
- package/dist/claude-code/.claude/skills/state/SKILL.md +106 -0
- package/hooks/gdd-decision-injector.js +58 -0
- package/hooks/gdd-fact-force.js +434 -0
- package/hooks/gdd-risk-gate.js +406 -0
- package/hooks/hooks.json +18 -0
- package/package.json +1 -1
- package/reference/schemas/events.schema.json +61 -1
- package/reference/skill-graph.md +3 -1
- package/scripts/lib/manifest/skills.json +16 -0
- package/scripts/lib/risk/calibration.cjs +385 -0
- package/scripts/lib/risk/compute-risk.cjs +229 -0
- package/scripts/lib/risk/consumers.cjs +211 -0
- package/scripts/lib/risk/override.cjs +87 -0
- package/scripts/lib/risk/route.cjs +59 -0
- package/scripts/lib/risk/tables.cjs +221 -0
- package/scripts/lib/state/migrate-to-sqlite.cjs +664 -0
- package/scripts/lib/state/query-surface.cjs +391 -0
- package/scripts/lib/state/render-markdown.cjs +717 -0
- package/scripts/lib/state/state-backend.cjs +345 -0
- package/scripts/lib/state/state-store.cjs +735 -0
- package/sdk/cli/index.js +193 -96
- package/sdk/dashboard/data/source.cjs +44 -5
- package/sdk/mcp/gdd-state/server.js +127 -30
- package/sdk/mcp/gdd-state/tools/get.ts +8 -0
- package/sdk/state/index.ts +267 -13
- package/sdk/state/lockfile.ts +48 -0
- package/sdk/state/schema.sql +218 -0
- package/skills/override/SKILL.md +86 -0
- package/skills/state/SKILL.md +106 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-override
|
|
3
|
+
description: "Escalation surface for a risk-blocked action or a fact-force gate. Use when the Phase 56 risk gate blocked a writer action (suggested_action=block) and a reviewer has signed off, or when the first-write fact-force gate is holding a file you have legitimately reviewed. Activates for requests involving overriding a blocked edit, approving a high-risk change, or clearing a fact-force hold on a path."
|
|
4
|
+
argument-hint: "<finding-id | factforce <path>> [--approver <who>] [--reason <text>]"
|
|
5
|
+
user-invocable: true
|
|
6
|
+
tools: Read, Write, Bash, Grep, Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /gdd:override
|
|
10
|
+
|
|
11
|
+
A risk-blocked action is hard: the Phase 56 risk gate routes `suggested_action=block`
|
|
12
|
+
to `override` (see `scripts/lib/risk/route.cjs`), and the fact-force gate holds the
|
|
13
|
+
first write to a file until its facts are read. This skill is the audited way past
|
|
14
|
+
either hold. It mirrors `/gdd:unlock-decision`: a named approver plus a
|
|
15
|
+
reason, recorded before anything is let through. Override is never silent.
|
|
16
|
+
|
|
17
|
+
## Invocation
|
|
18
|
+
|
|
19
|
+
| Command | Behavior |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `/gdd:override <finding-id> --approver <who> --reason <text>` | Record a `D-XX` `override`-tagged decision in STATE.md `<decisions>` and let the risk-blocked action through. |
|
|
22
|
+
| `/gdd:override factforce <path> --approver <who> --reason <text>` | Set `checked[path]` in the session fact-force state so the fact-force gate stops holding that path. |
|
|
23
|
+
|
|
24
|
+
Both modes ask for a rationale: the audit trail is the reason override exists.
|
|
25
|
+
|
|
26
|
+
## Steps
|
|
27
|
+
|
|
28
|
+
1. **Parse args.** Mode is `factforce` when the first token is the literal `factforce`
|
|
29
|
+
(the next token is the `<path>`); otherwise the first token is a `<finding-id>`.
|
|
30
|
+
`--approver` is required (a non-empty name). Missing `--approver` prints the usage
|
|
31
|
+
and changes nothing. If `--reason` is absent, ASK for one (AskUserQuestion or a
|
|
32
|
+
prompt) before continuing: an override with no rationale is rejected.
|
|
33
|
+
|
|
34
|
+
2. **Preview.** Show what will be written and stop for confirmation:
|
|
35
|
+
- finding mode: the decision entry from `overrideDecisionEntry(<id>, {approver, reason})`
|
|
36
|
+
(its `text`, `status: locked`, and `override` tag) plus the action it unblocks.
|
|
37
|
+
- factforce mode: the `<path>` that will gain `checked[path] = true` and the
|
|
38
|
+
session-state file it lands in.
|
|
39
|
+
|
|
40
|
+
3. **Apply (finding mode).** Record the audited decision via the STATE writer
|
|
41
|
+
`mcp__gdd_state__add_decision` (it auto-assigns the next `D-N`). Pass the `text`
|
|
42
|
+
from the pure builder so the `override` tag is embedded and greppable:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
node -e '
|
|
46
|
+
const o = require("./scripts/lib/risk/override.cjs");
|
|
47
|
+
const [id, who, reason] = process.argv.slice(1);
|
|
48
|
+
const entry = o.overrideDecisionEntry(id, { approver: who, reason });
|
|
49
|
+
console.log(JSON.stringify(entry));
|
|
50
|
+
' "<finding-id>" "<who>" "<reason>"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Then call `mcp__gdd_state__add_decision` with `{ text: <entry.text>, status: "locked" }`.
|
|
54
|
+
The blocked action is now approved on the audit record; proceed with it.
|
|
55
|
+
|
|
56
|
+
4. **Apply (factforce mode).** Set `checked[path]` in the session state file at
|
|
57
|
+
`<cwd>/.design/locks/factforce-<session_id>.json` (atomic tmp then rename), using
|
|
58
|
+
the pure helper so the shape matches what the fact-force gate reads:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
node -e '
|
|
62
|
+
const fs = require("fs"); const path = require("path");
|
|
63
|
+
const o = require("./scripts/lib/risk/override.cjs");
|
|
64
|
+
const [file, p] = process.argv.slice(1);
|
|
65
|
+
let state = {}; try { state = JSON.parse(fs.readFileSync(file, "utf8")); } catch {}
|
|
66
|
+
const next = o.setFactForceChecked(state, p);
|
|
67
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
68
|
+
const tmp = file + ".tmp";
|
|
69
|
+
fs.writeFileSync(tmp, JSON.stringify(next, null, 2) + "\n");
|
|
70
|
+
fs.renameSync(tmp, file);
|
|
71
|
+
console.log(JSON.stringify(next.checked));
|
|
72
|
+
' "<cwd>/.design/locks/factforce-<session_id>.json" "<path>"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The fact-force gate stops holding `<path>` for the rest of the session.
|
|
76
|
+
|
|
77
|
+
5. **Report** the recorded approver, the reason, and either the new `D-XX` id (finding
|
|
78
|
+
mode) or the unblocked path (factforce mode).
|
|
79
|
+
|
|
80
|
+
## Do Not
|
|
81
|
+
|
|
82
|
+
- Do not skip the rationale: every override is audited.
|
|
83
|
+
- Do not override a finding that the risk gate did not actually block.
|
|
84
|
+
- Do not edit `scripts/lib/risk/route.cjs` or `compute-risk.cjs`: this skill consumes them.
|
|
85
|
+
|
|
86
|
+
## OVERRIDE COMPLETE
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-state
|
|
3
|
+
description: "Query, recover, or roll back the Phase 57 SQLite state backbone. Use when you need to inspect the decisions/blockers/plans tables with a raw SELECT, rebuild a corrupt state.sqlite from the markdown STATE.md, or revert to the markdown-only source of truth by removing state.sqlite. Activates for requests involving querying the SQLite state database, recovering from SQLite corruption, or reverting the migration (demigrate)."
|
|
4
|
+
argument-hint: "<query \"<sql>\" | recover | demigrate>"
|
|
5
|
+
user-invocable: true
|
|
6
|
+
tools: Read, Bash, Grep, Glob
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /gdd:state
|
|
10
|
+
|
|
11
|
+
The Phase 57 SQLite state backbone is opt-in (`--migrate-state`) and fully reversible.
|
|
12
|
+
Markdown `.design/STATE.md` is always the human-editable SoT; SQLite is a faster query
|
|
13
|
+
layer derived from it. This skill exposes three subcommands for operating on that layer.
|
|
14
|
+
|
|
15
|
+
## Subcommands
|
|
16
|
+
|
|
17
|
+
| Subcommand | What it does |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `/gdd:state query "<sql>"` | Run a read-only SELECT against `.design/state.sqlite`. |
|
|
20
|
+
| `/gdd:state recover` | Rotate the current sqlite to a `.bak` and rebuild from markdown. |
|
|
21
|
+
| `/gdd:state demigrate` | Remove `.design/state.sqlite`; markdown becomes the SoT again. |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## query
|
|
26
|
+
|
|
27
|
+
Execute a read-only SELECT against the state database.
|
|
28
|
+
|
|
29
|
+
The engine opens the file with `readonly:true` so all writes are rejected at the
|
|
30
|
+
engine level. A first-token denylist (Set membership, no regex) additionally blocks
|
|
31
|
+
DROP, DELETE, UPDATE, INSERT, ALTER, ATTACH, CREATE, PRAGMA, VACUUM, ANALYZE,
|
|
32
|
+
REINDEX, and REPLACE before the connection is opened.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
node -e '
|
|
36
|
+
const qs = require("./scripts/lib/state/query-surface.cjs");
|
|
37
|
+
const result = qs.query(process.argv[1], { projectRoot: process.cwd() });
|
|
38
|
+
console.log(JSON.stringify(result, null, 2));
|
|
39
|
+
' "<sql>"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Outputs `{ rows: [...], backend: "sqlite" }` on success, or
|
|
43
|
+
`{ degraded: true, message: "..." }` when SQLite is not active.
|
|
44
|
+
|
|
45
|
+
Degrades gracefully (no throw) when `BACKEND==='markdown'` or when
|
|
46
|
+
`.design/state.sqlite` has not been created yet (run `--migrate-state` first).
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## recover
|
|
51
|
+
|
|
52
|
+
Rotate the current (possibly corrupt) `.design/state.sqlite` to `.bak.0`, then
|
|
53
|
+
rebuild a fresh database from the markdown `.design/STATE.md` using
|
|
54
|
+
`migrate-to-sqlite.cjs` in force mode. Runs `PRAGMA integrity_check` on the
|
|
55
|
+
result and reports the outcome.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
node -e '
|
|
59
|
+
const qs = require("./scripts/lib/state/query-surface.cjs");
|
|
60
|
+
const result = qs.recover({ projectRoot: process.cwd() });
|
|
61
|
+
console.log(JSON.stringify(result, null, 2));
|
|
62
|
+
'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Outputs `{ recovered: true, integrity: true, message: "..." }` on success.
|
|
66
|
+
|
|
67
|
+
Backup rotation keeps at most 10 files (`.bak.0` through `.bak.9`). The oldest
|
|
68
|
+
backup is overwritten when the cap is reached.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## demigrate
|
|
73
|
+
|
|
74
|
+
Remove `.design/state.sqlite` so the markdown `STATE.md` becomes the SoT again.
|
|
75
|
+
Idempotent: if the file does not exist, returns a clear no-op message without error.
|
|
76
|
+
A backup is taken in `.bak.0` before removal.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
node -e '
|
|
80
|
+
const qs = require("./scripts/lib/state/query-surface.cjs");
|
|
81
|
+
const result = qs.demigrate({ projectRoot: process.cwd() });
|
|
82
|
+
console.log(JSON.stringify(result, null, 2));
|
|
83
|
+
'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Outputs `{ demigrated: true, message: "..." }` when the file was removed, or
|
|
87
|
+
`{ demigrated: false, message: "..." }` when it was already absent (no-op).
|
|
88
|
+
|
|
89
|
+
To re-enable SQLite after a demigrate, run `--migrate-state` again.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Key design decisions
|
|
94
|
+
|
|
95
|
+
- **Markdown is always the SoT.** SQLite is opt-in via `--migrate-state` and
|
|
96
|
+
reversible via `demigrate`. The markdown file is never silently overwritten.
|
|
97
|
+
- **Read-only queries only.** The `query` subcommand enforces SELECT-only via both
|
|
98
|
+
the engine (`readonly:true`) and a defense-in-depth denylist. No writes
|
|
99
|
+
are possible through this skill.
|
|
100
|
+
- **Backup rotation cap.** `rotateBak` shifts `.bak.0..8` up by one index and caps
|
|
101
|
+
at `.bak.9` (10 files total). The oldest backup is overwritten automatically.
|
|
102
|
+
- **Graceful degradation.** All subcommands return a clear `{ degraded, message }`
|
|
103
|
+
object (no throw) when `better-sqlite3` is not installed or when
|
|
104
|
+
`GDD_STATE_BACKEND=markdown` is set.
|
|
105
|
+
|
|
106
|
+
## STATE COMPLETE
|