@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
@@ -1,320 +1,60 @@
1
- /**
2
- * The `briefing` hook kind.
3
- *
4
- * Ports `enact-m5/.agents/hooks/session-briefing/`
5
- * (`session-briefing.mjs` + `src/render.mjs` + `src/warmup.mjs`) onto the
6
- * `HookHandler` contract in `../contract.ts`.
7
- *
8
- * Two subprocess calls into `lean-ctx`, both behind the injected `Runner` so
9
- * tests never touch a real binary:
10
- *
11
- * 1. `hook codex-session-start` — the base lean-ctx session briefing text,
12
- * read out of its `hookSpecificOutput.additionalContext` JSON.
13
- * 2. `overview [task]` and `knowledge status` — the PROJECT WARMUP appendix,
14
- * always emitted (even with no lean-ctx at all) because its static
15
- * workflow block does not depend on either call succeeding.
16
- *
17
- * `lean-ctx` is a GLOBAL binary installed fleet-wide on `PATH` by
18
- * global-tools (see its `manifest.json`'s `"lean-ctx"` entry) — unlike the
19
- * reference tree, there is no repo-local `.agents/bin/lean-ctx-local`
20
- * wrapper here, so every call below resolves `lean-ctx` off the ambient
21
- * `PATH` directly. What stays repo-local is lean-ctx's own state: every call
22
- * still sets `LEAN_CTX_CONFIG_DIR`/`LEAN_CTX_DATA_DIR`/`LEAN_CTX_STATE_DIR`/
23
- * `LEAN_CTX_CACHE_DIR` rooted at `<root>/.agents/lean-ctx/<config/lean-ctx|data|state|cache>`
24
- * (`../../lean-ctx/env.ts`'s `leanCtxEnv` — shared with the `lean-ctx`
25
- * pre/post-tool-use hook kind, `../lean-ctx/index.ts`), so lean-ctx's
26
- * config/data/state/cache stay per-repository even though the binary itself
27
- * is now shared.
28
- *
29
- * HARDCUT (work item A.3): this used to set the plain `XDG_CONFIG_HOME`/
30
- * `XDG_DATA_HOME`/`XDG_STATE_HOME`/`XDG_CACHE_HOME` vars, mirroring what the
31
- * reference's wrapper script exported before exec'ing its own repo-local
32
- * binary. `../../lean-ctx/env.ts`'s header records the live verification
33
- * (this session, 2026-09-14) that the real v3.9.20 binary does not actually
34
- * key its config/data/state/cache resolution on those XDG vars at all — only
35
- * on the four `LEAN_CTX_*` ones now used here.
36
- *
37
- * lean-ctx missing or failing is advisory, never fatal: the warmup section
38
- * still goes out and the failure is named on stderr, but this never returns
39
- * exitCode 2 — a briefing hook has no host-visible "block" channel, and the
40
- * reference script's own header says the same ("Advises only — never block
41
- * the session or prompt"). A spawn that never exits (gap #1) degrades the
42
- * same way: the injected `Runner` is timeout-enforcing (see
43
- * `../../lib/spawn-with-timeout.ts`), so a hung `lean-ctx` child is killed
44
- * and reported exactly like a failed/ENOENT spawn — `status: null` — rather
45
- * than hanging the calling agent host.
46
- *
47
- * `deploy.mjs`-level concerns from the reference tree — wiring the hook into
48
- * each host's config, `--self-test`/`--host=`/`--event=` argv parsing, the
49
- * five-surface deploy fixture in `tests/test-wiring.mjs` — are out of scope
50
- * here: `src/hosts/*` and `src/main.ts`'s dispatch own that, per this task's
51
- * boundary.
52
- */
53
-
1
+ /** Static session-orientation briefing for supported agent hosts. */
54
2
  import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
55
3
  import { join } from 'node:path'
56
-
57
4
  import type { HookHandler, HookInvocation, HookResult, HostId } from '../contract.ts'
58
5
  import { spawnWithTimeout } from '../../lib/spawn-with-timeout.ts'
59
- import { leanCtxEnvFor } from '../../lean-ctx/env.ts'
60
-
61
- /** The marker lean-ctx's own `hook codex-session-start` output carries, when present. */
62
- export const MARKER = 'lean-ctx SESSION BRIEFING'
63
- export const WARMUP_MARKER = 'PROJECT WARMUP'
64
-
65
- const LEAN_CTX_BIN = 'lean-ctx'
66
6
 
