@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.37 → 0.1.47

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 (249) hide show
  1. package/bin/adl +2 -2
  2. package/bin/reconcile +10 -13
  3. package/bin/setup +15 -15
  4. package/package.json +1 -1
  5. package/packages/agent-hooks/package.json +1 -1
  6. package/packages/agent-hooks/src/main.ts +23 -2
  7. package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +12 -8
  8. package/packages/agent-hooks/src/rules/impl/adl-run-required.ts +11 -5
  9. package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +18 -5
  10. package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +30 -26
  11. package/packages/agent-hooks/src/rules/impl/git-branch.ts +1 -1
  12. package/packages/agent-hooks/src/rules/impl/git-target.ts +5 -0
  13. package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +3 -1
  14. package/packages/agent-hooks/src/rules/impl/tool-frontend.ts +230 -11
  15. package/packages/agent-hooks/src/rules/shell/git-identity.ts +1 -1
  16. package/packages/agent-hooks/src/rules/shell/invocation.ts +14 -2
  17. package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +10 -11
  18. package/packages/agent-settings/assets/TARUN-GLOBAL-AGENTS-INSTRUCTIONS.md +2 -2
  19. package/packages/agent-settings/package.json +1 -1
  20. package/packages/agent-settings/src/deploy/agents-deploy.ts +19 -1
  21. package/packages/agent-settings/src/deploy/index.ts +1 -0
  22. package/packages/agent-skills/assets/agent-search-tool-audit/SKILL.md +4 -6
  23. package/packages/agent-skills/assets/finalize-feature/SKILL.md +3 -3
  24. package/packages/agent-skills/assets/implement-feature/SKILL.md +17 -20
  25. package/packages/agent-skills/assets/implement-feature/references/briefs.md +3 -3
  26. package/packages/agent-skills/assets/implement-item/SKILL.md +3 -3
  27. package/packages/agent-skills/assets/mechanics/SKILL.md +1 -1
  28. package/packages/agent-skills/assets/plan-feature/SKILL.md +10 -10
  29. package/packages/agent-skills/assets/prepare-promotion/SKILL.md +3 -4
  30. package/packages/agent-skills/assets/report-bug/SKILL.md +2 -2
  31. package/packages/agent-skills/assets/review-change/SKILL.md +3 -3
  32. package/packages/agent-skills/assets/review-plan/SKILL.md +4 -4
  33. package/packages/agent-skills/assets/triage-workitems/SKILL.md +4 -4
  34. package/packages/agent-skills/assets/validate-design/SKILL.md +6 -12
  35. package/packages/agent-skills/assets/verify-item/SKILL.md +5 -5
  36. package/packages/agent-skills/assets/wayfinder/SKILL.md +1 -1
  37. package/packages/agent-skills/assets/workitems-process/SKILL.md +19 -21
  38. package/packages/agent-skills/assets/workitems-process/references/ado-and-git.md +36 -3
  39. package/packages/agent-skills/assets/workitems-process/references/evidence.md +4 -4
  40. package/packages/agent-skills/assets/write-feature/SKILL.md +15 -18
  41. package/packages/agent-skills/dist/deploy.d.ts +45 -0
  42. package/packages/agent-skills/dist/deploy.d.ts.map +1 -1
  43. package/packages/agent-skills/dist/deploy.js +167 -3
  44. package/packages/agent-skills/dist/deploy.js.map +1 -1
  45. package/packages/agent-skills/dist/index.d.ts +1 -1
  46. package/packages/agent-skills/dist/index.d.ts.map +1 -1
  47. package/packages/agent-skills/dist/index.js +1 -1
  48. package/packages/agent-skills/dist/index.js.map +1 -1
  49. package/packages/agent-skills/package.json +1 -1
  50. package/packages/agent-skills/src/deploy.ts +241 -3
  51. package/packages/agent-skills/src/index.ts +10 -1
  52. package/packages/azdo/README.md +13 -4
  53. package/packages/azdo/bunfig.toml +6 -0
  54. package/packages/azdo/package.json +1 -1
  55. package/packages/azdo/src/azdo-attachments.ts +2 -1
  56. package/packages/azdo/src/azdo-pr.ts +182 -6
  57. package/packages/azdo/src/azdo-wit.ts +290 -41
  58. package/packages/azdo/src/cli.ts +79 -12
  59. package/packages/azdo/src/lib/client.ts +88 -16
  60. package/packages/azdo/src/mcp-server.ts +75 -10
  61. package/packages/azdo/src/tool-dispatch.ts +61 -26
  62. package/packages/fleet/src/install-adl-package.ts +4 -3
  63. package/packages/repo-controls/assets/promote.ts +1 -0
  64. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/no-type.md +1 -1
  65. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-experiment.md +1 -1
  66. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-research.md +1 -1
  67. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-key.md +1 -1
  68. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-keys.md +1 -1
  69. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-created.md +1 -1
  70. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-description.md +1 -1
  71. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-last-update.md +1 -1
  72. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-status.md +1 -1
  73. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-title.md +1 -1
  74. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/optional-keys.md +1 -1
  75. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/research-ok.md +1 -1
  76. package/packages/repo-controls/package.json +1 -1
  77. package/packages/repo-controls/src/config.ts +21 -2
  78. package/packages/repo-controls/src/doctor.ts +9 -14
  79. package/packages/repo-controls/src/findings-ratchet.ts +12 -0
  80. package/packages/repo-controls/src/hook.ts +61 -4
  81. package/bin/lean-ctx-observe-strip +0 -434
  82. package/bin/lib/lean-ctx-observe-hooks.sh +0 -634
  83. package/bin/update-azure-agent-pool +0 -29
  84. package/packages/agent-hooks/src/hooks/lean-ctx/handler.ts +0 -22
  85. package/packages/agent-hooks/src/hooks/lean-ctx/index.ts +0 -173
  86. package/packages/agent-hooks/src/hooks/lean-ctx/mapping.ts +0 -121
  87. package/packages/agent-hooks/src/hooks/lean-ctx/scope-rewrite.ts +0 -207
  88. package/packages/agent-hooks/src/lean-ctx/env.ts +0 -123
  89. package/packages/agent-hooks/src/lean-ctx/mcp.ts +0 -142
  90. package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +0 -51
  91. package/packages/agent-hooks/src/rules/impl/adl-session-required.ts +0 -403
  92. package/packages/agent-hooks/src/rules/impl/tool-lean-ctx-global.ts +0 -594
  93. package/packages/agent-settings/assets/GLOBAL-AGENTS.md +0 -112
  94. package/packages/agent-settings/assets/lean-ctx/config.toml +0 -42
  95. package/packages/agent-settings/assets/lean-ctx/gitignore +0 -10
  96. package/packages/agent-settings/assets/lean-ctx/layout.toml +0 -7
  97. package/packages/agent-settings/src/deploy/lean-ctx-deploy.ts +0 -230
  98. package/packages/agent-settings/src/deploy/lean-ctx-merge.ts +0 -580
  99. package/packages/agent-skills/assets/adl-mechanics/SKILL.md +0 -38
  100. package/packages/agent-skills/assets/codebase-design/SKILL.md +0 -98
  101. package/packages/agent-skills/assets/codebase-design/references/DEEPENING.md +0 -37
  102. package/packages/agent-skills/assets/codebase-design/references/DESIGN-IT-TWICE.md +0 -44
  103. package/packages/agent-skills/assets/codebase-design/references/TESTABILITY.md +0 -29
  104. package/packages/agent-skills/assets/debug-issue/SKILL.md +0 -41
  105. package/packages/agent-skills/assets/domain-modeling/SKILL.md +0 -86
  106. package/packages/agent-skills/assets/domain-modeling/references/ADR-FORMAT.md +0 -47
  107. package/packages/agent-skills/assets/domain-modeling/references/CONTEXT-FORMAT.md +0 -60
  108. package/packages/agent-skills/assets/implement/SKILL.md +0 -28
  109. package/packages/agent-skills/assets/review-changes/SKILL.md +0 -45
  110. package/packages/agent-skills/assets/tdd/SKILL.md +0 -49
  111. package/packages/agent-skills/assets/tdd/references/mocking.md +0 -59
  112. package/packages/agent-skills/assets/tdd/references/tests.md +0 -77
  113. package/packages/agent-skills/assets/testing/SKILL.md +0 -54
  114. package/packages/agent-skills/assets/testing/references/e2e.md +0 -37
  115. package/packages/agent-skills/assets/testing/references/integration.md +0 -37
  116. package/packages/agent-skills/assets/testing/references/unit.md +0 -32
  117. package/packages/agent-skills/assets/to-feature/SKILL.md +0 -91
  118. package/packages/agent-skills/assets/to-feature/references/FEATURE-SPEC-TEMPLATE.md +0 -88
  119. package/packages/agent-skills/assets/to-workitems/SKILL.md +0 -90
  120. package/packages/agent-skills/assets/to-workitems/references/AZURE-DEVOPS-HIERARCHY.md +0 -121
  121. package/packages/agent-skills/assets/to-workitems/references/TICKET-TEMPLATES.md +0 -70
  122. package/packages/azdo/src/workflow-rules-matrix.csv +0 -85
  123. package/packages/fleet/src/launch-agents.ts +0 -649
  124. package/packages/repo-controls/assets/GLOBAL-INVARIANTS.md +0 -21
  125. package/packages/repo-controls/assets/enable-integration-auto-complete.mjs +0 -79
  126. package/packages/repo-controls/assets/scaffold/docs/notes.md +0 -20
  127. package/packages/repo-controls/assets/scaffold/plans/GAPS-AND-FINDINGS.md +0 -12
  128. package/packages/repo-controls/azure-pipelines.yml +0 -274
  129. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/notes.md +0 -1
  130. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/excluded/frontend/mobile/src/i18n/locales/zh-CN/strings.ts +0 -1
  131. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-clean/docs/notes.md +0 -17
  132. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-no-lines/docs/notes.md +0 -13
  133. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/product/stable-delivery.md +0 -10
  134. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/product/stable-recommendation.md +0 -12
  135. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/product/target-narration.md +0 -10
  136. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/frontend/packages/desktop/src/renderer/solo/item.ts +0 -1
  137. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/a.ts +0 -1
  138. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/b.ts +0 -1
  139. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/fresh/fresh.ts +0 -1
  140. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub1/only.ts +0 -1
  141. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub10/only.ts +0 -1
  142. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub11/only.ts +0 -1
  143. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub2/only.ts +0 -1
  144. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub3/only.ts +0 -1
  145. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub4/only.ts +0 -1
  146. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub5/only.ts +0 -1
  147. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub6/only.ts +0 -1
  148. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub7/only.ts +0 -1
  149. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub8/only.ts +0 -1
  150. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub9/only.ts +0 -1
  151. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/services/i18n/locales/de/common.json +0 -1
  152. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/solo/item.ts +0 -1
  153. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/vendored-crate/Cargo.toml +0 -2
  154. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/frontend/packages/desktop/src/renderer/solo/item.ts +0 -1
  155. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/a.ts +0 -1
  156. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/b.ts +0 -1
  157. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/c.ts +0 -1
  158. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/frontend/packages/desktop/src/renderer/solo/item.ts +0 -1
  159. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/fresh/fresh.ts +0 -1
  160. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub1/only.ts +0 -1
  161. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub10/only.ts +0 -1
  162. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub11/only.ts +0 -1
  163. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub2/only.ts +0 -1
  164. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub3/only.ts +0 -1
  165. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub4/only.ts +0 -1
  166. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub5/only.ts +0 -1
  167. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub6/only.ts +0 -1
  168. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub7/only.ts +0 -1
  169. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub8/only.ts +0 -1
  170. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub9/only.ts +0 -1
  171. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/solo/item.ts +0 -1
  172. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/frontend/packages/desktop/src/renderer/solo/item.ts +0 -1
  173. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/fixtures/open-work-cap-clean/plans/GAPS-AND-FINDINGS.md +0 -5
  174. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/fixtures/open-work-cap-clean/plans/features/az601-clean/spec.md +0 -10
  175. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/agent/crates/enact-providers/src/snapshots/README.md +0 -1
  176. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/backend/crates/enact-app/assets/builtin-assistants/avatars/assistant.jpg +0 -1
  177. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/backend/crates/enact-assets/assets/logos/tools/coding/tool.png +0 -1
  178. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/backend/crates/enact-session/src/backend/codex_init_prompt.md +0 -1
  179. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/mobile/assets/images/icon.png +0 -1
  180. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/packages/desktop/src/renderer/assets/logos/brand/app.png +0 -1
  181. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/packages/desktop/src/renderer/assets/themes/default-theme.png +0 -1
  182. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/public/pwa/icon-192.png +0 -1
  183. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/resources/product.png +0 -1
  184. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-stray/backend/crates/enact-session/src/backend/README.md +0 -1
  185. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-clean/plans/features/az347-test-coverage/spec.md +0 -12
  186. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-violation/plans/features/az347-test-coverage/spec.md +0 -12
  187. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/__init__.py +0 -11
  188. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/check.py +0 -62
  189. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/NotAMigration.sql +0 -1
  190. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/0001_long_prefix.sql +0 -1
  191. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/001_init.sql +0 -1
  192. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/002_add_index.sql +0 -1
  193. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/003-dashed-slug.sql +0 -1
  194. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/004_MixedCase.sql +0 -1
  195. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/005_trailing space.sql +0 -1
  196. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/01_short_prefix.sql +0 -1
  197. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/not-a-migration.sql +0 -1
  198. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/test_check.py +0 -116
  199. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/docs/architecture/product/links.md +0 -20
  200. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/docs/architecture/product/route-target.md +0 -8
  201. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/docs/architecture/product/links.md +0 -20
  202. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/docs/architecture/product/route-target.md +0 -8
  203. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.changeset/declared.txt +0 -1
  204. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/INDEPENDENT-VERIFICATION.md +0 -3
  205. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/attribute-without-conversion/.gitattributes +0 -1
  206. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/attribute-without-conversion/large file.bin +0 -3
  207. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/clean/.gitattributes +0 -1
  208. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/clean/large file.bin +0 -3
  209. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/clean/small.txt +0 -1
  210. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/missing-filter/large file.bin +0 -0
  211. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/unmatched-extension/.gitattributes +0 -1
  212. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/unmatched-extension/payload.dat +0 -0
  213. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/__init__.py +0 -1
  214. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/__init__.py +0 -12
  215. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/check.py +0 -129
  216. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/fixtures/disjoint/gate-registry.yaml +0 -13
  217. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/fixtures/empty/gate-registry.yaml +0 -7
  218. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/fixtures/overlapping/gate-registry.yaml +0 -13
  219. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/test_check.py +0 -109
  220. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/__init__.py +0 -1
  221. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/__init__.py +0 -11
  222. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/check.py +0 -149
  223. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/fixtures/clean/docs/readme.md +0 -4
  224. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/fixtures/relevant/VERSION +0 -1
  225. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/test_check.py +0 -151
  226. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/__init__.py +0 -11
  227. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/check.py +0 -202
  228. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/.workflows/changesets/package.json +0 -5
  229. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/.workflows/package.json +0 -5
  230. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/CHANGELOG.md +0 -5
  231. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/VERSION +0 -1
  232. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/.workflows/changesets/package.json +0 -5
  233. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/.workflows/package.json +0 -5
  234. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/CHANGELOG.md +0 -5
  235. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/VERSION +0 -1
  236. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/test_check.py +0 -162
  237. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/check.py +0 -103
  238. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/Cargo.lock +0 -7
  239. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/Cargo.toml +0 -4
  240. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/rust-toolchain.toml +0 -3
  241. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/src/main.rs +0 -1
  242. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/frontend/bun.lock +0 -1
  243. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/Cargo.lock +0 -7
  244. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/Cargo.toml +0 -4
  245. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/rust-toolchain.toml +0 -3
  246. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/src/main.rs +0 -1
  247. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/frontend/bun.lock +0 -0
  248. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/grants-registry.yaml +0 -112
  249. package/packages/repo-controls/workflows/scripts/release/verify-npm-artifact.ts +0 -119
