@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.12 → 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 (405) hide show
  1. package/bin/adl +2 -2
  2. package/bin/git +16 -17
  3. package/bin/git-ado +25 -24
  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/fleet-host.sh +8 -5
  9. package/bin/reconcile +482 -232
  10. package/bin/reconcile-host +30 -20
  11. package/bin/setup +20 -17
  12. package/bin/shell-path-policy +15 -5
  13. package/bin/sync-and-reconcile +62 -64
  14. package/bin/validate-manifest +33 -9
  15. package/package.json +2 -10
  16. package/packages/agent-hooks/README.md +14 -9
  17. package/packages/agent-hooks/assets/hooks.json +0 -20
  18. package/packages/agent-hooks/src/cli/args.ts +1 -1
  19. package/packages/agent-hooks/src/cli/doctor.ts +6 -58
  20. package/packages/agent-hooks/src/deploy/deploy.ts +12 -41
  21. package/packages/agent-hooks/src/deploy/doctor.ts +8 -11
  22. package/packages/agent-hooks/src/deploy/index.ts +14 -14
  23. package/packages/agent-hooks/src/deploy/json-merge.ts +7 -8
  24. package/packages/agent-hooks/src/deploy/legacy-lock.ts +2 -2
  25. package/packages/agent-hooks/src/deploy/list.ts +1 -1
  26. package/packages/agent-hooks/src/deploy/lock.ts +31 -12
  27. package/packages/agent-hooks/src/deploy/profile.ts +3 -4
  28. package/packages/agent-hooks/src/deploy/source.ts +1 -1
  29. package/packages/agent-hooks/src/gating/config.ts +10 -24
  30. package/packages/agent-hooks/src/gating/root.ts +3 -3
  31. package/packages/agent-hooks/src/hooks/briefing/handler.ts +2 -2
  32. package/packages/agent-hooks/src/hooks/briefing/index.ts +27 -287
  33. package/packages/agent-hooks/src/hooks/contract.ts +17 -17
  34. package/packages/agent-hooks/src/hooks/crg/background.ts +27 -0
  35. package/packages/agent-hooks/src/hooks/crg/index.ts +7 -6
  36. package/packages/agent-hooks/src/hooks/log.ts +8 -10
  37. package/packages/agent-hooks/src/hooks/user-prompt-submit/match.ts +1 -1
  38. package/packages/agent-hooks/src/hooks/user-prompt-submit/tokenizer.ts +1 -1
  39. package/packages/agent-hooks/src/hooks/user-prompt-submit/vector.ts +6 -5
  40. package/packages/agent-hooks/src/hosts/registry.ts +1 -1
  41. package/packages/agent-hooks/src/log/adl-dir.ts +44 -0
  42. package/packages/agent-hooks/src/log/writer.ts +16 -2
  43. package/packages/agent-hooks/src/main.ts +7 -41
  44. package/packages/agent-hooks/src/pre-tool-use/handler.ts +71 -82
  45. package/packages/agent-hooks/src/rules/engine.ts +13 -17
  46. package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +3 -3
  47. package/packages/agent-hooks/src/rules/impl/adl-git-credential-bypass.ts +12 -14
  48. package/packages/agent-hooks/src/rules/impl/adl-git-identity.ts +28 -28
  49. package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +8 -9
  50. package/packages/agent-hooks/src/rules/impl/adl-human-azdo-bypass.ts +56 -59
  51. package/packages/agent-hooks/src/rules/impl/adl-identity.ts +16 -23
  52. package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +19 -16
  53. package/packages/agent-hooks/src/rules/impl/adl-pr-complete-pending.ts +2 -2
  54. package/packages/agent-hooks/src/rules/impl/adl-pr-review-role.ts +9 -12
  55. package/packages/agent-hooks/src/rules/impl/adl-pr-role.ts +5 -7
  56. package/packages/agent-hooks/src/rules/impl/adl-run-required.ts +411 -0
  57. package/packages/agent-hooks/src/rules/impl/adl-token-minting-role.ts +4 -5
  58. package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +6 -7
  59. package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +77 -70
  60. package/packages/agent-hooks/src/rules/impl/deny-allowlist.ts +159 -0
  61. package/packages/agent-hooks/src/rules/impl/git-helpers.ts +21 -23
  62. package/packages/agent-hooks/src/rules/impl/git-worktree.ts +14 -28
  63. package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +3 -3
  64. package/packages/agent-hooks/src/rules/impl/messages.ts +1 -1
  65. package/packages/agent-hooks/src/rules/impl/pr-completion.ts +1 -1
  66. package/packages/agent-hooks/src/rules/impl/tool-azure-devops.ts +35 -46
  67. package/packages/agent-hooks/src/rules/impl/tool-find.ts +34 -7
  68. package/packages/agent-hooks/src/rules/impl/tool-grep.ts +34 -12
  69. package/packages/agent-hooks/src/rules/impl/tool-native-search.ts +52 -9
  70. package/packages/agent-hooks/src/rules/ports.ts +5 -7
  71. package/packages/agent-hooks/src/rules/registry.ts +4 -6
  72. package/packages/agent-hooks/src/rules/shell/git-identity.ts +86 -101
  73. package/packages/agent-hooks/src/rules/shell/git-internals.ts +1 -1
  74. package/packages/agent-hooks/src/rules/shell/invocation.ts +24 -118
  75. package/packages/agent-hooks/src/rules/shell/piped-script.ts +1 -1
  76. package/packages/agent-hooks/src/rules/shell/prefixes.ts +1 -1
  77. package/packages/agent-hooks/src/rules/shell/protected-carrier-writes.ts +11 -10
  78. package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +26 -26
  79. package/packages/agent-hooks/src/rules/shell/substitution.ts +1 -1
  80. package/packages/agent-hooks/src/rules/shell/xargs.ts +2 -2
  81. package/packages/agent-hooks/src/rules/spec.ts +2 -2
  82. package/packages/agent-settings/README.md +287 -0
  83. package/packages/agent-settings/assets/GLOBAL-AGENTS.md +14 -16
  84. package/packages/agent-settings/assets/agents/architect.toml +2 -0
  85. package/packages/agent-settings/assets/agents/code-reviewer.toml +2 -0
  86. package/packages/agent-settings/assets/agents/executor.toml +2 -0
  87. package/packages/agent-settings/assets/agents/explore.toml +2 -0
  88. package/packages/agent-settings/assets/agents/planner.toml +2 -0
  89. package/packages/agent-settings/assets/mcp.json +0 -4
  90. package/packages/agent-settings/deploy-profile.json +139 -0
  91. package/packages/agent-settings/deploy-profile.schema.json +147 -0
  92. package/packages/agent-settings/managed/README.md +29 -30
  93. package/packages/agent-settings/managed/codex-requirements.toml +9 -9
  94. package/packages/agent-settings/package.json +20 -0
  95. package/packages/agent-settings/src/deploy/agent-render.ts +2 -2
  96. package/packages/agent-settings/src/deploy/agent-toml.ts +1 -1
  97. package/packages/agent-settings/src/deploy/agents-deploy.ts +17 -3
  98. package/packages/agent-settings/src/deploy/doctor.ts +3 -83
  99. package/packages/agent-settings/src/deploy/index.ts +6 -33
  100. package/packages/agent-settings/src/deploy/legacy-lock.ts +6 -6
  101. package/packages/agent-settings/src/deploy/list.ts +5 -19
  102. package/packages/agent-settings/src/deploy/lock.ts +8 -18
  103. package/packages/agent-settings/src/deploy/mcp-deploy.ts +10 -5
  104. package/packages/agent-settings/src/deploy/mcp-merge.ts +22 -3
  105. package/packages/agent-settings/src/deploy/mcp-source.ts +1 -1
  106. package/packages/agent-settings/src/deploy/profile.ts +11 -35
  107. package/packages/agent-settings/src/deploy/retire-lean-ctx.ts +184 -0
  108. package/packages/agent-settings/src/deploy/settings.ts +17 -22
  109. package/packages/agent-settings/src/global-surface-sweep.ts +0 -2
  110. package/packages/agent-settings/src/kimi-hooks.ts +339 -192
  111. package/packages/agent-settings/src/opencode-hooks.ts +1 -1
  112. package/packages/agent-settings/tsconfig.json +23 -0
  113. package/packages/agent-skills/assets/agent-search-tool-audit/SKILL.md +120 -0
  114. package/packages/agent-skills/assets/agent-search-tool-audit/scripts/audit.sh +276 -0
  115. package/packages/agent-skills/assets/debug-issue/SKILL.md +8 -7
  116. package/packages/agent-skills/assets/explore-codebase/SKILL.md +13 -13
  117. package/packages/agent-skills/assets/refactor-safely/SKILL.md +12 -11
  118. package/packages/agent-skills/assets/review-changes/SKILL.md +7 -7
  119. package/packages/agent-skills/assets/testing/references/e2e.md +37 -0
  120. package/packages/agent-skills/assets/testing/references/integration.md +37 -0
  121. package/packages/agent-skills/assets/testing/references/unit.md +32 -0
  122. package/packages/agent-skills/dist/deploy.d.ts +2 -0
  123. package/packages/agent-skills/dist/deploy.d.ts.map +1 -1
  124. package/packages/agent-skills/dist/deploy.js +27 -1
  125. package/packages/agent-skills/dist/deploy.js.map +1 -1
  126. package/packages/agent-skills/dist/doctor.d.ts +0 -2
  127. package/packages/agent-skills/dist/doctor.d.ts.map +1 -1
  128. package/packages/agent-skills/dist/doctor.js +1 -1
  129. package/packages/agent-skills/dist/doctor.js.map +1 -1
  130. package/packages/agent-skills/dist/fs-utils.d.ts +0 -1
  131. package/packages/agent-skills/dist/fs-utils.d.ts.map +1 -1
  132. package/packages/agent-skills/dist/fs-utils.js +1 -1
  133. package/packages/agent-skills/dist/fs-utils.js.map +1 -1
  134. package/packages/agent-skills/src/deploy.ts +29 -1
  135. package/packages/agent-skills/src/doctor.ts +1 -1
  136. package/packages/agent-skills/src/fs-utils.ts +1 -1
  137. package/packages/azdo/README.md +10 -9
  138. package/packages/azdo/package.json +1 -3
  139. package/packages/azdo/src/azdo-pl.ts +2 -54
  140. package/packages/azdo/src/azdo-pr-review.ts +4 -4
  141. package/packages/azdo/src/azdo-repo-doctor.ts +101 -52
  142. package/packages/azdo/src/azdo-wit.ts +41 -2
  143. package/packages/azdo/src/lib/agent-identity.ts +12 -14
  144. package/packages/azdo/src/lib/agent-token.ts +2 -2
  145. package/packages/azdo/src/lib/client.ts +0 -5
  146. package/packages/azdo/src/lib/graph-identity.ts +4 -4
  147. package/packages/azdo/src/workflow-rules-matrix.csv +85 -0
  148. package/packages/azdo/src/workflow-rules.ts +128 -0
  149. package/packages/fleet/manifest.json +35 -11
  150. package/packages/fleet/manifest.schema.json +62 -10
  151. package/packages/fleet/src/default-agent-file.ts +3 -3
  152. package/packages/fleet/src/install-adl-package.ts +73 -15
  153. package/packages/fleet/src/install-embedding-model.ts +13 -13
  154. package/packages/fleet/src/managed-settings.ts +7 -7
  155. package/packages/fleet/src/repo-maintain.ts +91 -55
  156. package/packages/fleet/src/scratch-reap.ts +5 -5
  157. package/packages/fleet/src/vscode-settings.ts +5 -5
  158. package/packages/repo-controls/README.md +141 -43
  159. package/packages/repo-controls/assets/promote.ts +4 -4
  160. package/packages/repo-controls/assets/reconcile-guard.sh +10 -46
  161. package/packages/repo-controls/assets/version-bump.sh +31 -84
  162. package/packages/repo-controls/bunfig.toml +6 -7
  163. package/packages/repo-controls/package/adl-compliance/AGENTS.md +5 -6
  164. package/packages/repo-controls/package/adl-compliance/conftest.py +3 -1
  165. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +4 -16
  166. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +9 -2
  167. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/notes.md +1 -0
  168. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +11 -0
  169. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/__init__.py +7 -0
  170. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/check.py +266 -0
  171. 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
  172. 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
  173. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.hidden.md +1 -0
  174. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/a.md +1 -0
  175. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/b.md +1 -0
  176. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/data.csv +1 -0
  177. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/diagram.png +1 -0
  178. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/mock.png +1 -0
  179. 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
  180. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs.md +1 -0
  181. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/grants.yaml +4 -0
  182. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p1.md +1 -0
  183. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p2.md +1 -0
  184. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p3.md +1 -0
  185. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p4.md +1 -0
  186. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p5.md +1 -0
  187. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/build.md +1 -0
  188. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/overview.md +1 -0
  189. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/install.md +1 -0
  190. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/start.md +1 -0
  191. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/grants.yaml +4 -0
  192. 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
  193. 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
  194. 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
  195. 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
  196. 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
  197. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/a.md +1 -0
  198. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/b.md +1 -0
  199. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/c.md +1 -0
  200. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/grants.yaml +4 -0
  201. 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
  202. 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
  203. 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
  204. 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
  205. 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
  206. 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
  207. 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
  208. 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
  209. 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
  210. 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
  211. 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
  212. 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
  213. 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
  214. 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
  215. 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
  216. 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
  217. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/grants.yaml +4 -0
  218. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/a.md +1 -0
  219. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/b.md +1 -0
  220. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/c.md +1 -0
  221. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/grants.yaml +4 -0
  222. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/a.md +1 -0
  223. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/b.md +1 -0
  224. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/c.md +1 -0
  225. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/grants.yaml +4 -0
  226. 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
  227. 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
  228. 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
  229. 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
  230. 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
  231. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/grants.yaml +4 -0
  232. 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
  233. 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
  234. 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
  235. 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
  236. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/grants.yaml +4 -0
  237. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/a.md +1 -0
  238. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/b.md +1 -0
  239. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/c.md +1 -0
  240. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/d.md +1 -0
  241. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/a.md +1 -0
  242. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/b.md +1 -0
  243. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/grants.yaml +6 -0
  244. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/a.md +1 -0
  245. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/b.md +1 -0
  246. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/c.md +1 -0
  247. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/grants.yaml +3 -0
  248. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/test_check.py +345 -0
  249. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +18 -5
  250. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +35 -0
  251. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/__init__.py +7 -0
  252. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/check.py +91 -0
  253. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/AGENTS.md +3 -0
  254. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/CLAUDE.md +3 -0
  255. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/-leading-hyphen.md +3 -0
  256. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/AGENTS.md +3 -0
  257. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/double--hyphen.md +3 -0
  258. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/getting started.md +3 -0
  259. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/nested/page-here.md +3 -0
  260. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/trailing-hyphen-.md +3 -0
  261. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/ui-contract.md +4 -0
  262. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/user_profile.md +3 -0
  263. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/UI-CONTRACT.png +2 -0
  264. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/diagram.png +1 -0
  265. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/index.md +4 -0
  266. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/notes.md +3 -0
  267. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/reference.html +1 -0
  268. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/2026-10-experiment.md +3 -0
  269. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/UI-CONTRACT.md +6 -0
  270. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs.md +5 -0
  271. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/test_check.py +194 -0
  272. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +14 -2
  273. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +5 -5
  274. 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
  275. 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
  276. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +58 -6
  277. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +0 -1
  278. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +64 -17
  279. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +60 -9
  280. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-clean/docs/notes.md +17 -0
  281. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-no-lines/docs/notes.md +13 -0
  282. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +0 -1
  283. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +0 -1
  284. 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
  285. 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
  286. 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
  287. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs-okf-profiles.yaml +5 -0
  288. 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
  289. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +0 -1
  290. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/experiment-ok.md +15 -0
  291. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-key.md +15 -0
  292. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-keys.md +16 -0
  293. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-created.md +11 -0
  294. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-description.md +11 -0
  295. 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
  296. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-sources.md +10 -0
  297. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-status.md +11 -0
  298. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-title.md +11 -0
  299. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/optional-keys.md +16 -0
  300. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/research-ok.md +14 -0
  301. 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
  302. 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
  303. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/operations/runbook.md +26 -0
  304. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +228 -2
  305. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +5 -0
  306. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +11 -2
  307. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +5 -3
  308. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +160 -44
  309. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +0 -2
  310. 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
  311. 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
  312. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/grants.yaml +3 -0
  313. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +0 -2
  314. 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
  315. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/grants.yaml +5 -0
  316. 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
  317. 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
  318. 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
  319. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/grants.yaml +4 -0
  320. 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
  321. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/grants.yaml +5 -0
  322. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +0 -2
  323. 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
  324. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/grants.yaml +3 -0
  325. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/register.py +127 -0
  326. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +265 -29
  327. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +75 -2
  328. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +194 -0
  329. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +56 -10
  330. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +256 -0
  331. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +40 -12
  332. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +108 -0
  333. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +1 -1
  334. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +2 -3
  335. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +23 -6
  336. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +76 -0
  337. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +58 -17
  338. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +161 -0
  339. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +35 -3
  340. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +108 -1
  341. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +281 -61
  342. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/absolute-path.yaml +3 -0
  343. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/backslash-path.yaml +3 -0
  344. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/baseline-is-a-list.yaml +2 -0
  345. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/boolean-size.yaml +3 -0
  346. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/dot-segment.yaml +3 -0
  347. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/duplicate-path.yaml +4 -0
  348. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-file.yaml +0 -0
  349. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-segment.yaml +3 -0
  350. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/float-size.yaml +3 -0
  351. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/negative-size.yaml +3 -0
  352. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-over-limit-baseline.yaml +1 -0
  353. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-schema-version.yaml +1 -0
  354. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/non-string-path.yaml +3 -0
  355. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/not-yaml.yaml +2 -0
  356. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/null-size.yaml +3 -0
  357. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/parent-segment.yaml +3 -0
  358. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/string-size.yaml +3 -0
  359. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/top-level-is-a-list.yaml +2 -0
  360. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/trailing-slash.yaml +3 -0
  361. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/unknown-key.yaml +3 -0
  362. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/wrong-schema-version.yaml +2 -0
  363. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/zero-size.yaml +3 -0
  364. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/valid.yaml +4 -0
  365. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +758 -45
  366. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +4 -3
  367. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +2 -2
  368. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/cargo_lock.py +490 -0
  369. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +368 -55
  370. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +4 -2
  371. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_declared_paths.py +523 -0
  372. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_stale_lock.py +1179 -0
  373. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +122 -3
  374. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +33 -1
  375. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +0 -11
  376. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +16 -1
  377. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +1 -2
  378. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +12 -1
  379. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +133 -147
  380. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +133 -147
  381. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +1 -1
  382. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +52 -10
  383. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +23 -4
  384. package/packages/repo-controls/package.json +2 -9
  385. package/packages/repo-controls/scripts/hooks/post-merge +13 -0
  386. package/packages/repo-controls/scripts/hooks/pre-push +3 -3
  387. package/packages/repo-controls/src/azdo-push.ts +64 -36
  388. package/packages/repo-controls/src/azure-devops-governance.ts +7 -9
  389. package/packages/repo-controls/src/azure-devops-remote.ts +1 -1
  390. package/packages/repo-controls/src/cli.ts +29 -8
  391. package/packages/repo-controls/src/compliance-config.ts +410 -2
  392. package/packages/repo-controls/src/config.ts +133 -60
  393. package/packages/repo-controls/src/constants.ts +13 -27
  394. package/packages/repo-controls/src/coverage-ratchet.ts +4 -4
  395. package/packages/repo-controls/src/doctor.ts +46 -19
  396. package/packages/repo-controls/src/gitignore-block.ts +5 -29
  397. package/packages/repo-controls/src/hook-log.ts +1 -2
  398. package/packages/repo-controls/src/hook.ts +201 -45
  399. package/packages/repo-controls/src/install.ts +14 -8
  400. package/packages/repo-controls/src/integrity.ts +3 -3
  401. package/packages/repo-controls/src/lfs.ts +111 -0
  402. package/packages/repo-controls/src/promote.ts +8 -8
  403. package/packages/repo-controls/src/runtime.ts +9 -1
  404. package/packages/repo-controls/src/workflows-drift.ts +4 -5
  405. package/packages/repo-controls/src/worktree-guard.ts +3 -3
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The one place that makes a repository's `.adl/` folder self-ignoring.
3
+ *
4
+ * Every adl component that creates `<repo>/.adl/` (the `.adl/logs/` writer,
5
+ * `adl run`'s transcript, the crg background update, the git-hook log seam)
6
+ * calls `ensureAdlGitignore` right after it creates the directory. The file it
7
+ * writes, `.adl/.gitignore` containing exactly `*\n`, ignores the folder's whole
8
+ * content INCLUDING itself, so `.adl/` never shows in `git status` -- in any git
9
+ * repository, adl-controlled or not, without ever editing the repo's own
10
+ * `.gitignore` (the `/.adl/` block `adl repo controls install` writes covers
11
+ * controlled repos only). Logs carry commands and output, so they must not be
12
+ * committable by accident.
13
+ *
14
+ * `apps/cli` and `packages/repo-controls` import this module by relative path
15
+ * (as they already do `./writer.ts`), so there is exactly one copy.
16
+ */
17
+ import { writeFileSync } from "node:fs";
18
+ import { basename, dirname, join } from "node:path";
19
+
20
+ const ADL_DIR_NAME = ".adl";
21
+
22
+ /** Exactly this content, nothing else: ignore every entry, this file included. */
23
+ const ADL_GITIGNORE_CONTENT = "*\n";
24
+
25
+ /**
26
+ * Finds the nearest `.adl` directory at or above `path` and, if it has no
27
+ * `.gitignore` yet, writes one containing `*\n`. An existing `.gitignore` is
28
+ * never overwritten or read. A `path` with no `.adl` segment (the
29
+ * `~/.local/state/adl/logs` fallback, a test tmp dir) is a no-op. The `.adl`
30
+ * directory must already exist; a missing one throws, like any other write.
31
+ */
32
+ export function ensureAdlGitignore(path: string): void {
33
+ if (basename(path) !== ADL_DIR_NAME) {
34
+ const parent = dirname(path);
35
+ if (parent !== path) ensureAdlGitignore(parent);
36
+ return;
37
+ }
38
+ try {
39
+ // "wx": create only if absent -- an existing file is left untouched.
40
+ writeFileSync(join(path, ".gitignore"), ADL_GITIGNORE_CONTENT, { flag: "wx" });
41
+ } catch (error) {
42
+ if ((error as NodeJS.ErrnoException).code !== "EEXIST") throw error;
43
+ }
44
+ }
@@ -2,7 +2,7 @@
2
2
  * The `.adl/logs/` logger (docs/architecture/cli-design.md §5a, item 9). `agent-hooks`
3
3
  * "holds logs" (§12): this module lives here and writes `hooks.log` /
4
4
  * `hooks-deny.log` (`../hooks/log.ts`); `apps/cli/src/log.ts` re-exports it
5
- * unchanged so `adl run`'s `tool-calls.log` writer keeps working. The module
5
+ * unchanged so `adl run`'s `agents/tool-calls.log` writer keeps working. The module
6
6
  * is generic across all five documented files so a caller never has to
7
7
  * reinvent the format.
8
8
  *
@@ -28,7 +28,8 @@ import {
28
28
  writeFileSync,
29
29
  } from "node:fs";
30
30
  import { homedir } from "node:os";
31
- import { dirname, join } from "node:path";
31
+ import { basename, dirname, join } from "node:path";
32
+ import { ensureAdlGitignore } from "./adl-dir.ts";
32
33
 
33
34
  export type LogFileName = "hooks" | "hooks-deny" | "tool-rewrites" | "tool-calls" | "repo-controls";
34
35
 
@@ -128,9 +129,22 @@ function tightenMode(path: string, target: number): void {
128
129
  function ensureDirSecure(dir: string): void {
129
130
  const parent = dirname(dir);
130
131
  mkdirSync(parent, { recursive: true });
132
+ // A nested log stream such as `.adl/logs/agents/` must not leave the
133
+ // repository's `.adl/` ancestor at the default mkdir mode (0755).
134
+ // Root-level streams already tightened it as `parent`; locate it rather
135
+ // than changing unrelated ancestors of the state-directory fallback.
136
+ let ancestor = parent;
137
+ while (ancestor !== dirname(ancestor)) {
138
+ if (basename(ancestor) === ".adl") {
139
+ tightenMode(ancestor, 0o700);
140
+ break;
141
+ }
142
+ ancestor = dirname(ancestor);
143
+ }
131
144
  tightenMode(parent, 0o700);
132
145
  mkdirSync(dir, { recursive: true });
133
146
  tightenMode(dir, 0o700);
147
+ ensureAdlGitignore(dir);
134
148
  }
135
149
 
136
150
  function ensureFileSecure(filePath: string): void {
@@ -7,11 +7,9 @@
7
7
  *
8
8
  * adl hook <kind> [subcommand] --host=<claude|codex|cursor|kimi|opencode>
9
9
  *
10
- * kinds: pre-tool-use, user-prompt-submit, briefing, crg <subcommand>,
11
- * lean-ctx <subcommand>
10
+ * kinds: pre-tool-use, user-prompt-submit, briefing, crg <subcommand>
12
11
  * crg subcommands: after-file-edit, pre-commit, session-stop
13
- * lean-ctx subcommands: mcp, pre-tool-use, post-tool-use
14
- * payload: JSON on stdin (NOT for `lean-ctx mcp` — see below)
12
+ * payload: JSON on stdin
15
13
  * --version prints the package version and exits 0
16
14
  *
17
15
  * Operator commands (src/cli/; no --host, no stdin):
@@ -30,14 +28,6 @@
30
28
  * loud (non-zero exit, reason on stderr) — never silently ignored.
31
29
  * - `[hooks] enabled = false`: silent no-op, same as unmanaged.
32
30
  *
33
- * `lean-ctx mcp` is the one exception to this whole flow (work item A.1): it
34
- * takes no JSON payload, needs no `--host`, and never no-ops for an
35
- * unmanaged repo (an MCP client that just spawned it expects a running
36
- * server, not a silent exit) — see `src/lean-ctx/mcp.ts`'s header. It is
37
- * dispatched before `--host` resolution, before stdin is read at all, and
38
- * bypasses `HookHandler`/`HookResult` entirely (real stdio passthrough
39
- * cannot be buffered into a string).
40
- *
41
31
  * Every other hook kind is dispatched through the shared `HookHandler` shape
42
32
  * in `src/hooks/contract.ts` so a handler never touches `process`, argv, or
43
33
  * stdin directly.
@@ -49,7 +39,7 @@
49
39
  * the shared fail-closed signal `pre-tool-use`'s own decisions already use
50
40
  * (`FAIL_CLOSED_EXIT_CODE`, `src/rules/engine.ts`) for Kimi/OpenCode denials.
51
41
  * Every other kind is advisory or best-effort (`user-prompt-submit`,
52
- * `briefing`, `crg`, `lean-ctx` pre/post/mcp) and none of them has a "block"
42
+ * `briefing`, `crg`) and none of them has a "block"
53
43
  * concept at all — worse, on Claude Code and Codex, exit code 2 from
54
44
  * `UserPromptSubmit` specifically blocks the prompt AND ERASES IT (documented
55
45
  * Claude Code hook behaviour: a `UserPromptSubmit` hook exiting 2 shows
@@ -88,13 +78,11 @@ import { handlePreToolUse } from './pre-tool-use/handler.ts'
88
78
  import { handleUserPromptSubmit } from './hooks/user-prompt-submit/handler.ts'
89
79
  import { handleBriefing } from './hooks/briefing/handler.ts'
90
80
  import { handleCrg } from './hooks/crg/handler.ts'
91
- import { handleLeanCtx } from './hooks/lean-ctx/handler.ts'
92
- import { runLeanCtxMcp } from './lean-ctx/mcp.ts'
93
81
  import { runRules } from './cli/rules.ts'
94
82
  import { runDoctor } from './cli/doctor.ts'
95
83
  import { runLogged } from './hooks/log.ts'
96
84
 
97
- const HOOK_KINDS = ['pre-tool-use', 'user-prompt-submit', 'briefing', 'crg', 'lean-ctx'] as const
85
+ const HOOK_KINDS = ['pre-tool-use', 'user-prompt-submit', 'briefing', 'crg'] as const
98
86
  type HookKind = (typeof HOOK_KINDS)[number]
99
87
 
100
88
  function isHookKind(value: string | undefined): value is HookKind {
@@ -102,14 +90,12 @@ function isHookKind(value: string | undefined): value is HookKind {
102
90
  }
103
91
 
104
92
  const CRG_SUBCOMMANDS = ['after-file-edit', 'pre-commit', 'session-stop'] as const
105
- const LEAN_CTX_SUBCOMMANDS = ['mcp', 'pre-tool-use', 'post-tool-use'] as const
106
93
 
107
94
  const HANDLERS: Readonly<Record<HookKind, HookHandler>> = {
108
95
  'pre-tool-use': handlePreToolUse,
109
96
  'user-prompt-submit': handleUserPromptSubmit,
110
97
  briefing: handleBriefing,
111
98
  crg: handleCrg,
112
- 'lean-ctx': handleLeanCtx,
113
99
  }
114
100
 
115
101
  /** Exit code `pre-tool-use` alone uses to fail closed on an undecidable payload — see this file's header (work item D). */
@@ -167,24 +153,6 @@ export async function run(argv: readonly string[]): Promise<number> {
167
153
  }
168
154
  subcommand = candidate
169
155
  }
170
- if (kind === 'lean-ctx') {
171
- const candidate = argv[1]
172
- if (candidate === undefined || !(LEAN_CTX_SUBCOMMANDS as readonly string[]).includes(candidate)) {
173
- process.stderr.write(
174
- `adl hook: lean-ctx requires a subcommand (one of ${LEAN_CTX_SUBCOMMANDS.join(', ')})\n`,
175
- )
176
- return 1
177
- }
178
- subcommand = candidate
179
- }
180
-
181
- // `lean-ctx mcp` bypasses everything below: no --host, no stdin-as-JSON,
182
- // no HookHandler dispatch, and unmanaged is NOT a no-op — see
183
- // `./lean-ctx/mcp.ts`'s header and this file's own header (work item A.1).
184
- if (kind === 'lean-ctx' && subcommand === 'mcp') {
185
- return runLeanCtxMcp(process.cwd(), process.env)
186
- }
187
-
188
156
  // az385: host resolution failure fails CLOSED (FAIL_CLOSED_EXIT_CODE, 2)
189
157
  // only for pre-tool-use — the one kind whose job is "block a dangerous
190
158
  // action," matching the invalid-JSON-on-stdin split a few lines below and
@@ -217,11 +185,9 @@ export async function run(argv: readonly string[]): Promise<number> {
217
185
  // `adl-config.toml` where `adl hooks deploy` has run — nowhere else. No
218
186
  // git root, or no `adl-config.toml` above `cwd`: a strict no-op (this
219
187
  // file's own header) — no rule evaluation, no identity check, no
220
- // `hooks.log` write. This REVERSES the earlier "global identity baseline"
221
- // (W2 build item 3 / STATUS.md 12p): that baseline
222
- // ran the four (later seven, R2) identity rules even in an unmanaged
223
- // repo; Tarun decided the repos where `adl-config.toml` does not exist
224
- // have no business running hooks at all.
188
+ // `hooks.log` write. There is no global identity baseline: a repo where
189
+ // `adl-config.toml` does not exist has no business running hooks at all.
190
+ // The same no-op applies when `[hooks] enabled = false` (below).
225
191
  const managed = resolveManagedRepo(realRootIO, cwd)
226
192
  if (!managed.managed || managed.root === null || managed.configPath === null) {
227
193
  return writeResult(silentNoop())
@@ -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