wdi-method 0.4.6 → 0.5.2

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.
Files changed (87) hide show
  1. package/README.md +271 -252
  2. package/bin/wdi-method.js +1221 -1030
  3. package/kit/.constitution/method/README.md +73 -169
  4. package/kit/.constitution/{constitution.md → method/constitution.md} +10 -56
  5. package/kit/.constitution/{document → method/document}/architecture-guide.md +209 -209
  6. package/kit/.constitution/{document → method/document}/corpus-guide.md +4 -4
  7. package/kit/.constitution/{document → method/document}/delivery-flow-guide.md +338 -338
  8. package/kit/.constitution/{document → method/document}/sdd-guide.md +1 -1
  9. package/kit/.constitution/{document → method/document}/templates/cross-cutting.md +2 -2
  10. package/kit/.constitution/{document → method/document}/templates/design-system.md +67 -67
  11. package/kit/.constitution/{document → method/document}/templates/inventory.md +69 -69
  12. package/kit/.constitution/{document → method/document}/templates/sdd.md +1 -1
  13. package/kit/.constitution/{document → method/document}/templates/structure-codebase.md +129 -129
  14. package/kit/.constitution/{document → method/document}/templates/structure-document.md +90 -90
  15. package/kit/.constitution/{language-guide.md → method/language-guide.md} +2 -2
  16. package/kit/.constitution/{method-glossary.md → method/method-glossary.md} +169 -169
  17. package/kit/.constitution/{repo-guide.md → method/repo-guide.md} +120 -97
  18. package/kit/.constitution/method/scripts/__pycache__/validate.cpython-314.pyc +0 -0
  19. package/kit/.constitution/{scripts → method/scripts}/timeline.py +2 -2
  20. package/kit/.constitution/{scripts → method/scripts}/validate.py +1648 -1581
  21. package/kit/.constitution/{structure-guide.md → method/structure-guide.md} +3 -3
  22. package/kit/.constitution/method/why/README.md +169 -0
  23. package/kit/.constitution/method/{artifact-map.md → why/artifact-map.md} +5 -5
  24. package/kit/.constitution/method/{portability.md → why/portability.md} +6 -6
  25. package/kit/.constitution/method/{rationale.md → why/rationale.md} +5 -5
  26. package/kit/.constitution/project/README.md +68 -68
  27. package/kit/.constitution/project/constitution.md +64 -0
  28. package/kit/assets/bmad-custom/bmad-advanced-elicitation.toml +15 -15
  29. package/kit/assets/bmad-custom/bmad-architecture.toml +33 -33
  30. package/kit/assets/bmad-custom/bmad-code-review.toml +13 -13
  31. package/kit/assets/bmad-custom/bmad-correct-course.toml +28 -28
  32. package/kit/assets/bmad-custom/bmad-prd.toml +42 -42
  33. package/kit/assets/bmad-custom/bmad-product-brief.toml +34 -34
  34. package/kit/assets/bmad-custom/bmad-retrospective.toml +9 -9
  35. package/kit/assets/bmad-custom/bmad-spec.toml +16 -16
  36. package/kit/assets/bmad-custom/bmad-ux.toml +19 -19
  37. package/kit/skills/wdi-blueprint/SKILL.md +203 -203
  38. package/kit/skills/wdi-build/SKILL.md +244 -244
  39. package/kit/skills/wdi-component/SKILL.md +1 -1
  40. package/kit/skills/wdi-help/SKILL.md +98 -98
  41. package/kit/skills/wdi-init/SKILL.md +1 -1
  42. package/kit/skills/wdi-problem/SKILL.md +90 -90
  43. package/kit/skills/wdi-product/SKILL.md +127 -127
  44. package/kit/skills/wdi-reconcile/SKILL.md +2 -2
  45. package/kit/skills/wdi-report/SKILL.md +205 -205
  46. package/kit/skills/wdi-systematic-debugging/SKILL.md +193 -193
  47. package/kit/skills/wdi-ux/SKILL.md +145 -145
  48. package/kit-overlay/AGENTS.md +215 -212
  49. package/kit-overlay/README.md +24 -17
  50. package/kit-overlay/constitution.md +10 -56
  51. package/kit-overlay/portability.md +6 -6
  52. package/kit-overlay/repo-guide.md +120 -97
  53. package/package.json +4 -2
  54. package/scaffold/.control/questions/blocking.md +1 -1
  55. package/kit/.constitution/README.md +0 -66
  56. /package/kit/.constitution/{document → method/document}/bmad-guide.md +0 -0
  57. /package/kit/.constitution/{document → method/document}/bmad-skill-register.md +0 -0
  58. /package/kit/.constitution/{document → method/document}/brief-guide.md +0 -0
  59. /package/kit/.constitution/{document → method/document}/decision-guide.md +0 -0
  60. /package/kit/.constitution/{document → method/document}/prd-guide.md +0 -0
  61. /package/kit/.constitution/{document → method/document}/srs-guide.md +0 -0
  62. /package/kit/.constitution/{document → method/document}/templates/addendum.md +0 -0
  63. /package/kit/.constitution/{document → method/document}/templates/architecture-spine.md +0 -0
  64. /package/kit/.constitution/{document → method/document}/templates/brief.md +0 -0
  65. /package/kit/.constitution/{document → method/document}/templates/c4.md +0 -0
  66. /package/kit/.constitution/{document → method/document}/templates/contract.md +0 -0
  67. /package/kit/.constitution/{document → method/document}/templates/decision.md +0 -0
  68. /package/kit/.constitution/{document → method/document}/templates/flow.md +0 -0
  69. /package/kit/.constitution/{document → method/document}/templates/integration.md +0 -0
  70. /package/kit/.constitution/{document → method/document}/templates/lc.md +0 -0
  71. /package/kit/.constitution/{document → method/document}/templates/lifecycle.md +0 -0
  72. /package/kit/.constitution/{document → method/document}/templates/meeting.md +0 -0
  73. /package/kit/.constitution/{document → method/document}/templates/model.md +0 -0
  74. /package/kit/.constitution/{document → method/document}/templates/oq.md +0 -0
  75. /package/kit/.constitution/{document → method/document}/templates/prd.md +0 -0
  76. /package/kit/.constitution/{document → method/document}/templates/questions.md +0 -0
  77. /package/kit/.constitution/{document → method/document}/templates/rtr.md +0 -0
  78. /package/kit/.constitution/{document → method/document}/templates/rules.md +0 -0
  79. /package/kit/.constitution/{document → method/document}/templates/scn.md +0 -0
  80. /package/kit/.constitution/{document → method/document}/templates/srs.md +0 -0
  81. /package/kit/.constitution/{document → method/document}/templates/uc.md +0 -0
  82. /package/kit/.constitution/{document → method/document}/templates/ux.md +0 -0
  83. /package/kit/.constitution/{document → method/document}/ux-guide.md +0 -0
  84. /package/kit/.constitution/{scripts → method/scripts}/inventory.py +0 -0
  85. /package/kit/.constitution/{codebase/brownfield-guide.md → project/codebase-brownfield-guide.md} +0 -0
  86. /package/kit/.constitution/{codebase/conventions-guide.md → project/codebase-conventions-guide.md} +0 -0
  87. /package/kit/.constitution/{codebase/stack-guide.md → project/codebase-stack-guide.md} +0 -0