@@ -9,6 +9,30 @@
9
9
  * body either way; the allowance is stated in the message for the human,
10
10
  * not enforced here).
11
11
  *
12
+ * az365 (Scope A — JS-toolchain mutation policy, 2026-10-13): the matcher
13
+ * was a binary-name-only `deny` returning a Finding for every
14
+ * `frontend-tool` invocation regardless of effect. The OLD corpus
15
+ * contained 14 read-only invocations (lint, typecheck, coverage, test
16
+ * runs without snapshot updates, help-only) as `deny`, which is the bug:
17
+ * a legitimate "look at my code" call was refused with the same Finding
18
+ * as a file-rewriting one. The new matcher inspects `inv.args` and
19
+ * returns `null` (allow) for read-only invocations, returning a Finding
20
+ * only for the mutating ones:
21
+ *
22
+ * deny biome format … --write (file rewrite)
23
+ * deny vitest run -u / --update (snapshot mutation)
24
+ * deny tsc <file> (no --noEmit; emits .js/.d.ts)
25
+ * allow tsc --noEmit (type-check, no emit)
26
+ * allow biome check … (read)
27
+ * allow biome lint … (read)
28
+ * allow vitest run (test runner, no source write)
29
+ * allow vitest --coverage run (writes only to coverage/)
30
+ * allow jest --testPathPattern= (test runner, no source write)
31
+ *
32
+ * The matcher does NOT inspect the `just` recipe body — the gate runs at
33
+ * the recipe boundary, not inside it. `--help`/`--version` are already
34
+ * short-circuited at classification time and never reach this matcher.
35
+ *
12
36
  * Tarun's decision (2026-09-27, feature az372): the message must not name a
