@davidbalzan/groundwork 0.3.1
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/LICENSE +21 -0
- package/README.md +323 -0
- package/docs/DECISIONS.md +170 -0
- package/package.json +38 -0
- package/payload/doc-templates/COMMANDS.md +419 -0
- package/payload/doc-templates/DECISIONS.md +168 -0
- package/payload/doc-templates/FACTS.md +43 -0
- package/payload/doc-templates/GROUNDWORK_METHODOLOGY.md +1300 -0
- package/payload/doc-templates/STACK_MAP.md +90 -0
- package/payload/doc-templates/WORKSTREAMS.md +79 -0
- package/payload/doc-templates/_INDEX.md +54 -0
- package/payload/doc-templates/phases/README.md +36 -0
- package/payload/doc-templates/phases/templates/README.md +63 -0
- package/payload/doc-templates/phases/templates/TASK_TEMPLATE.md +302 -0
- package/payload/doc-templates/phases/templates/task_template_prompt.md +229 -0
- package/payload/doc-templates/templates/ARCHITECTURE_GUIDE_TEMPLATE.md +250 -0
- package/payload/doc-templates/templates/DESIGN_SYSTEM_TEMPLATE.md +336 -0
- package/payload/doc-templates/templates/DONE_TEMPLATE.md +21 -0
- package/payload/doc-templates/templates/PHASES_README_TEMPLATE.md +144 -0
- package/payload/doc-templates/templates/PHASE_README_TEMPLATE.md +142 -0
- package/payload/doc-templates/templates/PRD_TEMPLATE.md +348 -0
- package/payload/doc-templates/templates/PRODUCTION_ROADMAP_TEMPLATE.md +168 -0
- package/payload/doc-templates/templates/QUEUE_TEMPLATE.md +17 -0
- package/payload/doc-templates/templates/TECH_STACK_TEMPLATE.md +199 -0
- package/payload/scripts/check-task.mjs +98 -0
- package/payload/scripts/check-versions.mjs +113 -0
- package/payload/scripts/phase-status.mjs +69 -0
- package/payload/scripts/set-fact.mjs +86 -0
- package/payload/skills/add-data-layer/SKILL.md +129 -0
- package/payload/skills/check-task/SKILL.md +35 -0
- package/payload/skills/check-versions/SKILL.md +47 -0
- package/payload/skills/create-prd/SKILL.md +90 -0
- package/payload/skills/domain-model/SKILL.md +90 -0
- package/payload/skills/kickstart/SKILL.md +157 -0
- package/payload/skills/log-decision/SKILL.md +65 -0
- package/payload/skills/next/SKILL.md +65 -0
- package/payload/skills/plan-phase/SKILL.md +108 -0
- package/payload/skills/remember/SKILL.md +77 -0
- package/payload/skills/start-session/SKILL.md +52 -0
- package/payload/skills/update-workstreams/SKILL.md +60 -0
- package/src/cli.mjs +115 -0
- package/src/commands/add.mjs +39 -0
- package/src/commands/artifacts.mjs +24 -0
- package/src/commands/doctor.mjs +292 -0
- package/src/commands/init.mjs +147 -0
- package/src/commands/knowledge.mjs +148 -0
- package/src/commands/list.mjs +61 -0
- package/src/commands/status.mjs +96 -0
- package/src/commands/update.mjs +128 -0
- package/src/lib/adr-tripwire.mjs +171 -0
- package/src/lib/artifacts.mjs +124 -0
- package/src/lib/config.mjs +43 -0
- package/src/lib/fs.mjs +46 -0
- package/src/lib/log.mjs +22 -0
- package/src/lib/paths.mjs +36 -0
- package/src/lib/progress.mjs +26 -0
- package/src/lib/skills.mjs +42 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-data-layer
|
|
3
|
+
description: Add an optional Drizzle ORM + PostgreSQL data layer to a Groundwork project
|
|
4
|
+
argument-hint: "[postgres|mysql|sqlite] (default: postgres)"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Add Data Layer - Optional Persistence Module
|
|
8
|
+
|
|
9
|
+
The Groundwork starter is intentionally **database-agnostic** — no ORM or DB is wired in.
|
|
10
|
+
Run this only when a feature actually needs to store something (a foundation phase rarely
|
|
11
|
+
does). It adds a type-safe Drizzle data layer and records the choice as an ADR. When
|
|
12
|
+
updating docs, preserve frontmatter and use `[[wikilinks]]`.
|
|
13
|
+
|
|
14
|
+
## Default Recipe: Drizzle + PostgreSQL
|
|
15
|
+
|
|
16
|
+
### Stage 1: Confirm the choice
|
|
17
|
+
|
|
18
|
+
Ask only if ambiguous:
|
|
19
|
+
- **Engine?** PostgreSQL (default), MySQL, or SQLite.
|
|
20
|
+
- **Driver?** Postgres → `postgres` (postgres.js). MySQL → `mysql2`. SQLite → `better-sqlite3`.
|
|
21
|
+
|
|
22
|
+
### Stage 2: Install dependencies
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm --filter @<scope>/api add drizzle-orm postgres
|
|
26
|
+
pnpm --filter @<scope>/api add -D drizzle-kit
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
(MySQL: swap `postgres` → `mysql2`. SQLite: `better-sqlite3`.)
|
|
30
|
+
|
|
31
|
+
### Stage 3: Files to create (apps/api)
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
apps/api/
|
|
35
|
+
├── drizzle.config.ts # drizzle-kit config (schema path, out dir, dialect, dbCredentials)
|
|
36
|
+
├── src/db/
|
|
37
|
+
│ ├── client.ts # drizzle(postgres(env.DATABASE_URL)) singleton
|
|
38
|
+
│ ├── schema.ts # table definitions (pgTable/...) — start small
|
|
39
|
+
│ └── index.ts # re-export client + schema
|
|
40
|
+
└── migrations/ # generated SQL (drizzle-kit generate)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`src/db/client.ts` (Postgres):
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { drizzle } from "drizzle-orm/postgres-js";
|
|
47
|
+
import postgres from "postgres";
|
|
48
|
+
import { env } from "../env";
|
|
49
|
+
import * as schema from "./schema";
|
|
50
|
+
|
|
51
|
+
const client = postgres(env.DATABASE_URL, { max: 10 });
|
|
52
|
+
export const db = drizzle(client, { schema });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`drizzle.config.ts`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { defineConfig } from "drizzle-kit";
|
|
59
|
+
export default defineConfig({
|
|
60
|
+
schema: "./src/db/schema.ts",
|
|
61
|
+
out: "./migrations",
|
|
62
|
+
dialect: "postgresql",
|
|
63
|
+
dbCredentials: { url: process.env.DATABASE_URL! },
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Stage 4: Environment + validation
|
|
68
|
+
|
|
69
|
+
Add to `apps/api/src/env.ts` (Zod schema) and `.env.example`:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/app
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Stage 5: docker-compose service
|
|
76
|
+
|
|
77
|
+
Ensure `docker-compose.yml` has a Postgres service (most Groundwork starters already
|
|
78
|
+
ship one — verify the port/credentials match `DATABASE_URL`):
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
services:
|
|
82
|
+
db:
|
|
83
|
+
image: postgres:17
|
|
84
|
+
environment:
|
|
85
|
+
POSTGRES_PASSWORD: postgres
|
|
86
|
+
ports: ["5432:5432"]
|
|
87
|
+
volumes: ["pgdata:/var/lib/postgresql/data"]
|
|
88
|
+
volumes: { pgdata: {} }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Stage 6: Package scripts
|
|
92
|
+
|
|
93
|
+
Add to `apps/api/package.json`:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"scripts": {
|
|
98
|
+
"db:generate": "drizzle-kit generate",
|
|
99
|
+
"db:migrate": "drizzle-kit migrate",
|
|
100
|
+
"db:studio": "drizzle-kit studio"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Stage 7: Record the decision
|
|
106
|
+
|
|
107
|
+
1. `/log-decision "Use Drizzle ORM + PostgreSQL for persistence"` — capture why
|
|
108
|
+
(type-safety, migration story) and alternatives (Prisma, raw SQL, Kysely).
|
|
109
|
+
2. Update `docs/STACK_MAP.md`: move Drizzle + the DB engine from the **Optional
|
|
110
|
+
modules** section into the active **Backend** table with pinned versions.
|
|
111
|
+
3. Pin to **latest stable** versions (check the registry; do not copy versions from
|
|
112
|
+
memory).
|
|
113
|
+
|
|
114
|
+
## Verify
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
docker compose up -d db
|
|
118
|
+
pnpm --filter @<scope>/api db:generate
|
|
119
|
+
pnpm --filter @<scope>/api db:migrate
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Confirm the app boots and a trivial query against `db` works before closing the stream.
|
|
123
|
+
|
|
124
|
+
## Notes
|
|
125
|
+
|
|
126
|
+
- Keep `schema.ts` minimal at first — add tables as features need them, not upfront.
|
|
127
|
+
- For MySQL use `drizzle-orm/mysql2` + `mysqlTable`; for SQLite `drizzle-orm/better-sqlite3` + `sqliteTable`, and set `dialect` accordingly.
|
|
128
|
+
|
|
129
|
+
Engine requested: $ARGUMENTS
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: check-task
|
|
3
|
+
description: Mark a task as complete in the phase tasks file and update progress
|
|
4
|
+
argument-hint: "<task number or description>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Check Task - Progress Tracker
|
|
8
|
+
|
|
9
|
+
Mark a task complete in the phase tasks file and update progress.
|
|
10
|
+
|
|
11
|
+
## Fast path (preferred)
|
|
12
|
+
|
|
13
|
+
If `docs/.groundwork/scripts/check-task.mjs` exists, use it — it flips the checkbox and
|
|
14
|
+
recomputes progress deterministically (no hand-counting):
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
node docs/.groundwork/scripts/check-task.mjs "<task-id or text>"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
It auto-detects the active phase tasks file (most open checkboxes), updates the
|
|
21
|
+
`**Overall Progress**` line, and prints the new percentage. Fall back to the manual steps
|
|
22
|
+
only if the script is absent or the match is ambiguous.
|
|
23
|
+
|
|
24
|
+
## Manual fallback
|
|
25
|
+
|
|
26
|
+
1. Find the phase tasks file (`docs/phases/phaseN/PHASEN_TASKS.md`) — current phase per
|
|
27
|
+
`docs/PRODUCTION_ROADMAP.md` (Current Status).
|
|
28
|
+
2. Locate the task from `$ARGUMENTS` (number like `1.3`, description, or fuzzy match).
|
|
29
|
+
3. Flip its checkbox `[ ]` → `[x]`.
|
|
30
|
+
4. Update the `**Overall Progress**: X/Y tasks (Z%)` line if present.
|
|
31
|
+
5. **Cascade**: if all sub-tasks of a group are done, mark the parent done; if all tasks in
|
|
32
|
+
the phase are done, suggest updating `PRODUCTION_ROADMAP.md`.
|
|
33
|
+
6. Confirm which task was marked, the new percentage, and what's left in the group.
|
|
34
|
+
|
|
35
|
+
Task to mark complete: $ARGUMENTS
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: check-versions
|
|
3
|
+
description: Check the project's dependencies against latest stable and flag drift
|
|
4
|
+
argument-hint: "[--all | package names]"
|
|
5
|
+
allowed-tools: Read, Glob, Grep, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Check Versions - Dependency Freshness Audit
|
|
9
|
+
|
|
10
|
+
Verify the project is on current, stable dependency versions and keep
|
|
11
|
+
`docs/STACK_MAP.md` honest. Run this when bootstrapping a project and periodically
|
|
12
|
+
afterwards — drift is silent otherwise.
|
|
13
|
+
|
|
14
|
+
## Fast path (preferred)
|
|
15
|
+
|
|
16
|
+
The project ships a deterministic helper that queries the npm registry:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
node docs/.groundwork/scripts/check-versions.mjs # curated stack present in package.json
|
|
20
|
+
node docs/.groundwork/scripts/check-versions.mjs --all # every dependency
|
|
21
|
+
node docs/.groundwork/scripts/check-versions.mjs react vite # specific packages
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
It prints `pinned vs latest` with a status column and exits non-zero if anything is a
|
|
25
|
+
major behind. Run it and narrate the result.
|
|
26
|
+
|
|
27
|
+
## Instructions
|
|
28
|
+
|
|
29
|
+
1. **Run the script** above. If it is absent, read each `package.json` (root +
|
|
30
|
+
`apps/*` + `packages/*`) and check key deps with `npm view <pkg> version`.
|
|
31
|
+
2. **Summarize drift** — group into:
|
|
32
|
+
- ✅ on latest stable
|
|
33
|
+
- 🟡 same major, newer minor/patch available (safe bumps)
|
|
34
|
+
- 🔴 one or more majors behind (needs a planned migration)
|
|
35
|
+
3. **Reconcile with `docs/STACK_MAP.md`**:
|
|
36
|
+
- Update the `Latest stable` column and the `Last audited` date.
|
|
37
|
+
- For majors behind, add/refresh a row in the **Pending upgrades** section.
|
|
38
|
+
4. **Do NOT bump inline.** Recommend each major bump as its own workstream
|
|
39
|
+
(`/update-workstreams`) on a dedicated branch with build + test verification.
|
|
40
|
+
Minor/patch bumps can be batched into one small stream.
|
|
41
|
+
|
|
42
|
+
Run once right after `/kickstart` (whenever a `package.json` exists) so the first
|
|
43
|
+
`STACK_MAP.md` reflects reality, and periodically after. Report the table, the drift
|
|
44
|
+
summary, and the STACK_MAP edits you made (or propose); flag anything that should become an
|
|
45
|
+
upgrade workstream.
|
|
46
|
+
|
|
47
|
+
Packages/flags: $ARGUMENTS
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-prd
|
|
3
|
+
description: Define the product (problem, users, goals, scope, requirements) as a PRD. This is the FIRST step of the flow, right after install — run it before /kickstart, which scaffolds the project from this PRD.
|
|
4
|
+
argument-hint: "<product name or idea>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Create PRD - Product Requirements Document Generator
|
|
8
|
+
|
|
9
|
+
Generate a comprehensive PRD through a 6-stage discovery process.
|
|
10
|
+
|
|
11
|
+
## This is step 1 of the flow
|
|
12
|
+
|
|
13
|
+
**Run `/create-prd` first**, before `/kickstart`. The PRD is the single product-discovery
|
|
14
|
+
interview (problem, users, goals, scope, functional + non-functional requirements,
|
|
15
|
+
high-level phases). `/kickstart` then *consumes* it to scaffold the project docs **without
|
|
16
|
+
re-asking** — running kickstart first duplicates this discovery. Only the `groundwork init`
|
|
17
|
+
doc templates are needed; kickstart need not have run.
|
|
18
|
+
|
|
19
|
+
**Who runs this:** the product-context holder (you, or a coordinator acting as your proxy) —
|
|
20
|
+
this is a product-*definition* step, not execution. Don't delegate it to a narrow worker:
|
|
21
|
+
a worker lacks the product context the interview depends on, and its answers become guesses
|
|
22
|
+
baked into the spec. Workers run `/plan-phase` *tasks*; the spec is defined upstream.
|
|
23
|
+
|
|
24
|
+
## Pin the vocabulary (avoid overloaded terms)
|
|
25
|
+
|
|
26
|
+
Imprecise terms propagate into the schema and UI as contradictions. As you discover:
|
|
27
|
+
|
|
28
|
+
- **Flag overloaded/dual-meaning terms** the moment they appear ("ADR *and* lesson",
|
|
29
|
+
"account", "user vs customer"). Pick the canonical term, or model the relationship
|
|
30
|
+
explicitly (one umbrella concept with a `kind` vs two separate concepts).
|
|
31
|
+
- **Capture a `## Key Terms` section** in the PRD (one-line definitions). For anything
|
|
32
|
+
genuinely fuzzy, hand off to `/domain-model` (writes `docs/CONTEXT.md`).
|
|
33
|
+
- **Run a consistency pass before finishing**: terms in the vision/value prop must match
|
|
34
|
+
those in scope, requirements, and data shapes. If the value prop says "X and Y" but
|
|
35
|
+
scope only covers X, resolve it now — don't ship the contradiction to `/kickstart`.
|
|
36
|
+
(This semantic check is yours — only you/the model can catch a contradiction.
|
|
37
|
+
`groundwork doctor` later catches the *structural* gaps: missing PRD sections, phases
|
|
38
|
+
with no tasks, orphaned links.)
|
|
39
|
+
|
|
40
|
+
## Obsidian format (required)
|
|
41
|
+
|
|
42
|
+
Copy `docs/templates/PRD_TEMPLATE.md` (already structured); update the frontmatter `title`
|
|
43
|
+
to `"PRD: [Product Name]"` and `aliases`. Use `[[wikilinks]]` for cross-references
|
|
44
|
+
(`[[TECH_STACK]]`, `[[ARCHITECTURE_GUIDE]]`, `[[DECISIONS]]`).
|
|
45
|
+
|
|
46
|
+
## Instructions — 6-stage discovery
|
|
47
|
+
|
|
48
|
+
### Stage 1: Problem Discovery
|
|
49
|
+
Ask: what problem (concrete examples)? who experiences it (personas)? how solved today
|
|
50
|
+
(workarounds/pain)? why now (business context)? → capture problem statement, affected
|
|
51
|
+
segments, current alternatives, business impact.
|
|
52
|
+
|
|
53
|
+
### Stage 2: Vision & Goals
|
|
54
|
+
Ask: what does success look like? how measured (metrics + targets)? what are you NOT
|
|
55
|
+
building? timeline/constraints? → capture vision statement, 3–5 measurable goals,
|
|
56
|
+
non-goals/out-of-scope, timeline.
|
|
57
|
+
|
|
58
|
+
### Stage 3: User Requirements
|
|
59
|
+
Per persona: goals, pain points, technical level. Generate user stories
|
|
60
|
+
(`As a [persona], I want [action] so that [benefit]`), prioritized MoSCoW
|
|
61
|
+
(Must / Should / Could / Won't Have).
|
|
62
|
+
|
|
63
|
+
### Stage 4: Functional Requirements
|
|
64
|
+
For each Must-Have story: break into features; define testable acceptance criteria; map
|
|
65
|
+
user flows; identify dependencies.
|
|
66
|
+
|
|
67
|
+
### Stage 5: Non-Functional & Technical Requirements
|
|
68
|
+
Ask: performance (response times, concurrency); security (auth, data protection,
|
|
69
|
+
compliance); scalability (initial + growth); technology constraints (existing stack,
|
|
70
|
+
skills, budget); integrations (external systems, APIs).
|
|
71
|
+
|
|
72
|
+
### Stage 6: Risks & Planning
|
|
73
|
+
Identify technical/business risks, dependencies, and assumptions. Produce a risk matrix
|
|
74
|
+
with mitigations, a high-level phase breakdown, and key milestones.
|
|
75
|
+
|
|
76
|
+
**Quality bar:** requirements must be specific and testable ("<200ms p95", not "fast");
|
|
77
|
+
prioritize ruthlessly (not everything is Must-Have); capture the "why"; state non-goals.
|
|
78
|
+
|
|
79
|
+
## Output
|
|
80
|
+
|
|
81
|
+
Save the completed PRD (from `docs/templates/PRD_TEMPLATE.md`) to `docs/PRD.md` (or
|
|
82
|
+
`docs/PRD_[ProductName].md` if specified). Review and iterate with the user.
|
|
83
|
+
|
|
84
|
+
## Related Skills
|
|
85
|
+
|
|
86
|
+
After the PRD, in order: `/kickstart` (scaffold docs **from this PRD**) → `/check-versions`
|
|
87
|
+
→ `/plan-phase 1 [name]` → `/start-session`. (`/log-decision` whenever a technical
|
|
88
|
+
decision is made.)
|
|
89
|
+
|
|
90
|
+
## Product to document: $ARGUMENTS
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: domain-model
|
|
3
|
+
description: Build and sharpen the project's domain model — a ubiquitous-language glossary (and bounded-context map for larger systems). Use during system design (kickstart/plan-phase) or whenever terminology is fuzzy, conflicting, or being decided.
|
|
4
|
+
argument-hint: "[term or area to model]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Domain Model - Ubiquitous Language & Bounded Contexts
|
|
8
|
+
|
|
9
|
+
The *active* discipline of building the domain model as you design: challenge terms,
|
|
10
|
+
invent edge-case scenarios, and write the glossary down the moment it crystallises. (Merely
|
|
11
|
+
*reading* the glossary for vocabulary isn't this skill — this is for *changing* the model.)
|
|
12
|
+
|
|
13
|
+
> Adapted (MIT) from Matt Pocock's `domain-modeling` skill
|
|
14
|
+
> (github.com/mattpocock/skills), fitted to Groundwork's docs vault and `[[DECISIONS]]`.
|
|
15
|
+
|
|
16
|
+
Outputs (created **lazily**, only when there's something to write):
|
|
17
|
+
- **`docs/CONTEXT.md`** — the ubiquitous-language glossary (single context).
|
|
18
|
+
- **`docs/CONTEXT-MAP.md`** — only for multiple **bounded contexts**: lists each context,
|
|
19
|
+
where it lives, and how they relate. A `CONTEXT.md` sits beside each context's code.
|
|
20
|
+
|
|
21
|
+
Both start with YAML frontmatter and use `[[wikilinks]]`.
|
|
22
|
+
|
|
23
|
+
**Who runs this:** the product-context holder (you, or a coordinator acting as your proxy) —
|
|
24
|
+
defining the ubiquitous language is a spec decision, not execution. A narrow worker lacks the
|
|
25
|
+
product context to settle term conflicts, so don't delegate the model itself; workers *consume*
|
|
26
|
+
`CONTEXT.md`, they don't author it.
|
|
27
|
+
|
|
28
|
+
## During a design session
|
|
29
|
+
|
|
30
|
+
- **Challenge against the glossary.** If a term conflicts with `CONTEXT.md`, call it out:
|
|
31
|
+
"Your glossary defines 'cancellation' as X, but you mean Y — which is it?"
|
|
32
|
+
- **Sharpen fuzzy language.** Propose a precise canonical term for vague/overloaded words.
|
|
33
|
+
"You said 'account' — Customer or User? Those differ."
|
|
34
|
+
- **Stress-test with concrete scenarios** that force precision about boundaries between concepts.
|
|
35
|
+
- **Cross-reference with code**; surface contradictions.
|
|
36
|
+
- **Update `CONTEXT.md` inline** — capture each resolved term as it happens. Keep it
|
|
37
|
+
**devoid of implementation detail**: it's a glossary, not a spec.
|
|
38
|
+
|
|
39
|
+
## CONTEXT.md format
|
|
40
|
+
|
|
41
|
+
```markdown
|
|
42
|
+
---
|
|
43
|
+
title: "Domain Context"
|
|
44
|
+
tags: [groundwork/core]
|
|
45
|
+
aliases: ["Ubiquitous Language", "Glossary", "CONTEXT"]
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
# {Context Name}
|
|
49
|
+
{One or two sentences: what this context is and why it exists.}
|
|
50
|
+
|
|
51
|
+
## Language
|
|
52
|
+
**Order**: A confirmed, priced customer request ready to fulfil.
|
|
53
|
+
_Avoid_: Purchase, transaction
|
|
54
|
+
**Customer**: A person or organization that places orders.
|
|
55
|
+
_Avoid_: Client, buyer, account
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Rules: be opinionated (pick one term, list the rest under `_Avoid_`); tight definitions
|
|
59
|
+
(1–2 sentences, what it *is* not what it *does*); only context-specific terms (no general
|
|
60
|
+
programming concepts); group under subheadings when clusters emerge.
|
|
61
|
+
|
|
62
|
+
## CONTEXT-MAP.md format (multi-context only)
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
---
|
|
66
|
+
title: "Context Map"
|
|
67
|
+
tags: [groundwork/core]
|
|
68
|
+
aliases: ["Context Map"]
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
# Context Map
|
|
72
|
+
## Contexts
|
|
73
|
+
- [[ordering/CONTEXT|Ordering]] — receives and tracks customer orders
|
|
74
|
+
- [[billing/CONTEXT|Billing]] — generates invoices and processes payments
|
|
75
|
+
## Relationships
|
|
76
|
+
- **Ordering → Billing**: Ordering emits `OrderPlaced`; Billing consumes it to invoice
|
|
77
|
+
- **Ordering ↔ Billing**: shared types `CustomerId`, `Money`
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Decisions
|
|
81
|
+
|
|
82
|
+
When modeling surfaces a real architectural decision, record it with `/log-decision` — but
|
|
83
|
+
**only when all three hold**: hard to reverse, surprising without context, a real trade-off.
|
|
84
|
+
Boundary/ownership decisions ("Customer data is owned by the Customer context; others
|
|
85
|
+
reference it by ID") are prime ADR material.
|
|
86
|
+
|
|
87
|
+
`/kickstart` runs this during architecture design; `/plan-phase` uses the glossary to name
|
|
88
|
+
tasks/types precisely.
|
|
89
|
+
|
|
90
|
+
Term or area to model: $ARGUMENTS
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kickstart
|
|
3
|
+
description: Scaffold a project's docs (tech stack, architecture, roadmap, phases) FROM an existing PRD. Run AFTER /create-prd. Use when a PRD exists and the project docs/structure still need generating.
|
|
4
|
+
argument-hint: "<project name>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Kickstart - Project Initialization
|
|
8
|
+
|
|
9
|
+
Scaffold a project's Groundwork docs **from its PRD**: tech stack, architecture, roadmap,
|
|
10
|
+
and phase structure.
|
|
11
|
+
|
|
12
|
+
## Obsidian format (required)
|
|
13
|
+
|
|
14
|
+
Every generated file under `docs/`: (1) starts with YAML frontmatter (`title`; `tags` e.g.
|
|
15
|
+
`groundwork/core`/`groundwork/reference`/`groundwork/phase`; `aliases`); (2) uses
|
|
16
|
+
`[[wikilinks]]`, not `[text](path.md)`; (3) templates already include both — when copying,
|
|
17
|
+
preserve frontmatter (update title/aliases) and keep wikilinks as-is.
|
|
18
|
+
|
|
19
|
+
## Prerequisite: the PRD comes first
|
|
20
|
+
|
|
21
|
+
`/create-prd` is the entry point, not kickstart. The PRD defines the *product*; kickstart
|
|
22
|
+
turns it into the *scaffold* and must **not** re-interview on anything the PRD already
|
|
23
|
+
answers. Before anything else, look for `docs/PRD.md` (or `docs/PRD_*.md`):
|
|
24
|
+
|
|
25
|
+
- **PRD exists:** read it; derive project name, type, description, goals, scope, and phases
|
|
26
|
+
from it. Skip to what it doesn't cover (tech stack, architecture, design system).
|
|
27
|
+
- **No PRD:** recommend `/create-prd` first. Use the full question flow below only if the
|
|
28
|
+
user chooses to skip the PRD (tiny throwaway project).
|
|
29
|
+
|
|
30
|
+
**Who runs this (and only one agent):** run it as the product-context holder (you, or a
|
|
31
|
+
coordinator acting as your proxy), not a narrow execution worker — kickstart makes
|
|
32
|
+
stack/architecture choices that lean on the product understanding behind the PRD. And it is
|
|
33
|
+
a **single-writer** step: never let two agents scaffold the same repo at once — they race on
|
|
34
|
+
the same files. In a multi-agent setup the coordinator runs kickstart itself (or has David
|
|
35
|
+
run it) and *then* seeds workers from the generated docs; workers run `/plan-phase` tasks.
|
|
36
|
+
|
|
37
|
+
## Instructions
|
|
38
|
+
|
|
39
|
+
Pull every answer from the PRD first; only ask for what's genuinely missing.
|
|
40
|
+
|
|
41
|
+
### Stage 1: Project Setup (from the PRD)
|
|
42
|
+
|
|
43
|
+
Take name/type/description from the PRD if present, else ask: project name; type (web app,
|
|
44
|
+
API, CLI, library, mobile…); one-line description. Then create the structure:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
project-root/
|
|
48
|
+
├── docs/{phases/templates,templates}/
|
|
49
|
+
├── client/src/ # if frontend
|
|
50
|
+
└── server/src/ # if backend
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Stage 2: Tech Stack Discovery
|
|
54
|
+
|
|
55
|
+
Ask per layer (skip if N/A):
|
|
56
|
+
|
|
57
|
+
- **Frontend:** framework? build tool? styling? state management?
|
|
58
|
+
- **Backend:** runtime? framework? database? ORM?
|
|
59
|
+
- **Infra:** package manager? monorepo? deploy target?
|
|
60
|
+
|
|
61
|
+
Generate `docs/TECH_STACK.md` from `docs/templates/TECH_STACK_TEMPLATE.md`.
|
|
62
|
+
**Pin to latest stable — do not guess versions.** If a `package.json` exists, run
|
|
63
|
+
`/check-versions`; otherwise look up each package's latest stable on the registry (memory
|
|
64
|
+
drifts, the registry does not).
|
|
65
|
+
|
|
66
|
+
### Stage 2b: Version source of truth
|
|
67
|
+
|
|
68
|
+
Populate `docs/STACK_MAP.md` with pinned versions + latest-stable targets. **Version
|
|
69
|
+
numbers live only here** — every other doc links to it. Set the `Last audited` date; note
|
|
70
|
+
anything a major behind under **Pending upgrades**.
|
|
71
|
+
|
|
72
|
+
### Stage 3: Architecture Decisions
|
|
73
|
+
|
|
74
|
+
First, **establish the ubiquitous language** — run `/domain-model`: pull core domain terms
|
|
75
|
+
from the PRD, sharpen fuzzy/overloaded ones, capture them in `docs/CONTEXT.md` (and
|
|
76
|
+
`docs/CONTEXT-MAP.md` for multiple bounded contexts). Skip only for trivial projects.
|
|
77
|
+
|
|
78
|
+
Then, for each major technology choice, capture: why this choice, alternatives considered,
|
|
79
|
+
trade-offs. Generate:
|
|
80
|
+
|
|
81
|
+
- `docs/ARCHITECTURE_GUIDE.md` - from `ARCHITECTURE_GUIDE_TEMPLATE.md`
|
|
82
|
+
- `docs/DECISIONS.md` - initial ADRs, but **only when** a decision is hard to reverse,
|
|
83
|
+
surprising without context, and a real trade-off.
|
|
84
|
+
|
|
85
|
+
### Stage 4: Project Phases (from the PRD)
|
|
86
|
+
|
|
87
|
+
Derive phases from the PRD's scope/MoSCoW/milestones and **confirm** them with the user —
|
|
88
|
+
don't re-interview. If no PRD: ask MVP scope, post-MVP, hard deadlines. Suggested shapes:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
Web app: Foundation → Core Features → Polish → Launch
|
|
92
|
+
API: Foundation → Security → Features → Production
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Generate `docs/PRODUCTION_ROADMAP.md`, `docs/phases/README.md`, and
|
|
96
|
+
`docs/phases/phase1/README.md` from their templates.
|
|
97
|
+
|
|
98
|
+
### Stage 5: Initialize Workstreams & Queue
|
|
99
|
+
|
|
100
|
+
Generate `docs/WORKSTREAMS.md` from the `WORKSTREAMS.md` doc template — the live state of
|
|
101
|
+
parallel work streams (one row per stream; the swarm-native replacement for a single
|
|
102
|
+
"current focus" and the live counterpart to `[[QUEUE]]`). Start with one placeholder
|
|
103
|
+
stream pointing at Phase 1; leave `Recently Closed` empty.
|
|
104
|
+
|
|
105
|
+
Create `docs/QUEUE.md` from `docs/templates/QUEUE_TEMPLATE.md` (Queue empty at init;
|
|
106
|
+
`/plan-phase` adds phases as they're planned) and `docs/DONE.md` from
|
|
107
|
+
`docs/templates/DONE_TEMPLATE.md` (empty completion log).
|
|
108
|
+
|
|
109
|
+
### Stage 6: Design System (optional)
|
|
110
|
+
|
|
111
|
+
If the project has a frontend, ask color scheme, typography, and component style; generate
|
|
112
|
+
`docs/DESIGN_SYSTEM.md` from `docs/templates/DESIGN_SYSTEM_TEMPLATE.md`.
|
|
113
|
+
|
|
114
|
+
### Stage 7: Summary
|
|
115
|
+
|
|
116
|
+
Summarise what was created (see Output Files), then give next steps:
|
|
117
|
+
|
|
118
|
+
1. `/check-versions` - pin the stack to latest stable (if a `package.json` exists)
|
|
119
|
+
2. `/plan-phase 1 [name]` - create detailed tasks
|
|
120
|
+
3. `/start-session` - begin development
|
|
121
|
+
|
|
122
|
+
## Output Files
|
|
123
|
+
|
|
124
|
+
| File | Source Template | Purpose |
|
|
125
|
+
| ------------------------------ | ----------------------------------------------- | ----------------------------------- |
|
|
126
|
+
| `docs/TECH_STACK.md` | `docs/templates/TECH_STACK_TEMPLATE.md` | Technology choices (versions → STACK_MAP) |
|
|
127
|
+
| `docs/STACK_MAP.md` | (shipped doc) | Single source of truth for versions |
|
|
128
|
+
| `docs/CONTEXT.md` | (via `/domain-model`) | Ubiquitous-language glossary |
|
|
129
|
+
| `docs/ARCHITECTURE_GUIDE.md` | `docs/templates/ARCHITECTURE_GUIDE_TEMPLATE.md` | System design and patterns |
|
|
130
|
+
| `docs/DECISIONS.md` | (ADR template in existing file) | Architectural Decision Records |
|
|
131
|
+
| `docs/PRODUCTION_ROADMAP.md` | `docs/templates/PRODUCTION_ROADMAP_TEMPLATE.md` | High-level phase overview |
|
|
132
|
+
| `docs/DESIGN_SYSTEM.md` | `docs/templates/DESIGN_SYSTEM_TEMPLATE.md` | Visual design guidelines (optional) |
|
|
133
|
+
| `docs/phases/README.md` | `docs/templates/PHASES_README_TEMPLATE.md` | Phase navigation and progress |
|
|
134
|
+
| `docs/phases/phase1/README.md` | `docs/templates/PHASE_README_TEMPLATE.md` | First phase overview |
|
|
135
|
+
| `docs/WORKSTREAMS.md` | `WORKSTREAMS.md` doc template | Live state of parallel work streams |
|
|
136
|
+
| `docs/QUEUE.md` | `docs/templates/QUEUE_TEMPLATE.md` | Inbound task queue |
|
|
137
|
+
| `docs/DONE.md` | `docs/templates/DONE_TEMPLATE.md` | Completion log (append-only) |
|
|
138
|
+
|
|
139
|
+
Pre-existing (not generated): `docs/templates/PRD_TEMPLATE.md` (used by `/create-prd`),
|
|
140
|
+
`docs/phases/templates/TASK_TEMPLATE.md` + `task_template_prompt.md` (used by `/plan-phase`).
|
|
141
|
+
|
|
142
|
+
## Logging convention (inherited)
|
|
143
|
+
|
|
144
|
+
Projects ship structured logging: server (`apps/api`) uses pino → NDJSON to console **and**
|
|
145
|
+
`logs/api.log` at the repo root; the browser (`apps/web`) logger mirrors to console and
|
|
146
|
+
POSTs batched entries to `/api/logs`, which pino re-emits as `source: "client"` — so one
|
|
147
|
+
tailable `logs/api.log` captures both sides. `LOG_LEVEL` controls verbosity (default
|
|
148
|
+
`info`). Mention this in `ARCHITECTURE_GUIDE.md`/ADRs so it isn't lost. For other stacks
|
|
149
|
+
(Python/Go/…), keep the pattern: structured logs to file + console, browser logs forwarded
|
|
150
|
+
server-side, one tailable file.
|
|
151
|
+
|
|
152
|
+
## Related Skills
|
|
153
|
+
|
|
154
|
+
Runs **after** `/create-prd`. Then in order: `/check-versions` → `/plan-phase 1 [name]` →
|
|
155
|
+
`/start-session`; `/log-decision` whenever a decision is made.
|
|
156
|
+
|
|
157
|
+
## Project to initialize: $ARGUMENTS
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: log-decision
|
|
3
|
+
description: Create an Architectural Decision Record in DECISIONS.md
|
|
4
|
+
argument-hint: "<decision title>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Log Decision - ADR Creator
|
|
8
|
+
|
|
9
|
+
Append an Architectural Decision Record (ADR) to `docs/DECISIONS.md`.
|
|
10
|
+
|
|
11
|
+
## When to log an ADR (the gate)
|
|
12
|
+
|
|
13
|
+
Only record an ADR when **all three** hold — otherwise skip it (you'll just clutter the log):
|
|
14
|
+
|
|
15
|
+
1. **Hard to reverse** — changing your mind later carries real cost.
|
|
16
|
+
2. **Surprising without context** — a future reader will wonder "why did they do this?"
|
|
17
|
+
3. **The result of a real trade-off** — there were genuine alternatives and you chose one.
|
|
18
|
+
|
|
19
|
+
Prime material: architectural shape, integration patterns, lock-in tech choices (DB, auth,
|
|
20
|
+
message bus), boundary/ownership decisions, deliberate deviations from the obvious path.
|
|
21
|
+
Skip "we did the obvious thing." (For cross-project lessons, use `/remember` instead.)
|
|
22
|
+
|
|
23
|
+
## Instructions
|
|
24
|
+
|
|
25
|
+
1. **Read `docs/DECISIONS.md`** for the current format and the next ADR number (always increment).
|
|
26
|
+
2. **Gather** Title, Context, Decision, Consequences (positive / negative / risks), and
|
|
27
|
+
Alternatives Considered — from `$ARGUMENTS` or by asking for what's missing.
|
|
28
|
+
3. **Append the ADR** in the format below. Preserve the file's existing frontmatter.
|
|
29
|
+
4. **Update the index table** at the top with `| ADR-XXX | [Title] | Accepted | YYYY-MM-DD |`.
|
|
30
|
+
Use `[[wikilinks]]` in the body where relevant (`[[TECH_STACK]]`, `[[DECISIONS#adr-003|ADR-003]]`).
|
|
31
|
+
|
|
32
|
+
## ADR Format
|
|
33
|
+
|
|
34
|
+
```markdown
|
|
35
|
+
### ADR-XXX: [Decision Title]
|
|
36
|
+
|
|
37
|
+
**Date**: YYYY-MM-DD
|
|
38
|
+
**Status**: Accepted | Proposed | Superseded by ADR-XXX
|
|
39
|
+
|
|
40
|
+
#### Context
|
|
41
|
+
[The issue motivating this decision.]
|
|
42
|
+
|
|
43
|
+
#### Decision
|
|
44
|
+
[What we're doing.]
|
|
45
|
+
|
|
46
|
+
#### Consequences
|
|
47
|
+
**Positive:**
|
|
48
|
+
- [Benefit]
|
|
49
|
+
**Negative:**
|
|
50
|
+
- [Trade-off]
|
|
51
|
+
**Risks:**
|
|
52
|
+
- [Risk to monitor]
|
|
53
|
+
|
|
54
|
+
#### Alternatives Considered
|
|
55
|
+
| Alternative | Pros | Cons | Why Not Chosen |
|
|
56
|
+
| ----------- | ---- | ---- | -------------- |
|
|
57
|
+
| [Option] | ... | ... | ... |
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Key Rules
|
|
61
|
+
|
|
62
|
+
- ADRs are **immutable** — to change one, add a new ADR and mark the old "Superseded by ADR-XXX".
|
|
63
|
+
- Always increment the ADR number.
|
|
64
|
+
|
|
65
|
+
Decision to log: $ARGUMENTS
|