yadflow 3.19.0-next.2 → 4.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.md +317 -0
  2. package/README.md +75 -22
  3. package/bin/commands.mjs +41 -0
  4. package/bin/yad.mjs +430 -117
  5. package/cli/artifact-status.mjs +30 -11
  6. package/cli/checkpoint.mjs +47 -27
  7. package/cli/codeowners-command.mjs +170 -0
  8. package/cli/codeowners.mjs +397 -0
  9. package/cli/commit.mjs +13 -9
  10. package/cli/dial.mjs +183 -0
  11. package/cli/docs.mjs +88 -32
  12. package/cli/doctor.mjs +1465 -90
  13. package/cli/epic-state.mjs +3457 -211
  14. package/cli/epic.mjs +506 -0
  15. package/cli/errors.mjs +3 -0
  16. package/cli/gate.mjs +977 -183
  17. package/cli/history.mjs +556 -0
  18. package/cli/hook.mjs +264 -53
  19. package/cli/hubcommit.mjs +6 -17
  20. package/cli/index-command.mjs +87 -0
  21. package/cli/ledger.mjs +54 -4
  22. package/cli/lib.mjs +161 -9
  23. package/cli/manifest.mjs +328 -38
  24. package/cli/migrate.mjs +683 -52
  25. package/cli/mode.mjs +170 -0
  26. package/cli/next.mjs +345 -86
  27. package/cli/openpr.mjs +186 -34
  28. package/cli/people.mjs +654 -0
  29. package/cli/plan.mjs +392 -126
  30. package/cli/platform.mjs +109 -128
  31. package/cli/product-index.mjs +287 -0
  32. package/cli/protection.mjs +706 -0
  33. package/cli/reconcile.mjs +38 -12
  34. package/cli/repo-publish.mjs +24 -26
  35. package/cli/repo.mjs +23 -14
  36. package/cli/report.mjs +20 -14
  37. package/cli/review.mjs +19 -22
  38. package/cli/riskmap-command.mjs +289 -0
  39. package/cli/riskmap.mjs +373 -0
  40. package/cli/setup.mjs +119 -279
  41. package/cli/ship.mjs +6 -5
  42. package/cli/skill.mjs +180 -0
  43. package/cli/skip.mjs +211 -30
  44. package/cli/thread.mjs +41 -16
  45. package/cli/tidy.mjs +18 -18
  46. package/cli/update-commit.mjs +21 -21
  47. package/cli/usage.mjs +115 -109
  48. package/package.json +3 -3
  49. package/skills/sdlc/config.yaml +149 -70
  50. package/skills/sdlc/module-help.csv +24 -24
  51. package/skills/yad-analysis/SKILL.md +118 -58
  52. package/skills/yad-architecture/SKILL.md +28 -17
  53. package/skills/yad-architecture/references/contract-format.md +8 -5
  54. package/skills/yad-backfill/SKILL.md +10 -4
  55. package/skills/yad-backfill/references/backfill.md +1 -1
  56. package/skills/yad-change/SKILL.md +117 -42
  57. package/skills/yad-change/references/triage.md +42 -27
  58. package/skills/yad-checks/SKILL.md +61 -35
  59. package/skills/yad-checks/references/check-gates.md +257 -78
  60. package/skills/yad-checks/templates/checks/commit-message.sh +17 -3
  61. package/skills/yad-checks/templates/checks/contract-check.sh +58 -2
  62. package/skills/yad-checks/templates/checks/epic-open.sh +2 -2
  63. package/skills/yad-checks/templates/checks/ledger-guard.sh +55 -8
  64. package/skills/yad-checks/templates/checks/lineage-check.sh +23 -9
  65. package/skills/yad-checks/templates/checks/reconcile-debt-check.sh +1 -1
  66. package/skills/yad-checks/templates/checks/risk-map-check.sh +438 -0
  67. package/skills/yad-checks/templates/checks/verified-commits.sh +20 -46
  68. package/skills/yad-checks/templates/github/yad-checks.yml +13 -2
  69. package/skills/yad-checks/templates/github/yad-hub-checks.yml +3 -3
  70. package/skills/yad-checks/templates/github/yad-update-guard.yml +3 -4
  71. package/skills/yad-checks/templates/github/yad-verified-commits.yml +4 -4
  72. package/skills/yad-checks/templates/gitlab/yad-checks.gitlab-ci.yml +10 -1
  73. package/skills/yad-checks/templates/gitlab/yad-hub-checks.gitlab-ci.yml +3 -3
  74. package/skills/yad-checks/templates/gitlab/yad-verified-commits.gitlab-ci.yml +3 -3
  75. package/skills/yad-checks/templates/hooks/ledger-guard-cursor.sh +91 -0
  76. package/skills/yad-checks/templates/hooks/ledger-guard.sh +37 -6
  77. package/skills/yad-commit/SKILL.md +4 -4
  78. package/skills/yad-connect-design/SKILL.md +5 -5
  79. package/skills/yad-connect-design/references/design-context.md +1 -1
  80. package/skills/yad-connect-design/references/design-registry.md +2 -2
  81. package/skills/yad-connect-docs/SKILL.md +11 -11
  82. package/skills/yad-connect-docs/references/docs-registry.md +1 -1
  83. package/skills/yad-connect-learning/SKILL.md +5 -5
  84. package/skills/yad-connect-learning/references/learning-registry.md +2 -2
  85. package/skills/yad-connect-repos/SKILL.md +66 -45
  86. package/skills/yad-connect-repos/references/code-context.md +4 -4
  87. package/skills/yad-connect-repos/references/hub-config.md +47 -51
  88. package/skills/yad-connect-repos/references/repos-registry.md +8 -7
  89. package/skills/yad-connect-repos/references/risk-map.md +81 -0
  90. package/skills/yad-connect-testing/SKILL.md +5 -5
  91. package/skills/yad-connect-testing/references/testing-context.md +3 -4
  92. package/skills/yad-connect-testing/references/testing-registry.md +2 -2
  93. package/skills/yad-defects/SKILL.md +7 -7
  94. package/skills/yad-discovery/SKILL.md +130 -94
  95. package/skills/yad-discovery/references/discovery-schema.md +22 -6
  96. package/skills/yad-discovery/references/foundation-schema.md +374 -0
  97. package/skills/yad-docs/SKILL.md +13 -8
  98. package/skills/yad-docs/references/data-mapping.md +9 -7
  99. package/skills/yad-docs/templates/app/package-lock.json +3 -3
  100. package/skills/yad-docs-overview/SKILL.md +30 -15
  101. package/skills/yad-docs-overview/references/pipeline-model.md +33 -20
  102. package/skills/yad-docs-sync/SKILL.md +10 -5
  103. package/skills/yad-docs-sync/references/staleness.md +8 -7
  104. package/skills/yad-engineer-review/SKILL.md +81 -17
  105. package/skills/yad-engineer-review/references/ship-and-record.md +17 -8
  106. package/skills/yad-epic/SKILL.md +169 -91
  107. package/skills/yad-epic/references/state-schema.md +602 -93
  108. package/skills/yad-hub-bridge/SKILL.md +55 -37
  109. package/skills/yad-hub-bridge/references/bridge.md +94 -67
  110. package/skills/yad-hub-bridge/references/login-roster.md +163 -70
  111. package/skills/yad-hub-bridge/templates/checks/hub-route.sh +22 -19
  112. package/skills/yad-hub-bridge/templates/github/yad-gate-sync.yml +34 -14
  113. package/skills/yad-hub-bridge/templates/gitlab/gitlab-ci.include-root.yml +2 -2
  114. package/skills/yad-hub-bridge/templates/gitlab/yad-gate-sync.gitlab-ci.yml +21 -11
  115. package/skills/yad-implement/SKILL.md +27 -13
  116. package/skills/yad-implement/references/implement-conventions.md +2 -2
  117. package/skills/yad-learn/SKILL.md +9 -9
  118. package/skills/yad-learn/references/learning-state.md +2 -2
  119. package/skills/yad-open-pr/SKILL.md +61 -26
  120. package/skills/yad-pair-review/SKILL.md +7 -5
  121. package/skills/yad-pair-review/references/session-state.md +1 -1
  122. package/skills/yad-pr-template/SKILL.md +47 -26
  123. package/skills/yad-pr-template/references/risk-routing.md +97 -24
  124. package/skills/yad-pr-template/templates/checks/pr-template.sh +25 -11
  125. package/skills/yad-pr-template/templates/checks/pr-title.sh +23 -9
  126. package/skills/yad-pr-template/templates/checks/risk-route.sh +107 -14
  127. package/skills/yad-pr-template/templates/github/pull_request_template.md +7 -5
  128. package/skills/yad-pr-template/templates/gitlab/merge_request_templates/Default.md +7 -5
  129. package/skills/yad-pr-template/templates/hub/github/pull_request_template.md +14 -13
  130. package/skills/yad-pr-template/templates/hub/gitlab/merge_request_templates/Default.md +14 -12
  131. package/skills/yad-reconcile/SKILL.md +3 -3
  132. package/skills/yad-report/SKILL.md +5 -5
  133. package/skills/yad-review-companion/SKILL.md +6 -3
  134. package/skills/yad-review-gate/SKILL.md +188 -69
  135. package/skills/yad-review-gate/references/gating.md +228 -52
  136. package/skills/yad-run/SKILL.md +81 -51
  137. package/skills/yad-run/references/run-loop.md +61 -39
  138. package/skills/yad-ship/SKILL.md +15 -11
  139. package/skills/yad-spec/SKILL.md +21 -6
  140. package/skills/yad-spec/references/spec-handoff.md +17 -5
  141. package/skills/yad-status/SKILL.md +108 -50
  142. package/skills/yad-stories/SKILL.md +35 -20
  143. package/skills/yad-stories/references/story-schema.md +7 -6
  144. package/skills/yad-stub/SKILL.md +58 -47
  145. package/skills/yad-sync-repos/SKILL.md +2 -2
  146. package/skills/yad-test-cases/SKILL.md +30 -22
  147. package/skills/yad-test-cases/references/test-cases-schema.md +7 -4
  148. package/skills/yad-timeline/SKILL.md +8 -7
  149. package/skills/yad-ui/SKILL.md +38 -17
  150. package/cli/roster.mjs +0 -164
  151. package/skills/sdlc/install.sh +0 -68
