@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,7 +35,7 @@ import { gitIdentityNeedsIdentityMessage, hostCannotRewriteMessage, RULE_ID as G
35
35
  import { RULE_ID as GIT_CREDENTIAL_BYPASS_RULE_ID, SECURITY_RULE_ID as SECURITY_KEYCHAIN_ADO_RULE_ID } from '../rules/impl/adl-git-credential-bypass.ts'
36
36
  import { RULE_ID as HUMAN_AZDO_BYPASS_RULE_ID } from '../rules/impl/adl-human-azdo-bypass.ts'
37
37
  import { resolveFromEnvOrFile } from '../rules/impl/adl-identity.ts'
38
- import { identityBearingReason } from '../rules/impl/adl-session-required.ts'
38
+ import { identityBearingReason } from '../rules/impl/adl-run-required.ts'
39
39
  import { commandHasValidInlineIdentity, effectiveIdentityForCommand } from '../rules/shell/git-identity.ts'
40
40
  import { invocations } from '../rules/shell/invocation.ts'
41
41
  import { KNOWN_MCP_TOOL_NAMES, mcpToolName, toolNameEndingWithKnownSuffix } from '../rules/impl/mcp-tool.ts'
@@ -82,7 +82,7 @@ const RULES = requireRegistered(BUILTIN_RULES)
82
82
  export function toDecideInput(payload: Record<string, unknown>): DecideInput | null {
83
83
  const toolInput = (payload.tool_input ?? {}) as Record<string, unknown>
84
84
 
85
- // F4 (independent review, 2026-09-29): codex's `apply_patch` names its
85
+ // Codex's `apply_patch` names its
86
86
  // patch body `tool_input.command` — the same key name a real shell tool
87
87
  // call uses. Checked BEFORE the generic loop below, which would otherwise
88
88
  // read that patch TEXT as if it were a shell command and walk it through
@@ -167,13 +167,11 @@ function classifyCommandTool(payload: Record<string, unknown>): CommandToolClass
167
167
  if (typeof tool !== 'string' || tool.length === 0) return 'native-shell'
168
168
  if (tool.startsWith('mcp__') || tool.startsWith('MCP:')) return 'mcp'
169
169
  if (NATIVE_SHELL_TOOL_NAMES.has(tool)) return 'native-shell'
170
- // ASSUMPTION (unverified, W2 build item 4 — STATUS.md 12p):
171
- // OpenCode's and Kimi's own MCP tool-call naming has never actually been
172
- // observed in production (.adl/logs/hooks.log shows only mcp__-prefixed
173
- // calls, from Claude/Codex/Cursor) — they may carry no mcp__/MCP: prefix
174
- // at all, spelling the lean-ctx shell tool `<server>_ctx_shell` /
175
- // `<server>.ctx_shell` / `<server>:ctx_shell` (or the ctx_execute
176
- // sibling). Treated as MCP-class defensively: an unrewritten push through
170
+ // ASSUMPTION (unverified): OpenCode's and Kimi's own MCP tool-call naming
171
+ // has not been confirmed against a live capture (the tests use synthetic names) — they may
172
+ // carry no mcp__/MCP: prefix at all, spelling the lean-ctx shell tool
173
+ // `<server>_ctx_shell` / `<server>.ctx_shell` / `<server>:ctx_shell` (or
174
+ // the ctx_execute sibling). Treated as MCP-class defensively: an unrewritten push through
177
175
  // such a call would otherwise silently fall through to 'other' and reach
178
176
  // git-ado's human pass-through unrewritten — the exact incident this
179
177
  // module exists to close (see this file's own header).
@@ -229,7 +227,7 @@ export async function handlePreToolUse(inv: HookInvocation): Promise<HookResult>
229
227
 
230
228
  // The invocation's own environment, not the handler process's ambient one:
231
229
  // `main.ts` passes `process.env` here in production, and the identity rules
232
- // (`adl.session-required-for-writes`, `adl.git-push-branch-policy`,
230
+ // (`adl.run-required-for-writes`, `adl.git-push-branch-policy`,
233
231
  // `adl.git-identity`'s rewrite) must read the environment the caller handed
234
232
  // the invocation — tests inject it explicitly, and a host that scrubs its
235
233
  // hook child's environment must not inherit the hook wrapper's own identity.
@@ -257,24 +255,21 @@ export async function handlePreToolUse(inv: HookInvocation): Promise<HookResult>
257
255
  }
258
256
 
259
257
  /**
260
- * The identity rule ids — used below (not as a baseline any more; see
261
- * Tarun's rule) purely to tell `denyIdentity`/`passIdentity` which decisions
262
- * in a MANAGED repo's own normal rule pass are identity decisions worth
263
- * logging `identity_source`/`identityAgent` for, as opposed to an unrelated
264
- * deny (`fs.rm`, `git.no-verify`, …) that made no identity decision at all.
258
+ * The identity rule ids — used below purely to tell `denyIdentity`/
259
+ * `passIdentity` which decisions in a MANAGED repo's own normal rule pass
260
+ * are identity decisions worth logging `identity_source`/`identityAgent`
261
+ * for, as opposed to an unrelated deny (`fs.rm`, `git.no-verify`, …) that
262
+ * made no identity decision at all.
265
263
  *
266
- * HARDCUT (Tarun's rule, 2026-09-29): "the repos where `adl-
267
- * config.toml` does not exist have no business running hooks" — this
268
- * REVERSES the earlier "global identity baseline" (W2 build item 3 / R2,
269
- * STATUS.md 12p), which ran exactly these rules
270
- * (unconditionally enabled, with the schema's own defaults) even in an
271
- * UNMANAGED repo or one with `[hooks] enabled = false`. `main.ts` no longer
272
- * calls anything for either of those cases but a strict, silent no-op — see
273
- * its own header and `silentNoop`. The rule ids themselves stay meaningful
274
- * only for the logging purpose above, in the repos where hooks already run.
264
+ * This is NOT a baseline that runs anywhere else: hooks run only in a repo
265
+ * with its own `adl-config.toml` where `adl hooks deploy` has run
266
+ * (Tarun, 2026-09-29: "the repos where `adl-config.toml` does not exist have
267
+ * no business running hooks"). `main.ts` calls nothing but a strict, silent
268
+ * no-op for an unmanaged repo or one with `[hooks] enabled = false` — see its
269
+ * own header and `silentNoop`.
275
270
  */
276
271
  const IDENTITY_RULE_IDS: ReadonlySet<RuleId> = new Set([
277
- 'adl.session-required-for-writes',
272
+ 'adl.run-required-for-writes',
278
273
  'adl.git-identity',
279
274
  'adl.token-minting-role',
280
275
  'tool.azure-devops',
@@ -285,18 +280,17 @@ const IDENTITY_RULE_IDS: ReadonlySet<RuleId> = new Set([
285
280
  ])
286
281
 
287
282
  /**
288
- * F9 (independent review, 2026-09-29): the four role-gate rules that deny a
289
- * SPECIFIC Azure DevOps MCP tool call by the caller's identity
290
- * (`adl.workitem-requires-tarun-or-vivek`, `adl.pr-create-update-role`,
291
- * `adl.pr-review-role`, `adl.build-run-denied`). None of these are in
292
- * `IDENTITY_RULE_IDS` above — that set only ever covered the FALLBACK/
293
- * needs-identity/no-identity rules, never a rule that denies WITH an
294
- * identity already resolved, on the strength of who that identity is. Left
295
- * out of the deny-side identity logging entirely, even though every one of
296
- * them can only ever fire on the exact same Azure DevOps MCP tool-call shape
297
- * Decision 5's PASS-side logging already covers (`isAdoMcpToolCall`, below)
298
- * — a role-gate deny is JUST AS MUCH an identity decision as the PASS it
299
- * would have been without the role mismatch.
283
+ * The four role-gate rules that deny a SPECIFIC Azure DevOps MCP tool call by
284
+ * the caller's identity (`adl.workitem-requires-tarun-or-vivek`,
285
+ * `adl.pr-create-update-role`, `adl.pr-review-role`,
286
+ * `adl.build-run-denied`). None of these are in `IDENTITY_RULE_IDS` above —
287
+ * that set covers the rules that fire when no identity is resolved or
288
+ * carried, never a rule that denies WITH an identity already resolved, on the
289
+ * strength of who that identity is. Each of them can only fire on the same
290
+ * Azure DevOps MCP tool-call shape the PASS-side logging covers
291
+ * (`isAdoMcpToolCall`, below), so a role-gate deny is just as much an
292
+ * identity decision as the PASS it would have been without the role
293
+ * mismatch, and its deny log line carries `identity_source` too.
300
294
  */
301
295
  const ROLE_GATE_RULE_IDS: ReadonlySet<RuleId> = new Set([
302
296
  'adl.workitem-requires-tarun-or-vivek',
@@ -314,23 +308,23 @@ interface EffectiveIdentity {
314
308
  }
315
309
 
316
310
  /**
317
- * Where the effective agent identity for THIS decision came from (W2 build
318
- * item 5 — STATUS.md 12p), AND the agent it
319
- * actually names (M8, STATUS.md 12p) — a valid
311
+ * Where the effective agent identity for THIS decision came from
312
+ * (`identity_source` in the log), AND the agent it actually names: a valid
320
313
  * inline `ADL_AGENT_ID_AGENT=` on the command itself (step 1 of the
321
- * standard), else the session env or the machine default-agent file (steps
322
- * 2-3, `resolveFromEnvOrFile`'s own `source`/`agent`), else `none`/no agent.
323
- * A tool-call input carries no command text at all, so it can never be
324
- * `inline` — the override for an MCP tool call is `adl run --as` (session
325
- * env), matching the standard's own note on that.
314
+ * resolution order), else the session env or the machine default-agent file
315
+ * (steps 2-3, `resolveFromEnvOrFile`'s own `source`/`agent`), else
316
+ * `none`/no agent. A tool-call input carries no command text at all, so it
317
+ * can never be `inline`: its identity is the session env or the machine
318
+ * default-agent file. MCP is the primary route to Azure DevOps operations;
319
+ * `ADL_AGENT_ID_AGENT=<agent> adl mcp cli <command>` (which does carry an
320
+ * inline prefix) is the fallback when MCP is not working.
326
321
  *
327
322
  * The AGENT half matters because it can differ from the session's own
328
323
  * `ADL_AGENT_ID_AGENT`: `ADL_AGENT_ID_AGENT=agent-vivek git push …` run in
329
324
  * an agent-tarun session is agent-vivek's push, not agent-tarun's — the
330
- * override, not the session env, is what actually acted, and `../hooks/log.ts`
331
- * reads THIS agent for the log's `agent` column instead of the session
332
- * env var it used to read unconditionally (M8's second symptom: "the agent
333
- * column shows the session agent" even on an overridden command).
325
+ * override, not the session env, is what actually acted, and
326
+ * `../hooks/log.ts` reads THIS agent for the log's `agent` column rather
327
+ * than the session env var.
334
328
  */
335
329
  function effectiveIdentityFor(input: DecideInput, engineCtx: EngineContext): EffectiveIdentity {
336
330
  const resolution = resolveFromEnvOrFile(engineCtx.env)
@@ -344,10 +338,10 @@ function effectiveIdentityFor(input: DecideInput, engineCtx: EngineContext): Eff
344
338
  }
345
339
 
346
340
  /**
347
- * R7 (STATUS.md 12p, re-review 2026-09-28 night): the
348
- * resolved FALLBACK identity alone (steps 2-3 of the standard: env, else the
349
- * machine default-agent file) — never the coarse, whole-command "any inline
350
- * override anywhere on the line" `effectiveIdentityFor` also reports.
341
+ * The resolved FALLBACK identity alone (steps 2-3 of the resolution order:
342
+ * env, else the machine default-agent file) — never the coarse,
343
+ * whole-command "any inline override anywhere on the line"
344
+ * `effectiveIdentityFor` also reports.
351
345
  *
352
346
  * `adl.git-identity`'s REWRITE stage (`decision.rewrite`) and its own
353
347
  * fallback-based DENY reasons (`identity-mismatch`'s hint, `unrewritable-
@@ -393,11 +387,10 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
393
387
  //
394
388
  // Every branch below decided an identity (the rewrite ALWAYS comes from
395
389
  // adl.git-identity), so every inv.record?.() call here carries
396
- // identitySource/identityAgent. R7 (STATUS.md 12p):
397
- // the FALLBACK identity specifically, not `effectiveIdentityFor`'s coarse
398
- // whole-command value — see `fallbackIdentity`'s own doc for why a
399
- // rewrite is always about the fallback, never an inline override
400
- // elsewhere on a chained command.
390
+ // identitySource/identityAgent — the FALLBACK identity specifically, not
391
+ // `effectiveIdentityFor`'s coarse whole-command value (see
392
+ // `fallbackIdentity`'s own doc for why a rewrite is always about the
393
+ // fallback, never an inline override elsewhere on a chained command).
401
394
  if (!decision.blocked && decision.rewrite) {
402
395
  const identity = fallbackIdentity(engineCtx)
403
396
  const identitySource = identity.source
@@ -413,7 +406,7 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
413
406
  inv.record?.({ reason: `REWRITE ${decision.rewrite.ruleId}`, ...identityFields(identity) })
414
407
  return { stdout: `${JSON.stringify(rendered)}\n`, stderr: '', exitCode: 0 }
415
408
  }
416
- // C2: `native-shell` here is only reached when the host could not
409
+ // `native-shell` here is only reached when the host could not
417
410
  // render a rewrite for this payload shape (Kimi has none at all;
418
411
  // Cursor's beforeShellExecution has no tool_input to replace) — SKIP
419
412
  // (allow unchanged) is only safe when `ADL_AGENT_ID_AGENT` is actually
@@ -434,7 +427,7 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
434
427
  return denyHostCannotRewrite(spec, inv.host, message)
435
428
  }
436
429
 
437
- // R3 (STATUS.md 12p, re-review 2026-09-28 night): the
430
+ // Walker-found identity-bearing shapes the rewrite scanner missed: the
438
431
  // branch above only runs when `adl.git-identity`'s own narrow, offset-
439
432
  // based scanner recognized the command as identity-bearing at all
440
433
  // (`decision.rewrite` set) — it does not walk into `if`/`!`/`for..do`/
@@ -444,11 +437,11 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
444
437
  // backstop for a shape THIS scanner misses on a REWRITING host's native
445
438
  // shell). But `../rules/shell/invocation.ts`'s walker (reused here via
446
439
  // `identityBearingReason`, already proven against every one of those
447
- // shapes for `adl.session-required-for-writes`'s own deny) DOES find them
440
+ // shapes for `adl.run-required-for-writes`'s own deny) DOES find them
448
441
  // — and once found, there is no rewritten command to offer at all (this
449
442
  // scanner never computed one), so the only safe outcomes are: a
450
443
  // native-shell tool with an ENV-sourced identity (its child inherits it
451
- // regardless of any rewrite, exactly like the C2 branch above), or an
444
+ // regardless of any rewrite, exactly like the native-shell SKIP in the rewrite branch above), or an
452
445
  // inline override already on the command text (travels with the text
453
446
  // itself, no env inheritance needed) — anything else must be denied
454
447
  // rather than run with no identity anyone can prove reached the child.
@@ -476,13 +469,11 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
476
469
  // unrelated deny (fs.rm, git.no-verify, …) made no identity decision at
477
470
  // all. A PASS made one too when the command is identity-bearing but
478
471
  // needed no rewrite because it ALREADY carried a valid inline override
479
- // (M8, STATUS.md 12p — "the override's PASS
480
- // line"): `rewriteGitNetworkCommands`'s `unchanged` outcome covers BOTH
481
- // "not identity-bearing at all" and "fully covered by an inline override
482
- // already", and only `commandHasValidInlineIdentity` tells those two
483
- // apart from here.
484
- // R7 (STATUS.md 12p, re-review 2026-09-28 night): a
485
- // `adl.git-identity` deny (identity-mismatch/unrewritable-wrapper/
472
+ // (the override's PASS line): `rewriteGitNetworkCommands`'s `unchanged`
473
+ // outcome covers BOTH "not identity-bearing at all" and "fully covered by
474
+ // an inline override already", and only `commandHasValidInlineIdentity`
475
+ // tells those two apart from here.
476
+ // An `adl.git-identity` deny (identity-mismatch/unrewritable-wrapper/
486
477
  // network-alias-redefinition/dynamic-agent/unsafe-identity) is ALWAYS
487
478
  // about the piece LACKING a valid override — the same fallback-only
488
479
  // reasoning `fallbackIdentity`'s doc gives the rewrite branch, and
@@ -490,15 +481,13 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
490
481
  // hint ("your session's own resolved identity is X"). The coarse
491
482
  // `effectiveIdentityFor` could otherwise report an unrelated, valid
492
483
  // override sitting on a DIFFERENT piece of the same chained command. The
493
- // other three identity rules keep the coarse helper: `adl.session-
494
- // required-for-writes` only ever denies when `commandHasValidInlineIdentity`
495
- // is ALSO false (so the two never actually disagree for it), and `adl.
496
- // token-minting-role`/`tool.azure-devops` are not piece-correlated by this
497
- // change.
498
- // F9: computed here (moved ahead of the PASS-side comment below, which
499
- // used to be the only reader) so the DENY-side identity computation above
500
- // can also test it — a role-gate deny of an Azure DevOps MCP call is the
501
- // same shape as its PASS, just with the wrong identity.
484
+ // other identity rules keep the coarse helper: `adl.run-required-for-writes`
485
+ // only ever denies when `commandHasValidInlineIdentity` is ALSO false (so
486
+ // the two never actually disagree for it), and
487
+ // `adl.token-minting-role`/`tool.azure-devops` are not piece-correlated.
488
+ // `isAdoMcpToolCall` is computed ahead of `denyIdentity` because the
489
+ // DENY-side computation tests it too: a role-gate deny of an Azure DevOps
490
+ // MCP call is the same shape as its PASS, just with the wrong identity.
502
491
  const isAdoMcpToolCall = input.kind === 'tool-call' && KNOWN_MCP_TOOL_NAMES.has(mcpToolName(input.tool) ?? '')
503
492
  const denyIdentity =
504
493
  decision.blocked && (IDENTITY_RULE_IDS.has(decision.ruleId) || (isAdoMcpToolCall && ROLE_GATE_RULE_IDS.has(decision.ruleId)))
@@ -506,7 +495,7 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
506
495
  ? fallbackIdentity(engineCtx)
507
496
  : effectiveIdentityFor(input, engineCtx)
508
497
  : undefined
509
- // Decision 5 (STATUS.md 12p): an ALLOWED Azure DevOps MCP
498
+ // An ALLOWED Azure DevOps MCP
510
499
  // tool call — reads included (workitem_list_or_get/pr_list_or_get/
511
500
  // build_list_or_get, not only the four writes) — logs `identitySource`/
512
501
  // `identityAgent` too, the SAME field names the shell path already uses
@@ -515,11 +504,11 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
515
504
  // tool-call branch already reflects that, unchanged), so this is exactly
516
505
  // the session's resolved identity (env, else the machine default-agent
517
506
  // file). Every one of these calls ALREADY required a resolvable identity
518
- // to reach this PASS line at all (`adl.session-required-for-writes` denies
507
+ // to reach this PASS line at all (`adl.run-required-for-writes` denies
519
508
  // otherwise) — this only makes that already-decided identity visible in
520
509
  // the log, the same way the shell path's own inline-override PASS line
521
- // does (M8's "the override's PASS line"). `isAdoMcpToolCall` itself is
522
- // computed above, ahead of `denyIdentity` — F9 needs it there too.
510
+ // does. Tarun, 2026-09-29: every Azure DevOps MCP call logs
511
+ // `identity_source`, reads included.
523
512
  const passIdentity = !decision.blocked && ((input.kind === 'command' && commandHasValidInlineIdentity(input.command)) || isAdoMcpToolCall) ? effectiveIdentityFor(input, engineCtx) : undefined
524
513
  inv.record?.(
525
514
  decision.blocked
@@ -87,14 +87,14 @@ export type DecideInput =
87
87
  | { readonly kind: 'command'; readonly command: string }
88
88
  | { readonly kind: 'tool-call'; readonly tool: string; readonly input: Readonly<Record<string, unknown>> }
89
89
 
90
- export interface DenyDecision {
90
+ interface DenyDecision {
91
91
  readonly blocked: true
92
92
  readonly ruleId: RuleId
93
93
  readonly userMessage: string
94
94
  readonly agentMessage: string
95
95
  }
96
96
 
97
- export interface AdviceDecision {
97
+ interface AdviceDecision {
98
98
  readonly blocked: false
99
99
  readonly advice?: { readonly ruleId: RuleId; readonly userMessage: string; readonly agentMessage: string }
100
100
  /**
@@ -205,9 +205,8 @@ function decideCommand(command: string, ctx: EngineContext): Decision {
205
205
  }
206
206
 
207
207
  // adl.git-identity's REWRITE stage (docs/architecture/cli-design.md §1a;
208
- // widened by STATUS.md 12p, "The standard", to
209
- // every identity-bearing command class, not only network git): every rule
210
- // passed — carry the resolved identity (steps 2-3: session env, else the
208
+ // it covers every identity-bearing command class, not only network git):
209
+ // every rule passed — carry the resolved identity (steps 2-3: session env, else the
211
210
  // machine default-agent file) into every identity-bearing invocation in
212
211
  // the command. A VALID inline override (step 1) is honoured as-is
213
212
  // (`kind: 'unchanged'`, handled inside `rewriteGitNetworkCommands` itself,
@@ -216,19 +215,16 @@ function decideCommand(command: string, ctx: EngineContext): Decision {
216
215
  // rule can be disabled per-repo; an unsafe identity is never the rule's to
217
216
  // see).
218
217
  //
219
- // H3 (STATUS.md 12p): `needs-identity` (an
220
- // identity-bearing command with no inline override and no resolvable
221
- // fallback) USED to fall through here unhandled, relying entirely on
222
- // `adl.session-required-for-writes` having already denied the SAME
223
- // command earlier in the rule pass — a separate classification (the
218
+ // `needs-identity` (an identity-bearing command with no inline override
219
+ // and no resolvable fallback) is denied HERE, directly, rather than left
220
+ // to `adl.run-required-for-writes` having already denied the SAME command
221
+ // earlier in the rule pass: that rule is a separate classification (the
224
222
  // shared shell/invocation.ts walker) that can be disabled per repo
225
- // (`[rules."adl.session-required-for-writes"] enabled = false`) or simply
226
- // not recognize a shape this scanner does. Either way, nothing else here
227
- // stands between an unidentified network git command and a plain allow.
228
- // The engine now denies it directly instead of trusting another rule to
229
- // have already covered the same ground.
230
- // L4 (STATUS.md 12p): resolve the fallback
231
- // identity — which can read the REAL machine default-agent file
223
+ // (`[rules."adl.run-required-for-writes"] enabled = false`) or simply not
224
+ // recognize a shape this scanner does, and nothing else here would stand
225
+ // between an unidentified network git command and a plain allow.
226
+ //
227
+ // The fallback identity — which can read the REAL machine default-agent file
232
228
  // (`resolveFromEnvOrFile`) — ONLY when the command actually has an
233
229
  // identity-bearing piece that would use it. A probe scan with
234
230
  // `fallback: null` is fallback-INDEPENDENT for every outcome except
@@ -5,7 +5,7 @@
5
5
  * branch on `ADL_AGENT_ID_AGENT` at all: the matrix's own hook-action column
6
6
  * shows ❌ for both `agent-tarun`/`agent-vivek` and `agent-reviewer`, so there
7
7
  * is no identity this tool is allowed for. With no identity at all,
8
- * `adl.session-required-for-writes` (registered ahead of this rule) reports
8
+ * `adl.run-required-for-writes` (registered ahead of this rule) reports
9
9
  * first with its own, more specific "no session" message; this rule is what
10
10
  * fires once an identity IS present, which is the case that rule leaves
11
11
  * alone.
@@ -25,10 +25,10 @@ export const adlBuildRunDenied: RuleSpec = {
25
25
  category: 'tool-call',
26
26
  severity: 'deny',
27
27
  enabledByDefault: true,
28
- summary: 'Deny build_run for every identity (docs/operations/agent-permissions.md row 12) — the MCP tool AND its adl mcp cli equivalent (M4).',
28
+ summary: 'Deny build_run for every identity (docs/operations/agent-permissions.md row 12) — the MCP tool AND its adl mcp cli equivalent.',
29
29
  params: noParams,
30
30
  match(inv: Invocation): Finding | null {
31
- // M4 (STATUS.md 12p): also catch `adl mcp cli build-run` — same tool, same deny.
31
+ // Also catch `adl mcp cli build-run` — same tool, same deny.
32
32
  const call = toolCallFor(inv)
33
33
  if (call === null) return null
34
34
  if (mcpToolName(call.tool) !== 'build_run') return null
@@ -1,8 +1,8 @@
1
1
  /**
2
- * `adl.git-credential-bypass` — H2 (STATUS.md 12p): deny, for agents, every
2
+ * `adl.git-credential-bypass` — deny, for agents, every
3
3
  * shell shape that reaches Azure DevOps credentials or bypasses
4
4
  * `bin/git-ado`'s routing entirely, without touching any of the specific
5
- * verbs `adl.session-required-for-writes`/`adl.git-identity` already police:
5
+ * verbs `adl.run-required-for-writes`/`adl.git-identity` already police:
6
6
  *
7
7
  * - An absolute git binary other than the managed front controller
8
8
  * `/usr/local/bin/git` (that IS the path `bin/git-ado` installs itself
@@ -13,7 +13,7 @@
13
13
  * untouched.
14
14
  * - `git remote update` — fetches every configured remote, the same
15
15
  * network operation as `git fetch`, but not a verb
16
- * `adl.session-required-for-writes`'s `NETWORK_GIT_VERBS` recognizes.
16
+ * `adl.run-required-for-writes`'s `NETWORK_GIT_VERBS` recognizes.
17
17
  * - `git submodule update/sync/foreach` — `update`/`sync` can fetch a
18
18
  * submodule's own remote; `foreach` runs an arbitrary shell command once
19
19
  * per submodule, unauditable by this hook.
@@ -21,7 +21,7 @@
21
21
  * credential directly, sidestepping the front controller entirely.
22
22
  *
23
23
  * `security find-generic-password`/`find-internet-password` naming Azure
24
- * DevOps (the fifth H2 item — a macOS Keychain read, not a git operation at
24
+ * DevOps (a macOS Keychain read, not a git operation at
25
25
  * all) is `adl.security-keychain-ado` below, in the same file since it
26
26
  * shares `namesAzureDevops`, but registered as its own `category: 'tool'`
27
27
  * rule: `tests/unit/rules-git-deny-guidance.test.ts` requires every
@@ -33,14 +33,13 @@
33
33
  * an intentional, heavily-tested feature — `tests/unit/rules-git-worktree.
34
34
  * test.ts`'s dozens of `git -c alias.wt=worktree`-shaped corpus entries SEE
35
35
  * THROUGH a non-network inline alias on purpose). Two narrower, resolved
36
- * pieces of that space ARE covered, R9 correcting this header's stale
37
- * "BLOCKED" note (STATUS.md 12p):
36
+ * pieces of that space ARE covered:
38
37
  * - a SELF-referential inline `-c alias.<verb>=<value>`/`--config-env`
39
38
  * naming the LITERAL subcommand this invocation runs, where `<value>`'s
40
39
  * own verb is network/credential — `adl.git-identity`'s own
41
40
  * `network-alias-redefinition` reason (`../shell/git-identity.ts`), not
42
41
  * this rule.
43
- * - R4 (re-review 2026-09-28 night): a REPO-CONFIGURED alias (`.git/config`,
42
+ * - a REPO-CONFIGURED alias (`.git/config`,
44
43
  * invisible to the walker's own inline/env-var-only resolution) whose
45
44
  * value's verb is network/credential — `repo-alias-network-verb` below,
46
45
  * resolved via the injectable `ctx.index.configuredAlias` port
@@ -48,7 +47,7 @@
48
47
  * stay hermetic. Still narrower than a blanket deny: a non-network
49
48
  * repo-configured alias (`git st` → `alias.st=status`) is untouched.
50
49
  *
51
- * R4 also adds three more front-controller bypasses here, all sharing the
50
+ * Three more front-controller bypasses are denied here, all sharing the
52
51
  * same reasoning: `/usr/local/bin/git` (`bin/git-ado`) routes on the
53
52
  * LITERAL verb/binary an agent typed — it does not resolve `PATH`
54
53
  * overrides, `command -p`'s own default `$PATH`, or `xcrun`'s tool
@@ -130,7 +129,7 @@ const CREDENTIAL_HELPER_BINARY_PREFIX = 'credential-'
130
129
  * that holds a credential for a short-lived window and exits — `git
131
130
  * credential-cache exit` merely stops it); it never reads or writes a
132
131
  * platform secret store the way `credential-osxkeychain`/`credential-
133
- * manager`/… do, and this exact allow case predates R4 (H2's own corpus).
132
+ * manager`/… do, and this exact allow case is part of this rule's own corpus.
134
133
  * Excluded from the deny by name rather than widened into a blanket
135
134
  * "every credential-* helper", to avoid regressing that settled behaviour.
136
135
  */
@@ -143,9 +142,8 @@ function isDeniedCredentialHelper(subcommandOrName: string): boolean {
143
142
 
144
143
  /**
145
144
  * Git's own real subcommand vocabulary (porcelain and common plumbing),
146
- * lower-cased — R4 (STATUS.md 12p): gates the repo-
147
- * configured-alias lookup (`ctx.index.configuredAlias`) to an UNKNOWN verb
148
- * only, per this finding's own text ("resolve unknown git verbs"), so an
145
+ * lower-cased — gates the repo-configured-alias lookup
146
+ * (`ctx.index.configuredAlias`) to an UNKNOWN verb only, so an
149
147
  * ordinary `git status`/`git log`/… never pays for a `git config --get`
150
148
  * shell-out. Not exhaustive — an obscure real git verb missing here only
151
149
  * costs one harmless extra (correctness-preserving) lookup that resolves to
@@ -163,8 +161,8 @@ const KNOWN_GIT_VERBS: ReadonlySet<string> = new Set([
163
161
  /**
164
162
  * `PATH=`/`export PATH=` anywhere in `command`, co-occurring with a `git`
165
163
  * invocation this rule is already deciding — coarse (whole-command, not
166
- * piece-scoped) by design, matching R3's own precedent elsewhere in this
167
- * package: a PATH override ahead of `git` ANYWHERE on the line is suspicious
164
+ * piece-scoped) by design, matching the other coarse textual checks in this
165
+ * package (see `containsIdentityBearingToken` in `git-helpers.ts`): a PATH override ahead of `git` ANYWHERE on the line is suspicious
168
166
  * enough on its own that over-denial costs nothing legitimate.
169
167
  */
170
168
  function pathOverridePresent(command: string): boolean {
@@ -8,8 +8,9 @@
8
8
  * `adl run -- codex` session ran `git push -u origin feat/adl-m3-finish`
9
9
  * through the lean-ctx MCP tool `mcp__lean_ctx__ctx_shell`; Codex gives
10
10
  * `ADL_AGENT_ID_AGENT` only to its own shell tool, so the push executed with
11
- * no identity and `bin/git-ado`'s HUMAN pass-through (bin/git-ado:191-194)
12
- * pushed with Tarun's own credential helper. The hook knew the session
11
+ * no identity and `bin/git-ado` (which then passed an unset identity through
12
+ * to the human's credential helper; it now fails closed unless a real TTY and
13
+ * `ADL_HUMAN_AZDO=1`) pushed with Tarun's own credential. The hook knew the session
13
14
  * identity — it is in the hook's own environment — but passed the command
14
15
  * through unchanged. This module is the fix: the command is REWRITTEN to
15
16
  * carry the identity (`git push …` → `ADL_AGENT_ID_AGENT=agent-tarun git
@@ -25,9 +26,9 @@
25
26
  * into the human credential), or a `sudo`/`doas` wrapper, which strips
26
27
  * the environment the identity travels in. Both are denies rather than
27
28
  * rewrites: an inexact rewrite is a deny (cli-design.md §1a's rule). With
28
- * no session identity at all this rule stays silent —
29
- * `adl.session-required-for-writes` denies the write with the
30
- * `adl run` hint first.
29
+ * no agent identity at all this rule stays silent —
30
+ * `adl.run-required-for-writes` denies the write with the
31
+ * inline-prefix hint first.
31
32
  *
32
33
  * 2. The REWRITE stage, computed in `../engine.ts`'s `decideCommand` after
33
34
  * every rule passed: `../shell/git-identity.ts` rewrites the command
@@ -67,7 +68,7 @@ import { NETWORK_GIT_VERBS, scanGitIdentityConflicts, type GitIdentityDenyReason
67
68
 
68
69
  export const RULE_ID = 'adl.git-identity'
69
70
 
70
- export type GitIdentityRuleReason = Extract<
71
+ type GitIdentityRuleReason = Extract<
71
72
  GitIdentityDenyReason,
72
73
  'identity-mismatch' | 'unrewritable-wrapper' | 'network-alias-redefinition' | 'dynamic-agent'
73
74
  >
@@ -75,14 +76,13 @@ export type GitIdentityRuleReason = Extract<
75
76
  /** Messages for the rule's two deny reasons and for the engine rewrite-stage nets (unsafe identity). */
76
77
  export function gitIdentityDenyMessage(reason: GitIdentityDenyReason, ctx: MessageContext, identity: string | undefined): RuleMessage {
77
78
  if (reason === 'identity-mismatch') {
78
- // L1 (STATUS.md 12p): the 2026-09-28 standard
79
- // widened this reason to mean ONLY "empty or not a recognized agent" —
80
- // a valid inline override that merely NAMES A DIFFERENT agent than the
81
- // session's own is no longer a conflict at all (see
82
- // applyIdentityOutcome's doc in ../shell/git-identity.ts): it is the
83
- // override, and it wins. The old wording ("a different agent identity
84
- // ... conflicts with this session") described that earlier, no-longer-
85
- // true behavior and was actively misleading about what to actually fix.
79
+ // Under the one-agent-identity standard (Tarun, 2026-09-28) this reason
80
+ // means ONLY "empty or not a recognized agent": a valid inline override
81
+ // that merely NAMES A DIFFERENT agent than the session's own is not a
82
+ // conflict at all (see applyIdentityOutcome's doc in
83
+ // ../shell/git-identity.ts) — it is the override, and it wins. The
84
+ // message therefore says what to fix (an empty or unrecognized value),
85
+ // not that another agent "conflicts with this session".
86
86
  const user = 'the inline ADL_AGENT_ID_AGENT override on this command is empty or not a recognized agent'
87
87
  const hint = identity !== undefined ? ` Your session's own resolved identity is ${identity}; remove the override to use it,` : ' Remove the override,'
88
88
  return {
@@ -124,22 +124,22 @@ export function gitIdentityDenyMessage(reason: GitIdentityDenyReason, ctx: Messa
124
124
  `directly instead of aliasing it inline. Blocked: ${ctx.snippet}`,
125
125
  }
126
126
  }
127
- const user = "the session's agent identity is not a safe shell word"
127
+ const user = 'the agent identity is not a safe shell word'
128
128
  return {
129
129
  user,
130
130
  agent:
131
- `DENIED ${user}: this session's ${ADL_AGENT_ID_ENV_VAR} contains characters outside [A-Za-z0-9_-], ` +
132
- 'so the hook cannot place it on a command line. The session is misconfigured — start it with `adl run`. ' +
131
+ `DENIED ${user}: the ${ADL_AGENT_ID_ENV_VAR} value in this environment contains characters outside [A-Za-z0-9_-], ` +
132
+ `so the hook cannot place it on a command line. Prefix the command with ${ADL_AGENT_ID_ENV_VAR}=<agent-tarun|agent-vivek|agent-reviewer> instead. ` +
133
133
  `Blocked: ${ctx.snippet}`,
134
134
  }
135
135
  }
136
136
 
137
137
  /**
138
- * H3 (STATUS.md 12p): the deny rendered by
139
- * `../engine.ts`'s rewrite stage itself for a `needs-identity` outcome —
138
+ * The deny rendered by `../engine.ts`'s rewrite stage itself for a
139
+ * `needs-identity` outcome —
140
140
  * an identity-bearing command with no valid inline override and no
141
141
  * resolvable fallback (steps 2-3 of the standard). This is defense in
142
- * depth: `adl.session-required-for-writes` is expected to have already
142
+ * depth: `adl.run-required-for-writes` is expected to have already
143
143
  * denied the same command with this same standard message earlier in the
144
144
  * rule pass, but it is a SEPARATE classification that can be disabled per
145
145
  * repo or simply miss a shape this scanner recognizes — see engine.ts's own
@@ -159,14 +159,14 @@ export function gitIdentityNeedsIdentityMessage(ctx: MessageContext): RuleMessag
159
159
  * tool input, and the identity is not otherwise present in THIS invocation's
160
160
  * own environment: an MCP-class tool (Kimi has no `renderRewrite` at all),
161
161
  * or a native-shell tool whose identity resolved from the machine
162
- * default-agent file rather than the session env (C2 — the hook process
162
+ * default-agent file rather than the session env (the hook process
163
163
  * read that file itself; a child process this shell tool spawns never sees
164
164
  * `ADL_AGENT_ID_AGENT`, so it would reach Azure DevOps as the human, which
165
165
  * is the exact incident this module exists to close). `agent` is the
166
166
  * resolved fallback identity (steps 2-3 of the standard) when one resolved
167
167
  * — always the case at both call sites, since a `rewrite` decision only
168
168
  * exists once a fallback resolved — so the message can name the EXACT
169
- * prefix to add (M1), not just point at "an agent" in the abstract.
169
+ * prefix to add, not just point at "an agent" in the abstract.
170
170
  */
171
171
  export function hostCannotRewriteMessage(host: string, ctx: MessageContext, agent: string | undefined): RuleMessage {
172
172
  const prefix = `${ADL_AGENT_ID_ENV_VAR}=${agent ?? '<agent>'}`
@@ -174,7 +174,7 @@ export function hostCannotRewriteMessage(host: string, ctx: MessageContext, agen
174
174
  // OpenCode's fail-closed path) writes `message.user`, not `message.agent`,
175
175
  // to stderr (see ../../pre-tool-use/handler.ts's `denyHostCannotRewrite`),
176
176
  // and that stream is what the agent itself reads on those hosts.
177
- const user = `this agent surface (${host}) cannot carry the session identity into this command; prefix it with \`${prefix}\` and retry`
177
+ const user = `this agent surface (${host}) cannot carry the agent identity into this command; prefix it with \`${prefix}\` and retry`
178
178
  return {
179
179
  user,
180
180
  agent:
@@ -193,16 +193,16 @@ export const adlGitIdentity: RuleSpec = {
193
193
  summary: 'Deny an identity-bearing command whose inline ADL_AGENT_ID_AGENT is invalid/empty, or that runs through sudo/doas.',
194
194
  params: noParams,
195
195
  match(inv, ctx): Finding | null {
196
- // WIDENED 2026-09-28 (STATUS.md 12p, W2 build
197
- // item 3): every identity-bearing command class, not only network git —
196
+ // Every identity-bearing command class, not only network git
197
+ // (widened 2026-09-28 by the one-agent-identity standard) —
198
198
  // `adl mcp cli`/`adl repo doctor`/`adl repo controls azdo-push`/`adl id
199
199
  // token`, `adl-agent-id exec`, and curl/wget/httpie/xh to
200
200
  // dev.azure.com/*.visualstudio.com. This rule no longer requires a
201
201
  // resolved fallback identity to run (`identity === null` used to skip
202
- // straight to session-required) — an invalid/empty INLINE override is a
202
+ // straight to run-required) — an invalid/empty INLINE override is a
203
203
  // real problem independent of whether a fallback exists; the two rules
204
204
  // still cannot both win for the same invocation because the registry
205
- // orders session-required first (`../registry.ts`) and the engine's
205
+ // orders run-required first (`../registry.ts`) and the engine's
206
206
  // `firstFinding` stops at the first rule that reports anything at all.
207
207
  let isIdentityBearing = false
208
208
  if (inv.kind === 'git') {
@@ -213,7 +213,7 @@ export const adlGitIdentity: RuleSpec = {
213
213
  if (ADL_BINARY_NAMES.has(inv.name)) {
214
214
  isIdentityBearing = !dynamic && matchesIdentityShape(values, ADL_IDENTITY_COMMAND_SHAPES)
215
215
  } else if (ADL_AGENT_ID_BINARY_NAMES.has(inv.name)) {
216
- // M5 (STATUS.md 12p): leading dash-prefixed
216
+ // Leading dash-prefixed
217
217
  // global flags (`adl-agent-id --verbose exec …`) are skipped before
218
218
  // matching the `['exec']` shape — see skipLeadingDashFlags's doc.
219
219
  isIdentityBearing = !dynamic && matchesIdentityShape(skipLeadingDashFlags(values), ADL_AGENT_ID_COMMAND_SHAPES)