wdi-method 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/bin/wdi-method.js +906 -0
- package/kit/.constitution/README.md +66 -0
- package/kit/.constitution/codebase/brownfield-guide.md +18 -0
- package/kit/.constitution/codebase/conventions-guide.md +18 -0
- package/kit/.constitution/codebase/stack-guide.md +18 -0
- package/kit/.constitution/constitution.md +135 -0
- package/kit/.constitution/document/architecture-guide.md +209 -0
- package/kit/.constitution/document/bmad-guide.md +151 -0
- package/kit/.constitution/document/bmad-skill-register.md +71 -0
- package/kit/.constitution/document/brief-guide.md +94 -0
- package/kit/.constitution/document/corpus-guide.md +341 -0
- package/kit/.constitution/document/decision-guide.md +134 -0
- package/kit/.constitution/document/delivery-flow-guide.md +338 -0
- package/kit/.constitution/document/prd-guide.md +202 -0
- package/kit/.constitution/document/sdd-guide.md +206 -0
- package/kit/.constitution/document/srs-guide.md +147 -0
- package/kit/.constitution/document/templates/addendum.md +71 -0
- package/kit/.constitution/document/templates/architecture-spine.md +100 -0
- package/kit/.constitution/document/templates/brief.md +110 -0
- package/kit/.constitution/document/templates/c4.md +77 -0
- package/kit/.constitution/document/templates/contract.md +52 -0
- package/kit/.constitution/document/templates/cross-cutting.md +80 -0
- package/kit/.constitution/document/templates/decision.md +64 -0
- package/kit/.constitution/document/templates/design-system.md +67 -0
- package/kit/.constitution/document/templates/flow.md +51 -0
- package/kit/.constitution/document/templates/integration.md +69 -0
- package/kit/.constitution/document/templates/inventory.md +69 -0
- package/kit/.constitution/document/templates/lc.md +47 -0
- package/kit/.constitution/document/templates/lifecycle.md +52 -0
- package/kit/.constitution/document/templates/meeting.md +47 -0
- package/kit/.constitution/document/templates/model.md +55 -0
- package/kit/.constitution/document/templates/oq.md +45 -0
- package/kit/.constitution/document/templates/prd.md +226 -0
- package/kit/.constitution/document/templates/questions.md +75 -0
- package/kit/.constitution/document/templates/rtr.md +61 -0
- package/kit/.constitution/document/templates/rules.md +47 -0
- package/kit/.constitution/document/templates/scn.md +40 -0
- package/kit/.constitution/document/templates/sdd.md +146 -0
- package/kit/.constitution/document/templates/srs.md +149 -0
- package/kit/.constitution/document/templates/structure-codebase.md +129 -0
- package/kit/.constitution/document/templates/structure-document.md +90 -0
- package/kit/.constitution/document/templates/uc.md +69 -0
- package/kit/.constitution/document/templates/ux.md +77 -0
- package/kit/.constitution/document/ux-guide.md +99 -0
- package/kit/.constitution/language-guide.md +69 -0
- package/kit/.constitution/method/README.md +169 -0
- package/kit/.constitution/method/artifact-map.md +155 -0
- package/kit/.constitution/method/portability.md +91 -0
- package/kit/.constitution/method/rationale.md +246 -0
- package/kit/.constitution/method-glossary.md +169 -0
- package/kit/.constitution/project/README.md +68 -0
- package/kit/.constitution/repo-guide.md +97 -0
- package/kit/.constitution/scripts/inventory.py +527 -0
- package/kit/.constitution/scripts/timeline.py +665 -0
- package/kit/.constitution/scripts/validate.py +1579 -0
- package/kit/.constitution/structure-guide.md +202 -0
- package/kit/assets/bmad-custom/bmad-advanced-elicitation.toml +15 -0
- package/kit/assets/bmad-custom/bmad-architecture.toml +31 -0
- package/kit/assets/bmad-custom/bmad-build-auto.toml +10 -0
- package/kit/assets/bmad-custom/bmad-build.toml +52 -0
- package/kit/assets/bmad-custom/bmad-code-review.toml +12 -0
- package/kit/assets/bmad-custom/bmad-correct-course.toml +27 -0
- package/kit/assets/bmad-custom/bmad-deep-recon.toml +11 -0
- package/kit/assets/bmad-custom/bmad-prd.toml +42 -0
- package/kit/assets/bmad-custom/bmad-product-brief.toml +34 -0
- package/kit/assets/bmad-custom/bmad-retrospective.toml +9 -0
- package/kit/assets/bmad-custom/bmad-spec.toml +15 -0
- package/kit/assets/bmad-custom/bmad-ux.toml +19 -0
- package/kit/assets/bmad-custom/config.toml +6 -0
- package/kit/skills/wdi-blueprint/SKILL.md +203 -0
- package/kit/skills/wdi-build/SKILL.md +244 -0
- package/kit/skills/wdi-component/SKILL.md +172 -0
- package/kit/skills/wdi-decision/.gitkeep +0 -0
- package/kit/skills/wdi-decision/SKILL.md +183 -0
- package/kit/skills/wdi-help/.gitkeep +0 -0
- package/kit/skills/wdi-help/SKILL.md +98 -0
- package/kit/skills/wdi-init/SKILL.md +149 -0
- package/kit/skills/wdi-log/SKILL.md +107 -0
- package/kit/skills/wdi-problem/SKILL.md +90 -0
- package/kit/skills/wdi-product/SKILL.md +127 -0
- package/kit/skills/wdi-question/.gitkeep +0 -0
- package/kit/skills/wdi-question/SKILL.md +88 -0
- package/kit/skills/wdi-reconcile/.gitkeep +0 -0
- package/kit/skills/wdi-reconcile/SKILL.md +146 -0
- package/kit/skills/wdi-report/SKILL.md +205 -0
- package/kit/skills/wdi-review/SKILL.md +118 -0
- package/kit/skills/wdi-systematic-debugging/SKILL.md +193 -0
- package/kit/skills/wdi-systematic-debugging/references/condition-based-waiting.md +115 -0
- package/kit/skills/wdi-systematic-debugging/references/defense-in-depth.md +122 -0
- package/kit/skills/wdi-systematic-debugging/references/find-polluter.sh +72 -0
- package/kit/skills/wdi-systematic-debugging/references/root-cause-tracing.md +169 -0
- package/kit/skills/wdi-ux/SKILL.md +145 -0
- package/kit-overlay/AGENTS.md +196 -0
- package/kit-overlay/README.md +66 -0
- package/kit-overlay/constitution.md +135 -0
- package/kit-overlay/portability.md +91 -0
- package/kit-overlay/repo-guide.md +97 -0
- package/lib/agents-block.mjs +52 -0
- package/lib/identity.mjs +65 -0
- package/package.json +37 -0
- package/scaffold/.control/decisions/.gitkeep +0 -0
- package/scaffold/.control/generated/.gitkeep +2 -0
- package/scaffold/.control/meetings/.gitkeep +0 -0
- package/scaffold/.control/memlog/.gitkeep +0 -0
- package/scaffold/.control/product-glossary.md +21 -0
- package/scaffold/.control/project-non-technical-log.md +23 -0
- package/scaffold/.control/questions/answered.md +11 -0
- package/scaffold/.control/questions/assumptions.md +15 -0
- package/scaffold/.control/questions/blocking.md +21 -0
- package/scaffold/.control/questions/external.md +11 -0
- package/scaffold/.control/registry/components.yaml +21 -0
- package/scaffold/.control/registry/decisions.yaml +6 -0
- package/scaffold/.control/registry/defects.yaml +3 -0
- package/scaffold/.control/registry/index.yaml +46 -0
- package/scaffold/.control/registry/requirements.yaml +15 -0
- package/scaffold/.control/registry/risks.yaml +5 -0
- package/scaffold/.control/registry/usecases.yaml +6 -0
- package/scaffold/.control/registry/waves.yaml +5 -0
- package/scaffold/.control/structure-codebase.md +19 -0
- package/scaffold/.control/structure-document.md +25 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: Accepted
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Constitution — {product}
|
|
6
|
+
|
|
7
|
+
Rewrite Articles 2 and 5 for the product this repo is. Article 1 cites
|
|
8
|
+
`.control/registry/index.yaml` — replace `{product}` there at G1, not here.
|
|
9
|
+
Articles 3, 4, 6, and 7 are the method and travel unchanged.
|
|
10
|
+
|
|
11
|
+
An agent working here MUST be able to act on the contents of this repo alone.
|
|
12
|
+
|
|
13
|
+
## Article 1 — Scope
|
|
14
|
+
|
|
15
|
+
This repo covers the product named at `product.name` in
|
|
16
|
+
`.control/registry/index.yaml`. One product, one repo. A second product MUST
|
|
17
|
+
get a repo of its own.
|
|
18
|
+
|
|
19
|
+
`product.client` in the same file names the client if there is one, and stays
|
|
20
|
+
empty if there is not. The product brief at G1 uses `product.name` as its
|
|
21
|
+
title. Neither this file nor the brief is a second source of the name.
|
|
22
|
+
|
|
23
|
+
An agent working here MUST NOT demand that sibling organisation repositories
|
|
24
|
+
be open in the same session.
|
|
25
|
+
|
|
26
|
+
## Article 2 — Content boundary, `.work/`, and cross-repo references
|
|
27
|
+
|
|
28
|
+
All three are governed by [`repo-guide.md`](repo-guide.md). Its rules MUST NOT be
|
|
29
|
+
repeated here — one rule, one place.
|
|
30
|
+
|
|
31
|
+
What is particular to this repo, and therefore lives here:
|
|
32
|
+
|
|
33
|
+
- Name any extra boundary this product has (a public-repo rule, a ban on `3p.md`,
|
|
34
|
+
a `.work/` resting state). If there is none, delete this bullet list and the
|
|
35
|
+
sentence above it.
|
|
36
|
+
- `3p.md` MUST NOT be created in a product repo. Operational engagement memory
|
|
37
|
+
lives outside.
|
|
38
|
+
|
|
39
|
+
## Article 3 — Layers
|
|
40
|
+
|
|
41
|
+
The repo layout is governed by `corpus-guide.md` and mapped by
|
|
42
|
+
`.control/structure-document.md`. What MUST be known before opening either:
|
|
43
|
+
|
|
44
|
+
| Path | Role |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `.constitution/` | Rules — how we work. `method/` holds the non-binding explanation of them |
|
|
47
|
+
| `.control/` | Control — what currently holds and what has been decided |
|
|
48
|
+
| `.what/` | What is promised |
|
|
49
|
+
| `.how/` | How it is built |
|
|
50
|
+
| `_bmad-output/` | Run workspace; committed, not curated |
|
|
51
|
+
| `.work/` | Scratch; committed, emptied when a task closes |
|
|
52
|
+
| *(application roots)* | Application code — name them in this row |
|
|
53
|
+
|
|
54
|
+
The method does not use a `docs/` layer for corpus or rules. A leftover `docs/`
|
|
55
|
+
folder is inventory to sort, not a second home.
|
|
56
|
+
|
|
57
|
+
## Article 4 — Lifecycle
|
|
58
|
+
|
|
59
|
+
Every `.constitution/` file MUST carry a `status:` frontmatter, and it MUST be one of five:
|
|
60
|
+
|
|
61
|
+
| Status | Means |
|
|
62
|
+
|---|---|
|
|
63
|
+
| `Accepted` | **Binds.** It MAY be cited as the reason to reject a change |
|
|
64
|
+
| `Reference` | **Explains, does not bind.** It MUST NOT be cited as the reason to reject a change, and MUST NOT be installed as `doc_standards` or `persistent_facts` |
|
|
65
|
+
| `Draft` | Not settled. Its contents MAY be read as guidance but MUST NOT be used to reject a change |
|
|
66
|
+
| `Superseded` | Replaced. It MUST name its replacement |
|
|
67
|
+
| `Cancelled` | Withdrawn without a replacement, and kept so nobody rewrites it |
|
|
68
|
+
|
|
69
|
+
**One exception, by construction:** a file in `document/templates/` MUST NOT carry a `status:` of its own.
|
|
70
|
+
A template's frontmatter is the *artifact's* frontmatter — it is copied into what the template produces —
|
|
71
|
+
so a status there would land in the artifact and mean something else entirely.
|
|
72
|
+
|
|
73
|
+
A missing header anywhere else is a **finding**, not an implicit anything.
|
|
74
|
+
|
|
75
|
+
`Reference` exists so that the *explanation* of a rule can live beside the rule without competing with it —
|
|
76
|
+
`method/` holds four such files. Where a `Reference` file and an `Accepted` one disagree, the `Accepted`
|
|
77
|
+
one wins, and the disagreement MUST be reported as a defect rather than resolved by preferring whichever was
|
|
78
|
+
opened first. A rule MUST NOT be born in a `Reference` file; when one is noticed there, it is stated as a
|
|
79
|
+
finding and written in the guide that owns it.
|
|
80
|
+
|
|
81
|
+
## Article 5 — The method arrives from WDI Method
|
|
82
|
+
|
|
83
|
+
This is the **consumer** article. Use it in every product repo.
|
|
84
|
+
|
|
85
|
+
`.constitution/` guides and templates (except this file's Articles 1, 2, and 5,
|
|
86
|
+
`codebase/*-guide.md`, and any extra file this repo added), the `wdi-*` skills,
|
|
87
|
+
and `_bmad/custom/*.toml` arrive from the public WDI Method package via
|
|
88
|
+
`npx wdi-method install` / `update`.
|
|
89
|
+
|
|
90
|
+
- A method file MUST NOT be invented or patched here to improve the method. If a
|
|
91
|
+
rule is wrong, it is fixed in the WDI Method package, then brought here with
|
|
92
|
+
`update`.
|
|
93
|
+
- `wdi-method update` MUST overwrite method files and MUST NOT touch `.what/`,
|
|
94
|
+
`.how/`, `.control/` product state, this file's Articles 1–2 and 5,
|
|
95
|
+
`codebase/*-guide.md` once `Accepted`, extra constitution files this repo
|
|
96
|
+
added, or `_bmad/custom/*.user.toml`.
|
|
97
|
+
- A rule particular to this repo MUST be written out in full in this file or a
|
|
98
|
+
sibling, and MUST NOT be replaced by a pointer into another repository.
|
|
99
|
+
|
|
100
|
+
A prefix in `.claude/skills/` names the **method**, not the owner: `bmad-*` is
|
|
101
|
+
BMad's, `wdi-*` is this method's.
|
|
102
|
+
|
|
103
|
+
## Article 6 — Decisions
|
|
104
|
+
|
|
105
|
+
A decision worth remembering is a `DEC-NNN`. Its shape, the one test that decides whether it is
|
|
106
|
+
recorded at all, global numbering, the `draft → accepted → applied` status ladder, and supersession
|
|
107
|
+
are governed by [`document/decision-guide.md`](document/decision-guide.md). Decisions live in
|
|
108
|
+
`.control/decisions/` and are registered in `.control/registry/decisions.yaml`.
|
|
109
|
+
|
|
110
|
+
Recording a decision is **not mandatory**, and one case is: a decision that contradicts or changes an
|
|
111
|
+
`AD-N`. The guide owns both halves and they MUST NOT be restated here.
|
|
112
|
+
|
|
113
|
+
The name ADR is retired, along with `layer:` and `component:` on a decision. `ADR-NNN` appearing in a
|
|
114
|
+
document frozen before that date is a retired alias for `DEC-NNN`, and those documents MUST NOT be
|
|
115
|
+
rewritten for the prefix. A course correction is a `DEC-` of `type: course-correction`.
|
|
116
|
+
|
|
117
|
+
## Article 7 — Non-technical facts
|
|
118
|
+
|
|
119
|
+
A non-technical fact that constrains what may be built, used, or promised — a domain now held, a
|
|
120
|
+
third-party account now active, the legal entity a screen must name, a date that locks scope — MUST
|
|
121
|
+
be recorded in `.control/project-non-technical-log.md`, and MUST NOT be scattered into a `DEC-`, a
|
|
122
|
+
PRD, or a code comment as though it were an engineering constraint.
|
|
123
|
+
|
|
124
|
+
That file states its own entry shape, its closed category list, and which facts belong to another
|
|
125
|
+
home instead. It MUST be written through the skill `wdi-log` intent `fact`, never by hand.
|
|
126
|
+
|
|
127
|
+
Two boundaries hold over it and MUST NOT be relaxed there:
|
|
128
|
+
|
|
129
|
+
- The content boundary in [`repo-guide.md`](repo-guide.md). This file is not an exemption from it;
|
|
130
|
+
a commercial fact does not become admissible by being called non-technical.
|
|
131
|
+
- Article 2's ban on `3p.md`. Operational engagement memory stays outside this repo, and the log
|
|
132
|
+
MUST NOT grow into a substitute for it.
|
|
133
|
+
|
|
134
|
+
It is control, not chronology. What happened on a given day is recovered from git by `wdi-report`;
|
|
135
|
+
what is recorded here is what still holds.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: Reference
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Portability — what is method, what is product
|
|
6
|
+
|
|
7
|
+
**Opened when:** carrying a method change into the WDI Method package, or installing
|
|
8
|
+
the method in a product repo.
|
|
9
|
+
|
|
10
|
+
This file **explains**. It does not bind. Installing is the act, and that act lives in
|
|
11
|
+
the WDI Method package README plus `wdi-method` (`install` · `update` · `promote` ·
|
|
12
|
+
`verify`). Where this file and that README disagree, the README wins and the
|
|
13
|
+
disagreement is a defect.
|
|
14
|
+
|
|
15
|
+
It exists so that "promote the method, leave the product" is not a fresh re-reading of
|
|
16
|
+
fifty files every time.
|
|
17
|
+
|
|
18
|
+
## The seam
|
|
19
|
+
|
|
20
|
+
Most of `.constitution/` is portable as it stands. A handful name **this product**, and in most of
|
|
21
|
+
them only an *example* does — not a rule.
|
|
22
|
+
|
|
23
|
+
| File | What is this product's | What to do when carrying it |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `constitution.md` | Articles 1, 2, and 5 | **Rewrite 2 and 5.** Article 1 cites `index.yaml` `product.name`. Articles 3, 4, 6, 7 travel unchanged. `wdi-method promote` already replaces this file with the kit template |
|
|
26
|
+
| `document/architecture-guide.md` | Seed examples of stack and tree shape | Re-point the examples. Every rule around them travels |
|
|
27
|
+
| `document/corpus-guide.md` | Worked examples of `_platform` ownership | Re-point the examples. **Keep both kinds**: they teach the trap better than the rule alone |
|
|
28
|
+
| `templates/design-system.md` | The pointer to wherever this project keeps its tokens | Re-point at that project's token file |
|
|
29
|
+
| `templates/oq.md` | One example of a bad question title | Cosmetic |
|
|
30
|
+
|
|
31
|
+
Everything else — the five gates, the two fields, the fifteen skills, the templates, `validate.py`,
|
|
32
|
+
`inventory.py`, `method-glossary.md`, and the three files beside this one — carries without edit.
|
|
33
|
+
|
|
34
|
+
## What does NOT travel
|
|
35
|
+
|
|
36
|
+
| Stays behind | Why |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `.control/` | This product's state. A new project scaffolds its own through `wdi-init` intent `setup`, or receives empty stubs on first `install` |
|
|
39
|
+
| `.what/` · `.how/` | This product's promises and build |
|
|
40
|
+
| `.constitution/codebase/*-guide.md` | Written by the **project**, not the method. They ship as empty `Draft` stubs |
|
|
41
|
+
| `_bmad-output/` | Run workspace |
|
|
42
|
+
| The `bmad-*` skills themselves | BMad's, installed by BMad. Only `_bmad/custom/*.toml` is ours |
|
|
43
|
+
|
|
44
|
+
## What travels beside `.constitution/`
|
|
45
|
+
|
|
46
|
+
The method is not `.constitution/` alone. Three sets move together, and carrying one without the
|
|
47
|
+
others leaves a method that cannot run:
|
|
48
|
+
|
|
49
|
+
| Set | Note |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `.constitution/` | Minus the product articles; `promote` / `install` handle the seam |
|
|
52
|
+
| `.claude/skills/wdi-*/` (and `.agents/skills/wdi-*/` when those agents are selected) | Every wrapper. A wrapper without its guide, or a guide without its wrapper, is half a method |
|
|
53
|
+
| `_bmad/custom/*.toml` | The one most likely to be forgotten. `*.user.toml` stays behind |
|
|
54
|
+
| `AGENTS.md` | The routing table is the method; from `## Code` down is the product. `install` / `update` MUST NOT overwrite an existing `AGENTS.md` |
|
|
55
|
+
|
|
56
|
+
## Two directions
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
a product repo with a newer working copy of the method
|
|
60
|
+
--promote-->
|
|
61
|
+
WDI Method (this package)
|
|
62
|
+
--install / update-->
|
|
63
|
+
product repos
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- **Promote** copies the method *up* once it has settled in a working copy.
|
|
67
|
+
- **Install / update** copies that snapshot *out* to a repo that consumes it.
|
|
68
|
+
- Do not run `update` against a repo you are about to promote from — that would overwrite the newer copy.
|
|
69
|
+
- There is no SHA lock and no per-file increment. The snapshot is the unit. The package version on npm / GitHub is the name of that snapshot.
|
|
70
|
+
|
|
71
|
+
## Installing in a fresh repo
|
|
72
|
+
|
|
73
|
+
BMad first (`npx bmad-method install`), then WDI Method. There is no numbered install runbook:
|
|
74
|
+
the steps that a runbook used to carry are now `wdi-init` intent `setup`. The order the acts come in:
|
|
75
|
+
|
|
76
|
+
1. `npx bmad-method install` in the product repo.
|
|
77
|
+
2. `npx wdi-method install` (optionally `--agents …`).
|
|
78
|
+
3. Set `product.name` in `.control/registry/index.yaml`. Rewrite `constitution.md` Articles 2 and 5.
|
|
79
|
+
4. Merge the method routing into `AGENTS.md` if that file already existed.
|
|
80
|
+
5. Run `wdi-init` intent `setup`.
|
|
81
|
+
6. Sort what already existed. A file that is already the artifact one slot asks for goes into that
|
|
82
|
+
slot through the skill that owns it; everything else goes to `_bmad-output/prior-knowledge/`.
|
|
83
|
+
`corpus-guide.md` owns that test.
|
|
84
|
+
7. Then G1 — which confirms `product.name` and writes the brief under that name.
|
|
85
|
+
|
|
86
|
+
**Two things a fresh install MUST NOT do:**
|
|
87
|
+
|
|
88
|
+
- Set `mode` and `risk_accepted` before the components exist. They are per-component fields, and the
|
|
89
|
+
components are born at the tail of G2.
|
|
90
|
+
- Fill `.control/generated/` by hand. It is script output, and a hand-written table there is the one
|
|
91
|
+
lie no validator catches.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: Accepted
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Repo Guide
|
|
6
|
+
|
|
7
|
+
**Loaded when:** adding a file that is neither code nor corpus, or unsure whether something may be
|
|
8
|
+
kept in this repo
|
|
9
|
+
|
|
10
|
+
Every other guide answers *where in the corpus does this go*. This one answers the question that
|
|
11
|
+
comes before it: **does it belong in this repository at all?**
|
|
12
|
+
|
|
13
|
+
## What this repository is
|
|
14
|
+
|
|
15
|
+
One product, built for one owner. It holds what is needed to build and run that product, and
|
|
16
|
+
nothing that merely relates to it commercially or organisationally.
|
|
17
|
+
|
|
18
|
+
| MAY be here | MUST NOT be here |
|
|
19
|
+
|---|---|
|
|
20
|
+
| Application code, configuration, migrations, tests | Proposals, contracts, meeting notes with the client |
|
|
21
|
+
| The corpus — `.constitution/` `.control/` `.what/` `.how/` | Contract values, pricing strategy, margins, rate cards |
|
|
22
|
+
| Technical documentation, ADR, diagrams | Real customer data, production credentials, tokens |
|
|
23
|
+
| Synthetic seed data | Anything whose leak would harm a bargaining position |
|
|
24
|
+
| Built deliverables | An archive of commercial documents |
|
|
25
|
+
|
|
26
|
+
The test is not "is it secret". It is **what changes when this file changes** — a commitment, or how
|
|
27
|
+
the thing is built. Only the second belongs here.
|
|
28
|
+
|
|
29
|
+
## Two failure modes, and why the second is worse
|
|
30
|
+
|
|
31
|
+
The obvious one is a credential in a commit. It is loud, it is caught, and it has a known remedy.
|
|
32
|
+
|
|
33
|
+
The quiet one is a **commercial fact restated as a technical one** — a limit that exists because of
|
|
34
|
+
what was negotiated, written into an ADR as though it were an engineering constraint. It survives
|
|
35
|
+
every scan, it is never noticed as a leak, and it teaches the next reader that the boundary is
|
|
36
|
+
soft.
|
|
37
|
+
|
|
38
|
+
When a technical decision genuinely follows from a commercial one, the ADR MUST state the technical
|
|
39
|
+
fact and MUST NOT state the commercial one. *"Retention is 90 days"* is a technical fact.
|
|
40
|
+
*"Retention is 90 days because the client would not pay for more"* is a commercial one wearing a
|
|
41
|
+
technical coat.
|
|
42
|
+
|
|
43
|
+
## `.work/` — scratch that is committed
|
|
44
|
+
|
|
45
|
+
`.work/` holds work in progress that has no home yet: notes while reading an unfamiliar system,
|
|
46
|
+
drafts, exploratory output, a working paper for a change spanning several sessions.
|
|
47
|
+
|
|
48
|
+
It is **committed**, so that a session picked up on another machine finds it, and so a reviewer can
|
|
49
|
+
see what a change was actually reasoning about.
|
|
50
|
+
|
|
51
|
+
It is **ephemeral**, and the two together are what make its rules matter:
|
|
52
|
+
|
|
53
|
+
- Any durable outcome MUST be moved out before the task closes — to the corpus if it is truth, to
|
|
54
|
+
`_bmad-output/` if it is a run's byproduct.
|
|
55
|
+
- Obsolete scratch MUST be deleted when its task closes. `.work/` that only grows stops being
|
|
56
|
+
scratch and becomes a second, unindexed corpus that nobody trusts and nobody deletes.
|
|
57
|
+
- Secrets and commercial figures MUST NOT be written here. Being scratch is not an exemption; it is
|
|
58
|
+
the reason people assume it is one.
|
|
59
|
+
- Nothing MUST be read from `.work/` as authority. If something there is right, it belongs
|
|
60
|
+
somewhere with an owner.
|
|
61
|
+
|
|
62
|
+
`.work/` MUST NOT be confused with `_bmad-output/`. That folder holds the output of skill runs, is
|
|
63
|
+
never curated, and is cited by path. `.work/` holds what a human or agent wrote by hand while
|
|
64
|
+
working, and is meant to empty out.
|
|
65
|
+
|
|
66
|
+
## Referring to things outside this repository
|
|
67
|
+
|
|
68
|
+
Engagement context — who the client is, what was agreed, what is due — lives elsewhere. This repo
|
|
69
|
+
MUST work without it. An agent MUST be able to act on the rules stated here without opening any
|
|
70
|
+
other repository.
|
|
71
|
+
|
|
72
|
+
When an artifact genuinely needs external context:
|
|
73
|
+
|
|
74
|
+
- MUST state the technical fact locally, in full.
|
|
75
|
+
- MAY name the external source by **repository and path**, as provenance.
|
|
76
|
+
- MUST NOT paste the external content in, and MUST NOT replace a technical statement with a pointer
|
|
77
|
+
to a commercial document.
|
|
78
|
+
|
|
79
|
+
A pointer where a specification should be is the failure this rule exists to stop: the reader who
|
|
80
|
+
cannot open that path is left with nothing, and the reader who can is reading the wrong kind of
|
|
81
|
+
document.
|
|
82
|
+
|
|
83
|
+
## How the method arrives
|
|
84
|
+
|
|
85
|
+
Method files in `.constitution/` (except this product's Articles 1, 2, and 5, `codebase/*-guide.md`
|
|
86
|
+
once `Accepted`, and any extra file this repo added), the `wdi-*` skills, and `_bmad/custom/*.toml`
|
|
87
|
+
arrive from the public WDI Method package via `npx wdi-method install` / `update`.
|
|
88
|
+
|
|
89
|
+
At **read time** this repo is self-contained: every file the rules need is here, readable with the
|
|
90
|
+
repo alone. At **change time** the method has one published writer — the WDI Method package. Two
|
|
91
|
+
rules follow:
|
|
92
|
+
|
|
93
|
+
- A method file MUST NOT be invented or patched here to improve the method. If a rule is wrong, it
|
|
94
|
+
is fixed in the WDI Method package, then brought here with `update`.
|
|
95
|
+
- A rule particular to this repo MUST be written out in full, and MUST NOT be replaced by a pointer
|
|
96
|
+
into another repository.
|
|
97
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export const BEGIN = "<!-- BEGIN:wdi-method -->";
|
|
2
|
+
export const END = "<!-- END:wdi-method -->";
|
|
3
|
+
|
|
4
|
+
export function extractBlock(template) {
|
|
5
|
+
const i = template.indexOf(BEGIN);
|
|
6
|
+
const j = template.indexOf(END);
|
|
7
|
+
if (i === -1 || j === -1 || j < i) {
|
|
8
|
+
throw new Error("AGENTS.md template is missing BEGIN/END:wdi-method markers");
|
|
9
|
+
}
|
|
10
|
+
return template.slice(i, j + END.length).trimEnd();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function hasMethodBlock(text) {
|
|
14
|
+
return text.includes(BEGIN) && text.includes(END) && text.indexOf(END) > text.indexOf(BEGIN);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function replaceMarkedBlock(text, block) {
|
|
18
|
+
const i = text.indexOf(BEGIN);
|
|
19
|
+
const j = text.indexOf(END);
|
|
20
|
+
return `${text.slice(0, i)}${block}${text.slice(j + END.length)}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function injectWithoutMarkers(text, block) {
|
|
24
|
+
const start = text.search(/^## Language\s*$/m);
|
|
25
|
+
if (start !== -1) {
|
|
26
|
+
const rest = text.slice(start);
|
|
27
|
+
const endRel = rest.search(/\n(?=## Code\b|<!-- BEGIN:|## Sync rule\b)/);
|
|
28
|
+
const end = endRel === -1 ? text.length : start + endRel;
|
|
29
|
+
const before = text.slice(0, start).replace(/\s+$/, "\n\n");
|
|
30
|
+
const after = text.slice(end).replace(/^\s+/, "\n\n");
|
|
31
|
+
return `${before}${block}${after}`;
|
|
32
|
+
}
|
|
33
|
+
const heading = text.match(/^#[^\n]+\n+/);
|
|
34
|
+
const at = heading ? heading[0].length : 0;
|
|
35
|
+
return `${text.slice(0, at)}\n${block}\n\n${text.slice(at).replace(/^\s+/, "")}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function upsertMethodBlock(existing, template) {
|
|
39
|
+
const block = extractBlock(template);
|
|
40
|
+
if (!existing || !existing.trim()) {
|
|
41
|
+
return template;
|
|
42
|
+
}
|
|
43
|
+
if (hasMethodBlock(existing)) {
|
|
44
|
+
return replaceMarkedBlock(existing, block);
|
|
45
|
+
}
|
|
46
|
+
return injectWithoutMarkers(existing, block);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function fillProductTitle(template, productName) {
|
|
50
|
+
if (!productName || productName === "{product}") return template;
|
|
51
|
+
return template.replace(/^# Agent Rules — \{product\}/m, `# Agent Rules — ${productName}`);
|
|
52
|
+
}
|
package/lib/identity.mjs
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const PRODUCT_BLOCK = /(?:^|\n)product:\n(?: .*\n)*/;
|
|
2
|
+
|
|
3
|
+
export function yamlQuote(value) {
|
|
4
|
+
return `"${String(value).replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function readProductIdentity(text) {
|
|
8
|
+
const name = text.match(/product:\n(?: .*\n)*? name:\s*"([^"]*)"/);
|
|
9
|
+
const client = text.match(/product:\n(?: .*\n)*? client:\s*"([^"]*)"/);
|
|
10
|
+
return {
|
|
11
|
+
name: name ? name[1] : "",
|
|
12
|
+
client: client ? client[1] : "",
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function writeProductIdentity(text, { name, client }) {
|
|
17
|
+
const block =
|
|
18
|
+
`product:\n name: ${yamlQuote(name)}\n client: ${yamlQuote(client ?? "")}\n`;
|
|
19
|
+
if (/^product:/m.test(text)) {
|
|
20
|
+
return text.replace(PRODUCT_BLOCK, (m) => (m.startsWith("\n") ? `\n${block}` : block));
|
|
21
|
+
}
|
|
22
|
+
return `${block}\n${text.replace(/^/, "")}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function identityIsPlaceholder(name) {
|
|
26
|
+
return !name || name === "{product}";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------- language policy
|
|
30
|
+
//
|
|
31
|
+
// Two settings, and only two. Everything else about language is NOT a choice: method terminology,
|
|
32
|
+
// document code prefixes, machine-facing markers, and code identifiers are always English —
|
|
33
|
+
// `language-guide.md` owns that, and a caller MUST NOT ask about them.
|
|
34
|
+
//
|
|
35
|
+
// doc_language the PROSE of working documents in .what/ .how/ .control/
|
|
36
|
+
// doc_filename_language the SLUG part of a document filename
|
|
37
|
+
//
|
|
38
|
+
// Both default to `en`. A corpus written before these existed is NOT migrated for them: the readers
|
|
39
|
+
// in validate.py accept both languages, so an existing document keeps working and only new writing
|
|
40
|
+
// follows the setting.
|
|
41
|
+
const POLICY_BLOCK = /(?:^|\n)policy:\n(?: .*\n)*/;
|
|
42
|
+
export const DOC_LANGUAGES = ["en", "id"];
|
|
43
|
+
|
|
44
|
+
export function readLanguagePolicy(text) {
|
|
45
|
+
const doc = text.match(/policy:\n(?: .*\n)*? doc_language:\s*([A-Za-z-]+)/);
|
|
46
|
+
const file = text.match(/policy:\n(?: .*\n)*? doc_filename_language:\s*([A-Za-z-]+)/);
|
|
47
|
+
return {
|
|
48
|
+
docLanguage: doc ? doc[1] : "",
|
|
49
|
+
docFilenameLanguage: file ? file[1] : "",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function writeLanguagePolicy(text, { docLanguage, docFilenameLanguage }) {
|
|
54
|
+
const block =
|
|
55
|
+
`policy:\n doc_language: ${docLanguage}\n doc_filename_language: ${docFilenameLanguage}\n`;
|
|
56
|
+
if (/^policy:/m.test(text)) {
|
|
57
|
+
return text.replace(POLICY_BLOCK, (m) => (m.startsWith("\n") ? `\n${block}` : block));
|
|
58
|
+
}
|
|
59
|
+
// Sits right after `product:` when that block exists — the two answer the same kind of question,
|
|
60
|
+
// so a reader who finds one finds the other.
|
|
61
|
+
if (/^product:/m.test(text)) {
|
|
62
|
+
return text.replace(/^product:\n(?: .*\n)*/m, (m) => `${m}\n${block}`);
|
|
63
|
+
}
|
|
64
|
+
return `${block}\n${text.replace(/^/, "")}`;
|
|
65
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wdi-method",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "WDI Method — software delivery method that wraps BMad",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"wdi-method": "./bin/wdi-method.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"lib/",
|
|
12
|
+
"kit/",
|
|
13
|
+
"kit-overlay/",
|
|
14
|
+
"scaffold/",
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "node --test tests/*.test.mjs",
|
|
23
|
+
"prepublishOnly": "node --test tests/*.test.mjs"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@clack/prompts": "^0.11.0"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/wiradigitalid/wdi-method.git"
|
|
32
|
+
},
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/wiradigitalid/wdi-method/issues"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/wiradigitalid/wdi-method#readme"
|
|
37
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Product Glossary
|
|
2
|
+
|
|
3
|
+
**Dimuat saat:** menulis dokumen apa pun di korpus.
|
|
4
|
+
|
|
5
|
+
SSOT kosakata **produk** — apa yang produk ini bicarakan. Tiap istilah didefinisikan **sekali** di
|
|
6
|
+
sini, lalu dipakai apa adanya di seluruh korpus.
|
|
7
|
+
|
|
8
|
+
Kosakata **metode** tinggal di `.constitution/method-glossary.md` dan MUST NOT didefinisikan ulang di
|
|
9
|
+
sini. Tes pemisahnya: apakah istilah ini tetap berlaku kalau dipakai di produk lain? Ya →
|
|
10
|
+
`method-glossary.md`, tidak → sini.
|
|
11
|
+
|
|
12
|
+
## Aturan
|
|
13
|
+
|
|
14
|
+
- Istilah baru yang muncul di dokumen mana pun MUST ditambahkan ke sini **dalam lintasan yang sama**.
|
|
15
|
+
- Definisi MUST menyebut hubungan ke istilah lain dan kardinalitasnya bila relevan.
|
|
16
|
+
- Satu istilah MUST NOT punya dua entri.
|
|
17
|
+
- Berkas ini lahir **kosong** dan diisi dari produknya. Entri pertamanya lahir bersama brief di G1.
|
|
18
|
+
|
|
19
|
+
## Entri
|
|
20
|
+
|
|
21
|
+
<!-- Urut abjad. Format: **Istilah** — definisi. Hubungan. Kardinalitas bila relevan. -->
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Project Non-Technical Log
|
|
2
|
+
|
|
3
|
+
**Dimuat saat:** sebuah fakta non-teknis yang membatasi pembangunan produk ini berubah, atau saat
|
|
4
|
+
mencari tahu apa yang sudah berlaku di luar kode.
|
|
5
|
+
|
|
6
|
+
Ditulis lewat skill `wdi-log` intent `fact`, tidak pernah dengan tangan langsung.
|
|
7
|
+
|
|
8
|
+
Tes satu kalimat: **kalau angkanya dihapus dan faktanya masih berguna bagi yang membangun, ia boleh
|
|
9
|
+
di sini.**
|
|
10
|
+
|
|
11
|
+
Kategori: `domain` · `akun` · `legal` · `jadwal` · `organisasi`.
|
|
12
|
+
|
|
13
|
+
## Berlaku
|
|
14
|
+
|
|
15
|
+
| id | Tanggal | Kategori | Fakta | Akibat | Sumber |
|
|
16
|
+
|---|---|---|---|---|---|
|
|
17
|
+
| — | — | — | — | — | — |
|
|
18
|
+
|
|
19
|
+
## Tidak Berlaku Lagi
|
|
20
|
+
|
|
21
|
+
| id | Fakta | Berhenti berlaku | Digantikan |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| — | — | — | — |
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Terjawab
|
|
2
|
+
|
|
3
|
+
**Dimuat saat:** mencari keputusan yang sudah diambil lewat pertanyaan, bukan lewat `DEC-`.
|
|
4
|
+
|
|
5
|
+
Baris pindah ke sini dari ketiga daftar lain. MUST NOT dihapus.
|
|
6
|
+
|
|
7
|
+
## Terjawab
|
|
8
|
+
|
|
9
|
+
| id | Pertanyaan | Jawaban | Ditutup |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| — | — | — | — |
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Asumsi
|
|
2
|
+
|
|
3
|
+
**Dimuat saat:** disapu sekali per gate; boleh dilewati.
|
|
4
|
+
|
|
5
|
+
Kelas **default** sebuah pertanyaan. Agent mengambil jawabannya sendiri lalu mencatatnya di sini, satu
|
|
6
|
+
baris: asumsinya, plus akibat kalau ia salah. Berkas ini **tidak menahan apa pun**.
|
|
7
|
+
|
|
8
|
+
Sebuah baris di sini MUST naik ke `blocking.md` begitu ia lulus salah satu dari tiga tes yang berkas
|
|
9
|
+
itu nyatakan.
|
|
10
|
+
|
|
11
|
+
## Terbuka
|
|
12
|
+
|
|
13
|
+
| id | Asumsi | Akibat kalau salah | Diambil | Oleh |
|
|
14
|
+
|---|---|---|---|---|
|
|
15
|
+
| — | — | — | — | — |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Pertanyaan yang Memblokir
|
|
2
|
+
|
|
3
|
+
**Dimuat saat:** setiap gate.
|
|
4
|
+
|
|
5
|
+
Hanya berkas ini yang menahan sebuah gate. Ditulis lewat `wdi-question`, tidak pernah dengan tangan
|
|
6
|
+
langsung; bentuk barisnya di `.constitution/document/templates/questions.md`.
|
|
7
|
+
|
|
8
|
+
Sasarannya **≤3 baris per Product Component**. Sebuah pertanyaan naik ke sini hanya lewat tiga tes,
|
|
9
|
+
salah satu cukup:
|
|
10
|
+
|
|
11
|
+
1. Menyentuh uang, data pribadi, atau kewajiban legal.
|
|
12
|
+
2. Mengubah bunyi janji sebuah `FR`.
|
|
13
|
+
3. Salah menjawab memaksa tulis ulang lebih dari satu komponen.
|
|
14
|
+
|
|
15
|
+
Gagal ketiganya → `assumptions.md`. Sebuah pertanyaan MUST NOT didaftarkan di sini "untuk aman".
|
|
16
|
+
|
|
17
|
+
## Terbuka
|
|
18
|
+
|
|
19
|
+
| id | Pertanyaan | Memblokir | Owner | Sebelum |
|
|
20
|
+
|---|---|---|---|---|
|
|
21
|
+
| — | — | — | — | — |
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Menunggu Pihak Luar
|
|
2
|
+
|
|
3
|
+
**Dimuat saat:** ada jawaban yang hanya bisa datang dari luar sesi ini.
|
|
4
|
+
|
|
5
|
+
Berkas ini **tidak menahan gate** kecuali barisnya juga ditunjuk dari `blocking.md`.
|
|
6
|
+
|
|
7
|
+
## Terbuka
|
|
8
|
+
|
|
9
|
+
| id | Pertanyaan | Menunggu | Sejak |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| — | — | — | — |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# components.yaml — SSOT untuk Product Component, container, dan Logical Component
|
|
2
|
+
#
|
|
3
|
+
# Tiga hal berbeda, dua di antaranya berbagi kata "component":
|
|
4
|
+
# Product Component (PC) — irisan DOMAIN, permukaan yang bisa disebut pengguna
|
|
5
|
+
# Container — unit yang berjalan atau dideploy sendiri; C4 L2 memilikinya
|
|
6
|
+
# Logical Component (LC) — satu unit build yang bisa ditunjuk
|
|
7
|
+
#
|
|
8
|
+
# `mode` — KEDALAMAN DOKUMEN. Ditulis HANYA pada komponen yang memang perlu beda dari global.
|
|
9
|
+
# `risk_accepted` — INTENSITAS REVIEW, bukan kedalaman. low · medium · high
|
|
10
|
+
# `owns` — entitas domain yang komponen ini BERWENANG MENULIS.
|
|
11
|
+
# `g4_passed` — hanya berarti pada komponen ber-mode di atas catalog.
|
|
12
|
+
#
|
|
13
|
+
# Komponen lahir lewat wdi-init intent `component` di ekor G2. Berkas ini lahir kosong.
|
|
14
|
+
|
|
15
|
+
product_components: []
|
|
16
|
+
|
|
17
|
+
platform_owns: []
|
|
18
|
+
|
|
19
|
+
containers: []
|
|
20
|
+
|
|
21
|
+
logical_components: []
|