package/CHANGELOG.md CHANGED
@@ -1,3 +1,320 @@
1
+ # [4.0.0-next.1](https://github.com/abdelrahmannasr/yadflow/compare/v3.19.0-next.2...v4.0.0-next.1) (2026-09-24)
2
+
3
+
4
+ * feat(checks)!: risk-route and hub-route print the approval count, not roles (E62) ([8754585](https://github.com/abdelrahmannasr/yadflow/commit/875458576c6800356980b302dd3366d0b7a5e02a))
5
+ * feat(checks)!: verified-commits checks signatures only; the author allowlist is gone (E62) ([67c0161](https://github.com/abdelrahmannasr/yadflow/commit/67c01612372f74e6c70b5af24636eae034fe34c7))
6
+ * feat(cli)!: every command answers --json in one envelope (E1) ([7862dfb](https://github.com/abdelrahmannasr/yadflow/commit/7862dfb7d496171bc5f8fa20e533ffc688c57f0e))
7
+ * feat(epic)!: shape 5 — the work-item type, and a chore may stand alone ([5eb24fb](https://github.com/abdelrahmannasr/yadflow/commit/5eb24fb04e5d6c686d92b69e4d1b8dd1ea41d46b))
8
+ * feat(gate)!: a team gate needs one approver, and approvals name the platform login (E62) ([3730b9c](https://github.com/abdelrahmannasr/yadflow/commit/3730b9cc4f58acede87f9a020ac1ded0b7cf1fdd))
9
+ * feat(gate)!: review and task PRs request no reviewers (E62) ([d9f3d76](https://github.com/abdelrahmannasr/yadflow/commit/d9f3d765cced1b50868197bf8622e891a2af0f3a))
10
+ * feat(gate)!: shape 9 — an approval's fingerprint leaves out the frontmatter status line ([226f9ec](https://github.com/abdelrahmannasr/yadflow/commit/226f9ec4b9c19bdd055a1f9094b5c95badd69864))
11
+ * feat(migrate)!: shape 8 — `yad migrate` moves the product level into foundation/ (E75) ([88e726f](https://github.com/abdelrahmannasr/yadflow/commit/88e726fe9b24737d02e2b7f32e167a60f09e6961))
12
+ * feat(setup)!: remove yad roster and stop collecting people in setup (E62) ([5eb6914](https://github.com/abdelrahmannasr/yadflow/commit/5eb69147c84aa6b83ddda2c3e394b4f183caca6a))
13
+ * feat(state)!: finish the hub to Product rename ([92a9750](https://github.com/abdelrahmannasr/yadflow/commit/92a9750e708ab130000872e09fd15ff68c4a3c00))
14
+ * feat(state)!: yad undefer re-opens a deferred step behind finished work (E41) ([518b7cc](https://github.com/abdelrahmannasr/yadflow/commit/518b7cc7c339f20cf417712b5e8da0e560312f29))
15
+ * feat(usage)!: yad usage lists people from activity, not from the roster (E62) ([0664996](https://github.com/abdelrahmannasr/yadflow/commit/0664996f4dae2f190fcd304cb259759054251a80))
16
+ * fix(docs)!: a failed docs build exits 1 and says which site failed ([381a000](https://github.com/abdelrahmannasr/yadflow/commit/381a0000754ff4eb9fec4856692d4627369d6420))
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * **agents:** answer Cursor in the protocol it actually reads ([d6d6175](https://github.com/abdelrahmannasr/yadflow/commit/d6d6175e71447e6ae735979631dd74802d3f0f13))
22
+ * **agents:** close the fifteen defects the deep review found ([cc42177](https://github.com/abdelrahmannasr/yadflow/commit/cc421772bceee0513a3ca30f382cdbb606de39d6))
23
+ * **agents:** close the five defects the E11 review found ([c4ca25f](https://github.com/abdelrahmannasr/yadflow/commit/c4ca25fd66d497157d2ee37707984b02f1c500b0))
24
+ * **agents:** close the four the audit had left open ([0e5dcd8](https://github.com/abdelrahmannasr/yadflow/commit/0e5dcd80a752f263a45865b3188edf57421818eb))
25
+ * **agents:** close the last three, and stop a comment claiming something false ([292a7b1](https://github.com/abdelrahmannasr/yadflow/commit/292a7b1c2b45457f230c39fc19f3db1535beb50d))
26
+ * **agents:** let the doctor see the script Cursor actually invokes ([a070911](https://github.com/abdelrahmannasr/yadflow/commit/a0709113dfca4b94608c0519157f0157060d3999))
27
+ * **artifact-status:** a "$" in a frontmatter value no longer corrupts the status flip ([545123a](https://github.com/abdelrahmannasr/yadflow/commit/545123a5889cf48910507872ba45607592650cd9))
28
+ * **checks:** a claimed Contract-Change with no lock at all now FAILS ([2008eea](https://github.com/abdelrahmannasr/yadflow/commit/2008eea518b4e20052fb277301140d33a9793182))
29
+ * **checks:** hub-route reads whole risk tags; route output stops claiming an author check ([53bda97](https://github.com/abdelrahmannasr/yadflow/commit/53bda9717e75367940abab8ab033f3429c274e22))
30
+ * **checks:** removing a contract slice under a lockless epic is allowed ([9d0b66a](https://github.com/abdelrahmannasr/yadflow/commit/9d0b66a412d19c6b222f9e3a24dbcac1a8bde4ad))
31
+ * **checks:** risk-route reads an older risk-map check as "not counted", never as "nothing is high" ([a486d7b](https://github.com/abdelrahmannasr/yadflow/commit/a486d7b7b46ae95df03f3a372b72f72cc61c0e6a))
32
+ * **checks:** run the risk-map awk in the C locale so every awk reads bytes ([4d0d748](https://github.com/abdelrahmannasr/yadflow/commit/4d0d748e0ce575178cfa2d1a9f42df82a40caf16))
33
+ * **cli:** a JSON refusal keeps what was done; every warning is collected (E1 review 1) ([41fce95](https://github.com/abdelrahmannasr/yadflow/commit/41fce957954e75bb64fb0ab4271270935e7dc2fc))
34
+ * **cli:** a later failure keeps its hint; every commit row has the same keys (E1 review 3) ([188b2de](https://github.com/abdelrahmannasr/yadflow/commit/188b2dec55ce8b25a9fa8fe8e471864141c1def4))
35
+ * **cli:** answer in JSON only when the running command is history (PR review 3) ([cdc8250](https://github.com/abdelrahmannasr/yadflow/commit/cdc8250b340693b5e80d8d49a26044305ec52a4a))
36
+ * **cli:** every line that names a skill asks the project, not the catalogue ([c085218](https://github.com/abdelrahmannasr/yadflow/commit/c08521818e951faddb04c4e26fe5639a70cc0f1b))
37
+ * **cli:** every sweep failure reaches the JSON; a refusal says what was committed (E1 review 2) ([dd7ef3e](https://github.com/abdelrahmannasr/yadflow/commit/dd7ef3e00713bdeba43b0870e70ac90ee4246bf7))
38
+ * **cli:** the history JSON error is exactly the documented refusal shape ([d20c9a3](https://github.com/abdelrahmannasr/yadflow/commit/d20c9a3ab7f83ed73139c62f4eb2622d8a44440d))
39
+ * **cli:** the review round — a write that ate a user's bindings, and five more ([3c63059](https://github.com/abdelrahmannasr/yadflow/commit/3c63059686c467c5a8b29367d1e7712472835b9b))
40
+ * **cli:** two more prototype holes, and yad-run reads the binding without a lane ([3a0a114](https://github.com/abdelrahmannasr/yadflow/commit/3a0a1146e2b50154a294cd8ae0e30dc0e4a2ee58))
41
+ * **codeowners:** a GitLab heading's unreadable default owners are reported (E68 review 3) ([cd9a1f1](https://github.com/abdelrahmannasr/yadflow/commit/cd9a1f1c6628040ccf3c35efad0c49185039e73e))
42
+ * **codeowners:** a path typed in another case is still the top folder; a refusal is JSON under --json (E69 review 5) ([397ccaf](https://github.com/abdelrahmannasr/yadflow/commit/397ccaf9efdf8b6807a04721a2bd726b49398863))
43
+ * **codeowners:** a pattern crosses a folder name holding a line break; no set copy per rule (E69 review 3) ([7341d79](https://github.com/abdelrahmannasr/yadflow/commit/7341d79080cc0d5558929869afbbfb812f84853e))
44
+ * **codeowners:** an exclusion's extra words are not an owner problem; describe the GitLab defaults rule ([4f50303](https://github.com/abdelrahmannasr/yadflow/commit/4f50303ac1fa9d50ad830a1c3ff7813f2a39bfc5))
45
+ * **codeowners:** exact dead-line answer for escaped characters; fast for every common shape; refuse --write= (E69 review 2) ([c52b17d](https://github.com/abdelrahmannasr/yadflow/commit/c52b17db4ba7829bd59497cd60a8e00eb52c839f))
46
+ * **codeowners:** no address in a not-read reason; fast dead-line check; exact file name; top folder only (E69 review 1) ([036f907](https://github.com/abdelrahmannasr/yadflow/commit/036f9078f09f220a45de5f10a44bb9998a3c8a9d))
47
+ * **codeowners:** read the file list only when a CODEOWNERS exists; a list git cannot produce is not known ([a2f0cc8](https://github.com/abdelrahmannasr/yadflow/commit/a2f0cc8a626be7720aaf3b7c99118a93a34ff002))
48
+ * **dial:** close the holes the E34 review found ([2038d19](https://github.com/abdelrahmannasr/yadflow/commit/2038d19bf596ae958e3b51fb2b0bc3b2fbbd4860))
49
+ * **docs:** a new yad release no longer marks every docs site stale ([bdbbff1](https://github.com/abdelrahmannasr/yadflow/commit/bdbbff1eaaf7d89e7582d43dbbc11df52de84bd4))
50
+ * **docs:** only a deploy where every site built ends on a tick (review 2) ([68251be](https://github.com/abdelrahmannasr/yadflow/commit/68251beb3d9208011481e77587ba4ffc46d923cf))
51
+ * **docs:** the review round — right site folder, a real test, no green tick after a failed deploy ([9f868d8](https://github.com/abdelrahmannasr/yadflow/commit/9f868d8332679ab437c49b8e07fc3a5d15534faf))
52
+ * **doctor:** "on every change" also when a scoped rule could not be read (E70 review 6) ([36e52ff](https://github.com/abdelrahmannasr/yadflow/commit/36e52ffd80b74a43404924f1b8aab9a0133ec8b6))
53
+ * **doctor:** a 404 on a list never means "they do not exist" (E70 review 27) ([8bdf98f](https://github.com/abdelrahmannasr/yadflow/commit/8bdf98f64dbb1924768d161d8019813e4aecf7f4))
54
+ * **doctor:** a 404 on the rules is a host without rulesets, not a permission (E70 review 28) ([f80f92d](https://github.com/abdelrahmannasr/yadflow/commit/f80f92d4c468195730ef1a9c28089fb07dfbcf28))
55
+ * **doctor:** a belief from a 404 may remove an offer, never add certainty (E70 review 30) ([a3f653d](https://github.com/abdelrahmannasr/yadflow/commit/a3f653d15514a7842cadefcd16772235df7dfee9)), closes [#7386](https://github.com/abdelrahmannasr/yadflow/issues/7386) [#29576](https://github.com/abdelrahmannasr/yadflow/issues/29576)
56
+ * **doctor:** a branch yad cannot read settles nothing (E70 review 24) ([8d9a46a](https://github.com/abdelrahmannasr/yadflow/commit/8d9a46a1a2826b09634fcfdbce4e820e94882392))
57
+ * **doctor:** a colon, not a second dash, in the GitLab sentence (E70 review 11) ([9d8c835](https://github.com/abdelrahmannasr/yadflow/commit/9d8c83525a69945753250f9acbedbe469dcc609a))
58
+ * **doctor:** a floor counts rules, not labels (E70 review 23) ([3f7d124](https://github.com/abdelrahmannasr/yadflow/commit/3f7d124d6698973d599da54bf64724f4fb8bf23a))
59
+ * **doctor:** a GitLab rule with no name reads as "an approval rule" (E70 review 12) ([5ada04a](https://github.com/abdelrahmannasr/yadflow/commit/5ada04abb6356099a81280a910bc181a09b37dae))
60
+ * **doctor:** a hint hedges wherever its own message does (E70 review 31) ([e256f06](https://github.com/abdelrahmannasr/yadflow/commit/e256f06c50db96cfbab79dda4e91a63fcf91c456))
61
+ * **doctor:** a pointer only where something was unread, and numbers that agree (E70 review 16) ([2ff23f5](https://github.com/abdelrahmannasr/yadflow/commit/2ff23f53b12d0fa3f5d5d00766a90c4333d6dd80))
62
+ * **doctor:** a protection line states only what the platform answered (E70 review 3) ([453f646](https://github.com/abdelrahmannasr/yadflow/commit/453f6463040578c297c46f4cd22ba0521860c27f))
63
+ * **doctor:** a read that answered nothing says so, and one source is named once (E70 review 22) ([25eabe8](https://github.com/abdelrahmannasr/yadflow/commit/25eabe8d02778514bafdbf25b3698caac6a4b2f5))
64
+ * **doctor:** a rule keyed on a wording must say when it stops firing (E70 review 32b) ([6beeb6f](https://github.com/abdelrahmannasr/yadflow/commit/6beeb6f8c3c1f72f30c869559b763f6e3a6097e0))
65
+ * **doctor:** a sentence for a count read beside a protection that was not (E70 review 8) ([8421b00](https://github.com/abdelrahmannasr/yadflow/commit/8421b0060e54308632bbfacaf89149eabb9da98c))
66
+ * **doctor:** an id reads as an id, and no sentence pairs two dashes (E70 review 13) ([8a07f2b](https://github.com/abdelrahmannasr/yadflow/commit/8a07f2bd8b99785ed3bcdf192269113c7ac038c4))
67
+ * **doctor:** apply round 16's fixes to their twins as well (E70 review 17) ([f99db88](https://github.com/abdelrahmannasr/yadflow/commit/f99db8823e34dce8eb84c3bde8f87c04385d0f7f))
68
+ * **doctor:** compare artifacts the way every reader of the field does ([75688d9](https://github.com/abdelrahmannasr/yadflow/commit/75688d9208608c1626cbfdbcb274b0e2f3960979))
69
+ * **doctor:** give the missing-default hint E109's two repository actions, from one string (E110) ([2e751a9](https://github.com/abdelrahmannasr/yadflow/commit/2e751a984e18a1faa007caee0488b11454292c33))
70
+ * **doctor:** name folders under epics/ that are not valid epic ids ([1e0e4ac](https://github.com/abdelrahmannasr/yadflow/commit/1e0e4ac6357f03def0362ef5201e39e352b3a40b))
71
+ * **doctor:** never read a count or "not protected" the platform did not prove (E70 review 1) ([4800bff](https://github.com/abdelrahmannasr/yadflow/commit/4800bffbbeb8bebdf8a20f228992c82d88a98028))
72
+ * **doctor:** never rule a cause out and then offer it again (E70 review 29) ([aeef14b](https://github.com/abdelrahmannasr/yadflow/commit/aeef14b152e6941e7681901ce633e87339b1435a))
73
+ * **doctor:** point the legacy BMAD hints at what still works (E3) ([60df2dc](https://github.com/abdelrahmannasr/yadflow/commit/60df2dc168751f27bd6a892698f211550abd18b6))
74
+ * **doctor:** read the GitLab branch itself; a rule on an unprotected branch is no hold (E70 review 2) ([90d8df9](https://github.com/abdelrahmannasr/yadflow/commit/90d8df9581ba9c7f21b528fc119a4fb00e75a774))
75
+ * **doctor:** restore a guard I wrongly called unreachable (E70 review 18) ([dabd9a1](https://github.com/abdelrahmannasr/yadflow/commit/dabd9a1042da5db52e51c48ba5671e833269ed87))
76
+ * **doctor:** say GitHub's flag the same way everywhere; fill the level table (E70 review 9) ([dca372b](https://github.com/abdelrahmannasr/yadflow/commit/dca372bd289461235cab097b08e87561f5f3c0c6))
77
+ * **doctor:** say only what this read leaves possible (E70 review 15) ([328cf0a](https://github.com/abdelrahmannasr/yadflow/commit/328cf0a6a32de5805b60f6f33ff159ba1c8c5d90))
78
+ * **doctor:** say the GitLab repository could not be read, not that your login cannot (E109) ([3a8ffa5](https://github.com/abdelrahmannasr/yadflow/commit/3a8ffa583d6ac7f15270a9c217c77be5700b585c))
79
+ * **doctor:** see a step that carries ONLY the new dial name ([8ad471f](https://github.com/abdelrahmannasr/yadflow/commit/8ad471f2d90ef4d90df6016b92b4064ce867631b))
80
+ * **doctor:** stop the theme checks reporting correct files ([c6c3a0c](https://github.com/abdelrahmannasr/yadflow/commit/c6c3a0c278ccad2734061e1bd04fbb8b578431f6))
81
+ * **doctor:** tell the two reach gaps apart, and check every partly read line (E70 review 25) ([31dcf1d](https://github.com/abdelrahmannasr/yadflow/commit/31dcf1d5fd0a6e7f55dc4ee249b9c9f277b00500))
82
+ * **doctor:** test the GitLab repository 404 on the shape GitLab really sends (E109) ([81f4001](https://github.com/abdelrahmannasr/yadflow/commit/81f4001f518ea9cd65f31bb93f265176244408a9))
83
+ * **doctor:** the banner needs no rule at all, and lint is green again (E70 review 5) ([7830496](https://github.com/abdelrahmannasr/yadflow/commit/783049648722440999cde7ca079f6d61f0cff536))
84
+ * **doctor:** the clause binds to the rule, not to the branch it names (E70 review 26) ([4ea1403](https://github.com/abdelrahmannasr/yadflow/commit/4ea140368d7d71451204f49304b71fba52c4bbf7))
85
+ * **doctor:** the joined GitLab phrase reads as a sentence (E70 review 10) ([f81a423](https://github.com/abdelrahmannasr/yadflow/commit/f81a423bf0b5a672e0441ebfa04f2ac3e7fd18d3))
86
+ * **doctor:** the last paired dashes, and a limit narrower than the code (E70 review 14) ([d67ae31](https://github.com/abdelrahmannasr/yadflow/commit/d67ae3144e6735db23e73b9a9daa54e29e99a0a4))
87
+ * **doctor:** the review round — a finding whose only remedy always failed ([2783186](https://github.com/abdelrahmannasr/yadflow/commit/27831861756450ed0067271a80f08062e3c35b44))
88
+ * **doctor:** the solo line carries the same facts; hedge what is not read (E70 review 4) ([7019585](https://github.com/abdelrahmannasr/yadflow/commit/7019585ec60deaa28f4217f52a531c8e2943e8fa))
89
+ * **doctor:** the split turns on what the read proved, not where the name came from (E70 review 32) ([3930636](https://github.com/abdelrahmannasr/yadflow/commit/3930636ea87f92275c19fa6751c4a5be1ba074c5))
90
+ * **doctor:** the tier framing belongs to a refusal, and the grid reaches every branch (E70 review 21) ([c2377ef](https://github.com/abdelrahmannasr/yadflow/commit/c2377ef37fd0ae9e11f9b6d7b4454c3db23c8e4c))
91
+ * **doctor:** two answers that disagree are not known; a rule elsewhere is not "no rules" (E70 review 7) ([b002fd8](https://github.com/abdelrahmannasr/yadflow/commit/b002fd89fe9d95b402cb422e7491093b89510b4d))
92
+ * **engine:** drop the profile field nothing read, and fix the test seam ([07af526](https://github.com/abdelrahmannasr/yadflow/commit/07af526629684ee5b5c53438b13e2983ccb82bfc))
93
+ * **epic:** close the holes the E42 review found ([574870f](https://github.com/abdelrahmannasr/yadflow/commit/574870f0d6ebfe1d0c5501daa74a7927662fc13e))
94
+ * **epic:** protect the reserved front-zero id, and stop a false type clash ([871f763](https://github.com/abdelrahmannasr/yadflow/commit/871f763bbf0df4ca92f4991b1456db00bb2aecec))
95
+ * **foundation:** close the holes the roadmap-status review found ([69392d4](https://github.com/abdelrahmannasr/yadflow/commit/69392d441b4212448e0e3092eb74dc313e1f19b2))
96
+ * **foundation:** skills that hand-apply the gate know the Foundation, and the preview lists every moved file ([8e20897](https://github.com/abdelrahmannasr/yadflow/commit/8e20897d56c4c047d207fffdd7a644ebb81ae149))
97
+ * **foundation:** the review round — one product level in the guard, and a move that cannot strand ([5bca4ba](https://github.com/abdelrahmannasr/yadflow/commit/5bca4baded95a108018a780fd0c6ec06f1b3c62b))
98
+ * **gate:** `gate status` counts approvals the way the gate counts them ([eda7429](https://github.com/abdelrahmannasr/yadflow/commit/eda7429d6454f93c3ce034456ab61ab6b5afa3a7))
99
+ * **gate:** `gate status` prints the shortfall, and honours a skip only where the gate does ([95c9c2a](https://github.com/abdelrahmannasr/yadflow/commit/95c9c2a49adfcea6f4e8daf13932d386d4c5a75a))
100
+ * **gate:** a hand-edited cap below 1 is not printed; the inherited test says what it checks (E72) ([49dcef7](https://github.com/abdelrahmannasr/yadflow/commit/49dcef760aa00a46ec157cba2f78b90f9103b77f))
101
+ * **gate:** a malformed record in the merged review's own epic no longer stops the merge ([24eec39](https://github.com/abdelrahmannasr/yadflow/commit/24eec393e6b8ddbdefe71944c0045bbccda2dc16))
102
+ * **gate:** a shared roster name is never matched by name; gate open stamps the old PR (E62) ([a2b15eb](https://github.com/abdelrahmannasr/yadflow/commit/a2b15eb0d4519a05abe77ebb2ff64b6039ce9ea9))
103
+ * **gate:** a short-lane review PR does not ask for a contract re-lock it cannot do ([4855f3a](https://github.com/abdelrahmannasr/yadflow/commit/4855f3afaf90a885d3e1ae1c4d1d133857d6d142))
104
+ * **gate:** an exact submission time beats the roster name table; usage and doctor follow the simulation ([4d2c55c](https://github.com/abdelrahmannasr/yadflow/commit/4d2c55c45c7409942287a1b8834f2c58da756e5d))
105
+ * **gate:** an exact submission time continues only that review's records, never the whole name ([beaa5e3](https://github.com/abdelrahmannasr/yadflow/commit/beaa5e35a3aa77e85207b00d271885bddbd69e39))
106
+ * **gate:** claim and keep older records per review, so a closed step never deletes the other person's history ([1ed2070](https://github.com/abdelrahmannasr/yadflow/commit/1ed2070779055ccf610c0ad0012978183c7b08d0))
107
+ * **gate:** close the gaps the E18 review found ([69aa2cf](https://github.com/abdelrahmannasr/yadflow/commit/69aa2cfcf88db681dfb08cc89a200ef58a23a88a))
108
+ * **gate:** close the holes the E76 review found ([e460fb2](https://github.com/abdelrahmannasr/yadflow/commit/e460fb21f8efd9eb34ef1569361973a8297f3321))
109
+ * **gate:** eighth review round — "after the cap", one dead branch, two comments (E73) ([62e47c3](https://github.com/abdelrahmannasr/yadflow/commit/62e47c3181908e49bc69407775b51ad49951f083))
110
+ * **gate:** fifth review round — an approval anywhere is evidence, and every what-if line is conditional (E73) ([5b78858](https://github.com/abdelrahmannasr/yadflow/commit/5b788587187cdce397d36bb9efdbd772cadaaefc))
111
+ * **gate:** fourth review round — the floor wording on every surface, and a cap only ever lowers (E72) ([81dc0d8](https://github.com/abdelrahmannasr/yadflow/commit/81dc0d866118b167ca18d40531abf3ba53a856e8))
112
+ * **gate:** fourth review round — two kinds of line, each said once, and the GitLab gate bot is not a person (E73) ([622c6d6](https://github.com/abdelrahmannasr/yadflow/commit/622c6d66d35df22fde619e09cd69c0dc6de97e3d))
113
+ * **gate:** keep people under a shared roster name apart; read the PR number from its own segment ([b30ba90](https://github.com/abdelrahmannasr/yadflow/commit/b30ba9051a8a4d291b70bad18f47807ac4fee21b)), closes [#2048](https://github.com/abdelrahmannasr/yadflow/issues/2048)
114
+ * **gate:** old approvals stay with their person in every platform order (E62 review) ([8379656](https://github.com/abdelrahmannasr/yadflow/commit/83796566ca4f35452e717b63b9f08c7caf081d4f))
115
+ * **gate:** recognise old approvals exactly, and never pass one that is stale (E62 review) ([58fe6d2](https://github.com/abdelrahmannasr/yadflow/commit/58fe6d295dbfaa795f771c79e1be1f6f0a052800))
116
+ * **gate:** review round — the names check needs a login, and sees a team of one that reads as two (E73) ([65512d0](https://github.com/abdelrahmannasr/yadflow/commit/65512d0decc079c0a76867b8b05065fe3baef37f))
117
+ * **gate:** round-2 review — singular in open-pr's cap, and doc/test wording that still read as enforced (E72) ([64323b0](https://github.com/abdelrahmannasr/yadflow/commit/64323b0695792c7c9e6dc6ccc97fb56f516ff76a))
118
+ * **gate:** second review round — the silent-path test compares ledgers; doc conditions stated whole (E73) ([5580624](https://github.com/abdelrahmannasr/yadflow/commit/5580624d87dcf685eba6cdb2403ffce112b28974))
119
+ * **gate:** seventh review round — the smallest team is the larger of the logins and the names (E73) ([bcbdb32](https://github.com/abdelrahmannasr/yadflow/commit/bcbdb32d3a1d8646999e183aed3b67a481a3ad7d))
120
+ * **gate:** show the capacity cap and hold on the base alone until E73 (E72) ([3da8498](https://github.com/abdelrahmannasr/yadflow/commit/3da849895011ff19d1368499d825a2b9723a5583))
121
+ * **gate:** sixth review round — "no approval" names the window, and a name is "not matched to a login" (E73) ([d592818](https://github.com/abdelrahmannasr/yadflow/commit/d592818b24d4e78d9bf3563398a45fef87447d92))
122
+ * **gate:** the login stamp merges only proven reviews and never stops a merge ([5c80ce9](https://github.com/abdelrahmannasr/yadflow/commit/5c80ce95a0852fcb2d593c0edf7aac80d54f50fd))
123
+ * **gate:** the product-level move waits for its review, a clean checkout, and the default branch ([91193be](https://github.com/abdelrahmannasr/yadflow/commit/91193be19f652db23f6229026db9d81df0f5db4b))
124
+ * **gate:** the review-PR body is the one surface where the count LASTS, so the line dates itself ([6b378fc](https://github.com/abdelrahmannasr/yadflow/commit/6b378fc28a23543da2b67bc1bf27f07f29bded46))
125
+ * **gate:** third review round — no cap on a shortcut pass, one copy of the cap's words (E72) ([81d86c8](https://github.com/abdelrahmannasr/yadflow/commit/81d86c86cea311a66c6658ac951371cc82b9e405))
126
+ * **gate:** third review round — the silent-path test compares the PR records too; one prefix on every site (E73) ([7b3d874](https://github.com/abdelrahmannasr/yadflow/commit/7b3d874c207f103479dc5df84a398cec1ca9fbf4))
127
+ * **history:** a printed [@word](https://github.com/word) is always a real login; GitLab defaults only for an ownerless entry (E68 review 4) ([cadd82b](https://github.com/abdelrahmannasr/yadflow/commit/cadd82bf43c8adecde2aa5aab1dc156f7b7bf708))
128
+ * **history:** count as the gate counts; keep a thread's root; print every field safely (E20 review 2) ([a539bfc](https://github.com/abdelrahmannasr/yadflow/commit/a539bfc595d22bd5e574e04b02d7f1fbcd2efae6))
129
+ * **history:** follow the real thread, print only safe text, judge approvals as gate status does (E20 review) ([2654480](https://github.com/abdelrahmannasr/yadflow/commit/265448010a526656ef818f710ed2e7e63e7f682c))
130
+ * **history:** name an approver by the gate's test; refuse every flag it does not take (PR review 2) ([406dce6](https://github.com/abdelrahmannasr/yadflow/commit/406dce685068993e7e187dbd76e107c6897f0468))
131
+ * **history:** second-review findings for E68, and E67's address-shaped name ([86e34c0](https://github.com/abdelrahmannasr/yadflow/commit/86e34c025dd37e397f16e22fac35485cf52ccaa6))
132
+ * **history:** the whole-PR review — strict settings, JSON refusals, shape done, exact search (E20) ([e9e13ed](https://github.com/abdelrahmannasr/yadflow/commit/e9e13ed4202c723fe3563be4cd254981ecdeb14c))
133
+ * **history:** waive a step by the gate's own test, not its final state (E20 review 3) ([dd5665e](https://github.com/abdelrahmannasr/yadflow/commit/dd5665ede9f4fec14a2b20425e5a59e12cf78009))
134
+ * **hub-bridge:** the gate-sync fragments ship the major their release publishes ([01ac858](https://github.com/abdelrahmannasr/yadflow/commit/01ac8587d5affc4e0f87c27f935b18f1342683c5))
135
+ * **index:** clean a title before unquoting it; drop bidi controls (E111 review 4) ([5ff9755](https://github.com/abdelrahmannasr/yadflow/commit/5ff97552f2af139c9634e2d398f79089ecc271a0))
136
+ * **index:** commit the index only when git holds exactly what it read (E19 review) ([1b354bc](https://github.com/abdelrahmannasr/yadflow/commit/1b354bcf4a5881aa9c74cdc028dec2562bc8418e))
137
+ * **index:** drop control characters from a title (E111 review 3) ([65ac5f7](https://github.com/abdelrahmannasr/yadflow/commit/65ac5f7c567c041c2cb027676440698ddf9e1078))
138
+ * **index:** read a double-quoted title with JSON's escapes; pin every title rule (E111 review 2) ([0a6b820](https://github.com/abdelrahmannasr/yadflow/commit/0a6b82081d63f26953c54a67af14b31ccf164674))
139
+ * **index:** read a YAML-quoted title as YAML does, keep it one line (E111 review) ([972920f](https://github.com/abdelrahmannasr/yadflow/commit/972920ffa7e462da8d79ec747060fa57d9d82b83))
140
+ * **ledger:** the lock loop could never give up — two `continue`s skipped the cap and the sleep ([e66eab6](https://github.com/abdelrahmannasr/yadflow/commit/e66eab61910eb3b4bd7c3f9ba50f9fa9c39b5fa9))
141
+ * **lifecycle:** place an epic in Build, and keep the discovery epic off the ladder ([1c01e0c](https://github.com/abdelrahmannasr/yadflow/commit/1c01e0c8cf7aa2410b12969e43e5e45b5402edf2))
142
+ * **migrate:** name every file the apply writes, and repair a half-made pair ([a3211e3](https://github.com/abdelrahmannasr/yadflow/commit/a3211e3dfc246bbe89ef3bc322fa6be29bd735bb))
143
+ * **migrate:** the --json preview names the product config's mirror partner ([1eb4738](https://github.com/abdelrahmannasr/yadflow/commit/1eb4738c64899db78fad46036603e2fc7b71f99c))
144
+ * **mode:** close the gaps the E10 review found ([afbeca4](https://github.com/abdelrahmannasr/yadflow/commit/afbeca4599f379e0e815a3bb48e253461f9d931a))
145
+ * **mode:** only a login's approval proves a second person; one wiring for the suggestion (E74) ([0bd132f](https://github.com/abdelrahmannasr/yadflow/commit/0bd132f7664645f56dcb182c29721f7a94713245))
146
+ * **next:** an off-route step is not an unknown one, and a phase is not a passed one ([7f08da2](https://github.com/abdelrahmannasr/yadflow/commit/7f08da218463caa7f630a464ba0423bba145c746))
147
+ * **open-pr:** no address, no cross-platform join, no quiet "nobody" (E68 review) ([0d7814e](https://github.com/abdelrahmannasr/yadflow/commit/0d7814e1021dfc73845e65e7403a6ea66d2f9b6d))
148
+ * **people:** a mistyped future approval is not proof even beside a current commit (E74) ([c1b9d7c](https://github.com/abdelrahmannasr/yadflow/commit/c1b9d7c18963133fca92e2eaaa4fdcd76676986e))
149
+ * **people:** ask git for an absolute date, so the count really does read no clock (E71) ([e065734](https://github.com/abdelrahmannasr/yadflow/commit/e0657347462310ef315068a3e9f3ba52d08b2b0a))
150
+ * **people:** close the identity question — `source: 'bridge'` is the proof, and the keyspace is namespaced ([9e055d7](https://github.com/abdelrahmannasr/yadflow/commit/9e055d711a70c2a6b6798dc5f87ec8a53be45158))
151
+ * **people:** the review round — eleven ways a partial read still became a number ([edf858e](https://github.com/abdelrahmannasr/yadflow/commit/edf858e6d3b2f5bd29877fe04517d8bcd5c4cdc8))
152
+ * **people:** validate the date git hands back — a formatter is not a validator ([dc1249a](https://github.com/abdelrahmannasr/yadflow/commit/dc1249aeae31e107eec359494b95e2230a16a4eb))
153
+ * **release:** refuse to ship a file-shape change as anything but a major ([173dc9a](https://github.com/abdelrahmannasr/yadflow/commit/173dc9a76453b0e5e0ec2341ad05458b71d9a085))
154
+ * **release:** the release checks ask semantic-release what a commit releases ([c5de745](https://github.com/abdelrahmannasr/yadflow/commit/c5de7453ed41bb5a6bac514652a857b6db5d7f8a))
155
+ * **risk-map:** close ten review findings in the map, its check and its command ([aafc578](https://github.com/abdelrahmannasr/yadflow/commit/aafc578c43cc2282e5aa837f3f88768cd7e5e30d))
156
+ * **risk-map:** doctor's section sat under threadChecks' comment; stale comments and help alignment ([5258b54](https://github.com/abdelrahmannasr/yadflow/commit/5258b54f352ba1d0276bec098d766e233beee77a))
157
+ * **risk-map:** every pathspec is :(literal) — a map name describes a directory, it never tells git what to do ([6a4ef28](https://github.com/abdelrahmannasr/yadflow/commit/6a4ef28bb105b3129445cef925d420863b7f271b))
158
+ * **risk-map:** first-review findings — a quoted path, a move out, an older check, and a name's own spacing ([016ad87](https://github.com/abdelrahmannasr/yadflow/commit/016ad87d050b611d69b6fb7d48a850dfac17a2a7))
159
+ * **risk-map:** first-review findings — read the base map from any subfolder, and never exit 1 on a trailing comma ([e6ac49f](https://github.com/abdelrahmannasr/yadflow/commit/e6ac49f32f5944d2beddbe3adc0b1b4ee2ca3ed7))
160
+ * **risk-map:** four second-review findings in the PR check and the file list ([c5eb332](https://github.com/abdelrahmannasr/yadflow/commit/c5eb33293b9dde0bfc0509dbcba45e94116646b0))
161
+ * **risk-map:** second-review findings — a failing git step is "not counted", and the check runs from the repo root ([c51a882](https://github.com/abdelrahmannasr/yadflow/commit/c51a882bcac73561b216e936ff495158d050782a))
162
+ * **risk-map:** second-review findings — a newline in a file name, and a merge that hid a real author ([845a341](https://github.com/abdelrahmannasr/yadflow/commit/845a341e08495cfc81dc24998e7bd80190587a62))
163
+ * **risk-map:** third-review finding — a failing git ls-tree is "not counted", not "no map" ([efeffc0](https://github.com/abdelrahmannasr/yadflow/commit/efeffc0e4bf5edfadbcc2a67fbc6b6397e1a63c5))
164
+ * **risk-map:** third-review findings — bytes for every tool in the check, and only the map itself counts as deleted ([ac4569e](https://github.com/abdelrahmannasr/yadflow/commit/ac4569ec8dba85ea39a7659e8b6038e7a1025d89))
165
+ * **setup:** keep a team's edit to .sdlc/config.yaml through yad update (E3) ([86b2034](https://github.com/abdelrahmannasr/yadflow/commit/86b20348a08bb0a82ce5de03bad0ec5347cbc15e))
166
+ * **skills:** the epic.md templates were unreadable by the gates they feed ([96922de](https://github.com/abdelrahmannasr/yadflow/commit/96922de4ae3e08efe8faee2cbff5abe6c468eabc))
167
+ * **skills:** the review gate must open the gate with the engine, not by hand ([f453509](https://github.com/abdelrahmannasr/yadflow/commit/f453509cbcdd0ec7fa9156af9324eb940846efb4))
168
+ * **skip:** close the holes the E39 review found ([33eb17a](https://github.com/abdelrahmannasr/yadflow/commit/33eb17a85f982456549b225603db04747cd27d94))
169
+ * **skip:** close the holes the verified-skip review found ([311e1ca](https://github.com/abdelrahmannasr/yadflow/commit/311e1cab3f439fc3a4752d997bdb2260ac42bf47))
170
+ * **skip:** refuse a skip on a ledger CI owns on a verified Product ([b9b2d1a](https://github.com/abdelrahmannasr/yadflow/commit/b9b2d1a54f7a31deaf75746581beb3e217611555)), closes [#162](https://github.com/abdelrahmannasr/yadflow/issues/162)
171
+ * **state:** a corrupt ledger gets an error with a hint, not a stack trace ([2cda22d](https://github.com/abdelrahmannasr/yadflow/commit/2cda22d76328e373dfc46b072385b02715529b95))
172
+ * **state:** a gate write moves the recorded shape, not just the fields ([6906c57](https://github.com/abdelrahmannasr/yadflow/commit/6906c577251d96ddf583e5fb83dfb265eb985a86))
173
+ * **state:** a short lane has no optional steps, and that is not a broken chain ([136eec8](https://github.com/abdelrahmannasr/yadflow/commit/136eec83888d5915facdf80c9dd073ff56d95513))
174
+ * **state:** close the holes the E41 review found in re-open and debt ([9b8565e](https://github.com/abdelrahmannasr/yadflow/commit/9b8565e165869f5a6b10f5c46c887bc422ce78d2))
175
+ * **state:** keep the product-level role under BOTH spellings, and report drift ([1b9ac44](https://github.com/abdelrahmannasr/yadflow/commit/1b9ac441a6055f2b17422f11c0aee0a025c7b3ba))
176
+ * **state:** make the two names one file, in both directions ([0a842c7](https://github.com/abdelrahmannasr/yadflow/commit/0a842c74560d96c47064009b3ab4714f0f00ab7f))
177
+ * **state:** one rule for "this epic's route never had that step" ([b687048](https://github.com/abdelrahmannasr/yadflow/commit/b687048e49c7bcfa4f512c7e92de31e6dce8f0d7))
178
+ * **state:** shape 6 stamps against the routes that existed when it landed ([939c862](https://github.com/abdelrahmannasr/yadflow/commit/939c86228b20540ad22c621c19b63e4859899647))
179
+ * **state:** the count reports, it does not hold a gate — yet (E7 review round) ([10bc3ff](https://github.com/abdelrahmannasr/yadflow/commit/10bc3ff06816ff6430bc47b8382363d57c6b9380))
180
+ * **state:** the review round — a live writer of `blocked` this change said did not exist ([7136b93](https://github.com/abdelrahmannasr/yadflow/commit/7136b930b10bba4e8ffe03d217e706409bd5153e))
181
+ * **state:** write the work-item type at the top of state.json, not the bottom ([195c03a](https://github.com/abdelrahmannasr/yadflow/commit/195c03aa96f5c12526b22d54c4db9ad9d4a4ef63))
182
+ * **thread:** an epic never owns an artifact its route has no step for ([6725c5a](https://github.com/abdelrahmannasr/yadflow/commit/6725c5ae9dde8e226f34ae1e1d5888fa86811641))
183
+
184
+
185
+ ### Features
186
+
187
+ * **agents:** support agents beyond Claude Code, and guard Cursor too (E11) ([8481398](https://github.com/abdelrahmannasr/yadflow/commit/848139856c5d23cdf52b601d02f7155d5756d9b4))
188
+ * **checks:** guard the Foundation ledger in foundation/ (E75) ([0608e41](https://github.com/abdelrahmannasr/yadflow/commit/0608e41f8a203a633b4ef2e3449711de9201890c)), closes [#162](https://github.com/abdelrahmannasr/yadflow/issues/162)
189
+ * **checks:** guard the Product index as CI-owned on a verified Product (E19) ([5396827](https://github.com/abdelrahmannasr/yadflow/commit/5396827650597341cd98e935c595c73899b4a61f))
190
+ * **checks:** risk-map-check.sh warns on every PR where the risk map went stale ([bc2ada8](https://github.com/abdelrahmannasr/yadflow/commit/bc2ada8707a9499d5ef8afcb1e4259be02980eef))
191
+ * **cli:** add `yad skill` to bind, list and unbind a step's skill ([7b4c9c6](https://github.com/abdelrahmannasr/yadflow/commit/7b4c9c6cdc2e5734a5f670b805003782d877674f))
192
+ * **cli:** the project chooses which skill runs a step (E6) ([a07746e](https://github.com/abdelrahmannasr/yadflow/commit/a07746e327056448f1c3566490cf7d17aa13122d))
193
+ * **cli:** warn before any command reads a project on a newer file shape ([f5695da](https://github.com/abdelrahmannasr/yadflow/commit/f5695da00299169f3bdb34913aa7c90448501510))
194
+ * **cli:** yad epic new — the engine writes an epic's lifecycle (E17) ([92e67d6](https://github.com/abdelrahmannasr/yadflow/commit/92e67d635efddcadbd8f4399dac27b0c56402cbe))
195
+ * **codeowners:** warn when CODEOWNERS is stale (E69) ([6c35d6a](https://github.com/abdelrahmannasr/yadflow/commit/6c35d6a2d854e089561b708c6441616117816cf6))
196
+ * **defer:** yad defer --debt marks a deferral owed back, reminded until paid (E41) ([b20d57d](https://github.com/abdelrahmannasr/yadflow/commit/b20d57dc85abbb8509a6298bb5c98bff66cd827c))
197
+ * **defer:** yad defer and yad undefer set an optional step aside (E37) ([b6f2391](https://github.com/abdelrahmannasr/yadflow/commit/b6f2391df9feb0f9a0b9cf5af74eb928de138767))
198
+ * **dial:** yad dial, yad kill and yad unkill — the advance dial set freely (E34) ([56e8300](https://github.com/abdelrahmannasr/yadflow/commit/56e8300c37839f6a688d821f52ceee9ea682f219))
199
+ * **doctor:** keep the access cause open when GitLab names no default branch (E110) ([ddb8159](https://github.com/abdelrahmannasr/yadflow/commit/ddb8159c792e5bddb42fa135b68e25ab5774a073))
200
+ * **doctor:** name a leftover _bmad/sdlc/ folder (E3) ([5d7b1ab](https://github.com/abdelrahmannasr/yadflow/commit/5d7b1ab4632b5712226057a7d41a796070512bae))
201
+ * **doctor:** name the cause behind a GitLab branch 404 from its body (E109) ([64865d7](https://github.com/abdelrahmannasr/yadflow/commit/64865d71a8449453e05942f0dac69ec413b5e4c0))
202
+ * **doctor:** people:roster-unused says when the roster can go ([eb0c012](https://github.com/abdelrahmannasr/yadflow/commit/eb0c012963af43a15b62dc3c229cd32f7c791a3a))
203
+ * **doctor:** say whether each repo's branch requires an approval (E70) ([e93dd3b](https://github.com/abdelrahmannasr/yadflow/commit/e93dd3b7cbe4ed52fc1d9a9a7b91613c2bfe0cf8))
204
+ * **engine:** lifecycle profiles, with today's chains written down (E5) ([44564d4](https://github.com/abdelrahmannasr/yadflow/commit/44564d44d826265138d6fdc1f5feee5ab5760988))
205
+ * **engine:** the step catalogue, validated in code (E4) ([c3823bf](https://github.com/abdelrahmannasr/yadflow/commit/c3823bf4bed067a91496fe79c8cd490088c9e71c))
206
+ * **epic:** `yad foundation new` — the engine seeds the Product level (E75) ([2cf2241](https://github.com/abdelrahmannasr/yadflow/commit/2cf2241556d8bfef4e6682460c51ab86319024e7))
207
+ * **epic:** the grouping theme tag (E31) ([bf8a31c](https://github.com/abdelrahmannasr/yadflow/commit/bf8a31c880c445dedd1b4abb78f6314971c1cacb))
208
+ * **epic:** yad epic new --parent seeds a threaded change-epic (E42) ([3786ae2](https://github.com/abdelrahmannasr/yadflow/commit/3786ae246ec9b5759de590c72a928e33e2ad7d96))
209
+ * **foundation:** yad foundation status reads roadmap features from the epic ledgers ([e6a4a85](https://github.com/abdelrahmannasr/yadflow/commit/e6a4a853b2f31204ed687b16f0bdba3dd68c245c))
210
+ * **gate:** approvals record the platform's evidence; GitLab's approval time is read ([0e16728](https://github.com/abdelrahmannasr/yadflow/commit/0e167282349f832128757caeda10200617b0a2d7)), closes [#156](https://github.com/abdelrahmannasr/yadflow/issues/156)
211
+ * **gate:** cap the approval count at the active people less one, and record every cap (E72) ([f99e77d](https://github.com/abdelrahmannasr/yadflow/commit/f99e77da98484623d6ed1cb270dcc1dea3a08c1f))
212
+ * **gate:** every surface that reports a gate prints the arithmetic ([0ac5617](https://github.com/abdelrahmannasr/yadflow/commit/0ac56179cd49ab3d66ee2e8642500cd3f420e27c))
213
+ * **gate:** print how many people there are to ask, on every surface a gate reports itself (E71) ([cfabed9](https://github.com/abdelrahmannasr/yadflow/commit/cfabed9521d431b043ab356b46f9f54ec306a005))
214
+ * **gate:** record how a step closed (E18) ([a1c9050](https://github.com/abdelrahmannasr/yadflow/commit/a1c905037061437ecdf6183df26f246cb8cb049b))
215
+ * **gate:** record the platform login on older records while the roster exists ([cc7b02f](https://github.com/abdelrahmannasr/yadflow/commit/cc7b02f36658c5517fcc49b3f464ca1cfeeff048))
216
+ * **gate:** rename the PR ledger too, and guard both names ([c0b8b00](https://github.com/abdelrahmannasr/yadflow/commit/c0b8b00bdf77203346127984f67cce95206ba054))
217
+ * **gate:** say on the closing record when solo mode waived the approvals (E10) ([f733e5e](https://github.com/abdelrahmannasr/yadflow/commit/f733e5e10a9b8ae3c6255e4e724122e9346ac64b))
218
+ * **gate:** say when a gate may not be met — reported, never enforced (E73) ([444b67c](https://github.com/abdelrahmannasr/yadflow/commit/444b67c0e77087d286fab60bd853e1f3272320c0))
219
+ * **gate:** the gate bot converts a verified Product's product level to foundation/ ([ad3bc94](https://github.com/abdelrahmannasr/yadflow/commit/ad3bc94b0a373bd131bb1609afd6cac610aeeef8))
220
+ * **gate:** warn when a Foundation section still holds only its template (E76) ([8a5be38](https://github.com/abdelrahmannasr/yadflow/commit/8a5be38404bcb022cf9e98b10d529815d6bc4ad4))
221
+ * **history:** yad history — list, show, search, all with --json (E20) ([c37c9fe](https://github.com/abdelrahmannasr/yadflow/commit/c37c9fe8c346855c3a04d6921438ccaade336d3f))
222
+ * **index:** `yad index` rebuilds the front door on the default branch (E19) ([5b6dfd6](https://github.com/abdelrahmannasr/yadflow/commit/5b6dfd6f3ae01a5f9409fb63e59f32dad5ab429d))
223
+ * **index:** a title for every work item, carried by the Product index (E111) ([7ab7833](https://github.com/abdelrahmannasr/yadflow/commit/7ab78334eab64153e5d5e7a31939416ff4224f19))
224
+ * **index:** build the Product index from every work item's own files (E19) ([5024d61](https://github.com/abdelrahmannasr/yadflow/commit/5024d61807a4354c6969dedf1d0d87aa01e318c2))
225
+ * **index:** the gate, CI and migrate keep the index; doctor says when it is behind (E19) ([97aba2b](https://github.com/abdelrahmannasr/yadflow/commit/97aba2be1d3c934548c195a5d8b6b1647ba8910b))
226
+ * **lifecycle:** name the six phases, derived from the step ([1b77249](https://github.com/abdelrahmannasr/yadflow/commit/1b77249c197ca70df7f95270004ca94a6b930d6a))
227
+ * **mode:** suggest team mode when the count disagrees with solo (E74) ([4756ef9](https://github.com/abdelrahmannasr/yadflow/commit/4756ef92ecedfe0dda0e5bfa3f2785a10ac6424a))
228
+ * **mode:** yad mode solo|team sets who must approve, and records the change (E10) ([ce4077c](https://github.com/abdelrahmannasr/yadflow/commit/ce4077c5055812f61736924c2f76c903acd6db66))
229
+ * **open-pr:** suggest reviewers from history and CODEOWNERS (E68) ([9214ed9](https://github.com/abdelrahmannasr/yadflow/commit/9214ed90123d55ea1fed59541df9148b0b322ed9))
230
+ * **people:** count active people live, three windows, unknown is never a small number (E71) ([1b186a0](https://github.com/abdelrahmannasr/yadflow/commit/1b186a0125f3b5a1ece5edc85521e0b58596fd59))
231
+ * **platform:** a record names the login gh/glab reports, not the roster's (E62) ([6c2ef4e](https://github.com/abdelrahmannasr/yadflow/commit/6c2ef4ee4df6da9e8f9000055e1aa32359ded0bc))
232
+ * **risk-map:** a directory to risk-level map per code repo, with yad risk-map check|draft and a doctor section ([f3d8115](https://github.com/abdelrahmannasr/yadflow/commit/f3d811547360381409560583cce2e601f1e73cc4))
233
+ * **risk-map:** a high directory asks for an approver who has worked there lately (E67) ([28f4e58](https://github.com/abdelrahmannasr/yadflow/commit/28f4e58903432d4bb1cfa7e45529ad65f840c9b6))
234
+ * **risk-map:** a high directory on the base branch's map adds the high step (E66) ([ad6fcac](https://github.com/abdelrahmannasr/yadflow/commit/ad6fcaca496c7dbc377268a9771bdf18b3737e91))
235
+ * **setup:** install the module config into .sdlc/, not _bmad/sdlc/ (E3) ([da18dac](https://github.com/abdelrahmannasr/yadflow/commit/da18dacc1b02c9dba9f1079aeb26c89286805137))
236
+ * **setup:** let a scripted setup choose its agent directories ([8c13a06](https://github.com/abdelrahmannasr/yadflow/commit/8c13a0672a231b70646501a8b780da85bf503ff6))
237
+ * **skills:** the epic and change templates carry a theme ([8b0c71d](https://github.com/abdelrahmannasr/yadflow/commit/8b0c71ddeaec9ea189e663644f7353a1a3c8246a))
238
+ * **skills:** the skills call the engine instead of writing state.json (E17b) ([f0e0d77](https://github.com/abdelrahmannasr/yadflow/commit/f0e0d77eb97ae20a929f04d5bb4d947546c3d4bc))
239
+ * **skip:** yad skip <epic> <story> --repo skips a whole Build lane (E39) ([261e73e](https://github.com/abdelrahmannasr/yadflow/commit/261e73e360bb31cc35272d7c4f6a06394b713515))
240
+ * **skip:** yad skip and yad unskip name no step (E36) ([abbb4e0](https://github.com/abdelrahmannasr/yadflow/commit/abbb4e080fc2c21c61776f555a5b1c66e2359b53))
241
+ * **state:** a chore lane and a spike lane (E40) ([f521c22](https://github.com/abdelrahmannasr/yadflow/commit/f521c22487e5ad44b029e977ae6716925f4ec731))
242
+ * **state:** a Shape author step is not a gate because it is locked (E34) ([298546e](https://github.com/abdelrahmannasr/yadflow/commit/298546ef6ef67ea1c42cf01178aecc494bd938ef))
243
+ * **state:** a step is optional because the epic's ROUTE says so (E35) ([1641b46](https://github.com/abdelrahmannasr/yadflow/commit/1641b46e6fd3b57526862ce4448c4506ccdce4ec))
244
+ * **state:** a step's gate says how many people it needs (E7) ([314e709](https://github.com/abdelrahmannasr/yadflow/commit/314e70982a0b61927c0a379516d4233c08260b99))
245
+ * **state:** every ledger walker finds the Foundation (E75) ([bf86753](https://github.com/abdelrahmannasr/yadflow/commit/bf867537d17150633faa5a9014df2c4b1e59238c))
246
+ * **state:** give the product settings their new name, keeping the old one beside it ([8d0cf1b](https://github.com/abdelrahmannasr/yadflow/commit/8d0cf1b500a6a15fcbb5e53b7806966bf1457a90))
247
+ * **state:** the Product level — Foundation in the model (E75) ([676bbd1](https://github.com/abdelrahmannasr/yadflow/commit/676bbd1ae4557e0c4eb744f62f75ada74969b36b))
248
+ * **state:** the step-state model, and shape 7 writes it (E38) ([4064067](https://github.com/abdelrahmannasr/yadflow/commit/40640673adae5f2065041d92d431fdda522b6b32))
249
+ * **unblock:** yad unblock clears a recorded blocker (E37) ([5ba73f5](https://github.com/abdelrahmannasr/yadflow/commit/5ba73f560923fcf297ab460a82cca26ee2c1feeb))
250
+ * **update:** name an edited gate-sync fragment left on another major ([b33f9e6](https://github.com/abdelrahmannasr/yadflow/commit/b33f9e61c51101f2e5ebb9756e185ece3ce7de74)), closes [#164](https://github.com/abdelrahmannasr/yadflow/issues/164)
251
+
252
+
253
+ ### BREAKING CHANGES
254
+
255
+ * `yad docs build`, `yad docs deploy` and
256
+ `yad docs sync --refresh` now exit 1 when a site's npm install or build
257
+ fails, or when a site named with --epic/--overview was never generated;
258
+ `yad docs build` also exits 1 when npm is not on PATH. Under --json these
259
+ are refusals (`ok: false`) naming the site. A script that ran them and
260
+ ignored build failures will now stop.
261
+ * every `--json` answer is now the E1 envelope. `yad
262
+ history --json` carries `jsonVersion` instead of `schemaVersion`; `yad
263
+ thread --json` and the review bundles gain `ok`; `yad usage --json`
264
+ wraps the model (`--format json` still prints the bare model); a refusal
265
+ always has `error`, `code` and `hint`; `warnings` is always present. The
266
+ full list is in docs/CLI.md, "--json on every command".
267
+ * the ROUTE line of risk-route.sh and hub-route.sh
268
+ changed; anything parsing it must be updated.
269
+ * in a repo whose refreshed gate has landed, a Verified
270
+ commit from an email nobody listed now passes CI.
271
+ * `yad roster` is removed, and `yad setup` no longer
272
+ collects reviewers or repo owners.
273
+ * `yad usage --json` members carry no `role` or `rostered`,
274
+ and the `dormant` and `reviewer-not-reviewing` flags are no longer raised.
275
+ * review and task PRs no longer request reviewers
276
+ automatically.
277
+ * the owner/reviewer/domain-owner rule no longer holds a
278
+ team gate; one approver does. `defaultReviewers` and the roster shape
279
+ check are gone.
280
+ * file shape 10. An older yadflow reading a chain with a
281
+ re-opened step names that step the blocker of the work after it, and
282
+ re-opens that work when its review passes. See docs/migrations/shape-10.md.
283
+ * file shape 9. An older yadflow fingerprints the whole
284
+ file, so it reads every approval this release records on a file with a
285
+ `status:` line as stale. On a local ledger with mixed versions, that
286
+ holds an open gate for the teammate on the older release. Upgrade
287
+ everyone on the project together. A verified project runs
288
+ `yad migrate --apply` and commits the result; CI brings each state.json
289
+ to shape 9 at its next write.
290
+ * file shape 8. A migrated project keeps its product level
291
+ in `foundation/`, which a 3.x yadflow does not read. Upgrade everyone on
292
+ the project together. On a verified Product, run `yad update` so the
293
+ committed checks guard `foundation/`.
294
+ * **state:** shape 7 is the first file shape that changes a value in place
295
+ rather than adding a key beside an old one, so a 3.x CLI cannot read a migrated
296
+ project: it sees `todo` as an unknown status and reads `skipped` / `satisfied` as
297
+ "not done", which makes a UI-less epic or a change-epic look stuck. This release
298
+ reads every pre-shape-7 project correctly; run `yad migrate --preview` first and
299
+ upgrade everyone on the project. See docs/migrations/shape-7.md.
300
+
301
+ Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
302
+ * file shape 5. Run `yad migrate` to preview, then
303
+ `yad migrate --apply`. See docs/migrations/shape-5.md.
304
+ * project files change shape twice in this release, and both are
305
+ handled by one command. Shape 2 records who writes the ledger as
306
+ `"ledger": "verified" | "local"` in the product settings; shape 3 renames those
307
+ settings from `.sdlc/hub.json` to `.sdlc/product.json`, renames each epic's
308
+ `hub-prs.json` to `product-prs.json`, and gives every reviewer's product-level
309
+ role a second spelling. Nothing is taken away: every old name is still written
310
+ and is still the one read, so a check gate committed in your repository keeps
311
+ working whether or not you have run `yad update`. Run `npx yadflow@<version>
312
+ migrate` to preview — it writes nothing — then `yad migrate --apply`, which backs
313
+ up every file it rewrites. docs/migrations/shape-2.md and shape-3.md explain both.
314
+
315
+ Shape 2 shipped earlier as 3.19.0-next without declaring a break, which meant the
316
+ "run yad migrate first" banner never fired for it. This footer covers both.
317
+
1
318
  # [3.19.0-next.2](https://github.com/abdelrahmannasr/yadflow/compare/v3.19.0-next.1...v3.19.0-next.2) (2026-09-07)
2
319
 
3
320
 
package/README.md CHANGED
@@ -13,8 +13,8 @@ AI builds and a human clears every gate.**
13
13
  > Yadflow doesn't write your code; it governs how AI-written code ships. Keep Cursor, GitHub Copilot,
14
14
  > Claude Code, Continue — or hand-written commits. The zero-dependency `yad` CLI and the CI gates
15
15
  > review the work **no matter who or what produced it.** The workflow skills run today in
16
- > **Claude Code** (plus `.agents`, Zencoder, and OpenCode), and **BMAD is the default packaging,
17
- > not a limitation.**
16
+ > **Claude Code, Codex CLI, Cursor, Gemini CLI, GitHub Copilot, Zencoder and opencode** — see
17
+ > [which agent reads which directory](#which-ai-agents-are-supported).
18
18
 
19
19
  ## The problem
20
20
 
@@ -27,26 +27,26 @@ AI, the harder it gets to keep control of quality, architecture, and accountabil
27
27
 
28
28
  Yadflow puts a **human gate on every step** of the lifecycle. Each step does its work, writes its
29
29
  output to a plain file, and **waits** — it never advances until a human clears its gate (by approving,
30
- or in solo mode by merging your own PR), or, later, once a step has *earned* the right to auto-advance.
30
+ or in solo mode, switched with `yad mode`, by merging your own PR) — or, for a Build step the team set to `auto`, on its own after a clean run.
31
31
  Reviews ride real PR/MRs; all state lives in files you
32
32
  can read, diff, and edit — no database, nothing hidden. The result is a paper trail for every decision
33
33
  and a hard wall between "AI proposed" and "we shipped it."
34
34
 
35
- It installs as a custom [BMAD](https://github.com/bmad-code-org/BMAD-METHOD) module and works across
36
- one product hub + many code repos, solo or team.
35
+ It installs with one command (`npx yadflow setup`) and works across one Product + many code repos,
36
+ solo or team.
37
37
 
38
38
  ## How the workflow looks
39
39
 
40
40
  <!-- Source: docs/diagrams/sdlc-overview.mmd — edit the .mmd and run `npm run diagrams` to regenerate -->
41
- ![Yadflow SDLC overview — setup, human-gated Shape, per-story Build, earned automation](https://raw.githubusercontent.com/abdelrahmannasr/yadflow/main/docs/diagrams/sdlc-overview.svg)
41
+ ![Yadflow SDLC overview — setup, human-gated Shape, per-story Build, automation you switch on](https://raw.githubusercontent.com/abdelrahmannasr/yadflow/main/docs/diagrams/sdlc-overview.svg)
42
42
 
43
43
  **Legend:** 🟨 **artifact** (a step writes a file and stops) · 🟧 **gate** (a human review that must
44
- pass) · 🟦 **earns automation** (a Build step that can later auto-advance once it proves itself) ·
45
- ⬜ **locked** (the engineer review and every Shape step — permanently human).
44
+ pass) · 🟦 **can run on auto** (a Build step the team may set to advance on its own, with `yad dial`) ·
45
+ ⬜ **locked** (the engineer review — always a person).
46
46
 
47
47
  ## Quickstart
48
48
 
49
- From your **product hub** repo (an empty git repo is fine):
49
+ From your **Product** repo (an empty git repo is fine):
50
50
 
51
51
  ```bash
52
52
  npx yadflow setup # 1. guided wizard: install skills, connect repos, wire CI gates
@@ -80,23 +80,75 @@ In one pass it produces:
80
80
 
81
81
  - **The `yad` CLI** — zero-dependency Node (`setup`, `gate`, `commit`, `open-pr`, `ship`, `repo`,
82
82
  `thread`, `reconcile`, `usage`, `doctor`), run via `npx` or a global install.
83
- - **38 workflow skills** installed into your AI assistant — **Claude Code** (`.claude/`) first-class,
84
- plus `.agents`, Zencoder, and OpenCode.
85
- - **`.sdlc/` config** — the product hub, connected repos, reviewer roster, and tool connections
83
+ - **38 workflow skills** installed into your AI assistant — Claude Code, Codex CLI, Cursor,
84
+ Gemini CLI, GitHub Copilot, Zencoder and opencode. See
85
+ [which agent reads which directory](#which-ai-agents-are-supported).
86
+ - **`.sdlc/` config** — the Product, connected repos, and tool connections
86
87
  (design, testing, learning), all as plain JSON you can read and diff.
87
- - **CI gates**, wired into every connected repo and the hub as **GitHub Actions or GitLab CI** —
88
- spec-link, contract-check, verified-commits, build/test/lint, the feature-thread gates, and the
89
- push-on-main **`yad-update-guard`** (which re-checks any direct-to-default commit — e.g. from
88
+ - **CI gates**, wired into every connected repo and the Product as **GitHub Actions or GitLab CI** —
89
+ spec-link, contract-check, verified-commits, build/test/lint, the feature-thread gates, the advisory
90
+ risk-map check (warns when a code repo's `.sdlc/risk-map` — a risk level per directory, no names — is
91
+ stale, says how many approvers a PR asks for — one more when it touches a `high` directory — and names
92
+ who has worked in that directory in the last 30 days), and the push-on-main **`yad-update-guard`** (which re-checks any direct-to-default commit — e.g. from
90
93
  `yad update --push` — with just `verified-commits` + `commit-message`), shipped as CI-agnostic bash
91
94
  under `checks/`.
92
- - **An agent guardrail** on a verified hub — `hooks/ledger-guard.sh`, a harness hook that refuses an
95
+ - **An agent guardrail** on a verified Product — `hooks/ledger-guard.sh`, a harness hook that refuses an
93
96
  agent the CI-owned gate-ledger write at the moment it tries it and names the command that owns the
94
97
  transition, instead of letting it surface as a CI failure twenty minutes later. Harness-agnostic
95
98
  (stdin payload, exit 0 allows / 2 denies) and fails open — the CI gate stays the authority.
96
99
  - **PR/MR templates** and an opt-in CodeRabbit config.
97
100
 
98
101
  Your first `yad-epic` seeds the `epics/EP-<slug>/` ledger — state, approvals, and the contract lock —
99
- so the audit trail starts the moment you begin real work.
102
+ so the audit trail starts the moment you begin real work. `yad epic new <slug>` does the same seeding
103
+ from the CLI when you would rather lay the track before the writing starts.
104
+
105
+ Before any epic, you can also frame the whole product once: `yad foundation new` seeds the
106
+ **Foundation** — the Product level, in `foundation/` — and the `yad-discovery` skill writes its
107
+ sections (purpose, scope, MVP, roadmap, stack, repos). It is optional, and each epic reads its approved
108
+ roadmap.
109
+
110
+ ## Which AI agents are supported
111
+
112
+ An **agent skill** is a folder holding a `SKILL.md` file — instructions the agent loads when the task
113
+ matches. `SKILL.md` is now a format several agents read, and `.agents/skills/` is the directory
114
+ several of them agreed to look in. So one install can serve more than one agent.
115
+
116
+ `yad setup` asks which directories to install into. Pick by the agent you use:
117
+
118
+ | Directory | Agents that read it |
119
+ | --- | --- |
120
+ | `.claude/` | Claude Code. Cursor also reads it for compatibility. |
121
+ | `.agents/` | Codex CLI, Gemini CLI, Cursor, GitHub Copilot |
122
+ | `.cursor/` | Cursor — its own directory. Not needed if you install `.agents/`. |
123
+ | `.gemini/` | Gemini CLI — its own directory. Not needed if you install `.agents/`. |
124
+ | `.zencoder/` | Zencoder |
125
+ | `.opencode/` | opencode — installed as flat `commands/<skill>.md` files, not folders |
126
+
127
+ A fresh setup offers **`.claude,.agents`**, which together cover every agent in the table. A project that already
128
+ has an INSTALL in one of them — a `skills/` folder, or an armed hook entry — is offered that one
129
+ instead; a `.cursor/` holding only Cursor rules is not an install, and is offered the default. Checked against each agent's
130
+ own documentation on 2026-09-16; `yad doctor` prints the same table's verdict for your project.
131
+
132
+ ### The local ledger guard, per agent
133
+
134
+ In **verified mode** — where CI owns the gate ledger — yadflow installs a local guardrail that stops
135
+ an agent hand-editing the gate files, at the moment of the edit rather than twenty minutes later in a
136
+ failed pipeline. It needs a hook that can run *before* a write and refuse it. Two agents have one:
137
+
138
+ | Agent | Wired into | Event |
139
+ | --- | --- | --- |
140
+ | Claude Code | `.claude/settings.json` | `PreToolUse` |
141
+ | Cursor | `.cursor/hooks.json` | `preToolUse` |
142
+
143
+ Cursor answers this kind of hook in JSON rather than by exit code, and treats an empty answer as a
144
+ refusal — so a `.cursor` project also gets a small adapter script, `hooks/ledger-guard-cursor.sh`,
145
+ which always replies properly. Without it the guard would have blocked every file write instead of
146
+ just the gate files.
147
+
148
+ Every other directory gets the script (`hooks/ledger-guard.sh`) and no wiring — they have no such
149
+ hook, so those agents are guarded by CI alone. `yad doctor` says so by name rather than staying
150
+ silent. The Cursor wiring follows Cursor's published hook protocol and has not yet been exercised
151
+ against a live Cursor session.
100
152
 
101
153
  ## Your first five minutes
102
154
 
@@ -116,14 +168,14 @@ Every step is the same contract: *AI proposes → a human decides → the trail
116
168
 
117
169
  ## How it works (in five points)
118
170
 
119
- - **Shape = decide.** Once per epic, in the product hub: epic, architecture + a locked contract,
171
+ - **Shape = decide.** Once per epic, in the Product: epic, architecture + a locked contract,
120
172
  UI, stories, test cases. Always human-gated — nothing auto-advances.
121
173
  - **Build = make it real.** Once per story per code repo: spec → implement → checks → ship.
122
174
  - **Every step stops at a gate.** A human moves it forward (local, or by merging a review PR/MR).
123
175
  <!-- IMAGE: docs/media/pr-gate.png — "The review gate rides a real PR/MR: approve to advance, comment to block." -->
124
- - **Automation is opt-in and earned.** A safe Build step can earn auto-advance after it proves
125
- itself — and a one-command kill switch reverts everything to manual. The engineer review and all
126
- Shape steps are never automatable.
176
+ - **Automation is opt-in.** The team switches a Build step to auto with `yad dial`, which shows that
177
+ step's run record as advice — and `yad kill` holds everything at manual in one command. A review
178
+ gate — the engineer review and every Shape review — is never automatic.
127
179
  - **Everything is files.** State, approvals, the contract lock, the build log — all plain files under
128
180
  `epics/EP-<slug>/`. No database. The audit trail *is* the repo.
129
181
 
@@ -139,7 +191,7 @@ complementary: bring your favorite, and Yadflow wraps the engineering process ar
139
191
  | **Layer** | Writes the code | Governs how it ships |
140
192
  | **Output** | Diffs, completions | Gated artifacts + a file-based audit trail |
141
193
  | **Answers** | "Write this for me" | "Should this merge — and who approved it?" |
142
- | **Review** | You eyeball the diff | Human-gated PR/MR, contract lock, earned automation |
194
+ | **Review** | You eyeball the diff | Human-gated PR/MR, contract lock, switchable automation |
143
195
  | **Fit** | Bring your own | Wraps around all of them |
144
196
 
145
197
  ## Review, made a pairing — and a lesson
@@ -174,6 +226,7 @@ workflow-hygiene flags — derived read-only, so an EM can see how the team actu
174
226
  - **[docs/SKILLS.md](docs/SKILLS.md)** — the catalogue of all 38 agent skills.
175
227
  - **[docs/WALKTHROUGH.md](docs/WALKTHROUGH.md)** — the by-hand, end-to-end path through every phase.
176
228
  - **[CONTRIBUTING.md](CONTRIBUTING.md)** · **[RESEARCH-NOTES.md](RESEARCH-NOTES.md)** · **[RELEASING.md](RELEASING.md)**
229
+ - **[SECURITY.md](SECURITY.md)** — how to report a vulnerability, which versions get fixes, and the supply-chain stance. **[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)** — the community standards for taking part.
177
230
 
178
231
  ---
179
232
 
@@ -0,0 +1,41 @@
1
+ // Every command module, behind ONE dynamic import (E11 review).
2
+ //
3
+ // `yad hook ledger-guard` runs on EVERY file-editing tool call an agent makes, inside its tool
4
+ // loop. It needs `cli/hook.mjs` and nothing else, but a static import list in `bin/yad.mjs` is
5
+ // hoisted and evaluated before any code runs — so the hook was loading all 29 modules of the CLI,
6
+ // measured at ~30ms against ~14ms for what it actually uses, on every single edit.
7
+ //
8
+ // Re-exporting through one module keeps that mechanical: `bin/yad.mjs` awaits this once, after it
9
+ // has already handled `hook`, and every command reads off the result. Nothing here is lazy in
10
+ // itself — importing this file still loads everything, which is exactly right for a command that
11
+ // is about to do real work.
12
+
13
+ export { runSetup } from '../cli/setup.mjs';
14
+ export { reconcile } from '../cli/reconcile.mjs';
15
+ export { gateOpen, gateSync, gateComments, gateStatus, gateCi, gateReview, gateTrailer, gateWalkthrough, gateRepair } from '../cli/gate.mjs';
16
+ export { isValidEpicId, seedableProfiles } from '../cli/epic-state.mjs';
17
+ export { runEpicNew, runFoundationNew, runFoundationStatus } from '../cli/epic.mjs';
18
+ export { runSkillBind, runSkillList, runSkillUnbind } from '../cli/skill.mjs';
19
+ export { runCommit } from '../cli/commit.mjs';
20
+ export { runOpenPr } from '../cli/openpr.mjs';
21
+ export { reviewTrailer, reviewContext, reviewNudge, reviewReconcile, reviewWalkthrough } from '../cli/review.mjs';
22
+ export { runShip } from '../cli/ship.mjs';
23
+ export { runCheckpoint } from '../cli/checkpoint.mjs';
24
+ export { runTidy } from '../cli/tidy.mjs';
25
+ export { runIndex } from '../cli/index-command.mjs';
26
+ export { runHistory, HISTORY_FLAGS } from '../cli/history.mjs';
27
+ export { runRepo } from '../cli/repo.mjs';
28
+ export { runRiskMap } from '../cli/riskmap-command.mjs';
29
+ export { runCodeowners } from '../cli/codeowners-command.mjs';
30
+ export { runDocs } from '../cli/docs.mjs';
31
+ export { runDoctor } from '../cli/doctor.mjs';
32
+ export { runMigrate, warnIfProjectAhead } from '../cli/migrate.mjs';
33
+ export { runNext } from '../cli/next.mjs';
34
+ export { runSkip, runDefer, runUnblock, runLaneSkip } from '../cli/skip.mjs';
35
+ export { runDial, runKill } from '../cli/dial.mjs';
36
+ export { runMode } from '../cli/mode.mjs';
37
+ export { syncStatuses } from '../cli/artifact-status.mjs';
38
+ export { runThread, runReconcile } from '../cli/thread.mjs';
39
+ export { runReport } from '../cli/report.mjs';
40
+ export { runUsage } from '../cli/usage.mjs';
41
+ export { maybeNotifyUpdate } from '../cli/update-notice.mjs';