@esneiderbravo/speclaw 0.3.4 → 0.3.7
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/README.md +66 -15
- package/dist/cli/commands/budget.js +36 -0
- package/dist/cli/commands/doctor.js +53 -11
- package/dist/cli/commands/init.js +3 -1
- package/dist/cli/commands/telemetry.js +16 -0
- package/dist/cli/commands/update.js +36 -3
- package/dist/cli/index.js +19 -4
- package/dist/modules/compass/indexer.js +10 -0
- package/dist/modules/compass/map.js +114 -0
- package/dist/modules/compass/register.js +30 -64
- package/dist/modules/foundation/assets/docs/compass.template.md +3 -0
- package/dist/modules/foundation/context-budget.js +58 -0
- package/dist/modules/foundation/doctor.js +626 -161
- package/dist/modules/foundation/graph.js +7 -4
- package/dist/modules/foundation/hooks.js +12 -0
- package/dist/modules/foundation/laws.js +1 -0
- package/dist/modules/foundation/register-core.js +108 -0
- package/dist/modules/foundation/register.js +22 -159
- package/dist/modules/foundation/scaffold.js +1 -1
- package/dist/modules/lawbook/assets/skills/archive/SKILL.md +1 -31
- package/dist/modules/lawbook/assets/skills/archive/steps/01-confirm-done.md +7 -0
- package/dist/modules/lawbook/assets/skills/archive/steps/02-reconcile.md +15 -0
- package/dist/modules/lawbook/assets/skills/archive/steps/03-validate-and-sync.md +7 -0
- package/dist/modules/lawbook/assets/skills/archive/steps/04-archive.md +9 -0
- package/dist/modules/lawbook/assets/skills/archive/steps/05-report.md +7 -0
- package/dist/modules/lawbook/assets/skills/build/SKILL.md +2 -100
- package/dist/modules/lawbook/assets/skills/build/steps/01-load-change.md +7 -0
- package/dist/modules/lawbook/assets/skills/build/steps/02-branch.md +6 -0
- package/dist/modules/lawbook/assets/skills/build/steps/03-implement.md +11 -0
- package/dist/modules/lawbook/assets/skills/build/steps/04-quality-gates.md +10 -0
- package/dist/modules/lawbook/assets/skills/build/steps/05-manual-verification.md +22 -0
- package/dist/modules/lawbook/assets/skills/build/steps/06-discipline-reports.md +44 -0
- package/dist/modules/lawbook/assets/skills/build/steps/07-hand-off.md +9 -0
- package/dist/modules/lawbook/assets/skills/draft/SKILL.md +3 -80
- package/dist/modules/lawbook/assets/skills/draft/steps/01-ensure-workspace.md +5 -0
- package/dist/modules/lawbook/assets/skills/draft/steps/02-understand.md +12 -0
- package/dist/modules/lawbook/assets/skills/draft/steps/03-name-capabilities.md +14 -0
- package/dist/modules/lawbook/assets/skills/draft/steps/04-write-artifacts.md +41 -0
- package/dist/modules/lawbook/assets/skills/draft/steps/05-validate.md +11 -0
- package/dist/modules/lawbook/assets/skills/draft/steps/06-hand-off.md +5 -0
- package/dist/modules/lawbook/assets/skills/explore/SKILL.md +6 -22
- package/dist/modules/lawbook/assets/skills/explore/steps/01-investigate.md +16 -0
- package/dist/modules/lawbook/assets/skills/explore/steps/02-summarize.md +7 -0
- package/dist/modules/lawbook/assets/skills/sync/SKILL.md +1 -30
- package/dist/modules/lawbook/assets/skills/sync/steps/01-confirm.md +5 -0
- package/dist/modules/lawbook/assets/skills/sync/steps/02-reconcile.md +16 -0
- package/dist/modules/lawbook/assets/skills/sync/steps/03-validate.md +6 -0
- package/dist/modules/lawbook/assets/skills/sync/steps/04-promote.md +10 -0
- package/dist/modules/lawbook/assets/skills/sync/steps/05-report.md +7 -0
- package/dist/modules/lawbook/register.js +17 -36
- package/dist/modules/tools/register.js +15 -15
- package/dist/server.js +13 -7
- package/dist/shared/budget.js +159 -0
- package/dist/shared/exposure.js +110 -0
- package/dist/shared/manifest.js +11 -2
- package/dist/shared/mcp.js +33 -0
- package/dist/shared/redact.js +90 -0
- package/dist/shared/schema-tokens.js +86 -0
- package/dist/shared/tokens.js +41 -0
- package/package.json +2 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Write the discipline reports (mandatory)
|
|
2
|
+
|
|
3
|
+
Record the evidence of testing under `lawbook/changes/<name>/reports/`, one file
|
|
4
|
+
per discipline the change touched, named for that discipline. The set is **open,
|
|
5
|
+
not a fixed list** — `backend.md`, `frontend.md`, and `api.md` are the common
|
|
6
|
+
ones, but write `database.md`, `infra.md`, `security.md`, `performance.md`,
|
|
7
|
+
`e2e.md`, etc. when the change exercises those concerns, and coin a clear
|
|
8
|
+
`<discipline>.md` for anything none of them fit. Omit disciplines the change did
|
|
9
|
+
not touch; the archive is blocked until at least one discipline report exists.
|
|
10
|
+
|
|
11
|
+
**`api.md` is mandatory whenever the change touches an API surface** — a new or
|
|
12
|
+
modified endpoint, its request/response contract, its status codes, or its
|
|
13
|
+
auth/permission or ordering guarantees. A `backend.md` unit report does not
|
|
14
|
+
substitute for it: the contract is a distinct concern. In `api.md` document the
|
|
15
|
+
method and path, the auth/permissions, the response shape and every status code
|
|
16
|
+
the change governs (e.g. `200`/`401`/`403`/`404`), any ordering guarantee, and
|
|
17
|
+
how the contract was exercised (test client and/or `curl`) — kept isolated from
|
|
18
|
+
any live data store per the manual-verification step.
|
|
19
|
+
|
|
20
|
+
Each report MUST follow this structure, in order — the fixed shape is what makes
|
|
21
|
+
the evidence trustworthy and reproducible, rather than left to improvisation:
|
|
22
|
+
|
|
23
|
+
1. **Title + header** — `# <Discipline> checks — <change> (<date>)`, then a line
|
|
24
|
+
`Date · Branch · Environment/cwd` naming where the commands ran.
|
|
25
|
+
2. **Gates & results** — a `| Check | Command | Result |` table: each gate, the
|
|
26
|
+
exact command, and its real result with pass/fail counts (e.g. "62 files, 434
|
|
27
|
+
passed") and ✅/⚠️/❌. Quote real output — never paraphrase a green you did
|
|
28
|
+
not see.
|
|
29
|
+
3. **Tests added / updated** — each new or changed test and what it asserts; note
|
|
30
|
+
TDD evidence ("failed before the fix, passes after") where it applies.
|
|
31
|
+
4. **Spec-scenario coverage** — a table mapping each `#### Scenario` in this
|
|
32
|
+
change's delta specs to how it was verified (a test id, a gate, or a manual
|
|
33
|
+
step). Every scenario must appear.
|
|
34
|
+
5. **Pre-existing / unrelated failures** — any failing check not caused by this
|
|
35
|
+
change, with proof it is pre-existing (e.g. it reproduces with the change
|
|
36
|
+
stashed) — or state "none".
|
|
37
|
+
6. **Pending manual steps** — anything not automated, stated plainly — or "none".
|
|
38
|
+
7. **Verdict** — one line.
|
|
39
|
+
|
|
40
|
+
If a test kind does not yet apply (e.g. no unit runner), the report says so in
|
|
41
|
+
place of that evidence and records the gates and manual verification that stood
|
|
42
|
+
in.
|
|
43
|
+
|
|
44
|
+
Next: read `steps/07-hand-off.md` and do only what it says.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Hand off
|
|
2
|
+
|
|
3
|
+
When every task is checked and gates are green, tell the user the change is
|
|
4
|
+
ready to `sync` and `archive`. Keep the delta specs current as you build, but
|
|
5
|
+
know that `sync` formally reconciles the delta specs against what was actually
|
|
6
|
+
built — so behavior that drifted past the original spec is caught there, not
|
|
7
|
+
left to chance.
|
|
8
|
+
|
|
9
|
+
No further steps remain — build workflow complete.
|
|
@@ -9,84 +9,7 @@ Turn a request into a complete, reviewable change under `lawbook/changes/<name>/
|
|
|
9
9
|
before any implementation. This is speclaw's own spec-driven workflow — no
|
|
10
10
|
external CLI; the mechanical steps are speclaw MCP tools.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Use when the user wants to start, plan, or propose a new feature, fix, or
|
|
13
|
+
refactor.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## Step 1 — Understand the request and the code
|
|
17
|
-
|
|
18
|
-
- **Refresh the index first.** Run `compass_index` before reasoning about the
|
|
19
|
-
code — it is incremental (unchanged files are skipped by hash), so this is
|
|
20
|
-
cheap and guarantees your decisions rest on the current graph, not a stale one.
|
|
21
|
-
- Clarify what the user wants (feature / fix / refactor) and confirm scope.
|
|
22
|
-
- Use `compass_explore` and `compass_recall` (speclaw's code index) BEFORE
|
|
23
|
-
grep/read to locate the real code the change touches and its blast radius.
|
|
24
|
-
- Read the governing standards in `docs/standards/` (architecture, backend,
|
|
25
|
-
frontend, testing) so the change complies with the project's law.
|
|
26
|
-
|
|
27
|
-
## Step 2 — Pick a change name and its capabilities
|
|
28
|
-
|
|
29
|
-
- **Change name:** kebab-case, action-oriented (e.g. `add-login`,
|
|
30
|
-
`fix-shift-overlap`). This is the folder under `lawbook/changes/`, and it is
|
|
31
|
-
per-feature — always distinct.
|
|
32
|
-
- **Capabilities:** run `lawbook_list` to see the canonical capabilities. A
|
|
33
|
-
capability is the living contract for an area of behavior — it is *not* the
|
|
34
|
-
change. When your change modifies behavior an existing capability already
|
|
35
|
-
governs, reuse that capability's **exact** name so `sync` updates its spec.
|
|
36
|
-
Introduce a new capability only as a deliberate choice for a genuinely distinct
|
|
37
|
-
area of behavior — never as a near-duplicate (`transfer` next to an existing
|
|
38
|
-
`transfers`) of one that already exists.
|
|
39
|
-
|
|
40
|
-
## Step 3 — Write the artifacts
|
|
41
|
-
|
|
42
|
-
Create under `lawbook/changes/<name>/`:
|
|
43
|
-
|
|
44
|
-
- **proposal.md** — the why, the what, non-goals, and whether migrations are
|
|
45
|
-
needed. Reference the team's tracker ticket if there is one.
|
|
46
|
-
- **specs/<capability>/spec.md** — the delta spec for each affected capability.
|
|
47
|
-
`sync` promotes this by overwriting the whole canonical file, so the delta must
|
|
48
|
-
carry the capability's **full** intended spec. When you are updating an existing
|
|
49
|
-
capability, **start from the current `lawbook/specs/<capability>/spec.md`** and
|
|
50
|
-
edit on top of it, so its existing requirements are carried forward — do not
|
|
51
|
-
author it from scratch, or promotion will silently drop them. Use normative
|
|
52
|
-
language and testable scenarios:
|
|
53
|
-
```markdown
|
|
54
|
-
# <Capability>
|
|
55
|
-
|
|
56
|
-
### Requirement: <name>
|
|
57
|
-
The system SHALL <requirement>.
|
|
58
|
-
|
|
59
|
-
#### Scenario: <name>
|
|
60
|
-
- Given <context>
|
|
61
|
-
- When <action>
|
|
62
|
-
- Then <observable outcome>
|
|
63
|
-
```
|
|
64
|
-
- **design.md** — always: approach, alternatives weighed, and the trade-offs
|
|
65
|
-
behind the decision. For a small change, keep it short — but write it.
|
|
66
|
-
- **tasks.md** — ordered, checkable steps. MUST include the mandatory steps
|
|
67
|
-
from `lawbook/config.yaml` (feature branch first; tests reviewed and run;
|
|
68
|
-
manual verification executed by the agent; discipline reports produced; docs
|
|
69
|
-
updated; archive within the PR).
|
|
70
|
-
- **reports/** — create the folder with a short `reports/README.md` naming the
|
|
71
|
-
discipline reports the change will need — one per discipline it touches, from an
|
|
72
|
-
open set (`backend.md`, `frontend.md`, `api.md`, `database.md`, `infra.md`,
|
|
73
|
-
`security.md`, … — and `api.md` is required when the change touches any API
|
|
74
|
-
surface) that `build` will fill, following the required report structure
|
|
75
|
-
(header · gates table ·
|
|
76
|
-
tests added · spec-scenario coverage · pre-existing failures · pending manual ·
|
|
77
|
-
verdict — see the `build` skill, Step 5). Every change ships this folder;
|
|
78
|
-
archive is blocked until it holds at least one discipline report.
|
|
79
|
-
|
|
80
|
-
## Step 4 — Validate
|
|
81
|
-
|
|
82
|
-
Run the `lawbook_validate` tool for the change and fix every issue it reports
|
|
83
|
-
(missing artifacts, non-normative specs, missing scenarios) before handing off
|
|
84
|
-
to implementation. Read its advisory **warnings** too: a near-duplicate
|
|
85
|
-
capability name usually means you should reuse the existing capability's exact
|
|
86
|
-
name, and a dropped-requirement warning means the delta should start from the
|
|
87
|
-
canonical. Warnings do not block, but resolve them unless the divergence is
|
|
88
|
-
intentional.
|
|
89
|
-
|
|
90
|
-
## Step 5 — Hand off
|
|
91
|
-
|
|
92
|
-
Summarize the change and tell the user it's ready to `build`.
|
|
15
|
+
Read `steps/01-ensure-workspace.md` and do only what it says.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Understand the request and the code
|
|
2
|
+
|
|
3
|
+
- **Refresh the index first.** Run `compass_index` before reasoning about the
|
|
4
|
+
code — it is incremental (unchanged files are skipped by hash), so this is
|
|
5
|
+
cheap and guarantees your decisions rest on the current graph, not a stale one.
|
|
6
|
+
- Clarify what the user wants (feature / fix / refactor) and confirm scope.
|
|
7
|
+
- Use `compass_explore` and `compass_recall` (speclaw's code index) BEFORE
|
|
8
|
+
grep/read to locate the real code the change touches and its blast radius.
|
|
9
|
+
- Read the governing standards in `docs/standards/` (architecture, backend,
|
|
10
|
+
frontend, testing) so the change complies with the project's law.
|
|
11
|
+
|
|
12
|
+
Next: read `steps/03-name-capabilities.md` and do only what it says.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Pick a change name and its capabilities
|
|
2
|
+
|
|
3
|
+
- **Change name:** kebab-case, action-oriented (e.g. `add-login`,
|
|
4
|
+
`fix-shift-overlap`). This is the folder under `lawbook/changes/`, and it is
|
|
5
|
+
per-feature — always distinct.
|
|
6
|
+
- **Capabilities:** run `lawbook_list` to see the canonical capabilities. A
|
|
7
|
+
capability is the living contract for an area of behavior — it is *not* the
|
|
8
|
+
change. When your change modifies behavior an existing capability already
|
|
9
|
+
governs, reuse that capability's **exact** name so `sync` updates its spec.
|
|
10
|
+
Introduce a new capability only as a deliberate choice for a genuinely distinct
|
|
11
|
+
area of behavior — never as a near-duplicate (`transfer` next to an existing
|
|
12
|
+
`transfers`) of one that already exists.
|
|
13
|
+
|
|
14
|
+
Next: read `steps/04-write-artifacts.md` and do only what it says.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Write the artifacts
|
|
2
|
+
|
|
3
|
+
Create under `lawbook/changes/<name>/`:
|
|
4
|
+
|
|
5
|
+
- **proposal.md** — the why, the what, non-goals, and whether migrations are
|
|
6
|
+
needed. Reference the team's tracker ticket if there is one.
|
|
7
|
+
- **specs/<capability>/spec.md** — the delta spec for each affected capability.
|
|
8
|
+
`sync` promotes this by overwriting the whole canonical file, so the delta must
|
|
9
|
+
carry the capability's **full** intended spec. When you are updating an existing
|
|
10
|
+
capability, **start from the current `lawbook/specs/<capability>/spec.md`** and
|
|
11
|
+
edit on top of it, so its existing requirements are carried forward — do not
|
|
12
|
+
author it from scratch, or promotion will silently drop them. Use normative
|
|
13
|
+
language and testable scenarios:
|
|
14
|
+
```markdown
|
|
15
|
+
# <Capability>
|
|
16
|
+
|
|
17
|
+
### Requirement: <name>
|
|
18
|
+
The system SHALL <requirement>.
|
|
19
|
+
|
|
20
|
+
#### Scenario: <name>
|
|
21
|
+
- Given <context>
|
|
22
|
+
- When <action>
|
|
23
|
+
- Then <observable outcome>
|
|
24
|
+
```
|
|
25
|
+
- **design.md** — always: approach, alternatives weighed, and the trade-offs
|
|
26
|
+
behind the decision. For a small change, keep it short — but write it.
|
|
27
|
+
- **tasks.md** — ordered, checkable steps. MUST include the mandatory steps
|
|
28
|
+
from `lawbook/config.yaml` (feature branch first; tests reviewed and run;
|
|
29
|
+
manual verification executed by the agent; discipline reports produced; docs
|
|
30
|
+
updated; archive within the PR).
|
|
31
|
+
- **reports/** — create the folder with a short `reports/README.md` naming the
|
|
32
|
+
discipline reports the change will need — one per discipline it touches, from an
|
|
33
|
+
open set (`backend.md`, `frontend.md`, `api.md`, `database.md`, `infra.md`,
|
|
34
|
+
`security.md`, … — and `api.md` is required when the change touches any API
|
|
35
|
+
surface) that `build` will fill, following the required report structure
|
|
36
|
+
(header · gates table · tests added · spec-scenario coverage · pre-existing
|
|
37
|
+
failures · pending manual · verdict — see the `build` skill's discipline-reports
|
|
38
|
+
step). Every change ships this folder; archive is blocked until it holds at
|
|
39
|
+
least one discipline report.
|
|
40
|
+
|
|
41
|
+
Next: read `steps/05-validate.md` and do only what it says.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Validate
|
|
2
|
+
|
|
3
|
+
Run the `lawbook_validate` tool for the change and fix every issue it reports
|
|
4
|
+
(missing artifacts, non-normative specs, missing scenarios) before handing off
|
|
5
|
+
to implementation. Read its advisory **warnings** too: a near-duplicate
|
|
6
|
+
capability name usually means you should reuse the existing capability's exact
|
|
7
|
+
name, and a dropped-requirement warning means the delta should start from the
|
|
8
|
+
canonical. Warnings do not block, but resolve them unless the divergence is
|
|
9
|
+
intentional.
|
|
10
|
+
|
|
11
|
+
Next: read `steps/06-hand-off.md` and do only what it says.
|
|
@@ -5,27 +5,11 @@ description: Enter explore mode — a thinking partner for investigating an idea
|
|
|
5
5
|
|
|
6
6
|
# explore — Think it through
|
|
7
7
|
|
|
8
|
-
A low-commitment
|
|
9
|
-
during) a change. Nothing is written to `lawbook/`
|
|
10
|
-
understanding and a recommended direction.
|
|
8
|
+
A low-commitment thinking partner for investigating ideas and the codebase
|
|
9
|
+
before (or during) a change. Nothing is written to `lawbook/` — the output is
|
|
10
|
+
shared understanding and a recommended direction.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Use when the user wants to think something through, understand how something
|
|
13
|
+
works, or clarify requirements before drafting a change.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
incremental (unchanged files skipped by hash), so it is cheap and keeps your
|
|
16
|
-
reasoning on the current graph rather than a stale one.
|
|
17
|
-
- **Understand the code first.** Use `compass_recall` to find relevant code by
|
|
18
|
-
meaning and `compass_explore` to read a symbol's source plus its callers and
|
|
19
|
-
callees — before grep/read.
|
|
20
|
-
- **Ask sharp questions** to surface hidden assumptions, constraints, and edge
|
|
21
|
-
cases. Confirm scope and non-goals.
|
|
22
|
-
- **Check the law.** Read the relevant `docs/standards/` so any direction you
|
|
23
|
-
propose already fits the project's architecture and conventions.
|
|
24
|
-
- **Weigh approaches.** Lay out the viable options with trade-offs and give a
|
|
25
|
-
recommendation, not an exhaustive survey.
|
|
26
|
-
|
|
27
|
-
## Output
|
|
28
|
-
|
|
29
|
-
A concise summary: the problem as understood, the constraints, the recommended
|
|
30
|
-
approach, and the open questions. When the direction is clear, offer to `draft`
|
|
31
|
-
the change.
|
|
15
|
+
Read `steps/01-investigate.md` and do only what it says.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Investigate
|
|
2
|
+
|
|
3
|
+
- **Refresh the index first.** Run `compass_index` before investigating — it is
|
|
4
|
+
incremental (unchanged files skipped by hash), so it is cheap and keeps your
|
|
5
|
+
reasoning on the current graph rather than a stale one.
|
|
6
|
+
- **Understand the code first.** Use `compass_recall` to find relevant code by
|
|
7
|
+
meaning and `compass_explore` to read a symbol's source plus its callers and
|
|
8
|
+
callees — before grep/read.
|
|
9
|
+
- **Ask sharp questions** to surface hidden assumptions, constraints, and edge
|
|
10
|
+
cases. Confirm scope and non-goals.
|
|
11
|
+
- **Check the law.** Read the relevant `docs/standards/` so any direction you
|
|
12
|
+
propose already fits the project's architecture and conventions.
|
|
13
|
+
- **Weigh approaches.** Lay out the viable options with trade-offs and give a
|
|
14
|
+
recommendation, not an exhaustive survey.
|
|
15
|
+
|
|
16
|
+
Next: read `steps/02-summarize.md` and do only what it says.
|
|
@@ -13,33 +13,4 @@ become the source of truth but the change isn't finished (e.g. multi-PR work).
|
|
|
13
13
|
promoting, YOU reconcile the delta specs against what was actually built, so the
|
|
14
14
|
specs that become canonical describe reality, not just the original draft.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
1. Confirm which change to sync (run `lawbook_list` if unsure).
|
|
19
|
-
|
|
20
|
-
2. **Reconcile code → delta specs (agent-executed).** Before promoting, compare
|
|
21
|
-
what was built against the change's delta specs:
|
|
22
|
-
- Reconstruct what shipped: `git diff <branch-point>...HEAD` for the change's
|
|
23
|
-
branch, then `compass_explore` / `compass_impact` on the touched symbols to
|
|
24
|
-
understand behavior, not just changed lines.
|
|
25
|
-
- Diff intent vs reality: list behavior that is implemented but missing from,
|
|
26
|
-
or contradicted by, `lawbook/changes/<name>/specs/**`.
|
|
27
|
-
- Write the gaps into the delta specs — normative `SHALL`/`MUST` requirements
|
|
28
|
-
under `### Requirement:` and `#### Scenario:` acceptance criteria — so the
|
|
29
|
-
contract matches what was built. Capture only behavior that actually
|
|
30
|
-
exists; never invent scope that was not implemented.
|
|
31
|
-
- If nothing drifted, make no edits and say so.
|
|
32
|
-
|
|
33
|
-
3. Run `lawbook_validate` for the change; do not sync a change whose specs are
|
|
34
|
-
invalid.
|
|
35
|
-
|
|
36
|
-
4. Run the `lawbook_sync` tool for the change. It copies each
|
|
37
|
-
`lawbook/changes/<name>/specs/<capability>/spec.md` over the canonical
|
|
38
|
-
`lawbook/specs/<capability>/spec.md` and reports what it promoted, flagging
|
|
39
|
-
each as **created** (new capability) or **updated** (overwrote an existing
|
|
40
|
-
one). A capability you expected to update showing up as *created* means the
|
|
41
|
-
delta forked a near-duplicate — fix the name before promoting.
|
|
42
|
-
|
|
43
|
-
5. Report to the user what you reconciled (or that nothing drifted) and the
|
|
44
|
-
promoted files (created vs updated). The change stays active — `archive` it
|
|
45
|
-
when it's fully done.
|
|
16
|
+
Read `steps/01-confirm.md` and do only what it says.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Reconcile code → delta specs (agent-executed)
|
|
2
|
+
|
|
3
|
+
Before promoting, compare what was built against the change's delta specs:
|
|
4
|
+
|
|
5
|
+
- Reconstruct what shipped: `git diff <branch-point>...HEAD` for the change's
|
|
6
|
+
branch, then `compass_explore` / `compass_impact` on the touched symbols to
|
|
7
|
+
understand behavior, not just changed lines.
|
|
8
|
+
- Diff intent vs reality: list behavior that is implemented but missing from,
|
|
9
|
+
or contradicted by, `lawbook/changes/<name>/specs/**`.
|
|
10
|
+
- Write the gaps into the delta specs — normative `SHALL`/`MUST` requirements
|
|
11
|
+
under `### Requirement:` and `#### Scenario:` acceptance criteria — so the
|
|
12
|
+
contract matches what was built. Capture only behavior that actually
|
|
13
|
+
exists; never invent scope that was not implemented.
|
|
14
|
+
- If nothing drifted, make no edits and say so.
|
|
15
|
+
|
|
16
|
+
Next: read `steps/03-validate.md` and do only what it says.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Promote
|
|
2
|
+
|
|
3
|
+
Run the `lawbook_sync` tool for the change. It copies each
|
|
4
|
+
`lawbook/changes/<name>/specs/<capability>/spec.md` over the canonical
|
|
5
|
+
`lawbook/specs/<capability>/spec.md` and reports what it promoted, flagging
|
|
6
|
+
each as **created** (new capability) or **updated** (overwrote an existing
|
|
7
|
+
one). A capability you expected to update showing up as *created* means the
|
|
8
|
+
delta forked a near-duplicate — fix the name before promoting.
|
|
9
|
+
|
|
10
|
+
Next: read `steps/05-report.md` and do only what it says.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { text } from "../../shared/mcp.js";
|
|
3
|
+
import { defineTool, text } from "../../shared/mcp.js";
|
|
4
|
+
import { shouldExpose } from "../../shared/exposure.js";
|
|
4
5
|
import { assetsDir } from "../../shared/paths.js";
|
|
5
6
|
import { copyRendered } from "../../shared/install.js";
|
|
6
7
|
import { specInit, specValidate, specSync, specArchive, specList } from "./engine.js";
|
|
@@ -16,41 +17,21 @@ export function installWorkflow(projectPath, vars, report, opts) {
|
|
|
16
17
|
copyRendered(path.join(ASSETS, "commands"), path.join(aiSpecs, "commands", "lawbook"), vars, report, opts);
|
|
17
18
|
copyRendered(path.join(ASSETS, "rules"), path.join(aiSpecs, "rules"), vars, report, opts);
|
|
18
19
|
}
|
|
19
|
-
// ─── The spec module: speclaw's own spec-driven workflow (no external OpenSpec) ───
|
|
20
|
-
// Mechanical operations behind the draft/build/sync/archive/explore commands.
|
|
21
20
|
/** Register the spec workflow MCP tools (init, list, validate, sync, archive). */
|
|
22
|
-
export function registerSpec(server) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}, async ({ projectPath }) => text(specList(projectPath)));
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
},
|
|
37
|
-
}, async ({ projectPath, change }) => text(specValidate(projectPath, change)));
|
|
38
|
-
server.registerTool("lawbook_sync", {
|
|
39
|
-
description: "Promote a change's delta specs into the canonical lawbook/specs/ (per capability), without archiving. Reports each promoted spec as created (new capability) or updated (overwrote an existing one). Backs the `sync` command.",
|
|
40
|
-
inputSchema: {
|
|
41
|
-
projectPath: z.string().describe("Absolute path to the project"),
|
|
42
|
-
change: z.string().describe("Change name (folder under lawbook/changes/)"),
|
|
43
|
-
},
|
|
44
|
-
}, async ({ projectPath, change }) => text(specSync(projectPath, change)));
|
|
45
|
-
server.registerTool("lawbook_archive", {
|
|
46
|
-
description: "Finalize a change: sync its delta specs into lawbook/specs/, then move it to lawbook/changes/archive/<date>-<name>/. Backs the `archive` command. Pass today's date as YYYY-MM-DD.",
|
|
47
|
-
inputSchema: {
|
|
48
|
-
projectPath: z.string().describe("Absolute path to the project"),
|
|
49
|
-
change: z.string().describe("Change name (folder under lawbook/changes/)"),
|
|
50
|
-
date: z
|
|
51
|
-
.string()
|
|
52
|
-
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
53
|
-
.describe("Today's date, YYYY-MM-DD"),
|
|
54
|
-
},
|
|
21
|
+
export function registerSpec(server, opts = {}) {
|
|
22
|
+
const minimal = Boolean(opts.minimal);
|
|
23
|
+
const add = (name, description, inputSchema, handler) => {
|
|
24
|
+
if (!shouldExpose(name, minimal))
|
|
25
|
+
return;
|
|
26
|
+
defineTool(server, { name, description, inputSchema, handler });
|
|
27
|
+
};
|
|
28
|
+
add("lawbook_init", "Create the lawbook/ workspace (specs, changes, archive, config). Idempotent.", { projectPath: z.string() }, async ({ projectPath }) => text(specInit(projectPath)));
|
|
29
|
+
add("lawbook_list", "List active changes, archives, and canonical capabilities under lawbook/.", { projectPath: z.string() }, async ({ projectPath }) => text(specList(projectPath)));
|
|
30
|
+
add("lawbook_validate", "Validate a change's proposal, tasks, and delta specs before build or sync.", { projectPath: z.string(), change: z.string() }, async ({ projectPath, change }) => text(specValidate(projectPath, change)));
|
|
31
|
+
add("lawbook_sync", "Promote a change's delta specs into canonical lawbook/specs/ without archiving.", { projectPath: z.string(), change: z.string() }, async ({ projectPath, change }) => text(specSync(projectPath, change)));
|
|
32
|
+
add("lawbook_archive", "Sync a change into canonical specs, then move it under changes/archive/.", {
|
|
33
|
+
projectPath: z.string(),
|
|
34
|
+
change: z.string(),
|
|
35
|
+
date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
|
|
55
36
|
}, async ({ projectPath, change, date }) => text(specArchive(projectPath, change, date)));
|
|
56
37
|
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { text } from "../../shared/mcp.js";
|
|
2
|
+
import { defineTool, text } from "../../shared/mcp.js";
|
|
3
|
+
import { shouldExpose } from "../../shared/exposure.js";
|
|
3
4
|
import { emptyReport } from "../../shared/install.js";
|
|
4
5
|
import { refreshAgents } from "../../shared/agents.js";
|
|
5
6
|
import { loadPacks, installPack } from "./packs.js";
|
|
6
7
|
export { loadPacks, installPack };
|
|
7
|
-
// ─── The tools module: opt-in packs of skills, agents, and commands ───
|
|
8
8
|
/** Register the tools-module MCP tools (list_packs, add_pack). */
|
|
9
|
-
export function registerTools(server) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
export function registerTools(server, opts = {}) {
|
|
10
|
+
const minimal = Boolean(opts.minimal);
|
|
11
|
+
const add = (name, description, inputSchema, handler) => {
|
|
12
|
+
if (!shouldExpose(name, minimal))
|
|
13
|
+
return;
|
|
14
|
+
defineTool(server, { name, description, inputSchema, handler });
|
|
15
|
+
};
|
|
16
|
+
add("list_packs", "List available speclaw skill packs and what each contains.", {}, async () => text(loadPacks()));
|
|
17
|
+
add("add_pack", "Install one pack into an initialized project and refresh IDE symlinks.", {
|
|
18
|
+
projectPath: z.string(),
|
|
19
|
+
pack: z.string(),
|
|
20
|
+
vars: z.record(z.string()).optional(),
|
|
21
21
|
}, async ({ projectPath, pack, vars }) => {
|
|
22
22
|
const report = emptyReport();
|
|
23
23
|
installPack(projectPath, pack, vars ?? {}, report);
|
|
24
|
-
refreshAgents(projectPath, report);
|
|
24
|
+
refreshAgents(projectPath, report);
|
|
25
25
|
return text(report);
|
|
26
26
|
});
|
|
27
27
|
}
|
package/dist/server.js
CHANGED
|
@@ -4,14 +4,20 @@ import { registerCompass } from "./modules/compass/register.js";
|
|
|
4
4
|
import { registerSpec } from "./modules/lawbook/register.js";
|
|
5
5
|
import { registerFoundation } from "./modules/foundation/register.js";
|
|
6
6
|
import { registerTools } from "./modules/tools/register.js";
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import { isMinimalMode } from "./shared/exposure.js";
|
|
8
|
+
/**
|
|
9
|
+
* Build the speclaw MCP server with every module's tools registered.
|
|
10
|
+
*
|
|
11
|
+
* @param opts - Optional exposure overrides; defaults to {@link isMinimalMode}.
|
|
12
|
+
*/
|
|
13
|
+
export function buildServer(opts = {}) {
|
|
14
|
+
const minimal = opts.minimal ?? isMinimalMode();
|
|
9
15
|
const server = new McpServer({ name: "speclaw", version: "0.1.0" });
|
|
10
|
-
|
|
11
|
-
registerFoundation(server);
|
|
12
|
-
registerSpec(server);
|
|
13
|
-
registerCompass(server);
|
|
14
|
-
registerTools(server);
|
|
16
|
+
const reg = { minimal };
|
|
17
|
+
registerFoundation(server, reg);
|
|
18
|
+
registerSpec(server, reg);
|
|
19
|
+
registerCompass(server, reg);
|
|
20
|
+
registerTools(server, reg);
|
|
15
21
|
return server;
|
|
16
22
|
}
|
|
17
23
|
/** Start the MCP server over stdio (used by `speclaw mcp`). */
|