67
- const OVERVIEW_MAX_LINES = 28
68
- const OVERVIEW_TIMEOUT_MS = 12_000
69
- const DEFAULT_TIMEOUT_MS = 8_000
70
-
71
- export interface RunResult {
72
- readonly status: number | null
73
- readonly stdout: string
74
- readonly stderr: string
75
- /** `true` only when the spawn was killed for exceeding `timeoutMs` — see gap #1. */
76
- readonly timedOut?: boolean
77
- }
78
-
79
- export interface RunOptions {
80
- readonly cwd: string
81
- readonly env: Readonly<Record<string, string | undefined>>
82
- readonly input?: string
83
- /** Wall-clock spawn timeout in ms; overridable per call, defaults per call site below. */
84
- readonly timeoutMs?: number
85
- }
86
-
87
- /** Process spawning, injected so tests never need a real `lean-ctx` binary. */
7
+ interface RunResult { readonly status: number | null; readonly stdout: string; readonly stderr: string; readonly timedOut?: boolean }
8
+ interface RunOptions { readonly cwd: string; readonly env: Readonly<Record<string, string | undefined>>; readonly input?: string; readonly timeoutMs?: number }
88
9
  export type Runner = (cmd: string, args: readonly string[], opts: RunOptions) => Promise<RunResult>
