@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.10 → 0.1.26

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 (413) hide show
  1. package/bin/adl +2 -2
  2. package/bin/git +17 -18
  3. package/bin/git-ado +27 -26
  4. package/bin/git-defaults +173 -0
  5. package/bin/health-check +8 -1
  6. package/bin/kimi-hooks +1 -1
  7. package/bin/lib/adl-package.sh +257 -0
  8. package/bin/lib/bun-compile-build.sh +1 -1
  9. package/bin/lib/fleet-host.sh +62 -0
  10. package/bin/lib/lean-ctx-observe-hooks.sh +9 -9
  11. package/bin/reconcile +693 -470
  12. package/bin/reconcile-host +121 -0
  13. package/bin/setup +219 -0
  14. package/bin/shell-path-policy +15 -5
  15. package/bin/sync-and-reconcile +79 -68
  16. package/bin/validate-manifest +46 -51
  17. package/package.json +2 -12
  18. package/packages/agent-hooks/README.md +14 -9
  19. package/packages/agent-hooks/assets/hooks.json +0 -20
  20. package/packages/agent-hooks/package.json +1 -2
  21. package/packages/agent-hooks/src/cli/args.ts +1 -1
  22. package/packages/agent-hooks/src/cli/doctor.ts +6 -58
  23. package/packages/agent-hooks/src/deploy/deploy.ts +12 -41
  24. package/packages/agent-hooks/src/deploy/doctor.ts +8 -11
  25. package/packages/agent-hooks/src/deploy/index.ts +14 -14
  26. package/packages/agent-hooks/src/deploy/json-merge.ts +7 -8
  27. package/packages/agent-hooks/src/deploy/legacy-lock.ts +2 -2
  28. package/packages/agent-hooks/src/deploy/list.ts +1 -1
  29. package/packages/agent-hooks/src/deploy/lock.ts +31 -12
  30. package/packages/agent-hooks/src/deploy/profile.ts +3 -4
  31. package/packages/agent-hooks/src/deploy/source.ts +1 -1
  32. package/packages/agent-hooks/src/gating/config.ts +10 -24
  33. package/packages/agent-hooks/src/gating/root.ts +3 -3
  34. package/packages/agent-hooks/src/hooks/briefing/handler.ts +2 -2
  35. package/packages/agent-hooks/src/hooks/briefing/index.ts +27 -287
  36. package/packages/agent-hooks/src/hooks/contract.ts +17 -17
  37. package/packages/agent-hooks/src/hooks/crg/background.ts +27 -0
  38. package/packages/agent-hooks/src/hooks/crg/index.ts +7 -6
  39. package/packages/agent-hooks/src/hooks/log.ts +8 -10
  40. package/packages/agent-hooks/src/hooks/user-prompt-submit/match.ts +1 -1
  41. package/packages/agent-hooks/src/hooks/user-prompt-submit/tokenizer.ts +1 -1
  42. package/packages/agent-hooks/src/hooks/user-prompt-submit/vector.ts +6 -5
  43. package/packages/agent-hooks/src/hosts/registry.ts +1 -1
  44. package/packages/agent-hooks/src/log/adl-dir.ts +44 -0
  45. package/packages/agent-hooks/src/log/writer.ts +16 -2
  46. package/packages/agent-hooks/src/main.ts +7 -41
  47. package/packages/agent-hooks/src/pre-tool-use/handler.ts +71 -82
  48. package/packages/agent-hooks/src/rules/engine.ts +13 -17
  49. package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +3 -3
  50. package/packages/agent-hooks/src/rules/impl/adl-git-credential-bypass.ts +12 -14
  51. package/packages/agent-hooks/src/rules/impl/adl-git-identity.ts +28 -28
  52. package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +8 -9
  53. package/packages/agent-hooks/src/rules/impl/adl-human-azdo-bypass.ts +56 -59
  54. package/packages/agent-hooks/src/rules/impl/adl-identity.ts +16 -23
  55. package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +19 -16
  56. package/packages/agent-hooks/src/rules/impl/adl-pr-complete-pending.ts +2 -2
  57. package/packages/agent-hooks/src/rules/impl/adl-pr-review-role.ts +9 -12
  58. package/packages/agent-hooks/src/rules/impl/adl-pr-role.ts +5 -7
  59. package/packages/agent-hooks/src/rules/impl/adl-run-required.ts +411 -0
  60. package/packages/agent-hooks/src/rules/impl/adl-token-minting-role.ts +4 -5
  61. package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +6 -7
  62. package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +77 -70
  63. package/packages/agent-hooks/src/rules/impl/deny-allowlist.ts +159 -0
  64. package/packages/agent-hooks/src/rules/impl/fs-trash.ts +2 -2
  65. package/packages/agent-hooks/src/rules/impl/git-helpers.ts +21 -23
  66. package/packages/agent-hooks/src/rules/impl/git-worktree.ts +14 -28
  67. package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +3 -3
  68. package/packages/agent-hooks/src/rules/impl/messages.ts +1 -1
  69. package/packages/agent-hooks/src/rules/impl/pr-completion.ts +1 -1
  70. package/packages/agent-hooks/src/rules/impl/tool-azure-devops.ts +35 -46
  71. package/packages/agent-hooks/src/rules/impl/tool-find.ts +34 -7
  72. package/packages/agent-hooks/src/rules/impl/tool-grep.ts +34 -12
  73. package/packages/agent-hooks/src/rules/impl/tool-native-search.ts +52 -9
  74. package/packages/agent-hooks/src/rules/ports.ts +5 -7
  75. package/packages/agent-hooks/src/rules/registry.ts +4 -6
  76. package/packages/agent-hooks/src/rules/shell/git-identity.ts +86 -101
  77. package/packages/agent-hooks/src/rules/shell/git-internals.ts +1 -1
  78. package/packages/agent-hooks/src/rules/shell/invocation.ts +24 -118
  79. package/packages/agent-hooks/src/rules/shell/piped-script.ts +1 -1
  80. package/packages/agent-hooks/src/rules/shell/prefixes.ts +1 -1
  81. package/packages/agent-hooks/src/rules/shell/protected-carrier-writes.ts +11 -10
  82. package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +26 -26
  83. package/packages/agent-hooks/src/rules/shell/substitution.ts +1 -1
  84. package/packages/agent-hooks/src/rules/shell/xargs.ts +2 -2
  85. package/packages/agent-hooks/src/rules/spec.ts +2 -2
  86. package/packages/agent-settings/README.md +287 -0
  87. package/packages/agent-settings/assets/GLOBAL-AGENTS.md +18 -18
  88. package/packages/agent-settings/assets/agents/architect.toml +2 -0
  89. package/packages/agent-settings/assets/agents/code-reviewer.toml +2 -0
  90. package/packages/agent-settings/assets/agents/executor.toml +2 -0
  91. package/packages/agent-settings/assets/agents/explore.toml +2 -0
  92. package/packages/agent-settings/assets/agents/planner.toml +2 -0
  93. package/packages/agent-settings/assets/mcp.json +0 -4
  94. package/packages/agent-settings/deploy-profile.json +139 -0
  95. package/packages/agent-settings/deploy-profile.schema.json +147 -0
  96. package/packages/agent-settings/managed/README.md +29 -30
  97. package/packages/agent-settings/managed/codex-requirements.toml +9 -9
  98. package/packages/agent-settings/package.json +20 -0
  99. package/packages/agent-settings/src/deploy/agent-render.ts +2 -2
  100. package/packages/agent-settings/src/deploy/agent-toml.ts +1 -1
  101. package/packages/agent-settings/src/deploy/agents-deploy.ts +17 -3
  102. package/packages/agent-settings/src/deploy/doctor.ts +3 -83
  103. package/packages/agent-settings/src/deploy/index.ts +6 -33
  104. package/packages/agent-settings/src/deploy/legacy-lock.ts +6 -6
  105. package/packages/agent-settings/src/deploy/list.ts +5 -19
  106. package/packages/agent-settings/src/deploy/lock.ts +8 -18
  107. package/packages/agent-settings/src/deploy/mcp-deploy.ts +10 -5
  108. package/packages/agent-settings/src/deploy/mcp-merge.ts +22 -3
  109. package/packages/agent-settings/src/deploy/mcp-source.ts +1 -1
  110. package/packages/agent-settings/src/deploy/profile.ts +11 -35
  111. package/packages/agent-settings/src/deploy/retire-lean-ctx.ts +184 -0
  112. package/packages/agent-settings/src/deploy/settings.ts +17 -22
  113. package/packages/agent-settings/src/global-surface-sweep.ts +5 -17
  114. package/packages/agent-settings/src/kimi-hooks.ts +339 -192
  115. package/packages/agent-settings/src/opencode-hooks.ts +1 -1
  116. package/packages/agent-settings/tsconfig.json +23 -0
  117. package/packages/agent-skills/assets/agent-search-tool-audit/SKILL.md +120 -0
  118. package/packages/agent-skills/assets/agent-search-tool-audit/scripts/audit.sh +276 -0
  119. package/packages/agent-skills/assets/debug-issue/SKILL.md +8 -7
  120. package/packages/agent-skills/assets/explore-codebase/SKILL.md +13 -13
  121. package/packages/agent-skills/assets/refactor-safely/SKILL.md +12 -11
  122. package/packages/agent-skills/assets/review-changes/SKILL.md +7 -7
  123. package/packages/agent-skills/assets/testing/references/e2e.md +37 -0
  124. package/packages/agent-skills/assets/testing/references/integration.md +37 -0
  125. package/packages/agent-skills/assets/testing/references/unit.md +32 -0
  126. package/packages/agent-skills/dist/deploy.d.ts +2 -0
  127. package/packages/agent-skills/dist/deploy.d.ts.map +1 -1
  128. package/packages/agent-skills/dist/deploy.js +27 -1
  129. package/packages/agent-skills/dist/deploy.js.map +1 -1
  130. package/packages/agent-skills/dist/doctor.d.ts +0 -2
  131. package/packages/agent-skills/dist/doctor.d.ts.map +1 -1
  132. package/packages/agent-skills/dist/doctor.js +1 -1
  133. package/packages/agent-skills/dist/doctor.js.map +1 -1
  134. package/packages/agent-skills/dist/fs-utils.d.ts +0 -1
  135. package/packages/agent-skills/dist/fs-utils.d.ts.map +1 -1
  136. package/packages/agent-skills/dist/fs-utils.js +1 -1
  137. package/packages/agent-skills/dist/fs-utils.js.map +1 -1
  138. package/packages/agent-skills/package.json +1 -1
  139. package/packages/agent-skills/src/deploy.ts +29 -1
  140. package/packages/agent-skills/src/doctor.ts +1 -1
  141. package/packages/agent-skills/src/fs-utils.ts +1 -1
  142. package/packages/azdo/README.md +10 -9
  143. package/packages/azdo/package.json +2 -5
  144. package/packages/azdo/src/azdo-pl.ts +2 -54
  145. package/packages/azdo/src/azdo-pr-review.ts +4 -4
  146. package/packages/azdo/src/azdo-repo-doctor.ts +101 -52
  147. package/packages/azdo/src/azdo-wit.ts +41 -2
  148. package/packages/azdo/src/lib/agent-identity.ts +12 -14
  149. package/packages/azdo/src/lib/agent-token.ts +2 -2
  150. package/packages/azdo/src/lib/client.ts +0 -5
  151. package/packages/azdo/src/lib/graph-identity.ts +4 -4
  152. package/packages/azdo/src/workflow-rules-matrix.csv +85 -0
  153. package/packages/azdo/src/workflow-rules.ts +128 -0
  154. package/packages/fleet/manifest.json +38 -33
  155. package/packages/fleet/manifest.schema.json +67 -65
  156. package/packages/fleet/src/default-agent-file.ts +3 -3
  157. package/packages/fleet/src/install-adl-package.ts +73 -15
  158. package/packages/fleet/src/install-embedding-model.ts +14 -14
  159. package/packages/fleet/src/managed-settings.ts +7 -7
  160. package/packages/fleet/src/repo-maintain.ts +439 -0
  161. package/packages/fleet/src/scratch-reap.ts +6 -6
  162. package/packages/fleet/src/vscode-settings.ts +5 -5
  163. package/packages/repo-controls/README.md +141 -43
  164. package/packages/repo-controls/assets/promote.ts +4 -4
  165. package/packages/repo-controls/assets/reconcile-guard.sh +10 -46
  166. package/packages/repo-controls/assets/version-bump.sh +31 -84
  167. package/packages/repo-controls/bunfig.toml +6 -7
  168. package/packages/repo-controls/package/adl-compliance/AGENTS.md +5 -6
  169. package/packages/repo-controls/package/adl-compliance/conftest.py +3 -1
  170. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +4 -16
  171. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +9 -2
  172. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/notes.md +1 -0
  173. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +11 -0
  174. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/__init__.py +7 -0
  175. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/check.py +266 -0
  176. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/c.md +1 -0
  177. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/d.md +1 -0
  178. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.hidden.md +1 -0
  179. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/a.md +1 -0
  180. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/b.md +1 -0
  181. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/data.csv +1 -0
  182. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/diagram.png +1 -0
  183. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/mock.png +1 -0
  184. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/sub/nested.md +1 -0
  185. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs.md +1 -0
  186. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/grants.yaml +4 -0
  187. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p1.md +1 -0
  188. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p2.md +1 -0
  189. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p3.md +1 -0
  190. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p4.md +1 -0
  191. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p5.md +1 -0
  192. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/build.md +1 -0
  193. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/overview.md +1 -0
  194. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/install.md +1 -0
  195. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/start.md +1 -0
  196. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/grants.yaml +4 -0
  197. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-001-tenancy.md +1 -0
  198. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-002-carrier.md +1 -0
  199. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-003-cli.md +1 -0
  200. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-old.md +1 -0
  201. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-older.md +1 -0
  202. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/a.md +1 -0
  203. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/b.md +1 -0
  204. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/c.md +1 -0
  205. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/grants.yaml +4 -0
  206. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-01.md +1 -0
  207. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-02.md +1 -0
  208. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-03.md +1 -0
  209. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-04.md +1 -0
  210. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-05.md +1 -0
  211. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-06.md +1 -0
  212. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-07.md +1 -0
  213. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-08.md +1 -0
  214. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-09.md +1 -0
  215. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-10.md +1 -0
  216. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-11.md +1 -0
  217. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-12.md +1 -0
  218. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-13.md +1 -0
  219. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-14.md +1 -0
  220. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-15.md +1 -0
  221. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-16.md +1 -0
  222. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/grants.yaml +4 -0
  223. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/a.md +1 -0
  224. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/b.md +1 -0
  225. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/c.md +1 -0
  226. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/grants.yaml +4 -0
  227. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/a.md +1 -0
  228. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/b.md +1 -0
  229. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/c.md +1 -0
  230. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/grants.yaml +4 -0
  231. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/a.md +1 -0
  232. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/b.md +1 -0
  233. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/c.md +1 -0
  234. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/d.md +1 -0
  235. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/e.md +1 -0
  236. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/grants.yaml +4 -0
  237. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/a.md +1 -0
  238. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/b.md +1 -0
  239. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/c.md +1 -0
  240. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/short/only.md +1 -0
  241. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/grants.yaml +4 -0
  242. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/a.md +1 -0
  243. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/b.md +1 -0
  244. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/c.md +1 -0
  245. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/d.md +1 -0
  246. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/a.md +1 -0
  247. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/b.md +1 -0
  248. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/grants.yaml +6 -0
  249. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/a.md +1 -0
  250. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/b.md +1 -0
  251. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/c.md +1 -0
  252. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/grants.yaml +3 -0
  253. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/test_check.py +345 -0
  254. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +18 -5
  255. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +35 -0
  256. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/__init__.py +7 -0
  257. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/check.py +91 -0
  258. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/AGENTS.md +3 -0
  259. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/CLAUDE.md +3 -0
  260. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/-leading-hyphen.md +3 -0
  261. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/AGENTS.md +3 -0
  262. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/double--hyphen.md +3 -0
  263. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/getting started.md +3 -0
  264. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/nested/page-here.md +3 -0
  265. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/trailing-hyphen-.md +3 -0
  266. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/ui-contract.md +4 -0
  267. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/user_profile.md +3 -0
  268. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/UI-CONTRACT.png +2 -0
  269. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/diagram.png +1 -0
  270. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/index.md +4 -0
  271. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/notes.md +3 -0
  272. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/reference.html +1 -0
  273. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/2026-10-experiment.md +3 -0
  274. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/UI-CONTRACT.md +6 -0
  275. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs.md +5 -0
  276. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/test_check.py +194 -0
  277. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +14 -2
  278. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +5 -5
  279. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-legacy/docs/compliance/index.md +10 -0
  280. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-type/docs/compliance/index.md +10 -0
  281. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +58 -6
  282. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +0 -1
  283. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +64 -17
  284. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +60 -9
  285. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-clean/docs/notes.md +17 -0
  286. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-no-lines/docs/notes.md +13 -0
  287. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +0 -1
  288. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +0 -1
  289. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/no-type.md +9 -0
  290. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-experiment.md +10 -0
  291. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-research.md +10 -0
  292. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs-okf-profiles.yaml +5 -0
  293. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs/architecture/bad-status.md +0 -1
  294. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +0 -1
  295. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/experiment-ok.md +15 -0
  296. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-key.md +15 -0
  297. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-keys.md +16 -0
  298. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-created.md +11 -0
  299. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-description.md +11 -0
  300. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-last-update.md +11 -0
  301. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-sources.md +10 -0
  302. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-status.md +11 -0
  303. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-title.md +11 -0
  304. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/optional-keys.md +16 -0
  305. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/research-ok.md +14 -0
  306. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/created-date.md +21 -0
  307. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/research-shaped.md +19 -0
  308. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/operations/runbook.md +26 -0
  309. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +228 -2
  310. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +5 -0
  311. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +11 -2
  312. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +5 -3
  313. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +160 -44
  314. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +0 -2
  315. 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 +1 -0
  316. 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 +1 -0
  317. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/grants.yaml +3 -0
  318. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +0 -2
  319. 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 +1 -0
  320. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/grants.yaml +5 -0
  321. 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 +1 -0
  322. 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 +1 -0
  323. 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 +1 -0
  324. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/grants.yaml +4 -0
  325. 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 +1 -0
  326. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/grants.yaml +5 -0
  327. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +0 -2
  328. 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 +1 -0
  329. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/grants.yaml +3 -0
  330. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/register.py +127 -0
  331. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +265 -29
  332. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +75 -2
  333. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +194 -0
  334. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +56 -10
  335. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +256 -0
  336. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +40 -12
  337. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +108 -0
  338. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +1 -1
  339. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +2 -3
  340. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +23 -6
  341. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +76 -0
  342. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +58 -17
  343. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +161 -0
  344. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +35 -3
  345. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +108 -1
  346. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +281 -61
  347. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/absolute-path.yaml +3 -0
  348. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/backslash-path.yaml +3 -0
  349. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/baseline-is-a-list.yaml +2 -0
  350. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/boolean-size.yaml +3 -0
  351. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/dot-segment.yaml +3 -0
  352. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/duplicate-path.yaml +4 -0
  353. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-file.yaml +0 -0
  354. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-segment.yaml +3 -0
  355. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/float-size.yaml +3 -0
  356. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/negative-size.yaml +3 -0
  357. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-over-limit-baseline.yaml +1 -0
  358. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-schema-version.yaml +1 -0
  359. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/non-string-path.yaml +3 -0
  360. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/not-yaml.yaml +2 -0
  361. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/null-size.yaml +3 -0
  362. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/parent-segment.yaml +3 -0
  363. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/string-size.yaml +3 -0
  364. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/top-level-is-a-list.yaml +2 -0
  365. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/trailing-slash.yaml +3 -0
  366. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/unknown-key.yaml +3 -0
  367. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/wrong-schema-version.yaml +2 -0
  368. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/zero-size.yaml +3 -0
  369. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/valid.yaml +4 -0
  370. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +758 -45
  371. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +4 -3
  372. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +2 -2
  373. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/cargo_lock.py +490 -0
  374. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +368 -55
  375. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +4 -2
  376. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_declared_paths.py +523 -0
  377. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_stale_lock.py +1179 -0
  378. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +122 -3
  379. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +33 -1
  380. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +0 -11
  381. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +16 -1
  382. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +1 -2
  383. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +12 -1
  384. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +133 -147
  385. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +133 -147
  386. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +1 -1
  387. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +52 -10
  388. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +23 -4
  389. package/packages/repo-controls/package.json +2 -10
  390. package/packages/repo-controls/scripts/hooks/post-merge +13 -0
  391. package/packages/repo-controls/scripts/hooks/pre-push +3 -3
  392. package/packages/repo-controls/src/azdo-push.ts +64 -36
  393. package/packages/repo-controls/src/azure-devops-governance.ts +7 -9
  394. package/packages/repo-controls/src/azure-devops-remote.ts +1 -1
  395. package/packages/repo-controls/src/cli.ts +29 -8
  396. package/packages/repo-controls/src/compliance-config.ts +410 -2
  397. package/packages/repo-controls/src/config.ts +133 -60
  398. package/packages/repo-controls/src/constants.ts +13 -27
  399. package/packages/repo-controls/src/coverage-ratchet.ts +4 -4
  400. package/packages/repo-controls/src/doctor.ts +46 -19
  401. package/packages/repo-controls/src/gitignore-block.ts +5 -29
  402. package/packages/repo-controls/src/hook-log.ts +1 -2
  403. package/packages/repo-controls/src/hook.ts +201 -45
  404. package/packages/repo-controls/src/install.ts +14 -8
  405. package/packages/repo-controls/src/integrity.ts +3 -3
  406. package/packages/repo-controls/src/lfs.ts +111 -0
  407. package/packages/repo-controls/src/promote.ts +8 -8
  408. package/packages/repo-controls/src/runtime.ts +9 -1
  409. package/packages/repo-controls/src/workflows-drift.ts +4 -5
  410. package/packages/repo-controls/src/worktree-guard.ts +3 -3
  411. package/packages/fleet/jobs/git-maintain/src/main.ts +0 -848
  412. package/packages/fleet/systemd/adl-azure-agent-update.service +0 -13
  413. package/packages/fleet/systemd/adl-azure-agent-update.timer +0 -10