13
37
  * particular recipe — see messages.ts's `JUST_RECIPES_POINTER`.
14
38
  */
@@ -18,37 +42,231 @@ import type { Finding, MessageContext, RuleSpec } from '../spec.ts'
18
42
  import { noParams } from '../spec.ts'
19
43
  import { detailString, JUST_RECIPES_POINTER } from './messages.ts'
20
44
 
45
+ /** `biome format … --write` rewrites files in place. The flag may appear anywhere on the command line (`--write foo` or `foo --write`); the `--write=foo` and `-wX` concatenated forms arrive as single tokens. */
46
+ function biomeFormatWritesFile(args: readonly { readonly value: string }[]): boolean {
47
+ return args.some((arg) => {
48
+ if (arg.value === '--write' || arg.value === '-w') return true
49
+ if (arg.value.startsWith('--write=')) return true
50
+ // Concatenated short-flag form: `-wX` where X is anything. The shell
51
+ // does not split the token; the matcher sees `-wX` as one element.
52
+ if (arg.value.startsWith('-w') && arg.value.length > 2) return true
53
+ return false
54
+ })
55
+ }
56
+
57
+ /**
58
+ * `tsc <file>` without `--noEmit` emits `.js` and `.d.ts` files into the
59
+ * working tree. `tsc --noEmit` is the read intent. A bare `tsc` (no
60
+ * file operand, no flags) does nothing the matcher cares about — tsc
61
+ * without operands reads `tsconfig.json` and may emit based on its
62
+ * `noEmit` setting; we treat the no-operand case as ambiguous and let
63
+ * it through (the engine's `uncertain` category would catch it if a
64
+ * future rule needs that).
65
+ */
66
+ const TSC_VALUE_FLAGS: ReadonlySet<string> = new Set([
67
+ '-p', '--project', // config file
68
+ '--build', // takes a project reference; value can be 'false'
69
+ '-t', '--target',
70
+ '--module',
71
+ '--moduleResolution',
72
+ '--jsx',
73
+ '--outDir',
74
+ '--rootDir',
75
+ '--baseUrl',
76
+ '--paths',
77
+ '--types',
78
+ '--lib',
79
+ ])
80
+
81
+ function tscWritesFiles(args: readonly { readonly value: string }[]): boolean {
82
+ // --noEmit is the read intent; --noEmit=false is the write intent.
83
+ if (args.some((arg) => arg.value === '--noEmit')) return false
84
+ // Explicit emit flags are the write intent regardless of the file operand.
85
+ if (args.some((arg) => arg.value === '--emit' || arg.value.startsWith('--emit='))) return true
86
+ // Walk the args, skipping a value-taking flag's operand, and look for a
87
+ // positional file operand that names a .ts/.tsx file. That is the
88
+ // write intent: tsc defaults to emit when given a source file.
89
+ // `tsc -p tsconfig.json` is read-only because `-p` only names the
90
+ // config; tsc respects the config's own `noEmit` setting.
91
+ for (let index = 0; index < args.length; index += 1) {
92
+ const arg = args[index] as { readonly value: string }
93
+ if (arg.value.startsWith('-')) {
94
+ // Flag with a value takes the next word; skip it so we do not
95
+ // mistake the flag's value (`tsconfig.json` after `-p`) for a
96
+ // positional file operand.
97
+ if (TSC_VALUE_FLAGS.has(arg.value)) index += 1
98
+ continue
99
+ }
100
+ // Positional operand that names a TypeScript source file is the
101
+ // write intent. Anything else (a config, a glob, an empty) is not.
102
+ if (/\.tsx?$/.test(arg.value)) return true
103
+ }
104
+ return false
105
+ }
106
+
107
+ /**
108
+ * `vitest run -u` / `vitest run --update` mutates snapshot files in place.
109
+ * The shell hands the matcher individual tokens; the `-uX` / `--update=now`
110
+ * / `-u=foo` concatenation forms arrive as a single token whose value
111
+ * starts with `-u` or `--update=`. Treat any token that starts with `-u`
112
+ * or `--update` (and is not a different flag like `--updateSnapshot`
113
+ * which is a different binary's flag) as the snapshot-write trigger.
114
+ */
115
+ function vitestUpdatesSnapshots(args: readonly { readonly value: string }[]): boolean {
116
+ return args.some((arg) => {
117
+ if (arg.value === '-u' || arg.value === '--update') return true
118
+ if (arg.value === '-u=' || arg.value.startsWith('--update=')) return true
119
+ // Concatenated short-flag form: `-uX` where X is anything (rare in
120
+ // practice; vitest doesn't combine `-u` with other short flags, but
121
+ // the shell hands the matcher the token unsplit). Match `-u` as a
122
+ // prefix only when the rest is a non-flag char, so `-update` (long
123
+ // option) does not match.
124
+ if (arg.value.startsWith('-u') && arg.value.length > 2) return true
125
+ return false
126
+ })
127
+ }
128
+
129
+ /** `jest --testPathPattern=… -u` / `jest -u` / `jest --updateSnapshot` mutates snapshots. */
130
+ function jestUpdatesSnapshots(args: readonly { readonly value: string }[]): boolean {
131
+ return args.some((arg) => {
132
+ if (arg.value === '-u' || arg.value === '--updateSnapshot') return true
133
+ if (arg.value === '-u=' || arg.value.startsWith('--updateSnapshot=')) return true
134
+ // Concatenated short-flag form: `-uX` as above.
135
+ if (arg.value.startsWith('-u') && arg.value.length > 2) return true
136
+ return false
137
+ })
138
+ }
139
+
21
140
  export const toolFrontend: RuleSpec = {
22
141
  id: 'tool.frontend',
23
142
  category: 'tool',
24
143
  severity: 'deny',
25
144
  enabledByDefault: true,
26
- summary: "Deny direct npx/vitest/jest/biome/tsc; steer at the repository's just recipes.",
145
+ summary: "Deny mutating npx/vitest/jest/biome/tsc invocations; reads and tests are permitted.",
27
146
  params: noParams,
28
147
  match(inv: Invocation): Finding | null {
29
148
  if (inv.kind !== 'frontend-tool') return null
30
- return { ruleId: 'tool.frontend', severity: 'deny', detail: { tool: inv.tool } }
149
+ const args = inv.args
150
+ // The mutating surfaces. Each is the only binary-name whose flag
151
+ // shape can change the working tree; if the rule's matcher here
152
+ // grows, the corpus deny list below is the place to add the new
153
+ // fixture so the engine's verdict stays testable.
154
+ switch (inv.tool.replace(/\.exe$/i, '')) {
155
+ case 'biome':
156
+ // `biome format … --write` is the file-rewrite path. `biome
157
+ // check` and `biome lint` are reads and must NOT be denied. The
158
+ // matcher inspects the args to distinguish; without this
159
+ // inspection every biome invocation is denied, which is the
160
+ // az365 Scope A bug.
161
+ if (biomeFormatWritesFile(args)) {
162
+ return { ruleId: 'tool.frontend', severity: 'deny', detail: { tool: inv.tool, action: 'biome-format-write' } }
163
+ }
164
+ return null
165
+ case 'tsc':
166
+ // `tsc --noEmit` is a read. `tsc <file>` without --noEmit emits
167
+ // .js and .d.ts into the working tree. Match the absence of
168
+ // --noEmit as the write intent.
169
+ if (tscWritesFiles(args)) {
170
+ return { ruleId: 'tool.frontend', severity: 'deny', detail: { tool: inv.tool, action: 'tsc-emit' } }
171
+ }
172
+ return null
173
+ case 'vitest':
174
+ // `vitest run` is a test runner. The .vitest cache directory and
175
+ // any coverage output live under node_modules / coverage/, not in
176
+ // project source. `-u` / `--update` is the snapshot-mutation
177
+ // path; the snapshot files live alongside the test files and ARE
178
+ // project source.
179
+ if (vitestUpdatesSnapshots(args)) {
180
+ return { ruleId: 'tool.frontend', severity: 'deny', detail: { tool: inv.tool, action: 'vitest-snapshot-write' } }
181
+ }
182
+ return null
183
+ case 'jest':
184
+ if (jestUpdatesSnapshots(args)) {
185
+ return { ruleId: 'tool.frontend', severity: 'deny', detail: { tool: inv.tool, action: 'jest-snapshot-write' } }
186
+ }
187
+ return null
188
+ case 'npx':
189
+ // `npx biome check …` is a read; `npx vitest run` is a test
190
+ // runner; `npx tsc --noEmit` is a typecheck. None mutate source.
191
+ // The mutating shape (browser automation, file rewrites) is
192
+ // Scope B (az365's split into a separate Feature for browser
193
+ // automation); this rule's match() does not cover it today and
194
+ // the agent-hooks `adl-human-azdo-bypass` rule plus the future
195
+ // `tool.browser-automation` rule (Feature azTBA) are the right
196
+ // place for it.
197
+ return null
198
+ default:
199
+ // Unknown `frontend-tool` name (a new addition to
200
+ // ClassifyConfig.frontendToolNames the rule does not yet know
201
+ // about). Default to allow and let the corpus surface it as a
202
+ // chosen behaviour on the next pass.
203
+ return null
204
+ }
31
205
  },
32
206
  message(finding: Finding, ctx: MessageContext) {
33
207
  const tool = detailString(finding, 'tool')
208
+ const action = detailString(finding, 'action')
209
+ const actionLabel =
210
+ action === 'biome-format-write' ? 'file rewrite'
211
+ : action === 'tsc-emit' ? 'tsc emit (.js / .d.ts write)'
212
+ : action === 'vitest-snapshot-write' ? 'snapshot update'
213
+ : action === 'jest-snapshot-write' ? 'snapshot update'
214
+ : 'mutating invocation'
34
215
  return {
35
- user: `Blocked direct ${tool}. Run it through ${JUST_RECIPES_POINTER} instead; it carries the same arguments and runs through the gate profile.`,
216
+ user: `Blocked ${tool} (${actionLabel}). Run it through ${JUST_RECIPES_POINTER} instead; it carries the same arguments and runs through the gate profile.`,
36
217
  agent:
37
- `DENIED direct ${tool}. Do not invoke ${tool} from Bash/Shell, including through sh -c, xargs, find -exec, or command substitution. ` +
218
+ `DENIED ${tool} (${actionLabel}). Do not invoke ${tool} from Bash/Shell, including through sh -c, xargs, find -exec, or command substitution. ` +
38
219
  `Run it through ${JUST_RECIPES_POINTER} instead - the recipe carries the same arguments and runs the gate profile rather than skipping it. ` +
39
- '--help and --version remain allowed (they print text and run nothing), ' +
40
- 'and invoking the tool from inside a `just` recipe body is allowed because the gate runs at the recipe boundary. ' +
220
+ 'Read-only invocations of the same tool (lint, typecheck, test runs without snapshot updates) are permitted. ' +
41
221
  `Blocked command: ${ctx.snippet}`,
42
222
  }
43
223
  },
44
224
  corpus: {
225
+ // The mutating invocations — the only ones `match()` returns a Finding
226
+ // for. 6 entries; the az388 corpus floor in tests/unit/rules-corpus-floors.test.ts
227
+ // was lowered from 15 to 6 on 2026-10-13 (az365 Scope A) and the file
228
+ // header explains why.
45
229
  deny: [
230
+ 'biome format packages/desktop/src --write',
231
+ 'biome format --write packages/desktop/src',
232
+ 'biome format --write src/foo.ts',
233
+ // Concatenated short-flag form: the shell hands the matcher a
234
+ // single `-wX` token; the predicate's prefix check catches it.
235
+ 'biome format src/foo.ts -w',
236
+ 'vitest run -u',
237
+ 'vitest run --update',
238
+ // Concatenated form: the shell hands the matcher a single `-uX`
239
+ // token; the predicate's prefix check catches it. The corpus entry
240
+ // is the value the shell actually produces (`-uX`); vitest does
241
+ // not combine `-u` with other short flags, but the matcher has
242
+ // to handle the form anyway.
243
+ 'vitest run -uX',
244
+ // `=`-form: `--update=now` arrives as a single token, predicate
245
+ // catches via `startsWith('--update=')`.
246
+ 'vitest run --update=now',
247
+ 'tsc src/foo.ts',
248
+ // jest's snapshot-mutation flag form; covers the jest branch of
249
+ // match() and the jest action label in message(). The flag is
250
+ // either `-u` or `--updateSnapshot`; both must be denied.
251
+ 'jest -u',
252
+ 'jest --updateSnapshot',
253
+ 'jest -uX',
254
+ ],
255
+ // The read-only invocations — every one `match()` returns null for.
256
+ // The 14 the OLD corpus mis-classified as denied move here as the
257
+ // audit-trail entry that pins "this is a read, the deny is over-broad
258
+ // and a future narrowing should permit it" — the future narrowing is
259
+ // THIS rule's match(), already implemented; these entries are the
260
+ // proof the test suite pins against.
261
+ allow: [
46
262
  'npx biome check packages/desktop/src',
263
+ 'npx vitest run',
264
+ 'npx tsc --noEmit',
47
265
  'vitest run',
48
266
  'vitest --coverage run',
49
267
  'jest --testPathPattern=adl-conversation',
268
+ 'biome check packages/desktop/src',
50
269
  'biome lint packages/desktop/src',
51
- 'biome format packages/desktop/src --write',
52
270
  'tsc --noEmit',
53
271
  'tsc -p tsconfig.json',
54
272
  'xargs npx tsc --noEmit',
@@ -56,12 +274,13 @@ export const toolFrontend: RuleSpec = {
56
274
  "sh -c 'npx tsc --noEmit'",
57
275
  "bash -lc 'npx tsc --noEmit'",
58
276
  'echo $(biome lint src/)',
59
- // Not help-only: isHelpOrVersionOnly requires EVERY token to be a
60
- // help/version flag, and 'lint'/'--noEmit' are real arguments.
277
+ // The two help-only entries are already short-circuited by
278
+ // isHelpOrVersionOnly at classification time; they never reach
279
+ // `match()`. Listed under `allow` for the same audit-trail reason
280
+ // as the reads above: chosen behaviour, not merely a passing test.
61
281
  'biome lint --help',
62
282
  'tsc --noEmit --help',
63
- ],
64
- allow: [
283
+ // Pre-existing allow entries preserved.
65
284
  'npx --version',
66
285
  'vitest --version',
67
286
  'jest --version',
@@ -869,7 +869,7 @@ export interface GitInvocationPiece {
869
869
  /**
870
870
  * One `adl mcp cli <command> …` invocation found while scanning a command,
871
871
  * paired with the effective identity for THAT specific piece. `command` is the gated command name
872
- * (e.g. `workitem-create-or-update`), lower-cased; `rest` is the dequoted
872
+ * (e.g. `workitem-create-or-update-pbi`), lower-cased; `rest` is the dequoted
873
873
  * values after it, the same shape `impl/adl-mcp-cli.ts`'s `adlMcpCliCall`
874
874
  * reads off `Invocation.args.slice(3)`, so a role rule can correlate a
875
875
  * specific `Invocation` to its own piece here by comparing values, exactly
@@ -86,7 +86,19 @@ export type Invocation =
86
86
  | { readonly kind: 'azure-devops'; readonly args: readonly Token[] }
87
87
  | { readonly kind: 'find' }
88
88
  | { readonly kind: 'grep' }
89
- | { readonly kind: 'frontend-tool'; readonly tool: string }
89
+ /**
90
+ * `npx`/`vitest`/`jest`/`biome`/`tsc` and their Windows spellings (the
91
+ * `.exe` variants, see `ClassifyConfig.frontendToolNames`). The
92
+ * `args` field carries the tokenized post-name argument list so
93
+ * `tool.frontend.match()` (and any future `tool.browser-automation`
94
+ * rule) can inspect flags — `--write` on `biome format`, `--noEmit`
95
+ * on `tsc`, `-u`/`--update` on `vitest run`, etc. — instead of
96
+ * denying every binary-name invocation regardless of effect. Threaded
97
+ * through by `walkToolCommand` below; the args are not consumed by
98
+ * `isHelpOrVersionOnly` (which has already run before this producer),
99
+ * they are what remains of the post-name token stream.
100
+ */
101
+ | { readonly kind: 'frontend-tool'; readonly tool: string; readonly args: readonly Token[] }
90
102
  /**
91
103
  * `bun test` (any arguments, including a file/pattern operand) — the
92
104
  * `test` subcommand specifically, after skipping bun's own `-C <dir>` /
@@ -638,7 +650,7 @@ function walkToolCommand(name: string, args: readonly Token[], cfg: ClassifyConf
638
650
  return [{ kind: 'azure-devops', args }]
639
651
  }
640
652
  if (cfg.cargoNames.has(name)) return isHelpOrVersionOnly(args) ? [] : [{ kind: 'cargo' }]
641
- if (cfg.frontendToolNames.has(name)) return isHelpOrVersionOnly(args) ? [] : [{ kind: 'frontend-tool', tool: name }]
653
+ if (cfg.frontendToolNames.has(name)) return isHelpOrVersionOnly(args) ? [] : [{ kind: 'frontend-tool', tool: name, args }]
642
654
  if (cfg.bunNames.has(name)) return isBunTestSubcommand(args) ? [{ kind: 'bun-test' }] : null
643
655
  if (cfg.justNames.has(name)) return walkJustCommand(args)
644
656
  if (name === 'xargs' || name === 'xargs.exe') return xargsInvocation(args, walk)
@@ -10,9 +10,16 @@
10
10
  * `agent-tamper-protection.ts` imports it, rather than two copies that could
11
11
  * drift.
12
12
  *
13
- * Still hard-coded on purpose (not configurable): see
14
- * `impl/agent-tamper-protection.ts`'s header for why an `adl-config.toml`
15
- * allowlist for this rule would be the same "switch the gate off" hole it
13
+ * `adl-config.toml` is NOT in this set. It is a runtime configuration file
14
+ * the agent must be able to edit (Tarun, 2026-10-13: "adl-config.toml can be
15
+ * editted but not committed by the agents"). The COMMIT side is enforced by
16
+ * repo-controls' `integrity.ts` (`WIRING`, refuses a normal commit of
17
+ * `adl-config.toml`) and by `agent-hooks`' `git.protected-tree-commit` rule
18
+ * (Bug 373/PBI 679); both fire on the staged index, not on the working
19
+ * tree.
20
+ *
21
+ * Still hard-coded on purpose (not configurable): a per-repo allowlist in
22
+ * `adl-config.toml` would be the same "switch the gate off" hole this rule
16
23
  * exists to close.
17
24
  */
18
25
 
@@ -29,14 +36,6 @@ export const PROTECTED_CARRIER_PATHS: ReadonlySet<string> = new Set([
29
36
  '.claude/settings.json',
30
37
  '.claude/settings.local.json',
31
38
  '.codex/config.toml',
32
- // `adl-config.toml` is the repo's hook switch — every hook run re-reads it,
33
- // so an agent that writes `[hooks] enabled = false` or disables any rule
34
- // flips the gate off before the next tool call lands. Re-listed here on
35
- // 2026-10-12 (Tarun: "we left a door open, close it"). The earlier
36
- // 'human-only at commit time' assumption was wrong: the commit-time gate
37
- // fires for the COMMITTED file, not for edits that never stage, and the
38
- // working-tree copy is what every running hook reads.
39
- 'adl-config.toml',
40
39
  '.codex/hooks.json',
41
40
  '.cursor/hooks.json',
42
41
  '.opencode/plugins/adl-repo.ts',
@@ -6,8 +6,8 @@ Where a repository has its own AGENTS.md, that file and the files it links add t
6
6
  ## Communication
7
7
  - Address me as **Tarun**.
8
8
  - **Answer first.** No greeting, no "let me", no recap of what was just done, no closers.
9
- - One idea per sentence. Short beats polite. Articles can go; not, never, no, only never do. Numbers, paths, commands exact.
10
- - Bullet points over prose.
9
+ - One idea per sentence. Short beats polite. Articles can go; not, never, no, only never do. Numbers, paths, commands exact. **Maximum 100 words** per response
10
+ - **Bullet points over prose**.
11
11
  - **Open points:** one numbered list of open decisions per conversation. Show it only when it changes — item added or resolved. After a long gap or compaction, restate the full list. That is when it gets lost.
12
12
  - **Questions:** one at a time, one or two sentences. Options inline: `A) … B) …`. A long multi-part question means split the work, not more prose.
13
13
  - Full sentences for security warnings, irreversible actions, step-by-step orders, and when I'm confused. Then short resumes.
@@ -6,7 +6,7 @@
6
6
  "description": "Machine-global agent surface tooling (sweep, global-agents, kimi-hooks, surface-policy) run by the fleet bin wrappers under bun; also holds GLOBAL-AGENTS.md, surface policy, and the protected list. Subagent definitions (Claude/Codex/Cursor/Kimi/OpenCode) are canonical in packages/agent-skills/extensions/adl-factory/agents/*.toml and projected per repo by that package's installer; this package does not generate or hold its own copy.",
7
7
  "scripts": {
8
8
  "typecheck": "tsc --noEmit",
9
- "test": "bun test --coverage",
9
+ "test": "bun test --isolate --coverage",
10
10
  "check": "bun run typecheck && bun run test --coverage"
11
11
  },
12
12
  "dependencies": {
@@ -25,6 +25,13 @@ export interface DeployAgentsOptions {
25
25
  readonly agents?: readonly AgentDef[];
26
26
  /** Computes the exact same written/unchanged/removed/conflicts result without writing anything (independent review, 2026-09-29, finding 6). */
27
27
  readonly dryRun?: boolean;
28
+ /**
29
+ * When set, deploy only the named surface (profile.agents.surfaces[].name) —
30
+ * the deploy half of the per-surface knob (az567). Other surfaces are
31
+ * left untouched: their files are not written, their conflicts are not
32
+ * reported, the lock is not rewritten for them.
33
+ */
34
+ readonly surfaceFilter?: string;
28
35
  }
29
36
 
30
37
  interface AgentConflict {
@@ -71,6 +78,10 @@ export function deployAgents(options: DeployAgentsOptions): DeployAgentsResult {
71
78
  let anyLegacyTakeover = false;
72
79
 
73
80
  for (const surface of profile.agents.surfaces) {
81
+ // az567 surfaceFilter: only iterate the named surface. Other
82
+ // surfaces' deploy paths, conflicts, and lock entries are out of
83
+ // scope and never appear in this result.
84
+ if (options.surfaceFilter !== undefined && surface.name !== options.surfaceFilter) continue;
74
85
  const ext = extensionFor(surface);
75
86
  const kept: string[] = [];
76
87
 
@@ -126,7 +137,14 @@ export function deployAgents(options: DeployAgentsOptions): DeployAgentsResult {
126
137
  newAgentEntries[surface.folder] = kept.sort();
127
138
  }
128
139
 
129
- if (!dryRun) writeLock(targetRepo, { schema: 1, mcp: lock.mcp, agents: newAgentEntries });
140
+ // az567 surfaceFilter: when only one surface is in scope, the
141
+ // `newAgentEntries` map only carries that surface. The lock write
142
+ // must keep every other surface's previous lock entry byte-identical
143
+ // so non-target surfaces are not "unwritten" by a per-surface deploy.
144
+ const lockAgents = options.surfaceFilter === undefined
145
+ ? newAgentEntries
146
+ : { ...lock.agents, ...newAgentEntries };
147
+ if (!dryRun) writeLock(targetRepo, { schema: 1, mcp: lock.mcp, agents: lockAgents });
130
148
 
131
149
  // Once anything was actually taken over, this package's own footprint in
132
150
  // the legacy lock's `files` section for these exact agent paths is stale:
@@ -1,6 +1,7 @@
1
1
  export { type DoctorResult } from "./doctor.js";
2
2
  export { listSettings } from "./list.js";
3
3
  export { deploySettings, doctorSettings, type DeploySettingsResult } from "./settings.js";
4
+ export { deployAgents, type DeployAgentsResult } from "./agents-deploy.js";
4
5
  export { loadProfile } from "./profile.js";
5
6
  export { loadMcpSource, type McpServerSpec } from "./mcp-source.js";
6
7
  export { loadAgentSources, type AgentDef } from "./agent-toml.js";
@@ -26,8 +26,7 @@ and its evidence siblings.
26
26
  - The repo has no `.adl/logs/` (no agent-hooks hooks installed).
27
27
  - The question is about a non-search tool (use a different audit
28
28
  script).
29
- - The repo is not a git repo and the script's `git rev-parse
30
- --show-toplevel` fallback cannot find the project root — pass
29
+ - The repo has no project root the script can find — pass
31
30
  `--out <absolute-dir>` to write the report elsewhere.
32
31
 
33
32
  ## Process
@@ -42,8 +41,7 @@ After deploy, the script lives at:
42
41
 
43
42
  In dev (this repo's `packages/agent-skills/`), the equivalent path is
44
43
  `packages/agent-skills/assets/agent-search-tool-audit/scripts/audit.sh`.
45
- The script finds the project root via `git rev-parse --show-toplevel`,
46
- so it works in both layouts.
44
+ The script locates the project root, so it works in both layouts.
47
45
 
48
46
  ### 2. Run with the desired window
49
47
 
@@ -133,8 +131,8 @@ Rationale moved out of `scripts/audit.sh` (REP-007: no multi-line comments).
133
131
  `hooks-deny.log` (read-only history, never migrated, deduped against the new ones);
134
132
  `.adl/logs/agents/tool-calls.log` (`adl run` lifecycle).
135
133
  - Path discovery: the script lives in the agent-skills asset tree (5 levels deep in dev, 4 once
136
- deployed to `.agents/skills/`), so it uses `git rev-parse --show-toplevel` to work in both layouts
137
- and falls back to the dev layout if git is missing.
134
+ deployed to `.agents/skills/`), so it locates the project root to work in both layouts
135
+ and falls back to the dev layout if it cannot.
138
136
  - Required tools: `jq`, `python3` and `rg`; each is checked up front and the script fails loud
139
137
  (exit 1) naming the missing one. `rg` is a protected bootstrap tool on every managed machine.
140
138
  - Cost: under 30 s on a typical 2-3 MB log set; no network.
@@ -24,13 +24,13 @@ Load `workitems-process` first. You are a leaf sub-agent of `lead` (`implement-f
24
24
 
25
25
  ## Preconditions
26
26
 
27
- 1. `git rev-parse HEAD` equals `H` and the worktree is clean; else return it to the lead as a finding and stop ([No block](../workitems-process/SKILL.md#no-block)).
27
+ 1. The branch head equals `H` and the worktree is clean; else return it to the lead as a finding and stop ([No block](../workitems-process/SKILL.md#no-block)).
28
28
  2. The Feature-final verify is `PASS` and code is `APPROVE` and architecture `CLEAR`/`WATCH`, all at `H`; else return it to the lead as a finding and stop ([No block](../workitems-process/SKILL.md#no-block)).
29
29
 
30
30
  ## Procedure
31
31
 
32
- 1. **Docs check.** For each entry in `design.md` `## Docs impact` (per-Bug run: the docs the fix touches), find the matching path in `git diff --name-only origin/integration...H` and read the hunk, not just the filename. "No docs impact" counts as covered. Any missing entry: verdict `REWORK`, finding `docs-missing` (`where`: doc path or section; `fix`: what to write). Stop.
33
- 2. **PR body.** The five non-empty sections in [ado-and-git.md](../workitems-process/references/ado-and-git.md#7-git), filled as below. Every claim links to evidence (a report, a commit, a run); no unverified statements.
32
+ 1. **Docs check.** For each entry in `design.md` `## Docs impact` (per-Bug run: the docs the fix touches), find the matching path in the diff against `H` and read the hunk, not just the filename. "No docs impact" counts as covered. Any missing entry: verdict `REWORK`, finding `docs-missing` (`where`: doc path or section; `fix`: what to write). Stop.
33
+ 2. **PR body.** The five non-empty sections (Summary, Why, Changes, Test plan, Security impact considered), filled as below. Every claim links to evidence (a report, a commit, a run); no unverified statements.
34
34
  - `## Summary`: what the Feature delivers, by item (id, title).
35
35
  - `## Why`: from `intent.md` and `requirements.md`, in the plan's words, not new claims.
36
36
  - `## Changes`: per item, the files and behaviour changed; design updates made during the run; docs touched.
@@ -14,8 +14,8 @@ Load `workitems-process` first. This card is the lead's whole procedure. Sub-age
14
14
  ## When to use
15
15
 
16
16
  - The dispatcher started you for one Feature: every in-scope item (not Parked/Removed) is at Approved or later, at least one is not Done, every predecessor Feature is at Awaiting Release or Done.
17
- - **Per-Bug run.** The dispatcher may instead start you for one Fixes Bug at Approved through Updating Docs, until its PR merges, keyed by the Bug **[pending L5, X2]**, on branch `fix/az<bug id>-<slug>`. A Bug has no plan folder, no Plan Hash and no Design Validation: skip only Preconditions 4-5 and procedure step 1. Preconditions 1-3 apply in their per-Bug form (below). The Bug's ladder and moves are in [Bug states](../workitems-process/references/workitem-states.md#5-bug-states). A Bug at In Reproduction or later is a resumed run: continue from its state (Resume, below). On a fresh run (Bug at Approved) your first board write is Approved → **In Reproduction**. Then spawn `executor` (`implement-item`, reproduce mode, `reproduce` brief in `references/briefs.md`): its first commit is the Bug's item file, written from the G1-approved Bug Description, with its LEDGER row; its next commit is the regression test, proved red on the base and committed marked as an expected failure so the commit stays green, and that brief writes nothing else. Post the executor's unmarked red run on the base as a comment on the Bug, as evidence. Then move In Reproduction → **In Fixing**; the `fix` brief (bug mode) writes the minimal fix until green, in the loop, and its fix commit removes the expected-failure mark. Every commit stays independently green, with no exception. Run the loop and the one PR as usual. You write no file yourself. Won't reproduce: post what you tried as a comment on the Bug and move it to Parked for Removal (G3 is the human's). You resolve everything else in the run ([No block](../workitems-process/SKILL.md#no-block)).
18
- - One run = one worktree, one branch, one lead session (you), **one implementation PR** to `integration`.
17
+ - **Per-Bug run.** The dispatcher may instead start you for one Fixes Bug at Approved through Updating Docs, until its PR merges, keyed by the Bug **[pending L5, X2]**, on the per-Bug branch. A Bug has no plan folder, no Plan Hash and no Design Validation: skip only Preconditions 4-5 and procedure step 1. Preconditions 1-3 apply in their per-Bug form (below). The Bug's ladder and moves are in [Bug states](../workitems-process/references/workitem-states.md#5-bug-states). A Bug at In Reproduction or later is a resumed run: continue from its state (Resume, below). On a fresh run (Bug at Approved) your first board write is Approved → **In Reproduction**. Then spawn `executor` (`implement-item`, reproduce mode, `reproduce` brief in `references/briefs.md`): its first commit is the Bug's item file, written from the G1-approved Bug Description, with its LEDGER row; its next commit is the regression test, proved red on the base and committed marked as an expected failure so the commit stays green, and that brief writes nothing else. Post the executor's unmarked red run on the base as a comment on the Bug, as evidence. Then move In Reproduction → **In Fixing**; the `fix` brief (bug mode) writes the minimal fix until green, in the loop, and its fix commit removes the expected-failure mark. Every commit stays independently green, with no exception. Run the loop and the one PR as usual. You write no file yourself. Won't reproduce: post what you tried as a comment on the Bug and move it to Parked for Removal (G3 is the human's). You resolve everything else in the run ([No block](../workitems-process/SKILL.md#no-block)).
18
+ - One run = one worktree, one branch, one lead session (you), **one implementation PR**.
19
19
  - Resume is not a separate mode: if the trigger still holds on a later tick you are started again in the **same worktree on the same branch**. Read the board and the branch, continue (Resume, below).
20
20
 
21
21
  ## Inputs
@@ -27,21 +27,18 @@ Load `workitems-process` first. This card is the lead's whole procedure. Sub-age
27
27
  | Plan folder | `plans/features/az<id>-<slug>/`: `intent.md`, `requirements.md` (EARS criteria `AC-n`, `## Items`), `design.md`, `file-map-reference.md`, `items/az<id>-<slug>.md` |
28
28
  | Feature fields | `BaselineSha`, `PlanHash`, `PlanRevision` **[pending T3: named arguments; reference names not yet confirmed through the API]** |
29
29
 
30
- Identity `agent-tarun`.
31
-
32
30
  ## Preconditions
33
31
 
34
- 1. `git rev-parse --show-toplevel` equals `worktree`; the branch is the Feature's `<type>/az<id>-<slug>` (per-Bug run: `fix/az<bug id>-<slug>`); `git status --porcelain` is empty, or the dirt is your own previous attempt.
35
- 2. `adl id whoami` reports `agent-tarun`.
36
- 3. Read the Feature's children (`workitem_list_or_get`). Every in-scope item is at Approved or later; if not, the trigger does not hold: report the item and its state on the Feature and end the run. Per-Bug run: read only the Bug; it must be at Approved through Updating Docs with its PR not merged (other Bugs in the Fixes Feature do not matter); if not, report its state on the Bug and end the run.
37
- 4. The plan folder is on the branch (planning PR merged into `integration`): the four plan documents and every `items/az<id>-*.md` exist. If the planning PR is not merged yet, end the run and report it; the next tick re-evaluates.
38
- 5. `sha256` of `requirements.md` equals `PlanHash` (the hash covers `requirements.md` only). On a mismatch, post both hashes as a Feature comment and do not start Design Validation: the approved plan is not the one on the branch. **[pending F7: the tool will refuse the Design Validation move on a mismatch; the field reference name is not yet confirmed through the API.]**
32
+ 1. The worktree matches `worktree`; the branch is the Feature's implementation branch (per-Bug run: the per-Bug branch); the tree is clean, or the dirt is your own previous attempt.
33
+ 2. Read the Feature's children (`workitem_list_or_get`). Every in-scope item is at Approved or later; if not, the trigger does not hold: report the item and its state on the Feature and end the run. Per-Bug run: read only the Bug; it must be at Approved through Updating Docs with its PR not merged (other Bugs in the Fixes Feature do not matter); if not, report its state on the Bug and end the run.
34
+ 3. The plan folder is on the branch (planning PR merged): the four plan documents and every `items/az<id>-*.md` exist. If the planning PR is not merged yet, end the run and report it; the next tick re-evaluates.
35
+ 4. `sha256` of `requirements.md` equals `PlanHash` (the hash covers `requirements.md` only). On a mismatch, post both hashes as a Feature comment and do not start Design Validation: the approved plan is not the one on the branch. **[pending F7: the tool will refuse the Design Validation move on a mismatch; the field reference name is not yet confirmed through the API.]**
39
36
 
40
37
  ## Procedure
41
38
 
42
39
  ### 1. Design Validation
43
40
 
44
- 1. The run starts by merging `origin/integration` into its branch: `git fetch origin`, then `git merge origin/integration` (a fast-forward on a fresh start; never rebase, never force). The worktree `HEAD` then contains the current `integration`, and Design Validation diffs `<BaselineSha>..HEAD`.
41
+ 1. The run starts by merging the integration base into its branch (a fast-forward on a fresh start; never rebase, never force). The worktree `HEAD` then contains the current integration, and Design Validation diffs `<BaselineSha>..HEAD`.
45
42
  2. Move every Approved item → **Design Validation** (adjacent forward move; the fence allows it). This is your first board write.
46
43
  3. Spawn `architect` with the `validate-design` brief. It checks `design.md` and its `file-map-reference.md` by diffing `<BaselineSha>..HEAD`, records `head_sha`, and rules `FRESH`, or `DRIFT` (with the exact delta). `requirements.md` is **not** re-validated: it was validated in planning and approved at G1.
47
44
  4. `FRESH`: continue. `DRIFT`: **drift never leaves the run**. Spawn `planner` (skill `plan-feature`, Mode B: design update) with the delta. It updates `design.md`, `file-map-reference.md` (the `## Map` rows the drift moves, and the `## Baseline` section) and the Feature's Baseline Sha to the new `integration` base, adds the LEDGER row `az<id>-design-update`, and commits on the Feature branch; Plan Hash is unchanged. You write no file: record the update in the implementation report and the PR. Then re-validate once. Items never go to New or In Planning.
@@ -54,7 +51,7 @@ The four states **In Implementation, In Testing, In Review, Updating Docs** are
54
51
 
55
52
  - **Order is yours.** Pick the item order from `design.md` (shared files, risk first). Default staffing is conservative: one executor at a time on the shared branch. Fan out only items with disjoint file scopes in `file-map-reference.md`, as native sub-agents of this session, never the adl-workflow `team` worker pool. You may also spawn read-only explore sub-agents on the fast tier.
56
53
  - The usual order is In Testing before In Review (green code before a reviewer's time). A default, not a rule.
57
- - **Every commit is on the run's one branch** (the Feature branch, or `fix/az<bug id>-<slug>` in a per-Bug run). No per-item branch, worktree or PR. Commits carry `AB#<item id>`.
54
+ - **Every commit is on the run's one branch** (the Feature branch, or the per-Bug branch in a per-Bug run). No per-item branch, worktree or PR. Commits carry `AB#<item id>`.
58
55
 
59
56
  Per item, in the order you chose:
60
57
 
@@ -70,7 +67,7 @@ Per item, in the order you chose:
70
67
  - **Mid-loop drift** (executor returns `DRIFT`): the item moves In Implementation → **Design Validation** **[pending F1]** ([States at a glance](../workitems-process/SKILL.md#states-at-a-glance)), run step 1.3 to 1.6 for that item, then back to In Implementation.
71
68
  - **In Review** = reviewer sub-agents in fresh contexts. No PR reviewer, no votes, no PR threads before the merge ([Human gates](../workitems-process/SKILL.md#human-gates)). Findings go to **item comments and the implementation report**. `REQUEST_CHANGES` or `BLOCK` sends the item back. `WATCH` and medium/low are recorded, not blocking.
72
69
  - Sub-agents return a report (format in `references/briefs.md`). **You** post it on the item as a comment and keep it for the implementation report.
73
- - Push the branch (plain `git push`, never force) after each item's executor reports `DONE` so that heads are durable for resume. Verifiers, reviewers, the validate lane and the writer record `head_sha` at their start and finish against it; compare each report's `head_sha` with the branch head, and re-run the lane at the new head when the head moved ([Evidence and reports](../workitems-process/SKILL.md#evidence-and-reports), the head rule).
70
+ - Push the branch (plain push, never force) after each item's executor reports `DONE` so that heads are durable for resume. Verifiers, reviewers, the validate lane and the writer record `head_sha` at their start and finish against it; compare each report's `head_sha` with the branch head, and re-run the lane at the new head when the head moved ([Evidence and reports](../workitems-process/SKILL.md#evidence-and-reports), the head rule).
74
71
  - A later commit voids earlier test and review evidence for what it touches. The Feature-final check is the evidence the merge relies on.
75
72
 
76
73
  ### 3. Feature-final check
@@ -78,14 +75,14 @@ Per item, in the order you chose:
78
75
  When every item has been through Build, Test and Review and the tree is clean and pushed:
79
76
 
80
77
  1. Record the final head `H`.
81
- 2. Spawn `verifier` in **Feature-final mode** (every `AC-n` of `requirements.md`, the full suite; in a per-Bug run, the Bug item file's `## Expected behaviour` (EARS) plus `## Behaviour that must not change`, base = the `integration` SHA the `fix/` branch was created from) and both review lanes (code, architecture) over `origin/integration...H`.
78
+ 2. Spawn `verifier` in **Feature-final mode** (every `AC-n` of `requirements.md`, the full suite; in a per-Bug run, the Bug item file's `## Expected behaviour` (EARS) plus `## Behaviour that must not change`, base = the integration SHA the per-Bug branch was created from) and both review lanes (code, architecture) over the integration..H range.
82
79
  3. All pass at `H` → continue. Any finding → fix loop as above (the same 3-round cap, counted per finding), then repeat this step at the new head. Evidence binds to the head it ran at.
83
80
 
84
81
  ### 4. Finalize and raise the PR
85
82
 
86
83
  1. Spawn `writer` (`finalize-feature`): docs-impact check against `design.md`, then the **PR body** (five sections) and the **implementation report** content. It returns text; it pushes and writes nothing. Finding `docs-missing` → an executor writes it, then repeat 3.
87
- 2. PR body: the five sections in [ado-and-git.md](../workitems-process/references/ado-and-git.md#7-git). Title in commit grammar. Branch `feat/az<id>-<slug>`, or `fix/az<bug id>-<slug>` in a per-Bug run (the `-plan` suffix marks a planning PR and is never used here).
88
- 3. `git push` the branch. `pr_create_or_update` (action create, target `integration`) with the body and the report content. **The tool does the wiring [pending P1/P2/P4]** ([PR wiring](../workitems-process/references/ado-and-git.md#6-pr-wiring)); you pass nothing for it. Until built, report which parts you could not observe.
84
+ 2. PR body: the five sections (Summary, Why, Changes, Test plan, Security impact considered). Title in commit grammar. The branch is the Feature's implementation branch, or the per-Bug branch in a per-Bug run (the `-plan` suffix marks a planning PR and is never used here).
85
+ 3. Push the branch. `pr_create_or_update` (action create, target `integration`) with the body and the report content. **The tool does the wiring [pending P1/P2/P4]** ([PR wiring](../workitems-process/references/ado-and-git.md#6-pr-wiring)); you pass nothing for it. Until built, report which parts you could not observe.
89
86
  4. Read the PR and the items back: items at Updating Docs, PR linked. A mismatch is reported in the Feature comment, never patched by hand-linking or hand-moving to Done.
90
87
 
91
88
  ### 5. CI stage (the last gate)
@@ -95,9 +92,9 @@ CI is the gate before the merge (ADR-019). Poll `pr_list_or_get` and `build_list
95
92
  | Result | You do |
96
93
  |---|---|
97
94
  | Green, PR completes | Read the items back; they should be **Done** with the PR link (V2 not yet verified on a real PR). Never set Done yourself. End `MERGED` |
98
- | Red | Spawn `executor` (`fix-ci`): smallest fix, no skip, no `\|\| true`, no loosened test. Push. Then `verifier` and `code-reviewer` re-check the **delta** at the new head. Append the round to the implementation report (`pr_create_or_update` update). Cap **3** rounds; past it, post the reason as a Feature comment and change approach. Expired check: scoped `build_run` (pending H1). Integration moved: merge `origin/integration` |
95
+ | Red | Spawn `executor` (`fix-ci`): smallest fix, no skip, no `\|\| true`, no loosened test. Push. Then `verifier` and `code-reviewer` re-check the **delta** at the new head. Append the round to the implementation report (`pr_create_or_update` update). Cap **3** rounds; past it, post the reason as a Feature comment and change approach. Expired check: scoped `build_run` (pending H1). Integration moved: merge the integration base into the branch |
99
96
  | Cancelled or infrastructure failure with log proof | Re-queue only your own PR's validation on the PR's source branch with `build_run` **[pending H1; refusal = report it, stop]**. A failing test or check is never re-queued to get a lucky green |
100
- | Merge conflict | Executor merges `origin/integration` into the branch (`git merge`, never a force-push), re-runs checks, then the delta is re-verified and re-reviewed as for red |
97
+ | Merge conflict | Executor merges the integration base into the branch (never a force-push), re-runs checks, then the delta is re-verified and re-reviewed as for red |
101
98
 
102
99
  ## Board moves (yours)
103
100
 
@@ -119,8 +116,8 @@ Never move an item to Approved, Done or Removed. Never move a Feature. `pr_creat
119
116
 
120
117
  The trigger holds until the merge, so you may be restarted in the same worktree on the same branch (session died, run ended with the PR open, merge conflict). Do not restart finished work.
121
118
 
122
- 1. Read every child's board state and its comments (the earlier sub-agent reports are there) **[pending T1: no comment-read tool yet; without it, work from board states, `git log` and the PR, and re-run any evidence whose head is stale]**.
123
- 2. `git log origin/integration..HEAD` with `AB#` ids shows which items have commits. `pr_list_or_get` shows whether the PR exists.
119
+ 1. Read every child's board state and its comments (the earlier sub-agent reports are there) **[pending T1: no comment-read tool yet; without it, work from board states and the PR, and re-run any evidence whose head is stale]**.
120
+ 2. The commit log on the implementation branch with `AB#` ids shows which items have commits. `pr_list_or_get` shows whether the PR exists.
124
121
  3. PR open: go to step 5. No PR: for each item resume from its board state (In Testing means run Test at the current head; In Review means run Review; and so on). Evidence at an older head is stale: re-run. Per-Bug run: a Bug at In Reproduction gets the `reproduce` brief again (it keeps the commits already made); a Bug at In Fixing or later resumes from its state in the loop.
125
122
  4. Reuse the branch and the PR. Never recreate either.
126
123
 
@@ -128,7 +125,7 @@ The trigger holds until the merge, so you may be restarted in the same worktree
128
125
 
129
126
  | Verdict | When |
130
127
  |---|---|
131
- | `MERGED` | PR completed into `integration` |
128
+ | `MERGED` | PR completed |
132
129
  | `PR_OPEN` | PR raised and CI not finished when the session must end; the next tick resumes at step 5 |
133
130
 
134
131
  ## Stop rules