@@ -1,205 +1,205 @@
1
- ---
2
- name: wdi-report
3
- description: Use when someone needs numbers about this project — progress for a client update, an estimate before the work is committed, or task rows ready to paste into a tracker. Three intents, progress and estimate and dispatch. Never invents a number.
4
- ---
5
-
6
- # WDI Report
7
-
8
- Three intents, and the first is deliberately fenced off from the other two **because their rules are opposite**.
9
-
10
- | Intent | Answers | Rule |
11
- |---|---|---|
12
- | `progress` | What has moved, what is late, how much is proven | **Entirely derived.** MUST NOT write one number, date, or percentage that did not come from the registry or from git |
13
- | `estimate` | How big this is, what the tasks are, how much load, what the timeline looks like | **Forward-facing.** MUST state which inputs exist and how precise that makes it, and MUST be labelled an estimate |
14
- | `dispatch` | Task rows ready for an outside tracker | Reads the same table as `estimate`; recomputes nothing |
15
-
16
- Confusing the first two is the failure this split exists to prevent: a forward-looking figure presented in the
17
- voice of a derived one is the most expensive kind of wrong.
18
-
19
- ## What owns what
20
-
21
- | Owner | Produces |
22
- |---|---|
23
- | `.constitution/scripts/validate.py` | `generated/rtm` · `dag` · `status` · `risks` · `components` · `decisions` · `blueprint` · `estimate` |
24
- | `.constitution/scripts/timeline.py` | `generated/timeline` · `generated/report` · `.control/reports/<period>.md` |
25
- | `.constitution/scripts/inventory.py` | The three inventories, derived from code |
26
- | `wdi-reconcile` | Drift between corpus and registry — read-only, no file |
27
- | **this skill** | The judgment on top: whether the tables are fresh enough to report on, and the human commentary written at publish time |
28
-
29
- All three scripts are deterministic and already written. You MUST NOT hand-derive anything they produce, and you
30
- MUST NOT write into `generated/` yourself. Your job starts where their output stops being self-explanatory.
31
-
32
- ---
33
-
34
- # Intent `progress`
35
-
36
- ## Step 1 — Refresh, or refuse
37
-
38
- ```bash
39
- uv run .constitution/scripts/timeline.py --refresh --generate
40
- ```
41
-
42
- `--refresh` runs the validators first, so both halves of `generated/` are derived at the same commit. Read what
43
- it prints before reading anything else:
44
-
45
- | What it says | What you MUST do |
46
- |---|---|
47
- | `rtm/status not yet generated` (exit 3) | Stop. The tables cannot be built, so there is nothing honest to report |
48
- | `git did not respond` (exit 3) | Stop. Every actual date comes from git; without it there is no time dimension |
49
- | `the registry has uncommitted changes` | Say so in the report header. The numbers describe a working tree, not `main` |
50
- | `story with no git history` | Name those stories. They count toward promise progress but cannot appear under Proven |
51
- | `n findings` | Report the count and, if any are red, say which gate they block |
52
-
53
- A report built on stale tables is worse than no report: it looks authoritative and is not.
54
-
55
- ## Step 2 — Read the derived time dimension
56
-
57
- You MUST NOT derive dates yourself. `timeline.py` reads each story file's history and takes the first commit whose
58
- frontmatter status left `draft` as the start, and the commit where it became `done` as the end. `FR` spans its
59
- stories; `CAP` spans its `FR`, and closes only when every story under it is closed.
60
-
61
- None of this is written back into any registry. A stored copy would be a second home for one fact, and the stored
62
- copy is the one that goes wrong.
63
-
64
- ## Step 3 — Read `generated/timeline` and `generated/report`
65
-
66
- `timeline` gives one row per `CAP`, plan beside actual, plus a gantt. `state` is `not-started`, `in-progress`,
67
- `done`, or **`overdue`** — the last being V14.
68
-
69
- You MUST list every overdue row **by name**, with what it is waiting on. The script prints them individually for
70
- the same reason: aggregating them into a count is how a slipping plan stays comfortable.
71
-
72
- `report` gives five composed sections covering the span since the last published report: **Proven** (RTM rows that
73
- turned green, named) · **Moved** (`CAP` and `FR` that started or closed) · **Late** · **Defects** (grouped by
74
- `root_cause`) · **Gates** (dated from the history of `index.yaml`).
75
-
76
- Section 4 grouped by root cause is worth reading twice: it answers how many defects were a wrong requirement rather
77
- than wrong code, and that ratio is a fact about the method, not about the team.
78
-
79
- The left edge is the `asof` of the newest published report. When there is none, the script says the period is
80
- unbounded on the left, and you MUST repeat that rather than picking a date.
81
-
82
- ## Step 4 — Publish
83
-
84
- ```bash
85
- uv run .constitution/scripts/timeline.py --publish weekly
86
- ```
87
-
88
- A published report is **frozen**. It states what was true on a date, exactly like minutes. The script refuses to
89
- overwrite one (exit 4) rather than trusting anyone to remember.
90
-
91
- - You MUST NOT edit a published report. If it was wrong, the next report says so.
92
- - The `## Catatan` block is the one part a person writes, once, at publish time, before the commit.
93
- - Commentary MUST cite rather than restate: a slip has a cause, and that cause already lives in a `DEC-`, an
94
- `OQ-`, a risk, or a defect.
95
-
96
- ## Step 5 — Lead with the honest number
97
-
98
- | Measure | Formula | Answers |
99
- |---|---|---|
100
- | **Progres janji** | green RTM rows ÷ total RTM rows | How much is **proven** |
101
- | Progres kerja | stories `done` ÷ stories in wave | How much was worked on |
102
- | Kesiapan gate | green validators ÷ applicable validators | Whether the next gate can open |
103
-
104
- You MUST present **progres janji** first and label it as the one that counts. Progres kerja MUST NOT lead a
105
- client-facing report: a story can be `done` while its RTM row is still red because the test has no name or the `UC`
106
- does not exist — and that gap is exactly what the client is entitled to know.
107
-
108
- ---
109
-
110
- # Intent `estimate`
111
-
112
- **It runs as early as G1, and sharpens every time an input arrives.** That is what makes it useful for sizing a
113
- project before there is a line of code.
114
-
115
- ## Step 1 — State the input, and the precision it buys
116
-
117
- You MUST say which of these exist and stop at the honest level. Claiming precision the inputs do not support is the
118
- one thing this intent can get badly wrong.
119
-
120
- | Input available | What can be estimated | Precision |
121
- |---|---|---|
122
- | **G1** — the brief | T-shirt size · rough capability count · the first risk list | very rough |
123
- | **+ G2** — the PRD | **The candidate task list = the `FR` list** · `estimate_mandays` per `CAP` · `must/should/could/wont` · order from `depends_on` between `CAP` | rough |
124
- | **+ tail of G2** — components born | Tasks grouped per component = per Epic · **`mode` per component, so document load is counted too** · `risk_accepted` marks exposure | medium |
125
- | **+ G3** — the blueprint | Table, endpoint, and screen counts → real implementation load, not load guessed from an `FR` count | good |
126
- | **+ G4** — component depth | Stories and test names → measured load | best |
127
-
128
- ## Step 2 — Inputs
129
-
130
- `requirements.yaml` (`estimate_mandays`, `priority`, `depends_on`, `target_release`) · `components.yaml` (`mode`,
131
- `risk_accepted`, `risk_note`) · the three `inventory-*.md` when they exist.
132
-
133
- `estimate_mandays` on `CAP` is the **source**, and it is used for real here rather than being decoration. When it is
134
- absent, say so — an estimate with no mandays input is a T-shirt size, and it MUST be reported as one.
135
-
136
- ## Step 3 — The output: one task table
137
-
138
- Written to `.control/generated/estimate.md` by `validate.py --generate`. **Default one row per `FR`**, because that
139
- is the ideal shape of a wave and because an `FR` has had a proof of done since birth.
140
-
141
- | Column | Content |
142
- |---|---|
143
- | Task | The title, from the `FR` |
144
- | `FR` | Its id |
145
- | Epic | The Product Component |
146
- | `mode` | That component's depth — this is what makes document load visible |
147
- | Paparan | `risk_accepted` + `risk_note` |
148
- | Beban | Mandays, derived from the parent `CAP`'s `estimate_mandays`, divided among its `FR` |
149
- | Prioritas | From the `CAP` |
150
- | Bergantung pada | From `depends_on` |
151
- | Rilis | The `CAP`'s `target_release` |
152
-
153
- ## Step 4 — Say what it is, and what it is not
154
-
155
- > A row in the estimate table is a **candidate** task. A wave in `waves.yaml` is a **real** one. The first missing
156
- > is normal; the second is not.
157
-
158
- The table is planning, not commitment. One row MAY become one wave, and three neighbouring rows MAY be merged into
159
- one. **That merge is a human decision made when the wave opens**, and this intent MUST NOT pretend to already know
160
- the answer.
161
-
162
- - Every output MUST carry the word estimate, visibly, at the top.
163
- - You MUST NOT present a mandays figure without naming what it was derived from.
164
- - You MUST NOT include a date this intent computed itself. Plan dates come from `planned_end` on a `CAP`; where
165
- there is none, the timeline is stated in sequence and dependency, not in dates.
166
-
167
- ---
168
-
169
- # Intent `dispatch`
170
-
171
- Reads `.control/generated/estimate.md` and `waves.yaml`. **It recomputes nothing.**
172
-
173
- It emits rows in a form that can be pasted into an outside tracker: Epic (the Product Component), Task (the wave, or
174
- the candidate row where no wave exists yet), Sub-task (the story, where one exists), labels for `FR` and `CAP`, and
175
- Fix Version from the release.
176
-
177
- - Output goes **to the screen**. This intent MUST NOT write a file, and MUST NOT write to the tracker — entering it
178
- is a human act.
179
- - The corpus never reads back from the tracker. **The corpus is the source of truth; the tracker is a view.**
180
- - A row whose Task is still a candidate MUST be marked as one. A candidate pasted as a real Task is how a tracker
181
- fills with issues nobody committed to.
182
-
183
- ---
184
-
185
- ## Rules
186
-
187
- - You MUST NOT invent progress. When a table is missing or stale, name it and stop.
188
- - You MUST NOT report `progress` in stories. The planning layer speaks in `CAP`, `FR`, and defects; stories are the
189
- execution layer and are born too late to plan against.
190
- - You MUST NOT hand-write anything under `generated/`. There is no exception.
191
- - You MUST NOT re-run `--publish` to "fix" a report. The refusal is the rule working.
192
- - When plan dates have moved since the last report, you MUST say so and point at the commit.
193
- - When there is no previous report, say the period is unbounded on the left rather than picking a date.
194
- - You MUST NOT mix the intents in one output. A derived number and a forward-looking one MUST NOT appear in the same
195
- table without the labels that separate them.
196
-
197
- ## Output
198
-
199
- **`progress`:** the published path, the freshness commit, progres janji, then the five sections — overdue rows named
200
- individually, never counted away.
201
-
202
- **`estimate`:** which inputs exist and the precision that buys, the task table, and what is a candidate rather than
203
- a commitment.
204
-
205
- **`dispatch`:** the paste-ready rows, on screen, with candidates marked.
1
+ ---
2
+ name: wdi-report
3
+ description: Use when someone needs numbers about this project — progress for a client update, an estimate before the work is committed, or task rows ready to paste into a tracker. Three intents, progress and estimate and dispatch. Never invents a number.
4
+ ---
5
+
6
+ # WDI Report
7
+
8
+ Three intents, and the first is deliberately fenced off from the other two **because their rules are opposite**.
9
+
10
+ | Intent | Answers | Rule |
11
+ |---|---|---|
12
+ | `progress` | What has moved, what is late, how much is proven | **Entirely derived.** MUST NOT write one number, date, or percentage that did not come from the registry or from git |
13
+ | `estimate` | How big this is, what the tasks are, how much load, what the timeline looks like | **Forward-facing.** MUST state which inputs exist and how precise that makes it, and MUST be labelled an estimate |
14
+ | `dispatch` | Task rows ready for an outside tracker | Reads the same table as `estimate`; recomputes nothing |
15
+
16
+ Confusing the first two is the failure this split exists to prevent: a forward-looking figure presented in the
17
+ voice of a derived one is the most expensive kind of wrong.
18
+
19
+ ## What owns what
20
+
21
+ | Owner | Produces |
22
+ |---|---|
23
+ | `.constitution/method/scripts/validate.py` | `generated/rtm` · `dag` · `status` · `risks` · `components` · `decisions` · `blueprint` · `estimate` |
24
+ | `.constitution/method/scripts/timeline.py` | `generated/timeline` · `generated/report` · `.control/reports/<period>.md` |
25
+ | `.constitution/method/scripts/inventory.py` | The three inventories, derived from code |
26
+ | `wdi-reconcile` | Drift between corpus and registry — read-only, no file |
27
+ | **this skill** | The judgment on top: whether the tables are fresh enough to report on, and the human commentary written at publish time |
28
+
29
+ All three scripts are deterministic and already written. You MUST NOT hand-derive anything they produce, and you
30
+ MUST NOT write into `generated/` yourself. Your job starts where their output stops being self-explanatory.
31
+
32
+ ---
33
+
34
+ # Intent `progress`
35
+
36
+ ## Step 1 — Refresh, or refuse
37
+
38
+ ```bash
39
+ uv run .constitution/method/scripts/timeline.py --refresh --generate
40
+ ```
41
+
42
+ `--refresh` runs the validators first, so both halves of `generated/` are derived at the same commit. Read what
43
+ it prints before reading anything else:
44
+
45
+ | What it says | What you MUST do |
46
+ |---|---|
47
+ | `rtm/status not yet generated` (exit 3) | Stop. The tables cannot be built, so there is nothing honest to report |
48
+ | `git did not respond` (exit 3) | Stop. Every actual date comes from git; without it there is no time dimension |
49
+ | `the registry has uncommitted changes` | Say so in the report header. The numbers describe a working tree, not `main` |
50
+ | `story with no git history` | Name those stories. They count toward promise progress but cannot appear under Proven |
51
+ | `n findings` | Report the count and, if any are red, say which gate they block |
52
+
53
+ A report built on stale tables is worse than no report: it looks authoritative and is not.
54
+
55
+ ## Step 2 — Read the derived time dimension
56
+
57
+ You MUST NOT derive dates yourself. `timeline.py` reads each story file's history and takes the first commit whose
58
+ frontmatter status left `draft` as the start, and the commit where it became `done` as the end. `FR` spans its
59
+ stories; `CAP` spans its `FR`, and closes only when every story under it is closed.
60
+
61
+ None of this is written back into any registry. A stored copy would be a second home for one fact, and the stored
62
+ copy is the one that goes wrong.
63
+
64
+ ## Step 3 — Read `generated/timeline` and `generated/report`
65
+
66
+ `timeline` gives one row per `CAP`, plan beside actual, plus a gantt. `state` is `not-started`, `in-progress`,
67
+ `done`, or **`overdue`** — the last being V14.
68
+
69
+ You MUST list every overdue row **by name**, with what it is waiting on. The script prints them individually for
70
+ the same reason: aggregating them into a count is how a slipping plan stays comfortable.
71
+
72
+ `report` gives five composed sections covering the span since the last published report: **Proven** (RTM rows that
73
+ turned green, named) · **Moved** (`CAP` and `FR` that started or closed) · **Late** · **Defects** (grouped by
74
+ `root_cause`) · **Gates** (dated from the history of `index.yaml`).
75
+
76
+ Section 4 grouped by root cause is worth reading twice: it answers how many defects were a wrong requirement rather
77
+ than wrong code, and that ratio is a fact about the method, not about the team.
78
+
79
+ The left edge is the `asof` of the newest published report. When there is none, the script says the period is
80
+ unbounded on the left, and you MUST repeat that rather than picking a date.
81
+
82
+ ## Step 4 — Publish
83
+
84
+ ```bash
85
+ uv run .constitution/method/scripts/timeline.py --publish weekly
86
+ ```
87
+
88
+ A published report is **frozen**. It states what was true on a date, exactly like minutes. The script refuses to
89
+ overwrite one (exit 4) rather than trusting anyone to remember.
90
+
91
+ - You MUST NOT edit a published report. If it was wrong, the next report says so.
92
+ - The `## Catatan` block is the one part a person writes, once, at publish time, before the commit.
93
+ - Commentary MUST cite rather than restate: a slip has a cause, and that cause already lives in a `DEC-`, an
94
+ `OQ-`, a risk, or a defect.
95
+
96
+ ## Step 5 — Lead with the honest number
97
+
98
+ | Measure | Formula | Answers |
99
+ |---|---|---|
100
+ | **Progres janji** | green RTM rows ÷ total RTM rows | How much is **proven** |
101
+ | Progres kerja | stories `done` ÷ stories in wave | How much was worked on |
102
+ | Kesiapan gate | green validators ÷ applicable validators | Whether the next gate can open |
103
+
104
+ You MUST present **progres janji** first and label it as the one that counts. Progres kerja MUST NOT lead a
105
+ client-facing report: a story can be `done` while its RTM row is still red because the test has no name or the `UC`
106
+ does not exist — and that gap is exactly what the client is entitled to know.
107
+
108
+ ---
109
+
110
+ # Intent `estimate`
111
+
112
+ **It runs as early as G1, and sharpens every time an input arrives.** That is what makes it useful for sizing a
113
+ project before there is a line of code.
114
+
115
+ ## Step 1 — State the input, and the precision it buys
116
+
117
+ You MUST say which of these exist and stop at the honest level. Claiming precision the inputs do not support is the
118
+ one thing this intent can get badly wrong.
119
+
120
+ | Input available | What can be estimated | Precision |
121
+ |---|---|---|
122
+ | **G1** — the brief | T-shirt size · rough capability count · the first risk list | very rough |
123
+ | **+ G2** — the PRD | **The candidate task list = the `FR` list** · `estimate_mandays` per `CAP` · `must/should/could/wont` · order from `depends_on` between `CAP` | rough |
124
+ | **+ tail of G2** — components born | Tasks grouped per component = per Epic · **`mode` per component, so document load is counted too** · `risk_accepted` marks exposure | medium |
125
+ | **+ G3** — the blueprint | Table, endpoint, and screen counts → real implementation load, not load guessed from an `FR` count | good |
126
+ | **+ G4** — component depth | Stories and test names → measured load | best |
127
+
128
+ ## Step 2 — Inputs
129
+
130
+ `requirements.yaml` (`estimate_mandays`, `priority`, `depends_on`, `target_release`) · `components.yaml` (`mode`,
131
+ `risk_accepted`, `risk_note`) · the three `inventory-*.md` when they exist.
132
+
133
+ `estimate_mandays` on `CAP` is the **source**, and it is used for real here rather than being decoration. When it is
134
+ absent, say so — an estimate with no mandays input is a T-shirt size, and it MUST be reported as one.
135
+
136
+ ## Step 3 — The output: one task table
137
+
138
+ Written to `.control/generated/estimate.md` by `validate.py --generate`. **Default one row per `FR`**, because that
139
+ is the ideal shape of a wave and because an `FR` has had a proof of done since birth.
140
+
141
+ | Column | Content |
142
+ |---|---|
143
+ | Task | The title, from the `FR` |
144
+ | `FR` | Its id |
145
+ | Epic | The Product Component |
146
+ | `mode` | That component's depth — this is what makes document load visible |
147
+ | Paparan | `risk_accepted` + `risk_note` |
148
+ | Beban | Mandays, derived from the parent `CAP`'s `estimate_mandays`, divided among its `FR` |
149
+ | Prioritas | From the `CAP` |
150
+ | Bergantung pada | From `depends_on` |
151
+ | Rilis | The `CAP`'s `target_release` |
152
+
153
+ ## Step 4 — Say what it is, and what it is not
154
+
155
+ > A row in the estimate table is a **candidate** task. A wave in `waves.yaml` is a **real** one. The first missing
156
+ > is normal; the second is not.
157
+
158
+ The table is planning, not commitment. One row MAY become one wave, and three neighbouring rows MAY be merged into
159
+ one. **That merge is a human decision made when the wave opens**, and this intent MUST NOT pretend to already know
160
+ the answer.
161
+
162
+ - Every output MUST carry the word estimate, visibly, at the top.
163
+ - You MUST NOT present a mandays figure without naming what it was derived from.
164
+ - You MUST NOT include a date this intent computed itself. Plan dates come from `planned_end` on a `CAP`; where
165
+ there is none, the timeline is stated in sequence and dependency, not in dates.
166
+
167
+ ---
168
+
169
+ # Intent `dispatch`
170
+
171
+ Reads `.control/generated/estimate.md` and `waves.yaml`. **It recomputes nothing.**
172
+
173
+ It emits rows in a form that can be pasted into an outside tracker: Epic (the Product Component), Task (the wave, or
174
+ the candidate row where no wave exists yet), Sub-task (the story, where one exists), labels for `FR` and `CAP`, and
175
+ Fix Version from the release.
176
+
177
+ - Output goes **to the screen**. This intent MUST NOT write a file, and MUST NOT write to the tracker — entering it
178
+ is a human act.
179
+ - The corpus never reads back from the tracker. **The corpus is the source of truth; the tracker is a view.**
180
+ - A row whose Task is still a candidate MUST be marked as one. A candidate pasted as a real Task is how a tracker
181
+ fills with issues nobody committed to.
182
+
183
+ ---
184
+
185
+ ## Rules
186
+
187
+ - You MUST NOT invent progress. When a table is missing or stale, name it and stop.
188
+ - You MUST NOT report `progress` in stories. The planning layer speaks in `CAP`, `FR`, and defects; stories are the
189
+ execution layer and are born too late to plan against.
190
+ - You MUST NOT hand-write anything under `generated/`. There is no exception.
191
+ - You MUST NOT re-run `--publish` to "fix" a report. The refusal is the rule working.
192
+ - When plan dates have moved since the last report, you MUST say so and point at the commit.
193
+ - When there is no previous report, say the period is unbounded on the left rather than picking a date.
194
+ - You MUST NOT mix the intents in one output. A derived number and a forward-looking one MUST NOT appear in the same
195
+ table without the labels that separate them.
196
+
197
+ ## Output
198
+
199
+ **`progress`:** the published path, the freshness commit, progres janji, then the five sections — overdue rows named
200
+ individually, never counted away.
201
+
202
+ **`estimate`:** which inputs exist and the precision that buys, the task table, and what is a candidate rather than
203
+ a commitment.
204
+
205
+ **`dispatch`:** the paste-ready rows, on screen, with candidates marked.