@@ -35,9 +35,15 @@ export interface StaticCheck {
35
35
  * repository whose trees are named anything else was graded against
36
36
  * enact-m5's, which is why this moved into config.
37
37
  */
38
- export interface CoverageConfig {
38
+ interface CoverageConfig {
39
39
  summary: string
40
40
  produce: string
41
+ // The push-phase twin of `produce`: the command pre-push runs when
42
+ // `pre_push.coverage_produce` is armed. Kept separate because a commit-phase
43
+ // producer may mutate the index; the push-phase one must not (a check-mode
44
+ // run is the shape). Empty means "not declared", which is only a problem
45
+ // once the gate itself is armed.
46
+ producePush: string
41
47
  sourceRoots: string[]
42
48
  srcTestRatioGlobs: string[]
43
49
  }
@@ -77,6 +83,7 @@ export interface RepoControlsConfig {
77
83
  postCommit: { staticChecks: StaticCheck[] }
78
84
  prePush: {
79
85
  coverageRatchet: boolean
86
+ coverageProduce: boolean
80
87
  findingsRatchet: boolean
81
88
  staticChecks: StaticCheck[]
82
89
  exportLinks: string[]
@@ -132,7 +139,7 @@ branches = { protected = ["main", "integration"], prefixes = ["feat", "fix", "do
132
139
  #
133
140
  # Every gate is OFF until its key is added here: installing wires the hooks and arms
134
141
  # nothing. Opt in by adding pre_commit (static_checks, staged_coverage, doc_freshness) or the
135
- # remaining pre_push keys (coverage_ratchet, findings_ratchet, static_checks). README,
142
+ # remaining pre_push keys (coverage_ratchet, coverage_produce, findings_ratchet, static_checks). README,
136
143
  # "Configuration", lists each one. Deliberately no example assignments in this comment — commented TOML
137
144
  # is indistinguishable from a real setting to find-and-replace, in an editor or a script.
138
145
  pre_push = { remote = "origin" }
@@ -162,19 +169,37 @@ const escapeRegExp = (text: string): string => text.replace(/[.*+?^${}()|[\]\\]/
162
169
  * the one root key it already owns, which needs no coordination with the other two
163
170
  * tools — the same "no tool parses another tool's table" rule the file is built on.
164
171
  */
165
- export const OWNED_TABLES = ['controls', 'controls.compliance'] as const
172
+ const OWNED_TABLES = ['controls', 'controls.compliance'] as const
166
173
 
167
174
  /**
168
- * Locates a table's exact byte span in a shared `adl-config.toml`: from the line
169
- * matching `^\[<tableName>\]\s*$` to the next line starting with `[` at column 0
170
- * that is neither `[<tableName>]` nor a dotted sub-table `[<tableName>.*]` of it
171
- * (so `[controls.compliance]` through `[controls.compliance.trees]` splice as one
172
- * span) — except that a sub-table listed in `OWNED_TABLES` terminates the span
173
- * instead, so parent and child stay independently spliceable. Known limitation: a
174
- * hand-edited block containing a multi-line string whose content starts a line with
175
- * `[` would confuse this — this tool never writes such content itself.
175
+ * Locates the byte ranges that make up one table in a shared `adl-config.toml`.
176
+ *
177
+ * A table's ranges are every run of consecutive sections whose header is the table's
178
+ * own `[<tableName>]`, a dotted sub-table `[<tableName>.*]`, or an array table nested
179
+ * under it `[[<tableName>.*]]` (so `[controls.pre_push]` followed by
180
+ * `[[controls.pre_push.static_checks]]` is one range, never split). A range runs to the
181
+ * next line starting with `[` at column 0 that is none of those — except that a
182
+ * sub-table listed in `OWNED_TABLES` terminates it instead, so parent and child stay
183
+ * independently spliceable (`[controls.compliance]` through
184
+ * `[controls.compliance.trees]` is `controls.compliance`'s, not `controls`').
185
+ *
186
+ * More than one range, and no `[<tableName>]` header at all, are both normal: a file
187
+ * written by `adl migrate` carries `[controls.branches]` / `[[controls.pre_push.static_checks]]`
188
+ * and never a bare `[controls]`, and TOML lets a table's descendants be scattered
189
+ * around other tables. Known limitation: a hand-edited block containing a multi-line
190
+ * string whose content starts a line with `[` would confuse this — this tool never
191
+ * writes such content itself.
176
192
  */
177
- function findTableSpan(text: string, tableName: string): { start: number; end: number } | null {
193
+ interface TableRanges {
194
+ text: string
195
+ lines: string[]
196
+ starts: number[]
197
+ ranges: { startLine: number; endLine: number; start: number; end: number }[]
198
+ /** The line index of the exact `[<tableName>]` header, or -1 when the table is only implied by descendants. */
199
+ headerLine: number
200
+ }
201
+
202
+ function findTableRanges(text: string, tableName: string): TableRanges {
178
203
  const starts: number[] = [0]
179
204
  for (let i = 0; i < text.length; i++) if (text[i] === '\n') starts.push(i + 1)
180
205
  const lines = text.split('\n').slice(0, starts.length)
@@ -182,7 +207,7 @@ function findTableSpan(text: string, tableName: string): { start: number; end: n
182
207
 
183
208
  const escaped = escapeRegExp(tableName)
184
209
  const headerRe = new RegExp(`^\\[${escaped}\\]\\s*$`)
185
- const subTableRe = new RegExp(`^\\[${escaped}\\.`)
210
+ const subTableRe = new RegExp(`^\\[\\[?${escaped}\\.`)
186
211
  // A dotted sub-table that this package manages as its own independent span
187
212
  // (`[controls.compliance]` living inside `[controls]`) must TERMINATE the parent's
188
213
  // span rather than be swallowed by it. Without this, appending compliance to a repo
@@ -190,49 +215,85 @@ function findTableSpan(text: string, tableName: string): { start: number; end: n
190
215
  // the next install would read that as drift and refuse — an upgrade path that fails
191
216
  // on every already-installed repo.
192
217
  const nestedRes = OWNED_TABLES.filter((name) => name !== tableName && name.startsWith(`${tableName}.`)).map(
193
- (name) => new RegExp(`^\\[${escapeRegExp(name)}\\]\\s*$|^\\[${escapeRegExp(name)}\\.`),
218
+ (name) => new RegExp(`^\\[\\[?${escapeRegExp(name)}(?:\\]|\\.)`),
194
219
  )
195
220
  const isSeparatelyOwned = (line: string): boolean => nestedRes.some((re) => re.test(line))
196
221
  const isSameTableLine = (line: string): boolean => (headerRe.test(line) || subTableRe.test(line)) && !isSeparatelyOwned(line)
197
222
 
198
- const startLine = lines.findIndex((line) => headerRe.test(line))
199
- if (startLine === -1) return null
200
-
201
- let endLine = starts.length
202
- for (let index = startLine + 1; index < starts.length; index++) {
223
+ const ranges: TableRanges['ranges'] = []
224
+ let headerLine = -1
225
+ const close = (startLine: number, endLine: number): void => {
226
+ // Trim blank lines immediately before the boundary: they separate this table from
227
+ // whatever follows (or end-of-file), not content the table itself owns — so appending
228
+ // another table afterwards never retroactively changes this table's own byte span.
229
+ let contentEnd = endLine
230
+ while (contentEnd > startLine + 1 && (lines[contentEnd - 1] ?? '').trim() === '') contentEnd--
231
+ ranges.push({ startLine, endLine: contentEnd, start: lineStart(startLine), end: contentEnd < starts.length ? lineStart(contentEnd) : text.length })
232
+ }
233
+ let open = -1
234
+ for (let index = 0; index < starts.length; index++) {
203
235
  const line = lines[index] ?? ''
204
- if (/^\[/.test(line) && !isSameTableLine(line)) {
205
- endLine = index
206
- break
236
+ if (!/^\[/.test(line)) continue
237
+ const same = isSameTableLine(line)
238
+ if (same && open === -1) open = index
239
+ if (same && headerLine === -1 && headerRe.test(line)) headerLine = index
240
+ if (!same && open !== -1) {
241
+ close(open, index)
242
+ open = -1
207
243
  }
208
244
  }
209
- // Trim blank lines immediately before the boundary: they separate this table from
210
- // whatever follows (or end-of-file), not content the table itself owns — so appending
211
- // another table afterwards never retroactively changes this table's own byte span.
212
- let contentEnd = endLine
213
- while (contentEnd > startLine + 1 && (lines[contentEnd - 1] ?? '').trim() === '') contentEnd--
214
- return { start: lineStart(startLine), end: contentEnd < starts.length ? lineStart(contentEnd) : text.length }
245
+ if (open !== -1) close(open, starts.length)
246
+ return { text, lines, starts, ranges, headerLine }
215
247
  }
216
248
 
217
- /** The exact bytes of a table's span (header through its last line, including dotted sub-tables), or `null` if absent. */
249
+ /** The exact bytes of a table's ranges (header through its last line, including dotted and array sub-tables), or `null` if absent. */
218
250
  export function extractTableSpan(text: string, tableName: string): string | null {
219
- const span = findTableSpan(text, tableName)
220
- return span === null ? null : text.slice(span.start, span.end)
251
+ const { ranges } = findTableRanges(text, tableName)
252
+ if (ranges.length === 0) return null
253
+ return ranges.map((range) => text.slice(range.start, range.end)).reduce((joined, piece) => (joined === '' || joined.endsWith('\n') ? joined + piece : `${joined}\n${piece}`), '')
221
254
  }
222
255
 
223
256
  /**
224
- * `text` with `addition` inserted at the END of a table's span — after its last line,
225
- * before whatever follows. Used to scaffold a single missing attribute into a table
226
- * this package did not create: every existing byte, including comments, ordering and
227
- * formatting, is preserved exactly, because nothing is parsed and re-serialized.
228
- * Returns `text` unchanged when the table is absent.
257
+ * The end of the `[<tableName>]` section's OWN keys: the first sub-table header after
258
+ * it, or the end of its range. A key appended after a sub-table header would belong to
259
+ * that sub-table, so scaffolding must land before it. Comment lines sitting directly on
260
+ * a sub-table header stay with it, and blank separator lines stay in front of it.
261
+ */
262
+ function ownKeysEnd(found: TableRanges): { offset: number; atRangeEnd: boolean } | null {
263
+ if (found.headerLine === -1) return null
264
+ const range = found.ranges.find((candidate) => candidate.startLine === found.headerLine)
265
+ if (range === undefined) return null
266
+ let sub = range.startLine + 1
267
+ while (sub < range.endLine && !/^\[/.test(found.lines[sub] ?? '')) sub++
268
+ if (sub >= range.endLine) return { offset: range.end, atRangeEnd: true }
269
+ let at = sub
270
+ while (at - 1 > range.startLine && (found.lines[at - 1] ?? '').trim().startsWith('#')) at--
271
+ while (at - 1 > range.startLine && (found.lines[at - 1] ?? '').trim() === '') at--
272
+ return { offset: found.starts[at] ?? found.text.length, atRangeEnd: false }
273
+ }
274
+
275
+ /**
276
+ * `text` with `addition` inserted at the END of a table's own keys — after its last
277
+ * key line, before its first sub-table header (or whatever follows it). Used to scaffold
278
+ * a single missing attribute into a table this package did not create: every existing
279
+ * byte, including comments, ordering and formatting, is preserved exactly, because
280
+ * nothing is parsed and re-serialized. When the table exists only through its
281
+ * descendants (no `[<tableName>]` header — what `adl migrate` writes), the attribute
282
+ * goes under a new `[<tableName>]` header at the end of the file, which TOML allows
283
+ * after the descendants. Returns `text` unchanged when the table is absent.
229
284
  */
230
285
  export function appendToTableSpan(text: string, tableName: string, addition: string): string {
231
- const span = findTableSpan(text, tableName)
232
- if (span === null) return text
233
- const before = text.slice(0, span.end)
286
+ const found = findTableRanges(text, tableName)
287
+ if (found.ranges.length === 0) return text
288
+ const lead = addition.startsWith('\n') ? '' : '\n'
289
+ const where = ownKeysEnd(found)
290
+ if (where === null) {
291
+ const base = text.endsWith('\n') ? text : `${text}\n`
292
+ return `${base}\n[${tableName}]${lead}${addition}`
293
+ }
294
+ const before = text.slice(0, where.offset)
234
295
  const separator = before.endsWith('\n') ? '' : '\n'
235
- return `${before}${separator}${addition}${text.slice(span.end)}`
296
+ return `${before}${separator}${addition}${text.slice(where.offset)}`
236
297
  }
237
298
 
238
299
  /**
@@ -244,27 +305,33 @@ export function appendToTableSpan(text: string, tableName: string, addition: str
244
305
  export const RETIRED_ATTRIBUTES = ['version'] as const
245
306
 
246
307
  /**
247
- * `text` with `key`'s assignment line removed from inside a table's span, along with a
248
- * blank line left immediately after it. Every other byte is untouched — nothing is
249
- * parsed and re-serialized. Returns `text` unchanged when the table or key is absent.
308
+ * `text` with `key`'s assignment line removed from the table's own keys (never from a
309
+ * sub-table or array table under it), along with a blank line left immediately after
310
+ * it. Every other byte is untouched — nothing is parsed and re-serialized. Returns
311
+ * `text` unchanged when the table or key is absent.
250
312
  */
251
313
  export function removeFromTableSpan(text: string, tableName: string, key: string): string {
252
- const span = findTableSpan(text, tableName)
253
- if (span === null) return text
254
- const body = text.slice(span.start, span.end)
314
+ const found = findTableRanges(text, tableName)
315
+ const where = ownKeysEnd(found)
316
+ const range = found.ranges.find((candidate) => candidate.startLine === found.headerLine)
317
+ if (where === null || range === undefined) return text
318
+ const body = text.slice(range.start, where.offset)
255
319
  const assignment = new RegExp(`^${escapeRegExp(key)}\\s*=.*\\n(\\n)?`, 'm')
256
320
  if (!assignment.test(body)) return text
257
- return text.slice(0, span.start) + body.replace(assignment, '') + text.slice(span.end)
321
+ return text.slice(0, range.start) + body.replace(assignment, '') + text.slice(where.offset)
258
322
  }
259
323
 
260
- /** `text` with a table's span removed (a no-op if there is none); other tables are untouched. */
324
+ /** `text` with every range of a table removed (a no-op if there are none); other tables are untouched. */
261
325
  export function removeTableSpan(text: string, tableName: string): string {
262
- const span = findTableSpan(text, tableName)
263
- if (span === null) return text
264
- let before = text.slice(0, span.start)
265
- const after = text.slice(span.end)
266
- if (before.endsWith('\n\n')) before = before.slice(0, -1)
267
- return before + after
326
+ const { ranges } = findTableRanges(text, tableName)
327
+ let result = text
328
+ for (const range of [...ranges].reverse()) {
329
+ let before = result.slice(0, range.start)
330
+ const after = result.slice(range.end)
331
+ if (before.endsWith('\n\n')) before = before.slice(0, -1)
332
+ result = before + after
333
+ }
334
+ return result
268
335
  }
269
336
 
270
337
  /** The exact bytes of the `[controls]` table, or `null` if absent. */
@@ -417,7 +484,7 @@ export function parseConfig(text: string): RepoControlsConfig {
417
484
  // so "no branch policy" cannot be spelled as an empty list. Everything else is
418
485
  // optional and defaults to off.
419
486
  const preCommit = problems.optionalTable(controls, 'pre_commit', ['static_checks', 'staged_coverage', 'doc_freshness', 'compliance'])
420
- const prePush = problems.table(controls, 'pre_push', ['coverage_ratchet', 'findings_ratchet', 'static_checks', 'export_links', 'remote'])
487
+ const prePush = problems.table(controls, 'pre_push', ['coverage_ratchet', 'coverage_produce', 'findings_ratchet', 'static_checks', 'export_links', 'remote'])
421
488
  // Optional, and every field defaults, so a repository that never writes this
422
489
  // table behaves exactly as before. `pre_push.coverage_ratchet` stays where it
423
490
  // is: that key says WHETHER the gate is armed, this table says WHAT it grades.
@@ -435,6 +502,7 @@ export function parseConfig(text: string): RepoControlsConfig {
435
502
  const coverage = problems.optionalTable(controls, 'coverage', [
436
503
  'summary',
437
504
  'produce',
505
+ 'produce_push',
438
506
  'source_roots',
439
507
  'src_test_ratio_globs',
440
508
  ])
@@ -468,13 +536,17 @@ export function parseConfig(text: string): RepoControlsConfig {
468
536
  // Same shape as `pre_push.static_checks`; this package never interprets
469
537
  // the command and names no tool.
470
538
  staticChecks: preCommit.static_checks === undefined ? [] : parseStaticChecks(preCommit.static_checks, problems, 'pre_commit.static_checks'),
471
- stagedCoverage: problems.optionalBool(preCommit, 'staged_coverage', 'pre_commit.staged_coverage', false),
472
- docFreshness: problems.optionalBool(preCommit, 'doc_freshness', 'pre_commit.doc_freshness', false),
473
- compliance: problems.optionalBool(preCommit, 'compliance', 'pre_commit.compliance', false),
539
+ stagedCoverage: problems.optionalBool(preCommit, 'staged_coverage', 'pre_commit.staged_coverage', true),
540
+ docFreshness: problems.optionalBool(preCommit, 'doc_freshness', 'pre_commit.doc_freshness', true),
541
+ compliance: problems.optionalBool(preCommit, 'compliance', 'pre_commit.compliance', true),
474
542
  },
475
543
  prePush: {
476
- coverageRatchet: problems.optionalBool(prePush, 'coverage_ratchet', 'pre_push.coverage_ratchet', false),
477
- findingsRatchet: problems.optionalBool(prePush, 'findings_ratchet', 'pre_push.findings_ratchet', false),
544
+ coverageRatchet: problems.optionalBool(prePush, 'coverage_ratchet', 'pre_push.coverage_ratchet', true),
545
+ // New gates opt in: the coverage measurement moved to pre-push, so a
546
+ // repository that never writes this key keeps measuring (or not) exactly
547
+ // where it did before.
548
+ coverageProduce: problems.optionalBool(prePush, 'coverage_produce', 'pre_push.coverage_produce', false),
549
+ findingsRatchet: problems.optionalBool(prePush, 'findings_ratchet', 'pre_push.findings_ratchet', true),
478
550
  staticChecks: prePush.static_checks === undefined ? [] : parseStaticChecks(prePush.static_checks, problems, 'pre_push.static_checks'),
479
551
  // Untracked paths the HEAD export needs, e.g. a dependency directory.
480
552
  // The hook used to hardcode `node_modules`, which assumed JavaScript in a
@@ -486,6 +558,7 @@ export function parseConfig(text: string): RepoControlsConfig {
486
558
  coverage: {
487
559
  summary: problems.optionalString(coverage, 'summary', 'coverage.summary', DEFAULT_COVERAGE_SUMMARY),
488
560
  produce: problems.optionalString(coverage, 'produce', 'coverage.produce', ''),
561
+ producePush: problems.optionalString(coverage, 'produce_push', 'coverage.produce_push', ''),
489
562
  sourceRoots: problems.optionalNames(coverage, 'source_roots', 'coverage.source_roots', []),
490
563
  srcTestRatioGlobs: problems.optionalNames(
491
564
  coverage,
@@ -3,19 +3,19 @@ import { join, resolve } from 'node:path'
3
3
 
4
4
  export const TOOL = 'adl-repo-controls'
5
5
  /**
6
- * Never published (adl-m3-finish item 1, 2026-09-27): kept only as this
6
+ * Never published (2026-09-27): kept only as this
7
7
  * package's own internal identity (USAGE text, error messages, the lock
8
8
  * file's `tool` field) — none of that is a claim that `adl-repo-controls`
9
9
  * is installable. NPM_INSTALL/PACKAGE_NAME describe a registry package that
10
10
  * does not exist; do not point a user-facing "how do I get this on PATH"
11
11
  * message at them (see ADL_NPM_INSTALL below for the one that is real).
12
12
  */
13
- export const PACKAGE_NAME = '@amsterdamdatalabs/adl-repo-controls'
14
- export const NPM_INSTALL = `npm i -g ${PACKAGE_NAME}`
13
+ const PACKAGE_NAME = '@amsterdamdatalabs/adl-repo-controls'
14
+ const NPM_INSTALL = `npm i -g ${PACKAGE_NAME}`
15
15
  /**
16
16
  * How a repository's committed git-hook stubs actually get `adl` onto
17
17
  * PATH: this package is folded into the `adl` binary's `repo controls`
18
- * namespace (docs/architecture/cli-design.md §6, STATUS.md item 10) and is never itself
18
+ * namespace (docs/architecture/cli-design.md §6) and is never itself
19
19
  * a standalone global command. `adl` is either fleet-installed
20
20
  * (bin/reconcile's `bun-compile` manager) or, for a machine not yet pinned
21
21
  * to the fleet, this published wrapper — see
@@ -23,7 +23,7 @@ export const NPM_INSTALL = `npm i -g ${PACKAGE_NAME}`
23
23
  * packaging/npm/wrapper-bin.js.
24
24
  */
25
25
  export const ADL_NPM_INSTALL = 'npm install -g @amsterdamdatalabs/adl-agent-control'
26
- export const PACKAGE_ROOT = resolve(import.meta.dir, '..')
26
+ const PACKAGE_ROOT = resolve(import.meta.dir, '..')
27
27
  export const VERSION: string = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8')).version
28
28
 
29
29
  /** Package-owned hook implementations, flattened in commit 20ec790. */
@@ -37,16 +37,21 @@ export const BUNDLE_ROOT = join(PACKAGE_ROOT, 'scripts')
37
37
  /** Bundled Python compliance engine (a `uv`-managed project), installed alongside this package. */
38
38
  export const COMPLIANCE_ROOT = join(PACKAGE_ROOT, 'package', 'adl-compliance')
39
39
 
40
- // `post-checkout` added 2026-09-27 (adl-m3-items item 2): the only backstop
40
+ // `post-checkout` added 2026-09-27: the only backstop
41
41
  // for the repo's worktree-count limit (see `MAX_WORKTREES` below and
42
42
  // `worktree-guard.ts`) that runs regardless of which agent host or shell path
43
43
  // created the worktree — see that file's header for why git has no
44
44
  // pre-worktree hook and `post-checkout` is the earliest hook a `git worktree
45
45
  // add` actually triggers.
46
- export const HOOK_NAMES = ['pre-commit', 'commit-msg', 'pre-push', 'post-commit', 'post-checkout'] as const
46
+ //
47
+ // `post-merge` added 2026-10-01 with Git LFS chaining: git-lfs installs
48
+ // pre-push, post-checkout, post-commit and post-merge, and none of them runs under
49
+ // `core.hooksPath=.workflows/hooks` unless the projected hook calls it
50
+ // (scripts/hooks/lib/lfs.sh). post-merge has no other job.
51
+ export const HOOK_NAMES = ['pre-commit', 'commit-msg', 'pre-push', 'post-commit', 'post-checkout', 'post-merge'] as const
47
52
  export type HookName = (typeof HOOK_NAMES)[number]
48
53
 
49
- export { MAX_WORKTREES } from './worktree-limit.ts'
54
+
50
55
 
51
56
  // Repository-relative paths written into target repositories.
52
57
  export const HOOKS_PATH = '.workflows/hooks'
@@ -59,8 +64,6 @@ export const WORKFLOWS_ROOT = '.workflows'
59
64
 
60
65
  /** The standalone promoter, deployed so CI needs nothing on PATH. */
61
66
  export const PROMOTE_REL = '.workflows/promote.ts'
62
- /** The standalone integration PR auto-complete helper. */
63
- export const AUTO_COMPLETE_REL = '.workflows/scripts/enable-integration-auto-complete.mjs'
64
67
  /** The standalone immutable package-version allocator for integration CI. */
65
68
  export const VERSION_BUMP_REL = '.workflows/version-bump.sh'
66
69
  /** The standalone CI stage-2 guard: a PR branch must contain integration's tip and be at its version + 1 patch. */
@@ -68,12 +71,6 @@ export const RECONCILE_GUARD_REL = '.workflows/reconcile-guard.sh'
68
71
 
69
72
  export const MANAGED_ASSETS = [
70
73
  { rel: PROMOTE_REL, source: join(PACKAGE_ROOT, 'assets', 'promote.ts'), mode: 0o755, doctorId: 'promote' },
71
- {
72
- rel: AUTO_COMPLETE_REL,
73
- source: join(PACKAGE_ROOT, 'assets', 'enable-integration-auto-complete.mjs'),
74
- mode: 0o755,
75
- doctorId: 'integration-auto-complete',
76
- },
77
74
  {
78
75
  rel: VERSION_BUMP_REL,
79
76
  source: join(PACKAGE_ROOT, 'assets', 'version-bump.sh'),
@@ -91,15 +88,4 @@ export const MANAGED_ASSETS = [
91
88
  export const CONFIG_REL = 'adl-config.toml'
92
89
  export const LOCK_REL = '.workflows/repo-controls.lock.json'
93
90
  export const GITIGNORE_REL = '.gitignore'
94
- /**
95
- * Legacy, pre-hard-cut repository-local log root (owner-qualified filenames
96
- * prevented collisions there). Nothing writes here any more: git-hook logs
97
- * moved to the shared `.adl/logs/` JSON-Lines format (Tarun, 2026-09-27,
98
- * docs/architecture/cli-design.md §5a — see `hook-log.ts`). Kept only so existing evidence
99
- * in an already-installed repository can still be named and quarantined in
100
- * place (`install.ts`'s `LEGACY_LOG_QUARANTINES`, `gitignore-block.ts`);
101
- * never read or written by this package.
102
- */
103
- export const LOGS_ROOT_REL = '.enact/logs'
104
-
105
91
  export const INSTALL_HINT = `run: ${TOOL} install --repo .`
@@ -24,17 +24,17 @@
24
24
  * was the package claiming a surface that is not its own.
25
25
  */
26
26
 
27
- export interface MetricSummary {
27
+ interface MetricSummary {
28
28
  total: number
29
29
  covered: number
30
30
  skipped?: number
31
31
  pct: number
32
32
  }
33
33
 
34
- export type CoverageMetric = 'lines' | 'statements' | 'functions' | 'branches'
35
- export const COVERAGE_METRICS: readonly CoverageMetric[] = ['lines', 'statements', 'functions', 'branches']
34
+ type CoverageMetric = 'lines' | 'statements' | 'functions' | 'branches'
35
+ const COVERAGE_METRICS: readonly CoverageMetric[] = ['lines', 'statements', 'functions', 'branches']
36
36
 
37
- export type FileSummary = Record<CoverageMetric, MetricSummary>
37
+ type FileSummary = Record<CoverageMetric, MetricSummary>
38
38
 
39
39
  /**
40
40
  * A summary is a map of repo-relative path -> per-file metrics, plus two
@@ -112,8 +112,8 @@ export function doctor(repoArg: string, env: Env, options: string | DoctorOption
112
112
  const bun = which('bun', env)
113
113
  add('bun', bun ? null : 'bun not found on PATH (the bundled enact-m5 scripts run with bun)', `bun at ${bun}`)
114
114
  // Checks for `adl`, not TOOL ("adl-repo-controls"): the installed git-hook
115
- // stubs exec `adl repo controls hook <name>` (adl-m3-finish item 1,
116
- // 2026-09-27 — see install.ts's `stubText`), never a standalone
115
+ // stubs exec `adl repo controls hook <name>` (2026-09-27 —
116
+ // see install.ts's `stubText`), never a standalone
117
117
  // `adl-repo-controls` binary, which is not published and never on PATH by
118
118
  // design. TOOL stays this package's own internal identity (USAGE text,
119
119
  // the lock file's `tool` field) — a different thing from what a repo's
@@ -154,37 +154,64 @@ export function doctor(repoArg: string, env: Env, options: string | DoctorOption
154
154
  )
155
155
  // The path the pre-push ratchet grades, not a default: a repository that
156
156
  // declares `[controls.coverage].summary` elsewhere was probed at the wrong
157
- // file and passed with its real summary missing.
157
+ // file and passed with its real summary missing. The gate has a safety
158
+ // gate: with no summary on either side of the index, the step is a no-op
159
+ // (see hook.ts), so this is informational rather than blocking.
158
160
  const coverageSummaryExists = existsSync(join(repo, config.coverage.summary))
159
161
  add(
160
162
  'coverage-summary',
161
163
  config.prePush.coverageRatchet && !coverageSummaryExists
162
- ? `pre_push.coverage_ratchet is enabled but ${config.coverage.summary} does not exist — the first push will be rejected until it does; commit a baseline or set pre_push.coverage_ratchet = false`
164
+ ? `pre_push.coverage_ratchet is enabled but ${config.coverage.summary} does not exist — the gate is a no-op until a baseline lands; commit one or set pre_push.coverage_ratchet = false`
163
165
  : null,
164
166
  `${config.coverage.summary} is present or the ratchet is disabled`,
167
+ 'warn',
168
+ )
169
+ // Same shape: `coverage_produce` defaults OFF, but armed with no declared
170
+ // `[controls.coverage].produce_push` it is NOT a no-op — the push gate
171
+ // fails loud (a step that measures nothing is not a pass), so doctor names
172
+ // the misconfiguration before the first push does.
173
+ add(
174
+ 'coverage-produce',
175
+ config.prePush.coverageProduce && config.coverage.producePush.trim() === ''
176
+ ? 'pre_push.coverage_produce is enabled but [controls.coverage].produce_push declares no command — the push gate fails every push until one is declared; add produce_push or set pre_push.coverage_produce = false'
177
+ : null,
178
+ 'pre_push.coverage_produce is disabled or [controls.coverage].produce_push is declared',
179
+ 'warn',
165
180
  )
166
- // Opt-in, like coverage_ratchet: silent when findings_ratchet is unset, so
167
- // a repo with no lint tooling at all (enact-repo-controls-m5,
168
- // enact-extensions, enact-vps-m5) is never asked for a floor it has no
169
- // use for.
181
+ // Same shape: `findings_ratchet` defaults ON but is a no-op when the floor
182
+ // file is absent. A repo with no lint tooling at all is never asked for a
183
+ // floor it has no use for.
170
184
  const findingsFloorExists = existsSync(join(repo, config.findings.floor))
171
185
  add(
172
186
  'findings-floor',
173
187
  config.prePush.findingsRatchet && !findingsFloorExists
174
- ? `pre_push.findings_ratchet is enabled but ${config.findings.floor} does not exist — the first push will be rejected until it does; commit a floor or set pre_push.findings_ratchet = false`
188
+ ? `pre_push.findings_ratchet is enabled but ${config.findings.floor} does not exist — the gate is a no-op until a floor lands; commit one or set pre_push.findings_ratchet = false`
175
189
  : null,
176
190
  `${config.findings.floor} is present or the ratchet is disabled`,
191
+ 'warn',
177
192
  )
178
- // A floor on its own measures nothing. The gate refuses to run with an
179
- // empty counter list rather than passing every push, so say it here
180
- // instead of letting someone find out when a push is rejected.
181
- add(
182
- 'findings-counters',
183
- config.prePush.findingsRatchet && Object.keys(config.findings.counters).length === 0
184
- ? 'pre_push.findings_ratchet is enabled but [controls.findings.counters] declares none — a ratchet with nothing to measure grades nothing, so the push is rejected; declare at least one counter or set pre_push.findings_ratchet = false'
185
- : null,
186
- 'at least one findings counter is declared, or the ratchet is disabled',
187
- )
193
+ // A floor on its own measures nothing. With the safety gate in hook.ts
194
+ // (counters empty + no floor → no-op), this is informational when the
195
+ // floor is missing; it stays a hard error only when a floor IS committed
196
+ // but no counter is declared to drive it (the runtime hard-fails too:
197
+ // `findingsRatchetReport` returns 1 when counters is empty).
198
+ if (config.prePush.findingsRatchet && findingsFloorExists && Object.keys(config.findings.counters).length === 0) {
199
+ add(
200
+ 'findings-counters',
201
+ 'pre_push.findings_ratchet is enabled and a floor is committed but [controls.findings.counters] declares none — a ratchet with nothing to measure grades nothing, so the push is rejected; declare at least one counter or set pre_push.findings_ratchet = false',
202
+ '',
203
+ 'fail',
204
+ )
205
+ } else if (config.prePush.findingsRatchet && Object.keys(config.findings.counters).length === 0) {
206
+ add(
207
+ 'findings-counters',
208
+ 'pre_push.findings_ratchet is enabled but [controls.findings.counters] declares none — the gate is a no-op until a counter is declared',
209
+ 'at least one findings counter is declared, or the ratchet is disabled',
210
+ 'warn',
211
+ )
212
+ } else {
213
+ add('findings-counters', null, 'at least one findings counter is declared, or the ratchet is disabled')
214
+ }
188
215
  // A release declaration is a claim that this repository promotes through a
189
216
  // PR. That claim is only armed when the remote branch policies are proved
190
217
  // here. Repositories with no release declaration remain outside this
@@ -1,12 +1,11 @@
1
1
  // One marker-bounded block, written into a target repository's root
2
2
  // `.gitignore` by `install()`, listing every repository-local directory the
3
- // adl process (repo-controls itself, plus the sibling tools it enrolls a
4
- // repository into: agent-hooks' `lean-ctx` runtime, the `adl` CLI's own
5
- // logger, and the `.scratchpad/` convention every agent surface follows) is
3
+ // adl process (repo-controls itself, the `adl` CLI's own logger, and the
4
+ // `.scratchpad/` convention every agent surface follows) is
6
5
  // known to create there. Before this module the only programmatic coverage
7
6
  // was two individually-appended lines (`GITIGNORE_LINES`, retired) plus a
8
7
  // data-dependent legacy-quarantine reconciliation; everything else
9
- // (`.scratchpad/`, `.agents/lean-ctx/*`, `.adl/`) accumulated by hand into
8
+ // (`.scratchpad/`, `.adl/`) accumulated by hand into
10
9
  // this monorepo's own root `.gitignore` over time and was never shipped to a
11
10
  // repository that only runs `install`. This is the single source of truth
12
11
  // for that list, and the one mechanism that writes or checks it — see
@@ -15,8 +14,7 @@
15
14
  //
16
15
  // Evidence for each entry, gathered 2026-09-27 by reading this monorepo's
17
16
  // own source (not guessed):
18
- // - `/.enact/logs/` — pre-hard-cut evidence only (constants.ts
19
- // `LOGS_ROOT_REL`). Neither repo-controls' git
17
+ // - `/.enact/logs/` — pre-hard-cut evidence only. Neither repo-controls' git
20
18
  // hooks (`src/hook-log.ts`, 2026-09-27) nor
21
19
  // agent-hooks' own hook log write here any more —
22
20
  // both moved to `.adl/logs/` JSON-Lines files
@@ -40,23 +38,6 @@
40
38
  // root's session/tool-call log; docs/architecture/cli-design.md
41
39
  // §5a). Whole `.adl/` dir ignored, matching this
42
40
  // monorepo's own hand-authored line.
43
- // - `/.agents/lean-ctx/{data,state,cache}/`
44
- // — packages/agent-hooks/src/lean-ctx/env.ts:
45
- // `leanCtxEnv` points the `lean-ctx` binary's
46
- // data/state/cache dirs under
47
- // `<repo>/<DEFAULT_LEAN_CTX_DIR>/{data,state,cache}`.
48
- // `config/` is deliberately NOT listed: this
49
- // monorepo's own `.agents/lean-ctx/config/lean-ctx/
50
- // *.toml` is git-tracked (confirmed via
51
- // `git ls-files .agents`), so it is committed
52
- // configuration, not generated state. A repository
53
- // whose `adl-config.toml` overrides
54
- // `[hooks] lean_ctx_dir` away from the default is
55
- // a known gap this static list does not cover —
56
- // repo-controls does not depend on agent-hooks, so
57
- // it cannot resolve that override at install time
58
- // without introducing a new cross-package
59
- // dependency nobody asked for.
60
41
  // - `/.scratchpad/`, `packages/*/.scratchpad/`
61
42
  // — not created by any single tool's code, but
62
43
  // mandated by the global agent convention (every
@@ -112,11 +93,6 @@ export const GITIGNORE_BLOCK_LINES: readonly string[] = [
112
93
  "# adl CLI: repo-root session/tool-call logs (docs/architecture/cli-design.md §5a)",
113
94
  '/.adl/',
114
95
  '',
115
- '# agent-hooks: lean-ctx per-repo runtime state (config/ subtree is committed)',
116
- '/.agents/lean-ctx/data/',
117
- '/.agents/lean-ctx/state/',
118
- '/.agents/lean-ctx/cache/',
119
- '',
120
96
  '# adl process convention: scratch and throwaway work, never committed',
121
97
  '/.scratchpad/',
122
98
  'packages/*/.scratchpad/',
@@ -224,7 +200,7 @@ export function removeGitignoreBlock(text: string): string {
224
200
  return joinText(next, nl)
225
201
  }
226
202
 
227
- export interface GitignoreBlockFinding {
203
+ interface GitignoreBlockFinding {
228
204
  /** Same id `doctor()` uses for this surface (`gitignore`). */
229
205
  readonly id: string
230
206
  readonly message: string
@@ -19,8 +19,7 @@
19
19
  * `.adl/logs/hooks-deny.log` (FAIL rows only — shared with agent-hooks' own
20
20
  * PreToolUse denies, so a human `git commit` denial and an agent's blocked
21
21
  * shell command land in one timeline). `.enact/logs/` is a hard cut: this
22
- * module never reads or writes it; whatever evidence is already there (see
23
- * `constants.ts`'s `LOGS_ROOT_REL`) is left exactly where it is.
22
+ * module never reads or writes it; whatever evidence is already there is left exactly where it is.
24
23
  *
25
24
  * Field mapping onto `LogEntryInput` (`../../agent-hooks/src/log/writer.ts`)
26
25
  * — the old CSV's single `git:<hook>` label now lands in the schema's real