@esneiderbravo/speclaw 0.1.1 → 0.1.3
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 +12 -8
- package/dist/cli/commands/init.js +16 -26
- package/dist/cli/commands/{spec.js → lawbook.js} +5 -5
- package/dist/cli/commands/visualize.js +44 -0
- package/dist/cli/index.js +11 -8
- package/dist/modules/compass/register.js +10 -0
- package/dist/modules/compass/visualize.js +218 -0
- package/dist/modules/foundation/assets/AGENTS.template.md +4 -4
- package/dist/modules/foundation/assets/CLAUDE.template.md +3 -3
- package/dist/modules/foundation/assets/LAWS.template.md +3 -3
- package/dist/modules/foundation/assets/docs/standards/base-standards.template.md +10 -5
- package/dist/modules/foundation/assets/docs/standards/conventions.template.md +12 -9
- package/dist/modules/foundation/assets/docs/standards/{spec-workflow.template.md → lawbook.template.md} +8 -8
- package/dist/modules/foundation/assets/docs/standards/testing-standards.template.md +1 -1
- package/dist/modules/foundation/doctor.js +7 -7
- package/dist/modules/foundation/register.js +6 -8
- package/dist/modules/foundation/scaffold.js +2 -3
- package/dist/modules/{spec → lawbook}/assets/commands/archive.md +2 -2
- package/dist/modules/{spec → lawbook}/assets/commands/draft.md +4 -4
- package/dist/modules/{spec → lawbook}/assets/commands/explore.md +1 -1
- package/dist/modules/{spec → lawbook}/assets/commands/sync.md +2 -2
- package/dist/modules/{spec → lawbook}/assets/rules/spec-tasks-mandatory-steps.md +6 -6
- package/dist/modules/{spec → lawbook}/assets/skills/archive/SKILL.md +7 -7
- package/dist/modules/{spec → lawbook}/assets/skills/build/SKILL.md +3 -3
- package/dist/modules/{spec → lawbook}/assets/skills/draft/SKILL.md +8 -8
- package/dist/modules/{spec → lawbook}/assets/skills/explore/SKILL.md +2 -2
- package/dist/modules/lawbook/assets/skills/sync/SKILL.md +21 -0
- package/dist/modules/{spec → lawbook}/engine.js +17 -17
- package/dist/modules/{spec → lawbook}/register.js +12 -12
- package/dist/modules/tools/assets/packs/agents/backend-developer.md +1 -1
- package/dist/modules/tools/assets/packs/agents/frontend-developer.md +1 -1
- package/dist/modules/tools/register.js +1 -1
- package/dist/server.js +2 -2
- package/package.json +2 -2
- package/dist/modules/spec/assets/skills/sync/SKILL.md +0 -21
- /package/dist/modules/{spec → lawbook}/assets/commands/build.md +0 -0
|
@@ -6,23 +6,26 @@ Naming, branching, PR, and tracking conventions. A law of the project — see
|
|
|
6
6
|
## Branches
|
|
7
7
|
|
|
8
8
|
- Pattern: `{{branch_pattern}}`
|
|
9
|
-
-
|
|
10
|
-
|
|
9
|
+
- Follow the branch/ticket convention this repo already uses (inferred from its
|
|
10
|
+
existing branch names and history) — don't invent a new one.
|
|
11
11
|
|
|
12
12
|
## Pull requests
|
|
13
13
|
|
|
14
14
|
- Title and body in the repo's artifact language, following the PR template.
|
|
15
|
-
-
|
|
16
|
-
|
|
15
|
+
- If the team uses a tracker, the body references its ticket so it links; the
|
|
16
|
+
ticket lives in the PR title/body only — never in the code.
|
|
17
17
|
- CI must be green before requesting review.
|
|
18
18
|
|
|
19
19
|
## Tracker
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
speclaw does not prescribe a ticket tool — each team configures its own. Follow
|
|
22
|
+
whatever convention this repo already uses (inferred from its branches, PRs, and
|
|
23
|
+
history); if there is none, leave tracker linkage to the team.
|
|
24
|
+
|
|
25
|
+
- New behavior, endpoints, schema changes, or UI flows get a spec change;
|
|
26
|
+
one-line fixes need not.
|
|
27
|
+
- Where a tracker is in use, ticket ↔ PR traceability is expected: closing a
|
|
28
|
+
ticket attaches its PR.
|
|
26
29
|
|
|
27
30
|
## Versioning & releases
|
|
28
31
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Lawbook — {{project_name}}
|
|
2
2
|
|
|
3
3
|
The process law of the project — see [`../../LAWS.md`](../../LAWS.md). This
|
|
4
4
|
repo is spec-driven through speclaw's **spec** module (no external CLI; the
|
|
@@ -9,18 +9,18 @@ mechanical steps are speclaw MCP tools).
|
|
|
9
9
|
No non-trivial change lands without a spec change:
|
|
10
10
|
|
|
11
11
|
1. **explore** — think an idea through before committing (writes nothing).
|
|
12
|
-
2. **draft** — create `
|
|
12
|
+
2. **draft** — create `lawbook/changes/<name>/`: `proposal.md`, delta specs under
|
|
13
13
|
`specs/<capability>/spec.md`, optional `design.md`, and `tasks.md`.
|
|
14
14
|
3. **build** — implement the tasks in order, keeping code and spec in
|
|
15
15
|
agreement.
|
|
16
16
|
4. **sync** — promote the change's delta specs into the canonical
|
|
17
|
-
`
|
|
18
|
-
5. **archive** — finalize: sync + move the change to `
|
|
19
|
-
(`
|
|
17
|
+
`lawbook/specs/` (`lawbook_sync`).
|
|
18
|
+
5. **archive** — finalize: sync + move the change to `lawbook/changes/archive/`
|
|
19
|
+
(`lawbook_archive`), **within the same PR** — never a post-merge chore.
|
|
20
20
|
|
|
21
21
|
## Mandatory task steps
|
|
22
22
|
|
|
23
|
-
`tasks.md` MUST include the steps defined in `
|
|
23
|
+
`tasks.md` MUST include the steps defined in `lawbook/config.yaml` and the
|
|
24
24
|
`spec-tasks-mandatory-steps` rule: feature branch first, tests reviewed and
|
|
25
25
|
run, manual verification executed by the agent, docs updated, archive within
|
|
26
26
|
the PR. The agent performs the manual testing itself — never delegates it.
|
|
@@ -32,11 +32,11 @@ the PR. The agent performs the manual testing itself — never delegates it.
|
|
|
32
32
|
- Scenario headers use exactly `#### Scenario:`.
|
|
33
33
|
- Acceptance criteria are testable without production integrations.
|
|
34
34
|
- The implemented code must match what the delta spec promises. Validate with
|
|
35
|
-
the `
|
|
35
|
+
the `lawbook_validate` tool before syncing or archiving.
|
|
36
36
|
|
|
37
37
|
## Archiving discipline
|
|
38
38
|
|
|
39
|
-
Always archive with the `archive` command / `
|
|
39
|
+
Always archive with the `archive` command / `lawbook_archive` tool, never a manual
|
|
40
40
|
`mv` — the tool performs the spec promotion and validation a manual move skips.
|
|
41
41
|
|
|
42
42
|
## Amendments to the law
|
|
@@ -30,5 +30,5 @@ suppressing a linter or deleting a test.
|
|
|
30
30
|
- When a change affects runtime behavior and it's feasible, verify it works by
|
|
31
31
|
exercising the endpoint/UI — don't assume green CI covers everything.
|
|
32
32
|
- The mandatory spec task steps
|
|
33
|
-
([`
|
|
33
|
+
([`lawbook.md`](lawbook.md)) define which manual checks
|
|
34
34
|
the agent must execute itself.
|
|
@@ -4,7 +4,7 @@ import { AGENTS, detectConfiguredAgents } from "../../shared/agents.js";
|
|
|
4
4
|
/**
|
|
5
5
|
* Run the speclaw installation health checks against a project: ai-specs and
|
|
6
6
|
* LAWS.md presence, agent contracts, the docs/standards set, per-agent IDE
|
|
7
|
-
* symlink health, the
|
|
7
|
+
* symlink health, the lawbook/ workflow, the Compass index, and .mcp.json wiring.
|
|
8
8
|
*
|
|
9
9
|
* @param projectPath - Absolute path to the project root.
|
|
10
10
|
* @returns One {@link Check} per verified item, each carrying a remediation hint.
|
|
@@ -39,7 +39,7 @@ export function doctor(projectPath) {
|
|
|
39
39
|
"testing-standards",
|
|
40
40
|
"documentation",
|
|
41
41
|
"conventions",
|
|
42
|
-
"
|
|
42
|
+
"lawbook",
|
|
43
43
|
];
|
|
44
44
|
const missingStandards = standards.filter((s) => !has(path.join("docs/standards", `${s}.md`)));
|
|
45
45
|
checks.push({
|
|
@@ -85,11 +85,11 @@ export function doctor(projectPath) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
checks.push({
|
|
88
|
-
name: "
|
|
89
|
-
ok: has("
|
|
90
|
-
detail: has("
|
|
91
|
-
? "
|
|
92
|
-
: "missing — run the `
|
|
88
|
+
name: "lawbook workflow",
|
|
89
|
+
ok: has("lawbook"),
|
|
90
|
+
detail: has("lawbook")
|
|
91
|
+
? "lawbook/ present"
|
|
92
|
+
: "missing — run the `lawbook_init` tool",
|
|
93
93
|
});
|
|
94
94
|
checks.push({
|
|
95
95
|
name: "Compass index",
|
|
@@ -16,8 +16,6 @@ const profileShape = {
|
|
|
16
16
|
branch_pattern: z.string().optional().describe("e.g. 'feature/<ticket-id>-<slug>'"),
|
|
17
17
|
commit_style: z.string().optional().describe("e.g. 'conventional commits, imperative, English'"),
|
|
18
18
|
custom_laws: z.string().optional().describe("Extra markdown appended to LAWS.md — project-specific binding rules the analysis surfaced"),
|
|
19
|
-
ticket_prefix: z.string().optional().describe("Ticket prefix in the team's tracker, e.g. 'FAR'"),
|
|
20
|
-
team_language: z.string().optional().describe("The team's working language for posted communication (reviews, replies, tickets), e.g. 'Spanish'. Repo artifacts stay in the repo's own language. Defaults to English."),
|
|
21
19
|
compass_hints: z.string().optional().describe("Markdown bullets with the repo's real entrypoints and common traces, inserted into docs/compass.md"),
|
|
22
20
|
base_standards_extra: z.string().optional().describe("Markdown with any project-specific cross-cutting rules, appended to docs/standards/base-standards.md"),
|
|
23
21
|
modules_table: z.string().optional().describe("Markdown table of the repo's real modules/bounded contexts + one-line responsibility, for docs/standards/architecture.md"),
|
|
@@ -38,19 +36,19 @@ export function registerFoundation(server) {
|
|
|
38
36
|
return text({
|
|
39
37
|
instructions: [
|
|
40
38
|
"1. Analyze the repository at projectPath and fill in every profile field below with REAL values from the codebase (read package.json / pyproject.toml / CI configs / README — do not invent).",
|
|
41
|
-
"2. The foundation is a set of GRANULAR standards under docs/standards/ (base, architecture, backend, frontend, testing, conventions,
|
|
42
|
-
"3. Suggest packs: add stack packs whose 'detect' hints match dependencies you found; offer the rest. Ask the user which packs to install (the
|
|
43
|
-
"4.
|
|
39
|
+
"2. The foundation is a set of GRANULAR standards under docs/standards/ (base, architecture, backend, frontend, testing, conventions, lawbook), bound by LAWS.md and referenced from CLAUDE.md/AGENTS.md. Fill their structured fields from the real repo: modules_table and layering_rules (architecture), backend_layers, frontend_layers, versioning_rules, and any base_standards_extra. Omit a field only when that standard genuinely doesn't apply to this stack.",
|
|
40
|
+
"3. Suggest packs: add stack packs whose 'detect' hints match dependencies you found; offer the rest. Ask the user which packs to install (the lawbook workflow is always installed).",
|
|
41
|
+
"4. Infer the working language and the branch/commit/tracker conventions from the repo itself — the language already used in docstrings, commit messages, branch names, and PR/ticket bodies. Do NOT ask the user or assume English; match what the repo does, and set branch_pattern/commit_style accordingly. speclaw does not prescribe a ticket tool — leave tracker linkage to the team's own convention.",
|
|
44
42
|
"5. Draft any custom_laws (extra binding rules for LAWS.md) from conventions you observed that the standard set doesn't cover.",
|
|
45
43
|
"6. Call the 'scaffold' tool with { projectPath, profile, packs }.",
|
|
46
|
-
"7. Follow the nextSteps returned by scaffold: complete the HTML-comment sections still left in docs/standards/*, then run the
|
|
44
|
+
"7. Follow the nextSteps returned by scaffold: complete the HTML-comment sections still left in docs/standards/*, then run the lawbook_init and compass_index tools (both built into speclaw — no external installs).",
|
|
47
45
|
],
|
|
48
46
|
profileFields: Object.fromEntries(Object.entries(profileShape).map(([key, schema]) => [key, schema.description ?? ""])),
|
|
49
47
|
packs,
|
|
50
48
|
});
|
|
51
49
|
});
|
|
52
50
|
server.registerTool("scaffold", {
|
|
53
|
-
description: "Write the speclaw setup into a project: the foundation (LAWS.md constitution + granular docs/standards/* + CLAUDE.md + AGENTS.md + docs/compass.md), the
|
|
51
|
+
description: "Write the speclaw setup into a project: the foundation (LAWS.md constitution + granular docs/standards/* + CLAUDE.md + AGENTS.md + docs/compass.md), the lawbook workflow (always), the selected tool packs, multi-IDE symlinks (.claude/.cursor/.codex/.agents), .mcp.json wiring for speclaw, and .gitignore for .speclaw/. Never overwrites existing files. Call init_project first.",
|
|
54
52
|
inputSchema: {
|
|
55
53
|
projectPath: z.string().describe("Absolute path to the project"),
|
|
56
54
|
profile: z.object(profileShape).describe("Project profile gathered by analyzing the repo"),
|
|
@@ -70,7 +68,7 @@ export function registerFoundation(server) {
|
|
|
70
68
|
return text(report);
|
|
71
69
|
});
|
|
72
70
|
server.registerTool("doctor", {
|
|
73
|
-
description: "Verify a speclaw installation: ai-specs presence, the foundation (LAWS.md + standards + agent contracts), IDE symlinks health, the
|
|
71
|
+
description: "Verify a speclaw installation: ai-specs presence, the foundation (LAWS.md + standards + agent contracts), IDE symlinks health, the lawbook/ workflow, the Compass index, and .mcp.json wiring. Returns a checklist with remediation hints.",
|
|
74
72
|
inputSchema: { projectPath: z.string().describe("Absolute path to the project") },
|
|
75
73
|
}, async ({ projectPath }) => {
|
|
76
74
|
const checks = doctor(projectPath);
|
|
@@ -4,7 +4,7 @@ import { assetsDir } from "../../shared/paths.js";
|
|
|
4
4
|
import { render } from "../../shared/render.js";
|
|
5
5
|
import { emptyReport, ensureGitignore } from "../../shared/install.js";
|
|
6
6
|
import { configureAgent } from "../../shared/agents.js";
|
|
7
|
-
import { installWorkflow } from "../
|
|
7
|
+
import { installWorkflow } from "../lawbook/register.js";
|
|
8
8
|
import { installPack, loadPacks } from "../tools/packs.js";
|
|
9
9
|
const ASSETS = assetsDir(import.meta.url);
|
|
10
10
|
// Every {{var}} the foundation templates may reference. Ones the agent didn't
|
|
@@ -19,7 +19,6 @@ const FOUNDATION_DEFAULTS = {
|
|
|
19
19
|
frontend_layers: "",
|
|
20
20
|
versioning_rules: "",
|
|
21
21
|
documentation_extra: "",
|
|
22
|
-
team_language: "English",
|
|
23
22
|
};
|
|
24
23
|
/**
|
|
25
24
|
* Render the foundation: walk the module's assets/, mirror its structure into
|
|
@@ -90,7 +89,7 @@ export function scaffold(projectPath, profile, packNames, agents = []) {
|
|
|
90
89
|
for (const id of agents)
|
|
91
90
|
configureAgent(projectPath, id, report); // only the chosen agents
|
|
92
91
|
report.nextSteps = [
|
|
93
|
-
"Run the `
|
|
92
|
+
"Run the `lawbook_init` tool to set up the spec-driven workflow (creates lawbook/). No external CLI needed — it's built into speclaw.",
|
|
94
93
|
"Run the `compass_index` tool to build the local code graph (.speclaw/). No install, no LLM — it's built into speclaw. Re-run it after significant edits.",
|
|
95
94
|
"Analyze the repo's real entrypoints and core flows, then fill in the 'Project-specific starting points' section of docs/compass.md (or pass compass_hints in the profile) so agents know where to start querying.",
|
|
96
95
|
"Fill in the per-standard sections left as HTML comments in docs/standards/* (architecture module table, backend/frontend layer tables, versioning) by analyzing the real repo. These are the granular laws CLAUDE.md, AGENTS.md and the dev agents reference.",
|
|
@@ -5,6 +5,6 @@ description: Finalize a completed change — sync specs into canonical, then arc
|
|
|
5
5
|
Archive the completed change: $ARGUMENTS
|
|
6
6
|
|
|
7
7
|
Follow the `archive` skill: confirm every task is done and gates are green,
|
|
8
|
-
run `
|
|
9
|
-
syncs the specs and moves the change to `
|
|
8
|
+
run `lawbook_validate`, then `lawbook_archive` with today's date (YYYY-MM-DD). It
|
|
9
|
+
syncs the specs and moves the change to `lawbook/changes/archive/`. Never move
|
|
10
10
|
the folder by hand.
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
description: Draft a new spec-driven change (proposal, delta specs, tasks) before coding.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
Draft a new change under `
|
|
5
|
+
Draft a new change under `lawbook/changes/<name>/` for: $ARGUMENTS
|
|
6
6
|
|
|
7
|
-
Follow the `draft` skill: ensure `
|
|
7
|
+
Follow the `draft` skill: ensure `lawbook/` exists (`lawbook_init`), investigate the
|
|
8
8
|
code with `compass_explore`/`compass_recall`, read the governing
|
|
9
9
|
`docs/standards/`, then write `proposal.md`, `specs/<capability>/spec.md`
|
|
10
10
|
(normative `SHALL`/`MUST` + `#### Scenario:`), optional `design.md`, and
|
|
11
|
-
`tasks.md` (with the mandatory steps from `
|
|
12
|
-
running `
|
|
11
|
+
`tasks.md` (with the mandatory steps from `lawbook/config.yaml`). Finish by
|
|
12
|
+
running `lawbook_validate` and fixing every issue.
|
|
@@ -7,4 +7,4 @@ Explore: $ARGUMENTS
|
|
|
7
7
|
Follow the `explore` skill: use `compass_recall`/`compass_explore` to understand
|
|
8
8
|
the code, ask sharp questions, check the relevant `docs/standards/`, weigh
|
|
9
9
|
approaches with trade-offs, and give a recommendation. Write nothing to
|
|
10
|
-
`
|
|
10
|
+
`lawbook/`; when the direction is clear, offer to `draft` the change.
|
|
@@ -4,6 +4,6 @@ description: Promote a change's delta specs into the canonical specs, without ar
|
|
|
4
4
|
|
|
5
5
|
Sync the change's specs into canonical: $ARGUMENTS
|
|
6
6
|
|
|
7
|
-
Follow the `sync` skill: validate the change (`
|
|
8
|
-
`
|
|
7
|
+
Follow the `sync` skill: validate the change (`lawbook_validate`), then run
|
|
8
|
+
`lawbook_sync` to promote each delta spec into `lawbook/specs/`. Report what was
|
|
9
9
|
promoted; leave the change active.
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Enforce the mandatory steps from
|
|
2
|
+
description: Enforce the mandatory steps from lawbook/config.yaml when creating tasks.md, and ensure the agent executes all manual verification itself.
|
|
3
3
|
alwaysApply: true
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Spec Tasks: Mandatory Steps
|
|
7
7
|
|
|
8
|
-
When creating or updating a `tasks.md` inside a `
|
|
8
|
+
When creating or updating a `tasks.md` inside a `lawbook/changes/<name>/`, you MUST:
|
|
9
9
|
|
|
10
|
-
## 1. Read
|
|
10
|
+
## 1. Read lawbook/config.yaml first
|
|
11
11
|
|
|
12
|
-
Before writing tasks, read `
|
|
12
|
+
Before writing tasks, read `lawbook/config.yaml` for the project's mandatory task
|
|
13
13
|
steps, branch convention, and testing/documentation requirements.
|
|
14
14
|
|
|
15
15
|
## 2. Include the mandatory steps, in order
|
|
@@ -22,7 +22,7 @@ steps, branch convention, and testing/documentation requirements.
|
|
|
22
22
|
- Perform manual verification of the behavior — **the agent executes this
|
|
23
23
|
itself, never the user.**
|
|
24
24
|
- Update the technical documentation the change touches.
|
|
25
|
-
- Archive the change within the same PR (the `archive` command / `
|
|
25
|
+
- Archive the change within the same PR (the `archive` command / `lawbook_archive`
|
|
26
26
|
tool).
|
|
27
27
|
|
|
28
28
|
## 3. Manual verification — the agent must execute it
|
|
@@ -33,5 +33,5 @@ not complete until the agent has verified it.
|
|
|
33
33
|
|
|
34
34
|
## 4. Archiving is part of the change
|
|
35
35
|
|
|
36
|
-
A change is not done until it is archived with `
|
|
36
|
+
A change is not done until it is archived with `lawbook_archive` (never a manual
|
|
37
37
|
`mv`). The archive lands in the same PR that implements the change.
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: archive
|
|
3
|
-
description: Finalize a completed change — sync its specs into canonical, then move it to the archive. Use when a change is done and merged-ready: "archive the change", "finalize X", "close out the change". Part of speclaw's
|
|
3
|
+
description: Finalize a completed change — sync its specs into canonical, then move it to the archive. Use when a change is done and merged-ready: "archive the change", "finalize X", "close out the change". Part of speclaw's lawbook module (draft → build → sync → archive). Archiving belongs in the same PR that implements the change.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# archive — Finalize and archive a change
|
|
7
7
|
|
|
8
8
|
Close out a completed change: its delta specs become canonical and the change
|
|
9
|
-
folder moves to `
|
|
9
|
+
folder moves to `lawbook/changes/archive/`. This is part of the PR that
|
|
10
10
|
implements the change, not a post-merge chore.
|
|
11
11
|
|
|
12
12
|
## Steps
|
|
13
13
|
|
|
14
14
|
1. Confirm the change is truly done: every task in `tasks.md` checked, quality
|
|
15
15
|
gates green, behavior verified.
|
|
16
|
-
2. Run `
|
|
17
|
-
3. Run the `
|
|
18
|
-
(`YYYY-MM-DD`). It syncs the delta specs into `
|
|
19
|
-
`
|
|
16
|
+
2. Run `lawbook_validate` for the change; resolve any issues first.
|
|
17
|
+
3. Run the `lawbook_archive` tool with the change name and today's date
|
|
18
|
+
(`YYYY-MM-DD`). It syncs the delta specs into `lawbook/specs/` and then moves
|
|
19
|
+
`lawbook/changes/<name>/` to `lawbook/changes/archive/<date>-<name>/`.
|
|
20
20
|
4. Report the archive path and the promoted specs. Never move the folder by
|
|
21
|
-
hand — always use `
|
|
21
|
+
hand — always use `lawbook_archive`, which performs the sync and validation a
|
|
22
22
|
manual move would skip.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: build
|
|
3
|
-
description: Implement the tasks of a drafted change, following its spec and the project's standards. Use when the user wants to start or continue implementing a change: "build X", "implement the change", "work through the tasks", "continue X". Part of speclaw's
|
|
3
|
+
description: Implement the tasks of a drafted change, following its spec and the project's standards. Use when the user wants to start or continue implementing a change: "build X", "implement the change", "work through the tasks", "continue X". Part of speclaw's lawbook module (draft → build → sync → archive).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# build — Implement a change
|
|
@@ -10,8 +10,8 @@ in lockstep.
|
|
|
10
10
|
|
|
11
11
|
## Step 0 — Load the change
|
|
12
12
|
|
|
13
|
-
- Read `
|
|
14
|
-
`specs/`. If unsure which change, run `
|
|
13
|
+
- Read `lawbook/changes/<name>/proposal.md`, `tasks.md`, and the delta specs under
|
|
14
|
+
`specs/`. If unsure which change, run `lawbook_list`.
|
|
15
15
|
- Read the governing standards in `docs/standards/` for the areas you'll touch.
|
|
16
16
|
|
|
17
17
|
## Step 1 — Branch first
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: draft
|
|
3
|
-
description: Draft a new spec-driven change — proposal, delta specs, and tasks — before writing any code. Use when the user wants to start, plan, or propose a new feature, fix, or refactor: "draft a change for X", "propose X", "let's plan X", "spec out X", "new change". Part of speclaw's
|
|
3
|
+
description: Draft a new spec-driven change — proposal, delta specs, and tasks — before writing any code. Use when the user wants to start, plan, or propose a new feature, fix, or refactor: "draft a change for X", "propose X", "let's plan X", "spec out X", "new change". Part of speclaw's lawbook module (draft → build → sync → archive).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# draft — Draft a new change
|
|
7
7
|
|
|
8
|
-
Turn a request into a complete, reviewable change under `
|
|
8
|
+
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
|
## Step 0 — Ensure the workspace exists
|
|
13
13
|
|
|
14
|
-
If `
|
|
14
|
+
If `lawbook/` is missing, run the `lawbook_init` tool once to create it.
|
|
15
15
|
|
|
16
16
|
## Step 1 — Understand the request and the code
|
|
17
17
|
|
|
@@ -25,14 +25,14 @@ If `spec/` is missing, run the `spec_init` tool once to create it.
|
|
|
25
25
|
## Step 2 — Pick a change name
|
|
26
26
|
|
|
27
27
|
Kebab-case, action-oriented (e.g. `add-login`, `fix-shift-overlap`). This is
|
|
28
|
-
the folder under `
|
|
28
|
+
the folder under `lawbook/changes/`.
|
|
29
29
|
|
|
30
30
|
## Step 3 — Write the artifacts
|
|
31
31
|
|
|
32
|
-
Create under `
|
|
32
|
+
Create under `lawbook/changes/<name>/`:
|
|
33
33
|
|
|
34
34
|
- **proposal.md** — the why, the what, non-goals, and whether migrations are
|
|
35
|
-
needed. Reference the tracker ticket
|
|
35
|
+
needed. Reference the team's tracker ticket if there is one.
|
|
36
36
|
- **specs/<capability>/spec.md** — the delta spec for each affected capability.
|
|
37
37
|
Use normative language and testable scenarios:
|
|
38
38
|
```markdown
|
|
@@ -49,13 +49,13 @@ Create under `spec/changes/<name>/`:
|
|
|
49
49
|
- **design.md** (optional) — for non-trivial changes: approach, alternatives,
|
|
50
50
|
trade-offs.
|
|
51
51
|
- **tasks.md** — ordered, checkable steps. MUST include the mandatory steps
|
|
52
|
-
from `
|
|
52
|
+
from `lawbook/config.yaml` (feature branch first; tests reviewed and run;
|
|
53
53
|
manual verification executed by the agent; docs updated; archive within the
|
|
54
54
|
PR).
|
|
55
55
|
|
|
56
56
|
## Step 4 — Validate
|
|
57
57
|
|
|
58
|
-
Run the `
|
|
58
|
+
Run the `lawbook_validate` tool for the change and fix every issue it reports
|
|
59
59
|
(missing artifacts, non-normative specs, missing scenarios) before handing off
|
|
60
60
|
to implementation.
|
|
61
61
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: explore
|
|
3
|
-
description: Enter explore mode — a thinking partner for investigating an idea, a problem, or the codebase before or during a change. Use when the user wants to think something through, understand how something works, or clarify requirements before committing to a spec: "help me think through X", "how does X work", "explore X", "I'm not sure how to approach X". Part of speclaw's
|
|
3
|
+
description: Enter explore mode — a thinking partner for investigating an idea, a problem, or the codebase before or during a change. Use when the user wants to think something through, understand how something works, or clarify requirements before committing to a spec: "help me think through X", "how does X work", "explore X", "I'm not sure how to approach X". Part of speclaw's lawbook module.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# explore — Think it through
|
|
7
7
|
|
|
8
8
|
A low-commitment mode for investigating ideas and the codebase before (or
|
|
9
|
-
during) a change. Nothing is written to `
|
|
9
|
+
during) a change. Nothing is written to `lawbook/` here — the output is shared
|
|
10
10
|
understanding and a recommended direction.
|
|
11
11
|
|
|
12
12
|
## How to explore
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sync
|
|
3
|
+
description: Promote a change's delta specs into the canonical specs, without archiving. Use when the user wants to update the source-of-truth specs from a change: "sync the specs", "update the canonical specs", "promote the specs". Part of speclaw's lawbook module (draft → build → sync → archive).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# sync — Promote delta specs to canonical
|
|
7
|
+
|
|
8
|
+
Update the project's canonical specifications (`lawbook/specs/`) with a change's
|
|
9
|
+
delta specs, without archiving the change. Use this when the specs should
|
|
10
|
+
become the source of truth but the change isn't finished (e.g. multi-PR work).
|
|
11
|
+
|
|
12
|
+
## Steps
|
|
13
|
+
|
|
14
|
+
1. Confirm which change to sync (run `lawbook_list` if unsure).
|
|
15
|
+
2. Run `lawbook_validate` for the change; do not sync a change whose specs are
|
|
16
|
+
invalid.
|
|
17
|
+
3. Run the `lawbook_sync` tool for the change. It copies each
|
|
18
|
+
`lawbook/changes/<name>/specs/<capability>/spec.md` over the canonical
|
|
19
|
+
`lawbook/specs/<capability>/spec.md` and reports what it promoted.
|
|
20
|
+
4. Report the promoted files to the user. The change stays active — `archive`
|
|
21
|
+
it when it's fully done.
|
|
@@ -4,20 +4,20 @@ import path from "node:path";
|
|
|
4
4
|
// (proposals, delta specs, changes, archive) but implemented from scratch and
|
|
5
5
|
// deliberately simpler: a change's specs/ holds the full intended spec for each
|
|
6
6
|
// affected capability, and sync promotes those into the canonical specs/.
|
|
7
|
-
const SPEC_DIR = "
|
|
7
|
+
const SPEC_DIR = "lawbook";
|
|
8
8
|
function specRoot(projectPath) {
|
|
9
9
|
return path.join(projectPath, SPEC_DIR);
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Report whether the
|
|
12
|
+
* Report whether the lawbook workspace (lawbook/) has been initialized for a project.
|
|
13
13
|
*
|
|
14
14
|
* @param projectPath - Absolute path to the project root.
|
|
15
|
-
* @returns True if the
|
|
15
|
+
* @returns True if the lawbook/ directory exists.
|
|
16
16
|
*/
|
|
17
17
|
export function specExists(projectPath) {
|
|
18
18
|
return fs.existsSync(specRoot(projectPath));
|
|
19
19
|
}
|
|
20
|
-
const CONFIG_YAML = `# speclaw
|
|
20
|
+
const CONFIG_YAML = `# speclaw lawbook module configuration
|
|
21
21
|
# The spec-driven workflow: draft -> build -> sync -> archive (explore anytime).
|
|
22
22
|
|
|
23
23
|
# Mandatory steps every change's tasks.md must include, in order.
|
|
@@ -27,14 +27,14 @@ mandatory_task_steps:
|
|
|
27
27
|
- "Run the quality gates and verify they pass (see docs/standards/testing-standards.md)."
|
|
28
28
|
- "Perform manual verification of the behavior — the agent executes this itself, never the user."
|
|
29
29
|
- "Update the technical documentation touched by the change."
|
|
30
|
-
- "Archive the change within the same PR (
|
|
30
|
+
- "Archive the change within the same PR (lawbook:archive)."
|
|
31
31
|
|
|
32
32
|
# A change is required for new behavior, endpoints, schema changes, or UI flows;
|
|
33
33
|
# one-line fixes need not have one.
|
|
34
34
|
`;
|
|
35
|
-
const README_MD = `#
|
|
35
|
+
const README_MD = `# lawbook/ — the spec-driven workflow (speclaw)
|
|
36
36
|
|
|
37
|
-
This directory is managed by speclaw's **
|
|
37
|
+
This directory is managed by speclaw's **lawbook** module.
|
|
38
38
|
|
|
39
39
|
- \`specs/\` — the canonical specifications (the current source of truth).
|
|
40
40
|
- \`changes/<name>/\` — an in-flight change: \`proposal.md\`, \`tasks.md\`,
|
|
@@ -44,11 +44,11 @@ This directory is managed by speclaw's **spec** module.
|
|
|
44
44
|
|
|
45
45
|
## Workflow
|
|
46
46
|
|
|
47
|
-
1. \`
|
|
48
|
-
2. \`
|
|
49
|
-
3. \`
|
|
50
|
-
4. \`
|
|
51
|
-
5. \`
|
|
47
|
+
1. \`lawbook:draft\` — describe the change; generates proposal, delta specs, tasks.
|
|
48
|
+
2. \`lawbook:build\` — implement the tasks.
|
|
49
|
+
3. \`lawbook:sync\` — promote the change's delta specs into \`specs/\`.
|
|
50
|
+
4. \`lawbook:archive\` — sync + move the change to \`changes/archive/\`.
|
|
51
|
+
5. \`lawbook:explore\` — think through an idea before or during a change.
|
|
52
52
|
`;
|
|
53
53
|
/**
|
|
54
54
|
* Initialize the spec/ workspace, creating the specs/, changes/, and archive
|
|
@@ -107,7 +107,7 @@ function deltaSpecFiles(changeDir) {
|
|
|
107
107
|
* header, and a "#### Scenario:" acceptance criterion.
|
|
108
108
|
*
|
|
109
109
|
* @param projectPath - Absolute path to the project root.
|
|
110
|
-
* @param change - Change name (folder under
|
|
110
|
+
* @param change - Change name (folder under lawbook/changes/).
|
|
111
111
|
* @returns The validation verdict and the list of issues to fix; never throws
|
|
112
112
|
* for a missing change — it is reported as an issue with `valid: false`.
|
|
113
113
|
*/
|
|
@@ -115,7 +115,7 @@ export function specValidate(projectPath, change) {
|
|
|
115
115
|
const changeDir = path.join(specRoot(projectPath), "changes", change);
|
|
116
116
|
const issues = [];
|
|
117
117
|
if (!fs.existsSync(changeDir)) {
|
|
118
|
-
return { change, valid: false, issues: [`change "${change}" not found under
|
|
118
|
+
return { change, valid: false, issues: [`change "${change}" not found under lawbook/changes/`], deltaSpecs: [] };
|
|
119
119
|
}
|
|
120
120
|
if (!fs.existsSync(path.join(changeDir, "proposal.md")))
|
|
121
121
|
issues.push("missing proposal.md");
|
|
@@ -145,7 +145,7 @@ export function specValidate(projectPath, change) {
|
|
|
145
145
|
* file for each affected capability.
|
|
146
146
|
*
|
|
147
147
|
* @param projectPath - Absolute path to the project root.
|
|
148
|
-
* @param change - Change name (folder under
|
|
148
|
+
* @param change - Change name (folder under lawbook/changes/).
|
|
149
149
|
* @returns The change name and the list of promoted spec paths.
|
|
150
150
|
* @throws If the change directory does not exist.
|
|
151
151
|
*/
|
|
@@ -168,7 +168,7 @@ export function specSync(projectPath, change) {
|
|
|
168
168
|
const dest = path.join(root, "specs", rel);
|
|
169
169
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
170
170
|
fs.copyFileSync(full, dest);
|
|
171
|
-
promoted.push(path.join("
|
|
171
|
+
promoted.push(path.join("lawbook/specs", rel));
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
};
|
|
@@ -180,7 +180,7 @@ export function specSync(projectPath, change) {
|
|
|
180
180
|
* it to changes/archive/<date>-<name>/.
|
|
181
181
|
*
|
|
182
182
|
* @param projectPath - Absolute path to the project root.
|
|
183
|
-
* @param change - Change name (folder under
|
|
183
|
+
* @param change - Change name (folder under lawbook/changes/).
|
|
184
184
|
* @param date - Archive date prefix, formatted YYYY-MM-DD.
|
|
185
185
|
* @returns The promoted specs and the archive destination path.
|
|
186
186
|
* @throws If the change does not exist, or the archive target already exists.
|
|
@@ -13,40 +13,40 @@ const ASSETS = assetsDir(import.meta.url);
|
|
|
13
13
|
export function installWorkflow(projectPath, vars, report) {
|
|
14
14
|
const aiSpecs = path.join(projectPath, "ai-specs");
|
|
15
15
|
copyRendered(path.join(ASSETS, "skills"), path.join(aiSpecs, "skills"), vars, report);
|
|
16
|
-
copyRendered(path.join(ASSETS, "commands"), path.join(aiSpecs, "commands", "
|
|
16
|
+
copyRendered(path.join(ASSETS, "commands"), path.join(aiSpecs, "commands", "lawbook"), vars, report);
|
|
17
17
|
copyRendered(path.join(ASSETS, "rules"), path.join(aiSpecs, "rules"), vars, report);
|
|
18
18
|
}
|
|
19
19
|
// ─── The spec module: speclaw's own spec-driven workflow (no external OpenSpec) ───
|
|
20
20
|
// Mechanical operations behind the draft/build/sync/archive/explore commands.
|
|
21
21
|
/** Register the spec workflow MCP tools (init, list, validate, sync, archive). */
|
|
22
22
|
export function registerSpec(server) {
|
|
23
|
-
server.registerTool("
|
|
24
|
-
description: "Initialize speclaw's spec-driven workflow in a project: creates
|
|
23
|
+
server.registerTool("lawbook_init", {
|
|
24
|
+
description: "Initialize speclaw's spec-driven workflow in a project: creates lawbook/ (specs/, changes/, changes/archive/, config.yaml, README). Idempotent — never overwrites existing files.",
|
|
25
25
|
inputSchema: { projectPath: z.string().describe("Absolute path to the project") },
|
|
26
26
|
}, async ({ projectPath }) => text(specInit(projectPath)));
|
|
27
|
-
server.registerTool("
|
|
27
|
+
server.registerTool("lawbook_list", {
|
|
28
28
|
description: "List the spec workspace: active changes, archived changes, and canonical capabilities under spec/.",
|
|
29
29
|
inputSchema: { projectPath: z.string().describe("Absolute path to the project") },
|
|
30
30
|
}, async ({ projectPath }) => text(specList(projectPath)));
|
|
31
|
-
server.registerTool("
|
|
31
|
+
server.registerTool("lawbook_validate", {
|
|
32
32
|
description: "Validate a change's artifacts: proposal.md and tasks.md present, and delta specs use normative language (SHALL/MUST), '### Requirement:' headers, and '#### Scenario:' acceptance criteria. Returns the issues to fix. Used by the draft/build commands before proceeding.",
|
|
33
33
|
inputSchema: {
|
|
34
34
|
projectPath: z.string().describe("Absolute path to the project"),
|
|
35
|
-
change: z.string().describe("Change name (folder under
|
|
35
|
+
change: z.string().describe("Change name (folder under lawbook/changes/)"),
|
|
36
36
|
},
|
|
37
37
|
}, async ({ projectPath, change }) => text(specValidate(projectPath, change)));
|
|
38
|
-
server.registerTool("
|
|
39
|
-
description: "Promote a change's delta specs into the canonical
|
|
38
|
+
server.registerTool("lawbook_sync", {
|
|
39
|
+
description: "Promote a change's delta specs into the canonical lawbook/specs/ (per capability), without archiving. Backs the `sync` command.",
|
|
40
40
|
inputSchema: {
|
|
41
41
|
projectPath: z.string().describe("Absolute path to the project"),
|
|
42
|
-
change: z.string().describe("Change name (folder under
|
|
42
|
+
change: z.string().describe("Change name (folder under lawbook/changes/)"),
|
|
43
43
|
},
|
|
44
44
|
}, async ({ projectPath, change }) => text(specSync(projectPath, change)));
|
|
45
|
-
server.registerTool("
|
|
46
|
-
description: "Finalize a change: sync its delta specs into
|
|
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
47
|
inputSchema: {
|
|
48
48
|
projectPath: z.string().describe("Absolute path to the project"),
|
|
49
|
-
change: z.string().describe("Change name (folder under
|
|
49
|
+
change: z.string().describe("Change name (folder under lawbook/changes/)"),
|
|
50
50
|
date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Today's date, YYYY-MM-DD"),
|
|
51
51
|
},
|
|
52
52
|
}, async ({ projectPath, change, date }) => text(specArchive(projectPath, change, date)));
|
|
@@ -22,7 +22,7 @@ Output path:
|
|
|
22
22
|
- [`docs/standards/backend-standards.md`](../../docs/standards/backend-standards.md) — layers, docstrings, typing, tests, migrations
|
|
23
23
|
- [`docs/standards/architecture.md`](../../docs/standards/architecture.md) — modules and layer boundaries
|
|
24
24
|
- [`docs/standards/testing-standards.md`](../../docs/standards/testing-standards.md) — quality gates
|
|
25
|
-
- [`docs/standards/
|
|
25
|
+
- [`docs/standards/lawbook.md`](../../docs/standards/lawbook.md) — spec-driven workflow
|
|
26
26
|
- [`docs/standards/base-standards.md`](../../docs/standards/base-standards.md) — cross-cutting rules
|
|
27
27
|
|
|
28
28
|
Use `compass_explore` to locate the real entrypoints, routers, schemas,
|
|
@@ -22,7 +22,7 @@ Output path:
|
|
|
22
22
|
- [`docs/standards/frontend-standards.md`](../../docs/standards/frontend-standards.md) — layers, rendering boundaries, state, i18n, UI
|
|
23
23
|
- [`docs/standards/architecture.md`](../../docs/standards/architecture.md) — modules and layer boundaries
|
|
24
24
|
- [`docs/standards/testing-standards.md`](../../docs/standards/testing-standards.md) — quality gates
|
|
25
|
-
- [`docs/standards/
|
|
25
|
+
- [`docs/standards/lawbook.md`](../../docs/standards/lawbook.md) — spec-driven workflow
|
|
26
26
|
- [`docs/standards/base-standards.md`](../../docs/standards/base-standards.md) — cross-cutting rules
|
|
27
27
|
|
|
28
28
|
Use `compass_explore` to locate the real entry files, feature routes, shared
|
|
@@ -12,7 +12,7 @@ export function registerTools(server) {
|
|
|
12
12
|
inputSchema: {},
|
|
13
13
|
}, async () => text(loadPacks()));
|
|
14
14
|
server.registerTool("add_pack", {
|
|
15
|
-
description: "Add a single pack to an already-initialized project, then refresh IDE symlinks. Pass template vars (organization,
|
|
15
|
+
description: "Add a single pack to an already-initialized project, then refresh IDE symlinks. Pass template vars (organization, ...) if the pack needs them.",
|
|
16
16
|
inputSchema: {
|
|
17
17
|
projectPath: z.string().describe("Absolute path to the project"),
|
|
18
18
|
pack: z.string().describe("Pack name (see list_packs)"),
|