wdi-method 0.6.1 → 0.6.4
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 +58 -7
- package/bin/wdi-method.js +144 -0
- package/kit/.constitution/method/README.md +1 -1
- package/kit/.constitution/method/document/decision-guide.md +208 -199
- package/kit/.constitution/method/document/delivery-flow-guide.md +412 -409
- package/kit/.constitution/method/document/templates/decision.md +6 -1
- package/kit/.constitution/method/method-glossary.md +183 -182
- package/kit/.constitution/method/scripts/validate.py +102 -2
- package/kit/.constitution/method/why/README.md +2 -1
- package/kit/.constitution/method/why/portability.md +98 -98
- package/kit/skills/wdi-autopilot/SKILL.md +375 -0
- package/kit/skills/wdi-build/SKILL.md +371 -357
- package/kit/skills/wdi-decision/SKILL.md +197 -187
- package/kit/skills/wdi-help/SKILL.md +110 -100
- package/kit/skills/wdi-question/SKILL.md +176 -170
- package/kit/skills/wdi-upgrade/SKILL.md +8 -0
- package/kit-overlay/AGENTS.md +227 -217
- package/kit-overlay/README.md +1 -1
- package/kit-overlay/portability.md +98 -98
- package/package.json +1 -1
- package/scaffold/docs/agents/domain.md +36 -0
- package/scaffold/docs/agents/issue-tracker.md +43 -0
package/README.md
CHANGED
|
@@ -25,7 +25,10 @@ page it is on.
|
|
|
25
25
|
## Install
|
|
26
26
|
|
|
27
27
|
Three steps, in this order. The first is required before step 3 will run; the second can wait until
|
|
28
|
-
|
|
28
|
+
**Both are required, and the installer refuses without either.** BMad has always been checked; the ticket
|
|
29
|
+
engines are checked too, because every repo that learned they were missing learned it inside `wdi-build`
|
|
30
|
+
with a spec already open. `--skip-engines-check` is the escape for the two cases that earn it: CI, and a
|
|
31
|
+
repo that will never reach G5.
|
|
29
32
|
|
|
30
33
|
**1. BMad Method** — in the product repo, picking the same agents you will give this installer:
|
|
31
34
|
|
|
@@ -44,8 +47,16 @@ claude plugins install mattpocock-skills # or, inside a session: /plugin i
|
|
|
44
47
|
npx skills@latest add mattpocock/skills
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
**You do not need to run `/setup-matt-pocock-skills` to get started.** Step 3 seeds `docs/agents/` with
|
|
51
|
+
the two answers WDI Method actually has a requirement on, so the engines are aligned from the first
|
|
52
|
+
install. Run the setup skill only to *change* something — to point at GitHub or Jira instead of local
|
|
53
|
+
markdown — and keep the three invariants the seeded `issue-tracker.md` names.
|
|
54
|
+
|
|
55
|
+
The seeding exists because the interview's own defaults are wrong here in one specific way: they send every
|
|
56
|
+
engineering skill looking for a root `CONTEXT.md` and `docs/adr/`, and Article 3 says this method has no
|
|
57
|
+
`docs/` layer for corpus or rules — `wdi-reconcile` reports both as findings. A repo that ran the setup
|
|
58
|
+
before installing this package keeps its own file, and the installer names the contradiction rather than
|
|
59
|
+
overwriting it.
|
|
49
60
|
|
|
50
61
|
**3. WDI Method:**
|
|
51
62
|
|
|
@@ -97,6 +108,36 @@ answers with the gate you are at, not with a menu.
|
|
|
97
108
|
|
|
98
109
|
---
|
|
99
110
|
|
|
111
|
+
## What to do right after install, and right after update
|
|
112
|
+
|
|
113
|
+
Two questions, and the honest answer to most of them is *nothing*. `wdi-help` answers them from the
|
|
114
|
+
registry at any time; this table is the same answer written down.
|
|
115
|
+
|
|
116
|
+
### After `install`
|
|
117
|
+
|
|
118
|
+
| | |
|
|
119
|
+
|---|---|
|
|
120
|
+
| Engines missing | You never get here — `install` refuses, and names both install paths. Install them, run it again |
|
|
121
|
+
| `/setup-matt-pocock-skills`? | **No.** The installer seeded `docs/agents/` already answered for this method. Run that interview only to *change* tracker |
|
|
122
|
+
| So what is first? | **`wdi-init` intent `setup`** — it sets the global `mode`, and nothing has started until it is |
|
|
123
|
+
| Then? | `wdi-problem` for G1. Or ask `wdi-help`, which reads the registry rather than this table |
|
|
124
|
+
|
|
125
|
+
### After `update`
|
|
126
|
+
|
|
127
|
+
| The summary said | Do |
|
|
128
|
+
|---|---|
|
|
129
|
+
| an **`upgrade`** line, naming content still in the old shape | **`wdi-upgrade`, before any other skill.** It moves every sentence into its new home, invents nothing, reports what it could not place, and ends in one commit. `wdi-help` and the validators read the new shape; a corpus half in the old one answers them wrongly |
|
|
130
|
+
| **no** `upgrade` line | Nothing. The update was mechanical and complete — carry on from wherever the gates say you are |
|
|
131
|
+
| `seeded docs/agents/` | Nothing. An older repo just received the engines' config, pre-answered. Read it if you like; do not run the setup interview to redo it |
|
|
132
|
+
| a warning that `domain.md` still points at a root `CONTEXT.md` | Add the correction that warning names to the top of that file. It was written by the setup interview before this package was installed, and it sends every engineering skill at two paths Article 3 forbids |
|
|
133
|
+
| a warning naming a **mandate** and `ad-n` | Only if you run `wdi-autopilot`. Decide whether that mandate should now park `AD-N` contradictions, and edit its `parked` list yourself — `update` never edits an authority you granted |
|
|
134
|
+
|
|
135
|
+
**`wdi-upgrade` is only ever about corpus content** — a brief, a PRD, an SRS, registry rows in the old
|
|
136
|
+
shape. It is not the answer to a missing engine, a missing tracker config, or anything under
|
|
137
|
+
`.control/memlog/`; each of those is handled by the installer itself or by the skill that owns it.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
100
141
|
## How to use it — the walk
|
|
101
142
|
|
|
102
143
|
A gate is a moment where a human reads **one page** and decides. Between gates the AI works in a
|
|
@@ -114,6 +155,16 @@ renders, decide — advance or refine.
|
|
|
114
155
|
| 6 | `wdi-report` intent `estimate` | `.control/generated/estimate.md` | which candidate row becomes the next spec |
|
|
115
156
|
| 7 | `wdi-build` — for that row | nothing: tickets are machine contracts. You answer `to-tickets`' quiz on granularity and blocking edges | **G5** — is it done and proven? Once per spec |
|
|
116
157
|
| 8 | `wdi-report` intent `progress` | the report it writes | what has moved, what is late, what is proven |
|
|
158
|
+
| 9 | `wdi-autopilot` — when you would rather review the result than walk steps 6–8 yourself | its preflight page, then its final report and ledger | one **mandate**: scope, what stays parked for you, smoke test by the agent or by you, loop interval, expiry |
|
|
159
|
+
|
|
160
|
+
**Unattended, on request.** `wdi-autopilot` moves owner time from the gates to two points: the mandate before,
|
|
161
|
+
the review after. From the gate you name it runs the same skills, answers what they would have asked, records
|
|
162
|
+
every answer in `.control/memlog/autopilot-<date>.md`, and stops only when every `FR` in scope is closed or the
|
|
163
|
+
mandate expires. It needs three things from the session: permission prompts bypassed (one prompt halts the
|
|
164
|
+
loop), a loop to fire it — `/loop 5m /wdi-autopilot` in Claude Code — and a way past the ticket engines'
|
|
165
|
+
`disable-model-invocation`, which the preflight names: a builder that reads and follows the engine's `SKILL.md`,
|
|
166
|
+
or a copy of the engines inside the repo. The validator `mandate-accept` keeps the one thing the method never
|
|
167
|
+
gives up: a person, dated, at the root of every delegated acceptance.
|
|
117
168
|
|
|
118
169
|
**Refine, do not advance.** When a page does not convince you, run the same skill again and say what is
|
|
119
170
|
wrong — it updates the document it owns. Nothing downstream exists yet, so nothing breaks. Advancing past a
|
|
@@ -282,7 +333,7 @@ which review lenses run, and which review traces a validator will demand.
|
|
|
282
333
|
|
|
283
334
|
---
|
|
284
335
|
|
|
285
|
-
## Five gates,
|
|
336
|
+
## Five gates, eighteen skills
|
|
286
337
|
|
|
287
338
|
| Gate | Decides | Skill |
|
|
288
339
|
|---|---|---|
|
|
@@ -293,7 +344,7 @@ which review lenses run, and which review traces a validator will demand.
|
|
|
293
344
|
| **G5 Release** | Whether it is done and proven | `wdi-build` |
|
|
294
345
|
|
|
295
346
|
Around them: `wdi-init` (scaffold, component birth, depth and risk settings, structure maps),
|
|
296
|
-
`wdi-decision`, `wdi-question`, `wdi-log`, `wdi-help`, `wdi-explain-to-me`, `wdi-reconcile`, `wdi-review`, `wdi-report`,
|
|
347
|
+
`wdi-decision`, `wdi-question`, `wdi-log`, `wdi-help`, `wdi-explain-to-me`, `wdi-autopilot`, `wdi-reconcile`, `wdi-review`, `wdi-report`,
|
|
297
348
|
`wdi-systematic-debugging`, and `wdi-upgrade` (moves a corpus written under an older kit into the current
|
|
298
349
|
shape — content moves, nothing is invented).
|
|
299
350
|
|
|
@@ -382,9 +433,9 @@ English, whatever the settings say — it travels to every repo through this pac
|
|
|
382
433
|
|
|
383
434
|
| | |
|
|
384
435
|
|---|---|
|
|
385
|
-
| Overwrites | everything in `.constitution/method/` · the
|
|
436
|
+
| Overwrites | everything in `.constitution/method/` · the eighteen wrappers · `_bmad/custom/*.toml` · the marked block in `AGENTS.md` |
|
|
386
437
|
| Renames | a file whose content needs no judgment to move — `waves.yaml` → `specs.yaml`, the pre-0.5 registry names. Content is never rewritten |
|
|
387
|
-
| Removes | Wrappers the method has retired — a `wdi-*` folder with a `SKILL.md` that is no longer one of the
|
|
438
|
+
| Removes | Wrappers the method has retired — a `wdi-*` folder with a `SKILL.md` that is no longer one of the eighteen. Each removal is printed |
|
|
388
439
|
| Reports | what is still in the OLD shape, as an `upgrade` line — and names `wdi-upgrade` as the next step. The installer does not move content; that is a decision, and the skill's |
|
|
389
440
|
| Keeps | All of `.constitution/project/`, plus your initiative slug and your language choice. A setting somebody already chose is not the installer's to change behind their back |
|
|
390
441
|
| Never resurrects | A folder you retired. On update, absence is treated as a decision |
|
package/bin/wdi-method.js
CHANGED
|
@@ -49,6 +49,7 @@ const WDI_SKILLS = [
|
|
|
49
49
|
"wdi-log",
|
|
50
50
|
"wdi-help",
|
|
51
51
|
"wdi-explain-to-me",
|
|
52
|
+
"wdi-autopilot",
|
|
52
53
|
"wdi-reconcile",
|
|
53
54
|
"wdi-review",
|
|
54
55
|
"wdi-report",
|
|
@@ -122,6 +123,7 @@ function usage() {
|
|
|
122
123
|
--doc-language <text> prose of working documents; free text, default English
|
|
123
124
|
--doc-filename-language <text> slug part of document filenames; free text, default English
|
|
124
125
|
--skip-bmad-check
|
|
126
|
+
--skip-engines-check install without to-spec / to-tickets / implement
|
|
125
127
|
|
|
126
128
|
BMad first, then this package. ${WDI_REPO}
|
|
127
129
|
`);
|
|
@@ -165,6 +167,7 @@ function parseArgs(argv) {
|
|
|
165
167
|
while (rest.length) {
|
|
166
168
|
const t = rest.shift();
|
|
167
169
|
if (t === "--skip-bmad-check") args.skipBmad = true;
|
|
170
|
+
else if (t === "--skip-engines-check") args.skipEngines = true;
|
|
168
171
|
else if (t === "--rescue") args.rescue = true;
|
|
169
172
|
else if (t === "--yes" || t === "-y") args.yes = true;
|
|
170
173
|
else if (t === "--agents") {
|
|
@@ -317,6 +320,29 @@ function bmadMissingMessage() {
|
|
|
317
320
|
].join("\n");
|
|
318
321
|
}
|
|
319
322
|
|
|
323
|
+
// The engines used to WARN and let the install through, on the reasoning that G1-G4 run without them and
|
|
324
|
+
// a first install has no G5 yet. Both halves are still true, and the reasoning stopped being enough:
|
|
325
|
+
// `wdi-autopilot` needs all three from its first iteration, and a warning inside a forty-line summary is
|
|
326
|
+
// read exactly as often as it is skipped. The failure it was meant to prevent — learning they are missing
|
|
327
|
+
// inside `wdi-build`, with a spec already open — kept happening anyway.
|
|
328
|
+
//
|
|
329
|
+
// So it blocks, and `--skip-engines-check` is the escape, exactly as `--skip-bmad-check` is for BMad. The
|
|
330
|
+
// escape matters: CI installs into a bare checkout, and a repo that will never reach G5 is a real case.
|
|
331
|
+
function enginesMissingMessage() {
|
|
332
|
+
return [
|
|
333
|
+
"The ticket engines are not installed. G5 (wdi-build) and wdi-autopilot need all three.",
|
|
334
|
+
"",
|
|
335
|
+
` Claude Code: ${ENGINES_INSTALL}`,
|
|
336
|
+
` Other agents: ${ENGINES_INSTALL_ANY}`,
|
|
337
|
+
"",
|
|
338
|
+
"You do NOT need to run the setup skill after this — the installer seeds docs/agents/ already",
|
|
339
|
+
`answered for this method. Run ${ENGINES_SETUP} only to change tracker.`,
|
|
340
|
+
`Source: ${ENGINES_REPO}`,
|
|
341
|
+
"",
|
|
342
|
+
"G1-G4 run without them. To install anyway and add them later: --skip-engines-check",
|
|
343
|
+
].join("\n");
|
|
344
|
+
}
|
|
345
|
+
|
|
320
346
|
// The product's custom room. Three properties, and all three MUST hold together:
|
|
321
347
|
// install/update seeds its content ONLY when absent — never written again after that
|
|
322
348
|
// promote SKIPS it entirely, so a product's own rules can never reach the public repo
|
|
@@ -424,6 +450,117 @@ function splitProductConstitution(file) {
|
|
|
424
450
|
// Two refusals matter more than the move. It never writes over an existing `specs.yaml`, and it
|
|
425
451
|
// never deletes a `waves.yaml` whose content has nowhere to go: a half-finished hand migration
|
|
426
452
|
// leaves BOTH files present, and which one is real is not something an installer can know.
|
|
453
|
+
// `wdi-autopilot` named its ledger for the DAY before 0.6.2 — `autopilot-<YYYY-MM-DD>.md`. The mandate
|
|
454
|
+
// it belongs to is named for the MANDATE now — `autopilot-<DEC-id>.md` — because two mandates opened
|
|
455
|
+
// on the same day would otherwise append to one file and destroy both as a record, and because
|
|
456
|
+
// `mandate-accept` (the validator introduced alongside the rename) looks for the file at that path and
|
|
457
|
+
// nowhere else. This is a pure rename, like `waves.yaml` → `specs.yaml`: the ledger's own content is
|
|
458
|
+
// never touched, only found and moved. Renaming it is what a script can safely do; restructuring its
|
|
459
|
+
// CONTENT into the `## Resume` / `## Decisions` split is not — that has to read git and the registry to
|
|
460
|
+
// know where the run actually stands, so it is the skill's own job on the next iteration it runs, not
|
|
461
|
+
// this installer's.
|
|
462
|
+
// `/setup-matt-pocock-skills` interviews the owner and writes `docs/agents/`. Two of its answers are
|
|
463
|
+
// wrong for a WDI repo, and BOTH repos that ran it had to hand-correct the SAME file afterwards:
|
|
464
|
+
//
|
|
465
|
+
// - `domain.md` tells agents to read and lazily create a root `CONTEXT.md` and `docs/adr/`. Article 3
|
|
466
|
+
// says this method has no `docs/` layer for corpus or rules, and `wdi-reconcile` reports both as
|
|
467
|
+
// findings. The homes already exist: `.control/product-glossary.md`, `.what/`, `.how/`, `DEC-`.
|
|
468
|
+
// - `issue-tracker.md`'s local-markdown default puts every ticket under `.scratch/<feature>/`, while
|
|
469
|
+
// `wdi-build` owns tickets at `{spec_folder}/issues/`. Two homes for one ticket set.
|
|
470
|
+
//
|
|
471
|
+
// Seeding them removes the interview for the answers WDI Method actually has a requirement on. Seeded
|
|
472
|
+
// ONCE and never overwritten — after the first install they are the product's, like every other file
|
|
473
|
+
// under a path the product owns. An owner who wants a different tracker re-runs the setup skill; the
|
|
474
|
+
// seeded file says which three invariants have to survive that.
|
|
475
|
+
function seedAgentDocs(target) {
|
|
476
|
+
const dir = path.join(target, "docs", "agents");
|
|
477
|
+
let wrote = 0;
|
|
478
|
+
for (const name of ["domain.md", "issue-tracker.md"]) {
|
|
479
|
+
const to = path.join(dir, name);
|
|
480
|
+
if (fs.existsSync(to)) continue;
|
|
481
|
+
const seed = path.join(ROOT, "scaffold", "docs", "agents", name);
|
|
482
|
+
if (!fs.existsSync(seed)) continue;
|
|
483
|
+
copyFile(seed, to);
|
|
484
|
+
wrote += 1;
|
|
485
|
+
}
|
|
486
|
+
if (wrote) {
|
|
487
|
+
note(`seeded docs/agents/ (${wrote} file${wrote === 1 ? "" : "s"}) — the engines' config, pre-answered`);
|
|
488
|
+
note(" do NOT run /setup-matt-pocock-skills to redo these; re-run it only to change tracker");
|
|
489
|
+
}
|
|
490
|
+
return wrote > 0;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// A repo that ran the setup skill BEFORE installing this package still carries the default `domain.md`,
|
|
494
|
+
// and it is actively misleading: it sends every engineering skill looking for a root `CONTEXT.md` and
|
|
495
|
+
// `docs/adr/`, and tells them to create both lazily. Seeding cannot fix it, because the file already
|
|
496
|
+
// exists and a file under a product-owned path is never overwritten. So it is named instead.
|
|
497
|
+
function warnStaleAgentDocs(target) {
|
|
498
|
+
const file = path.join(target, "docs", "agents", "domain.md");
|
|
499
|
+
if (!fs.existsSync(file)) return;
|
|
500
|
+
const text = fs.readFileSync(file, "utf8");
|
|
501
|
+
if (!/CONTEXT\.md|docs\/adr/.test(text)) return;
|
|
502
|
+
// An override note is what both real repos added by hand. Recognising it is what stops this warning
|
|
503
|
+
// from firing forever on a file somebody already fixed.
|
|
504
|
+
if (/does not use|MUST NOT be created|no `docs\/` layer/i.test(text)) return;
|
|
505
|
+
note("docs/agents/domain.md still points agents at a root CONTEXT.md and docs/adr/");
|
|
506
|
+
note(" Article 3: this method has no `docs/` layer for corpus or rules, and wdi-reconcile");
|
|
507
|
+
note(" reports both as findings. Say so at the top of that file — the glossary is at");
|
|
508
|
+
note(" .control/product-glossary.md and a decision is a DEC-, never an ADR");
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
function migrateAutopilotLedgers(target) {
|
|
512
|
+
const dir = path.join(target, ".control", "memlog");
|
|
513
|
+
if (!fs.existsSync(dir)) return;
|
|
514
|
+
const OLD = /^autopilot-(\d{4}-\d{2}-\d{2})\.md$/;
|
|
515
|
+
for (const name of fs.readdirSync(dir)) {
|
|
516
|
+
const m = OLD.exec(name);
|
|
517
|
+
if (!m) continue;
|
|
518
|
+
const from = path.join(dir, name);
|
|
519
|
+
const text = fs.readFileSync(from, "utf8");
|
|
520
|
+
const artifact = /^artifact:\s*(\S.*)$/m.exec(text)?.[1]?.trim();
|
|
521
|
+
const id = artifact && /(DEC-\d+)/.exec(artifact)?.[1];
|
|
522
|
+
if (!id) {
|
|
523
|
+
note(`.control/memlog/${name} looks like a pre-0.6.2 autopilot ledger, but its \`artifact:\` does`);
|
|
524
|
+
note(` not resolve to a DEC- id — rename it to autopilot-<the mandate's DEC- id>.md yourself`);
|
|
525
|
+
continue;
|
|
526
|
+
}
|
|
527
|
+
const to = path.join(dir, `autopilot-${id}.md`);
|
|
528
|
+
if (fs.existsSync(to)) {
|
|
529
|
+
note(`BOTH .control/memlog/${name} and autopilot-${id}.md exist — neither was touched`);
|
|
530
|
+
note(` the run's ledger is in one of them and I cannot tell which. Merge them, then delete the other`);
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
mv(from, to);
|
|
534
|
+
note(`renamed .control/memlog/${name} → autopilot-${id}.md (content unchanged)`);
|
|
535
|
+
note(` \`mandate-accept\` looks for a mandate's ledger at this exact path`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// A mandate opened before 0.6.2 recorded `parked: []` under the OLD default — full authority, AD-N
|
|
540
|
+
// contradictions included. 0.6.2 changed the DEFAULT for a NEW mandate to park `ad-n`, because
|
|
541
|
+
// decision-guide.md says narrowing an invariant MUST NOT be softened further. A default only applies
|
|
542
|
+
// at the moment a mandate is written, so an EXISTING accepted mandate keeps whatever it already says —
|
|
543
|
+
// silently adding `ad-n` to it would be overwriting a value the owner already chose, which `update`
|
|
544
|
+
// MUST NOT do to anything in the product's own registry. So this only ever WARNS, naming the mandate
|
|
545
|
+
// and the one line that would close the gap, and leaves the decision to whoever reads the summary.
|
|
546
|
+
function warnStaleMandates(target) {
|
|
547
|
+
const file = path.join(target, ".control", "registry", "decisions.yaml");
|
|
548
|
+
if (!fs.existsSync(file)) return;
|
|
549
|
+
const text = fs.readFileSync(file, "utf8");
|
|
550
|
+
const blocks = text.split(/\n(?=\s*-\s*id:\s*DEC-)/);
|
|
551
|
+
for (const block of blocks) {
|
|
552
|
+
if (!/type:\s*mandate/.test(block)) continue;
|
|
553
|
+
if (!/status:\s*accepted/.test(block)) continue;
|
|
554
|
+
const id = /id:\s*(DEC-\d+)/.exec(block)?.[1];
|
|
555
|
+
const parkedLine = /parked:\s*(\[[^\]]*\]|.*)$/m.exec(block)?.[0] || "";
|
|
556
|
+
const parkedBlockList = /parked:\s*\n((?:\s+-\s*\S.*\n?)*)/.exec(block)?.[1] || "";
|
|
557
|
+
if (/ad-n/.test(parkedLine) || /ad-n/.test(parkedBlockList)) continue;
|
|
558
|
+
note(`${id || "a mandate"} predates the \`ad-n\`-parked-by-default protection (0.6.2) — its \`parked\``);
|
|
559
|
+
note(` list does not name it, so it still decides an AD-N contradiction on its own`);
|
|
560
|
+
note(` add \`ad-n\` to its \`parked\` list in decisions.yaml yourself if you want the new default`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
427
564
|
function migrateRegistryNames(target) {
|
|
428
565
|
const reg = path.join(target, ".control", "registry");
|
|
429
566
|
const from = path.join(reg, "waves.yaml");
|
|
@@ -1026,6 +1163,10 @@ function apply(target, agents,
|
|
|
1026
1163
|
// is about to occupy. Running it after would leave two copies of most guides.
|
|
1027
1164
|
const migrated = migrateToTwoFolders(target);
|
|
1028
1165
|
migrateRegistryNames(target);
|
|
1166
|
+
migrateAutopilotLedgers(target);
|
|
1167
|
+
warnStaleMandates(target);
|
|
1168
|
+
seedAgentDocs(target);
|
|
1169
|
+
warnStaleAgentDocs(target);
|
|
1029
1170
|
seedRequirementSplit(target);
|
|
1030
1171
|
// The split MUST also be reachable without a migration. 0.5.2 only ran it from inside
|
|
1031
1172
|
// migrateToTwoFolders, which returns early when the old layout is absent — so a repo that took
|
|
@@ -1435,6 +1576,9 @@ function runNonInteractive(args) {
|
|
|
1435
1576
|
if (!args.skipBmad && !bmadPresent(target)) {
|
|
1436
1577
|
die(bmadMissingMessage());
|
|
1437
1578
|
}
|
|
1579
|
+
if (!args.skipEngines && !enginesPresent(target)) {
|
|
1580
|
+
die(enginesMissingMessage());
|
|
1581
|
+
}
|
|
1438
1582
|
const existing = readIndexIdentity(target);
|
|
1439
1583
|
const product = args.product || existing.name;
|
|
1440
1584
|
const client = args.client ?? existing.client;
|
|
@@ -29,7 +29,7 @@ Never a rule. When it disagrees with a guide, the guide wins and the disagreemen
|
|
|
29
29
|
|
|
30
30
|
| File | Opened when |
|
|
31
31
|
|---|---|
|
|
32
|
-
| [`why/README.md`](why/README.md) | You want the whole shape in five minutes — five gates, two settings,
|
|
32
|
+
| [`why/README.md`](why/README.md) | You want the whole shape in five minutes — five gates, two settings, eighteen skills, WDI ↔ BMad |
|
|
33
33
|
| [`why/artifact-map.md`](why/artifact-map.md) | "Where does this file go", or "does this document exist at my `mode`" |
|
|
34
34
|
| [`why/mode-risk-map.md`](why/mode-risk-map.md) | A `mode` and a `risk_accepted` are set and you want the two side by side — all twelve cells |
|
|
35
35
|
| [`why/rationale.md`](why/rationale.md) | Before changing a rule, to know what you would break |
|