89
-
90
- function deliveredStateDir(root: string): string {
91
- return join(root, '.agents/lean-ctx/state/session-briefing-delivered')
92
- }
93
-
94
- function sessionId(payload: Record<string, unknown>): string {
95
- const raw = payload['session_id'] ?? payload['conversation_id']
96
- return typeof raw === 'string' && raw.trim().length > 0 ? raw.trim() : 'unknown'
97
- }
98
-
99
- /** Cursor and Kimi have no host-native "fire once at SessionStart" channel; gate on a marker file instead. */
100
- function usesPromptGate(host: HostId): boolean {
101
- return host === 'cursor' || host === 'kimi'
10
+ /** Kept for the shared subprocess-runner contract used by focused tests. */
11
+ export const bunRunner: Runner = async (cmd, args, opts) => {
12
+ try {
13
+ const result = await spawnWithTimeout(cmd, args, { cwd: opts.cwd, env: opts.env, timeoutMs: opts.timeoutMs ?? 8_000, ...(opts.input === undefined ? {} : { stdin: opts.input }) })
14
+ return result.timedOut ? { status: null, stdout: result.stdout, stderr: result.stderr.trim() || `${cmd} timed out after ${opts.timeoutMs ?? 8_000}ms`, timedOut: true } : { status: result.exitCode, stdout: result.stdout, stderr: result.stderr }
15
+ } catch (error) { return { status: null, stdout: '', stderr: error instanceof Error ? error.message : String(error) } }
102
16
  }
103
17
 
104
- function deliveredPath(root: string, host: HostId, session: string): string {
105
- return join(deliveredStateDir(root), `${host}-${session}.done`)
106
- }
18
+ const WARMUP_MARKER = 'PROJECT WARMUP'
107
19
 
108
- function alreadyDelivered(root: string, host: HostId, session: string): boolean {
109
- if (!usesPromptGate(host)) return false
110
- return existsSync(deliveredPath(root, host, session))
20
+ function deliveredStateDir(root: string): string { return join(root, '.adl', 'state', 'session-briefing-delivered') }
21
+ function sessionId(payload: Record<string, unknown>): string {
22
+ const raw = payload.session_id ?? payload.conversation_id
23
+ return typeof raw === 'string' && raw.trim() ? raw.trim() : 'unknown'
111
24
  }
112
-
25
+ function usesPromptGate(host: HostId): boolean { return host === 'cursor' || host === 'kimi' }
26
+ function deliveredPath(root: string, host: HostId, session: string): string { return join(deliveredStateDir(root), `${host}-${session}.done`) }
27
+ function alreadyDelivered(root: string, host: HostId, session: string): boolean { return usesPromptGate(host) && existsSync(deliveredPath(root, host, session)) }
113
28
  function markDelivered(root: string, host: HostId, session: string): void {
114
29
  if (!usesPromptGate(host)) return
115
30
  mkdirSync(deliveredStateDir(root), { recursive: true })
116
31
  writeFileSync(deliveredPath(root, host, session), `${new Date().toISOString()}\n`)
117
32
  }
118
-
119
- function runLeanCtx(
120
- run: Runner,
121
- root: string,
122
- env: Readonly<Record<string, string | undefined>>,
123
- args: readonly string[],
124
- timeoutMs = DEFAULT_TIMEOUT_MS,
125
- ): Promise<RunResult> {
126
- return run(LEAN_CTX_BIN, args, { cwd: root, env: leanCtxEnvFor(root, env), timeoutMs })
127
- }
128
-
129
- function truncateLines(text: string, maxLines: number): string {
130
- const lines = text.split('\n')
131
- if (lines.length <= maxLines) return text
132
- return `${lines.slice(0, maxLines).join('\n')}\n… (${lines.length - maxLines} more lines; call ctx_overview for full map)`
133
- }
134
-
135
- function taskFromPayload(payload: Record<string, unknown>): string {
136
- const prompt = payload['prompt']
137
- const trimmed = typeof prompt === 'string' ? prompt.trim() : ''
138
- if (trimmed.length < 8) return ''
139
- return trimmed.length > 120 ? `${trimmed.slice(0, 117)}…` : trimmed
140
- }
141
-
142
- function workflowBlock(): string {
33
+ function briefingText(): string {
143
34
  return [
144
- WARMUP_MARKER,
145
- '',
146
- 'Start every session (ctx_* or lean-ctx; use ctx_call when not advertised):',
147
- '• ctx_overview / lean-ctx overview ["task"] — project map; FIRST on unfamiliar work',
35
+ WARMUP_MARKER, '',
36
+ 'Start every session with ctx_overview when it is available; use ctx_call when it is not advertised.',
148
37
  '• ctx_knowledge(action="wakeup") — cross-session facts and decisions',
149
- '• ctx_session(action="status") — last session findings in this repo',
150
- '',
151
- 'Knowledge: ctx_knowledge or lean-ctx knowledge — status | recall | search | remember | consolidate',
152
- 'Checkpoints: ctx_session(action="task"|"decision", …) after significant progress',
153
- '',
38
+ '• ctx_session(action="status") — last session findings in this repository', '',
154
39
  'After orientation: ctx_compose → ctx_read/ctx_search → ctx_shell (verify) → persist.',
155
40
  ].join('\n')
156
41
  }
157
-
158
- /**
159
- * The PROJECT WARMUP appendix. Always non-empty — its static workflow block
160
- * does not depend on `lean-ctx` at all — so a briefing is never fully silent
161
- * just because the binary is missing.
162
- */
163
- async function projectWarmupAppendix(
164
- run: Runner,
165
- root: string,
166
- env: Readonly<Record<string, string | undefined>>,
167
- payload: Record<string, unknown>,
168
- ): Promise<string> {
169
- const parts = [workflowBlock()]
170
-
171
- const task = taskFromPayload(payload)
172
- const overviewArgs = task ? ['overview', task] : ['overview']
173
- const overview = await runLeanCtx(run, root, env, overviewArgs, OVERVIEW_TIMEOUT_MS)
174
- if (overview.status === 0 && overview.stdout.trim()) {
175
- parts.push('', '--- ctx_overview (cached snapshot) ---', truncateLines(overview.stdout.trim(), OVERVIEW_MAX_LINES))
176
- }
177
-
178
- const knowledge = await runLeanCtx(run, root, env, ['knowledge', 'status'])
179
- if (knowledge.status === 0 && knowledge.stdout.trim()) {
180
- parts.push('', '--- ctx_knowledge status ---', knowledge.stdout.trim())
181
- }
182
-
183
- return parts.join('\n')
184
- }
185
-
186
- function composeBriefing(base: string, warmup: string): string {
187
- const b = base.trim()
188
- const w = warmup.trim()
189
- if (b && w) return `${b}\n\n${w}`
190
- return b || w
191
- }
192
-
193
- interface BaseBriefing {
194
- readonly text: string
195
- readonly failureNote: string
196
- readonly outcome: 'ok' | 'timeout' | 'error'
197
- }
198
-
199
- /** Runs `lean-ctx hook codex-session-start`; failure degrades to an empty base text plus a stderr note. */
200
- async function baseBriefing(
201
- run: Runner,
202
- root: string,
203
- env: Readonly<Record<string, string | undefined>>,
204
- payload: Record<string, unknown>,
205
- ): Promise<BaseBriefing> {
206
- const result = await run(LEAN_CTX_BIN, ['hook', 'codex-session-start'], {
207
- cwd: root,
208
- env: leanCtxEnvFor(root, env),
209
- input: JSON.stringify(payload),
210
- timeoutMs: DEFAULT_TIMEOUT_MS,
211
- })
212
-
213
- if (result.status !== 0 || !result.stdout.trim()) {
214
- const reason = result.stderr.trim() || `lean-ctx exited with status ${String(result.status)}`
215
- return {
216
- text: '',
217
- failureNote: `session-briefing: lean-ctx hook codex-session-start failed — ${reason}\n`,
218
- outcome: result.timedOut ? 'timeout' : 'error',
219
- }
220
- }
221
-
222
- try {
223
- const parsed = JSON.parse(result.stdout) as { hookSpecificOutput?: { additionalContext?: unknown } }
224
- const text = parsed.hookSpecificOutput?.additionalContext
225
- return { text: typeof text === 'string' ? text : '', failureNote: '', outcome: 'ok' }
226
- } catch (error) {
227
- const message = error instanceof Error ? error.message : String(error)
228
- return {
229
- text: '',
230
- failureNote: `session-briefing: lean-ctx hook codex-session-start returned invalid JSON — ${message}\n`,
231
- outcome: 'error',
232
- }
233
- }
234
- }
235
-
236
- /**
237
- * Wrap briefing text in a host's native envelope.
238
- *
239
- * Per official docs where they differ from the reference tree:
240
- * - Claude / Codex SessionStart (and any other event): `hookSpecificOutput.additionalContext`.
241
- * - Cursor: flat `additional_context` — the reference's nested
242
- * `hookSpecificOutput` shape for Cursor `UserPromptSubmit` is not part of
243
- * Cursor's documented hook contract, so it is not ported here.
244
- * - Kimi: bare stdout text (its `UserPromptSubmit` hook has no JSON envelope).
245
- * - OpenCode: `{"advice": "..."}`, consumed by this repo's own OpenCode plugin.
246
- */
247
42
  function renderBriefing(host: HostId, event: string, text: string): string {
248
- if (!text) return ''
249
43
  if (host === 'kimi') return `${text}\n`
250
44
  if (host === 'opencode') return JSON.stringify({ advice: text })
251
45
  if (host === 'cursor') return JSON.stringify({ additional_context: text })
252
46
  return JSON.stringify({ hookSpecificOutput: { hookEventName: event, additionalContext: text } })
253
47
  }
254
48
 
255
- export function createBriefingHandler(deps: { run: Runner }): HookHandler {
49
+ export function createBriefingHandler(): HookHandler {
256
50
  return async (inv: HookInvocation): Promise<HookResult> => {
257
- const { host, root, env } = inv
258
- const payload = inv.payload
259
- const event = inv.event ?? 'SessionStart'
260
- const session = sessionId(payload)
261
-
262
- if (alreadyDelivered(root, host, session)) {
51
+ const session = sessionId(inv.payload)
52
+ if (alreadyDelivered(inv.root, inv.host, session)) {
263
53
  inv.record?.({ reason: 'SKIP already delivered this session' })
264
54
  return { stdout: '', stderr: '', exitCode: 0 }
265
55
  }
266
-
267
- const { text: base, failureNote, outcome } = await baseBriefing(deps.run, root, env, payload)
268
- const warmup = await projectWarmupAppendix(deps.run, root, env, payload)
269
- const text = composeBriefing(base, warmup)
270
-
271
- markDelivered(root, host, session)
272
- const reasons = { ok: 'PASS', timeout: 'TIMEOUT lean-ctx hook codex-session-start', error: 'ERROR lean-ctx hook codex-session-start' }
273
- inv.record?.({
274
- reason: reasons[outcome],
275
- message: failureNote.trim(),
276
- downstream: 'lean-ctx hook codex-session-start, lean-ctx overview, lean-ctx knowledge status',
277
- })
278
-
279
- return {
280
- stdout: renderBriefing(host, event, text),
281
- stderr: failureNote,
282
- exitCode: 0,
283
- }
56
+ markDelivered(inv.root, inv.host, session)
57
+ inv.record?.({ reason: 'PASS', downstream: 'static session briefing' })
58
+ return { stdout: renderBriefing(inv.host, inv.event ?? 'SessionStart', briefingText()), stderr: '', exitCode: 0 }
284
59
  }
285
60
  }
286
-
287
- /**
288
- * The production `Runner`: a real, timeout-enforcing subprocess via
289
- * `spawnWithTimeout` (see `../../lib/spawn-with-timeout.ts`) — replaces the
290
- * reference tree's `Bun.spawnSync`, which had no timeout and could hang the
291
- * calling agent host forever on a stuck `lean-ctx` child (gap #1). A timeout
292
- * degrades exactly like an ENOENT/failed spawn: `status: null` with the
293
- * reason on stderr, plus `timedOut: true` so callers can tell the two apart.
294
- */
295
- export const bunRunner: Runner = async (cmd, args, opts) => {
296
- const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS
297
- try {
298
- const result = await spawnWithTimeout(cmd, args, {
299
- cwd: opts.cwd,
300
- env: opts.env,
301
- timeoutMs,
302
- ...(opts.input !== undefined ? { stdin: opts.input } : {}),
303
- })
304
- if (result.timedOut) {
305
- return {
306
- status: null,
307
- stdout: result.stdout,
308
- stderr: result.stderr.trim() || `${cmd} timed out after ${timeoutMs}ms`,
309
- timedOut: true,
310
- }
311
- }
312
- return { status: result.exitCode, stdout: result.stdout, stderr: result.stderr }
313
- } catch (error) {
314
- const message = error instanceof Error ? error.message : String(error)
315
- return { status: null, stdout: '', stderr: message }
316
- }
317
- }
318
-
319
- export const handleBriefing: HookHandler = createBriefingHandler({ run: bunRunner })
320
- export default handleBriefing
@@ -3,13 +3,12 @@
3
3
  *
4
4
  * `controls hook <kind> --host=X` is invoked by agent hosts (Claude Code,
5
5
  * Codex, Cursor, OpenCode, Kimi) with a JSON payload on stdin. Every kind
6
- * (`pre-tool-use`, `user-prompt-submit`, `briefing`, `crg`, `lean-ctx`
7
- * pre-tool-use/post-tool-use) is dispatched from `src/main.ts` through one
6
+ * (`pre-tool-use`, `user-prompt-submit`, `briefing`, `crg`) is dispatched
7
+ * from `src/main.ts` through one
8
8
  * `HookHandler` shape, so a handler never sees `process`, argv, or stdin
9
9
  * directly — only the `HookInvocation` it is called with, and it returns a
10
10
  * `HookResult` for `main.ts` to write to stdout/stderr and turn into a
11
- * process exit code. `lean-ctx mcp` is the one exception: it is not a
12
- * `HookHandler` at all — see `src/lean-ctx/mcp.ts`'s header.
11
+ * process exit code.
13
12
  *
14
13
  * This file is intentionally the *only* place that shape is defined: other
15
14
  * agents implementing `src/hooks/user-prompt-submit/`, `src/hooks/briefing/`,
@@ -31,26 +30,27 @@ export interface ActivityNote {
31
30
  /** `PASS`, `DENY <rule>`, `ERROR <what>`, `TIMEOUT <what>`, or `SKIP <why>`. */
32
31
  readonly reason: string
33
32
  readonly message?: string
34
- /** What the hook invoked downstream, e.g. `lean-ctx hook redirect`, `skills: tdd, research`. */
33
+ /** What the hook invoked downstream, e.g. `skills: tdd, research`. */
35
34
  readonly downstream?: string
36
35
  /** Set only for a blocked pre-tool-use decision: the rule id written to the deny log. */
37
36
  readonly denyRuleId?: string
38
37
  /**
39
38
  * Set only when an identity decision was actually made for this
40
- * invocation (a rewrite, or a deny/pass decided by one of the four
41
- * identity rules — `adl.session-required-for-writes`, `adl.git-identity`,
42
- * `adl.token-minting-role`, `tool.azure-devops`): where the effective
43
- * agent identity came from, per the one-agent-identity standard's own
44
- * resolution order (STATUS.md 12p, "The
45
- * standard") — `inline` (a valid `ADL_AGENT_ID_AGENT=` on the command
46
- * itself), `env` (the session environment), `default-file` (the machine
47
- * default-agent file), or `none` (nothing resolved at all). See
48
- * `../pre-tool-use/handler.ts`'s `identitySourceFor`.
39
+ * invocation (a rewrite, or a deny/pass decided by one of the identity
40
+ * rules — `adl.run-required-for-writes`, `adl.git-identity`,
41
+ * `adl.token-minting-role`, `tool.azure-devops`, … — or by a role gate on
42
+ * an Azure DevOps MCP call): where the effective agent identity came from,
43
+ * per the one-agent-identity resolution order — `inline` (a valid
44
+ * `ADL_AGENT_ID_AGENT=` on the command itself), `env` (the session
45
+ * environment), `default-file` (the machine default-agent file), or
46
+ * `none` (nothing resolved at all). An allowed Azure DevOps MCP call logs
47
+ * it too, reads included (Tarun, 2026-09-29). See
48
+ * `../pre-tool-use/handler.ts`'s `effectiveIdentityFor` and
49
+ * `fallbackIdentity`.
49
50
  */
50
51
  readonly identitySource?: 'inline' | 'env' | 'default-file' | 'none'
51
52
  /**
52
- * M8 (STATUS.md 12p): the EFFECTIVE agent
53
- * identity this decision actually used — set together with
53
+ * The EFFECTIVE agent identity this decision actually used — set together with
54
54
  * `identitySource`, whenever that is set to anything but `'none'`. Read
55
55
  * by `./log.ts` for the `agent` column INSTEAD OF the session's raw
56
56
  * `ADL_AGENT_ID_AGENT` env var — the two differ exactly when a command
@@ -63,7 +63,7 @@ export interface ActivityNote {
63
63
  }
64
64
 
65
65
  export interface HookInvocation {
66
- readonly kind: 'pre-tool-use' | 'user-prompt-submit' | 'briefing' | 'crg' | 'lean-ctx'
66
+ readonly kind: 'pre-tool-use' | 'user-prompt-submit' | 'briefing' | 'crg'
67
67
  readonly host: HostId
68
68
  readonly event?: string
69
69
  readonly subcommand?: string
@@ -29,11 +29,25 @@
29
29
  * pending marker exists clears it and runs once more. On its way out it
30
30
  * releases the lock, then re-checks the marker once and re-acquires the
31
31
  * lock (noclobber) if a hook queued in the meantime, closing the last gap.
32
+ *
33
+ * Self-heal: if `code-review-graph update --skip-flows` exits non-zero,
34
+ * the runner runs `code-review-graph build --skip-flows` once and logs a
35
+ * `SELF-HEAL:` marker to stderr (captured by the spawn into
36
+ * `crg-update.log`). The original error is already in the log because
37
+ * the spawn captures the update's own stderr; the marker is appended
38
+ * after, so the failure is never silently swallowed. The build runs at
39
+ * most once per runner invocation (a per-runner shell variable), so a
40
+ * runner that re-iterates because the pending marker was set does not
41
+ * re-trigger the build on the second iteration. If the build itself
42
+ * fails, the runner exits and the next edit tries again — persistent
43
+ * failures stay visible in the log instead of being hidden.
32
44
  */
33
45
 
34
46
  import { closeSync, mkdirSync, openSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs'
35
47
  import { join } from 'node:path'
36
48
 
49
+ import { ensureAdlGitignore } from '../../log/adl-dir.ts'
50
+
37
51
  export const LOCK_REL = '.adl/crg-update.lock'
38
52
  export const PENDING_REL = '.adl/crg-update.pending'
39
53
  export const UPDATE_LOG_REL = '.adl/logs/crg-update.log'
@@ -43,9 +57,21 @@ export const MAX_LOCK_AGE_MS = 30 * 60 * 1000
43
57
 
44
58
  export const RUNNER_SCRIPT = [
45
59
  'lock="$1"; pending="$2"; shift 2',
60
+ 'build_attempted=',
46
61
  'while :; do',
47
62
  ' rm -f "$pending"',
48
63
  ' "$@"',
64
+ ' rc=$?',
65
+ ' if [ "$rc" -ne 0 ] && [ -z "$build_attempted" ]; then',
66
+ ' echo "SELF-HEAL: $* exited $rc; running code-review-graph build --skip-flows" >&2',
67
+ ' if code-review-graph build --skip-flows; then',
68
+ ' echo "SELF-HEAL: build ok; next update will validate" >&2',
69
+ ' else',
70
+ ' build_rc=$?',
71
+ ' echo "SELF-HEAL: build failed (exit $build_rc); self-heal aborted" >&2',
72
+ ' fi',
73
+ ' build_attempted=1',
74
+ ' fi',
49
75
  ' if [ -e "$pending" ]; then continue; fi',
50
76
  ' rm -f "$lock"',
51
77
  ' if [ -e "$pending" ] && (set -C; echo $$ > "$lock") 2>/dev/null; then continue; fi',
@@ -160,6 +186,7 @@ function acquireAndStart(deps: BackgroundDeps, root: string, env: SpawnSpec['env
160
186
 
161
187
  export function requestUpdate(deps: BackgroundDeps, root: string, env: SpawnSpec['env']): UpdateRequest {
162
188
  mkdirSync(join(root, '.adl', 'logs'), { recursive: true, mode: 0o700 })
189
+ ensureAdlGitignore(join(root, '.adl'))
163
190
  const lockPath = join(root, LOCK_REL)
164
191
  const pendingPath = join(root, PENDING_REL)
165
192
 
@@ -47,7 +47,7 @@
47
47
 
48
48
  import type { HookHandler, HookInvocation, HookResult } from '../contract.ts'
49
49
  import { spawnWithTimeout } from '../../lib/spawn-with-timeout.ts'
50
- import { defaultBackgroundDeps, requestUpdate, type BackgroundDeps } from './background.ts'
50
+ import { requestUpdate, type BackgroundDeps } from './background.ts'
51
51
  import { toDecideInput } from '../../pre-tool-use/handler.ts'
52
52
  import { invocations } from '../../rules/shell/invocation.ts'
53
53
 
@@ -155,7 +155,8 @@ function isGitCommitInvocation(payload: Record<string, unknown>): boolean {
155
155
  }
156
156
 
157
157
  /**
158
- * `pre-commit.sh`: silent `detect-changes --brief`, stdout `{"passed":true}`,
158
+ * `pre-commit.sh`: silent `detect-changes --brief`, with Codex receiving its
159
+ * native allow envelope rather than the legacy `{"passed":true}` payload,
159
160
  * always exit 0 — but ONLY when the invoking payload's shell command is
160
161
  * actually a `git commit` (see this file's header, work item B). Anything
161
162
  * else — no shell command at all (a non-Bash tool call), or a shell command
@@ -168,7 +169,10 @@ async function preCommit(run: Runner, inv: HookInvocation): Promise<HookResult>
168
169
  return { stdout: '', stderr: '', exitCode: 0 }
169
170
  }
170
171
  const result = await runCrg(run, inv, ['detect-changes', '--brief'])
171
- return { stdout: '{"passed":true}\n', stderr: missingBinaryNote('pre-commit', result), exitCode: 0 }
172
+ const stdout = inv.host === 'codex'
173
+ ? `${JSON.stringify({ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'allow' } })}\n`
174
+ : '{"passed":true}\n'
175
+ return { stdout, stderr: missingBinaryNote('pre-commit', result), exitCode: 0 }
172
176
  }
173
177
 
174
178
  /**
@@ -235,6 +239,3 @@ export const bunRunner: Runner = async (cmd, args, opts) => {
235
239
  return { status: null, stdout: '', stderr: message }
236
240
  }
237
241
  }
238
-
239
- export const handleCrg: HookHandler = createCrgHandler({ run: bunRunner, background: defaultBackgroundDeps })
240
- export default handleCrg
@@ -40,8 +40,7 @@
40
40
  * `result` is never left empty just because a row has nothing to say.
41
41
  * - `rule` is set only for a blocked pre-tool-use decision
42
42
  * (`ActivityNote.denyRuleId`), same trigger as the old deny log.
43
- * - `agent` is `ActivityNote.identityAgent` (M8,
44
- * STATUS.md 12p) — the EFFECTIVE identity the
43
+ * - `agent` is `ActivityNote.identityAgent` — the EFFECTIVE identity the
45
44
  * decision actually used, set by `../pre-tool-use/handler.ts`'s
46
45
  * `effectiveIdentityFor` — when an identity decision was made; a valid
47
46
  * inline `ADL_AGENT_ID_AGENT=` override on the command differs from the
@@ -50,12 +49,12 @@
50
49
  * `ADL_AGENT_ID_AGENT` (`../rules/impl/adl-identity.ts`'s env var) for
51
50
  * any row with no identity decision at all. `human` has no source at
52
51
  * this layer and is left absent.
53
- * - `identity_source` (W2 build item 5, 2026-09-28) comes straight off
52
+ * - `identity_source` comes straight off
54
53
  * `ActivityNote.identitySource` (`./contract.ts`), set by
55
54
  * `../pre-tool-use/handler.ts`'s `decideAndRespond` only when an
56
55
  * identity decision was actually made for this invocation — absent
57
- * otherwise, never defaulted to `'none'` for an unrelated row. M8 widens
58
- * when this is set to also cover the "override's PASS" row: an
56
+ * otherwise, never defaulted to `'none'` for an unrelated row. It is set
57
+ * for the "override's PASS" row too: an
59
58
  * identity-bearing command whose only identity-bearing pieces already
60
59
  * carry a valid inline override needs no rewrite (`rewriteGitNetworkCommands`'s
61
60
  * `unchanged` outcome), but it still made a real identity decision.
@@ -79,9 +78,9 @@ import type { ActivityNote, HookHandler, HookInvocation, HookResult } from './co
79
78
 
80
79
  export const HOOKS_LOG_REL = '.adl/logs/hooks.log'
81
80
  export const HOOKS_DENY_LOG_REL = '.adl/logs/hooks-deny.log'
82
- export const MAX_LOGGED_COMMAND_LENGTH = 2000
81
+ const MAX_LOGGED_COMMAND_LENGTH = 2000
83
82
 
84
- export function truncateCommand(value: string): string {
83
+ function truncateCommand(value: string): string {
85
84
  return value.length > MAX_LOGGED_COMMAND_LENGTH ? `${value.slice(0, MAX_LOGGED_COMMAND_LENGTH)}...<truncated>` : value
86
85
  }
87
86
 
@@ -108,7 +107,7 @@ const stringAt = (record: Readonly<Record<string, unknown>>, key: string): strin
108
107
  * `{"command": "...", "cwd": "...", "sandbox": false}` (no `tool_input` at
109
108
  * all). No Cursor-specific field renaming was needed here.
110
109
  */
111
- export function toolSummary(payload: Readonly<Record<string, unknown>>): string {
110
+ function toolSummary(payload: Readonly<Record<string, unknown>>): string {
112
111
  const rawInput = payload.tool_input
113
112
  const input = typeof rawInput === 'object' && rawInput !== null && !Array.isArray(rawInput) ? (rawInput as Record<string, unknown>) : {}
114
113
  for (const key of ['command', 'cmd', 'script']) {
@@ -172,8 +171,7 @@ export async function runLogged(inv: HookInvocation, handler: HookHandler, now:
172
171
  const duration = Math.round(performance.now() - started)
173
172
  const sessionId = sessionOf(inv.payload)
174
173
  const runId = runIdOf(inv.env)
175
- // M8 (STATUS.md 12p): the EFFECTIVE identity
176
- // this decision used — set on `outcome` whenever an identity decision
174
+ // The EFFECTIVE identity this decision used — set on `outcome` whenever an identity decision
177
175
  // was actually made (`../pre-tool-use/handler.ts`'s `effectiveIdentityFor`)
178
176
  // — wins over the session's raw `ADL_AGENT_ID_AGENT` env var: they
179
177
  // differ exactly when the command carries a valid inline override
@@ -51,7 +51,7 @@ function processTerm(term: string): string | null {
51
51
  * so it is rebuilt per invocation rather than persisted — that keeps the hook
52
52
  * stateless and makes an edited SKILL.md take effect immediately.
53
53
  */
54
- export function buildIndex(skills: readonly Skill[]): MiniSearch {
54
+ function buildIndex(skills: readonly Skill[]): MiniSearch {
55
55
  const index = new MiniSearch({
56
56
  fields: ['name', 'keywords', 'description'],
57
57
  storeFields: ['label', 'description'],
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Minimal Unigram tokenizer over the pruned tokenizer.json of the
3
- * adl-embedding artifact. Pure TS — no dependency on a native tokenizer
3
+ * enact-embedding artifact. Pure TS — no dependency on a native tokenizer
4
4
  * package.
5
5
  *
6
6
  * Ported unchanged from enact-repo-controls-m5's
@@ -10,10 +10,11 @@
10
10
  * the artifact from a repo-local `.cache/enact-embedding/model/` directory
11
11
  * built by that repo's own installer. This hook instead treats the model as a
12
12
  * GLOBAL, machine-wide asset shared by every repository —
13
- * `resolveGlobalArtifactDir` resolves `${XDG_CACHE_HOME:-$HOME/.cache}/adl-embedding/model/`
14
- * (renamed from `enact-embedding`, matching `packages/fleet/src/install-embedding-model.ts`,
15
- * the installer that actually writes this directory) from the invocation's
16
- * own `env`, never `process.env` and never repo-relative.
13
+ * `resolveGlobalArtifactDir` resolves `${XDG_CACHE_HOME:-$HOME/.cache}/enact-embedding/model/`
14
+ * (matching `packages/fleet/src/install-embedding-model.ts`, the installer that
15
+ * actually writes this directory; the earlier `adl-embedding` name is a hard
16
+ * cut, never read as a fallback) from the invocation's own `env`, never
17
+ * `process.env` and never repo-relative.
17
18
  *
18
19
  * `loadVectorHalf`'s `LoadVectorResult.reason` (on `ok: false`) already
19
20
  * carries a specific, human-readable cause (directory missing, which files
@@ -37,7 +38,7 @@ const ARTIFACT_FILES = ['model.bin', 'tokenizer.json', 'tokenizer_config.json',
37
38
  export function resolveGlobalArtifactDir(env: Readonly<Record<string, string | undefined>>): string {
38
39
  const xdgCacheHome = env.XDG_CACHE_HOME
39
40
  const base = xdgCacheHome && xdgCacheHome.trim() !== '' ? xdgCacheHome : join(requireHome(env), '.cache')
40
- return join(base, 'adl-embedding', 'model')
41
+ return join(base, 'enact-embedding', 'model')
41
42
  }
42
43
 
43
44
  function requireHome(env: Readonly<Record<string, string | undefined>>): string {
@@ -15,7 +15,7 @@ import { cursorSpec } from './impl/cursor.ts'
15
15
  import { opencodeSpec } from './impl/opencode.ts'
16
16
  import { kimiSpec } from './impl/kimi.ts'
17
17
 
18
- export const HOST_SPECS: Readonly<Record<HostId, HostSpec>> = {
18
+ const HOST_SPECS: Readonly<Record<HostId, HostSpec>> = {
19
19
  claude: claudeSpec,
20
20
  codex: codexSpec,
21
21
  cursor: cursorSpec,