@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.12 → 0.1.28

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 (410) 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 +12 -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 +131 -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 +33 -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/scripts/probe-ado-rules.ts +311 -0
  140. package/packages/azdo/src/azdo-pl.ts +2 -54
  141. package/packages/azdo/src/azdo-pr-review.ts +4 -4
  142. package/packages/azdo/src/azdo-repo-doctor.ts +101 -52
  143. package/packages/azdo/src/azdo-wit.ts +44 -2
  144. package/packages/azdo/src/lib/agent-identity.ts +12 -14
  145. package/packages/azdo/src/lib/agent-token.ts +2 -2
  146. package/packages/azdo/src/lib/client.ts +0 -5
  147. package/packages/azdo/src/lib/graph-identity.ts +4 -4
  148. package/packages/azdo/src/workflow-ladder.csv +241 -0
  149. package/packages/azdo/src/workflow-rules-matrix.csv +85 -0
  150. package/packages/azdo/src/workflow-rules.ts +194 -0
  151. package/packages/fleet/manifest.json +35 -11
  152. package/packages/fleet/manifest.schema.json +62 -10
  153. package/packages/fleet/src/default-agent-file.ts +3 -3
  154. package/packages/fleet/src/install-adl-package.ts +73 -15
  155. package/packages/fleet/src/install-embedding-model.ts +13 -13
  156. package/packages/fleet/src/managed-settings.ts +7 -7
  157. package/packages/fleet/src/repo-maintain.ts +91 -55
  158. package/packages/fleet/src/scratch-reap.ts +5 -5
  159. package/packages/fleet/src/vscode-settings.ts +5 -5
  160. package/packages/repo-controls/README.md +141 -43
  161. package/packages/repo-controls/assets/promote.ts +4 -4
  162. package/packages/repo-controls/assets/reconcile-guard.sh +10 -46
  163. package/packages/repo-controls/assets/version-bump.sh +31 -84
  164. package/packages/repo-controls/bunfig.toml +6 -7
  165. package/packages/repo-controls/package/adl-compliance/AGENTS.md +5 -6
  166. package/packages/repo-controls/package/adl-compliance/conftest.py +3 -1
  167. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +4 -16
  168. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +9 -2
  169. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/notes.md +1 -0
  170. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +11 -0
  171. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/__init__.py +7 -0
  172. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/check.py +266 -0
  173. 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
  174. 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
  175. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.hidden.md +1 -0
  176. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/a.md +1 -0
  177. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/b.md +1 -0
  178. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/data.csv +1 -0
  179. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/diagram.png +1 -0
  180. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/mock.png +1 -0
  181. 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
  182. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs.md +1 -0
  183. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/grants.yaml +4 -0
  184. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p1.md +1 -0
  185. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p2.md +1 -0
  186. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p3.md +1 -0
  187. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p4.md +1 -0
  188. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p5.md +1 -0
  189. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/build.md +1 -0
  190. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/overview.md +1 -0
  191. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/install.md +1 -0
  192. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/start.md +1 -0
  193. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/grants.yaml +4 -0
  194. 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
  195. 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
  196. 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
  197. 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
  198. 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
  199. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/a.md +1 -0
  200. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/b.md +1 -0
  201. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/c.md +1 -0
  202. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/grants.yaml +4 -0
  203. 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
  204. 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
  205. 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
  206. 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
  207. 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
  208. 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
  209. 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
  210. 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
  211. 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
  212. 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
  213. 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
  214. 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
  215. 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
  216. 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
  217. 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
  218. 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
  219. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/grants.yaml +4 -0
  220. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/a.md +1 -0
  221. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/b.md +1 -0
  222. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/c.md +1 -0
  223. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/grants.yaml +4 -0
  224. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/a.md +1 -0
  225. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/b.md +1 -0
  226. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/c.md +1 -0
  227. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/grants.yaml +4 -0
  228. 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
  229. 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
  230. 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
  231. 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
  232. 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
  233. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/grants.yaml +4 -0
  234. 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
  235. 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
  236. 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
  237. 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
  238. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/grants.yaml +4 -0
  239. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/a.md +1 -0
  240. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/b.md +1 -0
  241. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/c.md +1 -0
  242. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/d.md +1 -0
  243. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/a.md +1 -0
  244. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/b.md +1 -0
  245. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/grants.yaml +6 -0
  246. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/a.md +1 -0
  247. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/b.md +1 -0
  248. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/c.md +1 -0
  249. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/grants.yaml +3 -0
  250. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/test_check.py +345 -0
  251. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +18 -5
  252. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +35 -0
  253. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/__init__.py +7 -0
  254. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/check.py +91 -0
  255. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/AGENTS.md +3 -0
  256. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/CLAUDE.md +3 -0
  257. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/-leading-hyphen.md +3 -0
  258. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/AGENTS.md +3 -0
  259. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/double--hyphen.md +3 -0
  260. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/getting started.md +3 -0
  261. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/nested/page-here.md +3 -0
  262. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/trailing-hyphen-.md +3 -0
  263. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/ui-contract.md +4 -0
  264. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/user_profile.md +3 -0
  265. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/UI-CONTRACT.png +2 -0
  266. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/diagram.png +1 -0
  267. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/index.md +4 -0
  268. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/notes.md +3 -0
  269. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/reference.html +1 -0
  270. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/2026-10-experiment.md +3 -0
  271. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/UI-CONTRACT.md +6 -0
  272. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs.md +5 -0
  273. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/test_check.py +194 -0
  274. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +14 -2
  275. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +5 -5
  276. 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
  277. 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
  278. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +58 -6
  279. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +0 -1
  280. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +64 -17
  281. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +60 -9
  282. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-clean/docs/notes.md +17 -0
  283. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-no-lines/docs/notes.md +13 -0
  284. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +0 -1
  285. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +0 -1
  286. 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
  287. 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
  288. 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
  289. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs-okf-profiles.yaml +5 -0
  290. 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
  291. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +0 -1
  292. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/experiment-ok.md +15 -0
  293. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-key.md +15 -0
  294. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-keys.md +16 -0
  295. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-created.md +11 -0
  296. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-description.md +11 -0
  297. 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
  298. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-sources.md +10 -0
  299. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-status.md +11 -0
  300. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-title.md +11 -0
  301. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/optional-keys.md +16 -0
  302. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/research-ok.md +14 -0
  303. 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
  304. 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
  305. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/operations/runbook.md +26 -0
  306. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +228 -2
  307. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +5 -0
  308. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +11 -2
  309. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +5 -3
  310. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +160 -44
  311. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +0 -2
  312. 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
  313. 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
  314. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/grants.yaml +3 -0
  315. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +0 -2
  316. 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
  317. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/grants.yaml +5 -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/a.ts +1 -0
  319. 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
  320. 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
  321. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/grants.yaml +4 -0
  322. 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
  323. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/grants.yaml +5 -0
  324. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +0 -2
  325. 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
  326. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/grants.yaml +3 -0
  327. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/register.py +127 -0
  328. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +265 -29
  329. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +75 -2
  330. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +194 -0
  331. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +56 -10
  332. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +258 -2
  333. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +40 -12
  334. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +108 -0
  335. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plan_metadata.py +9 -4
  336. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/check.py +1 -1
  337. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-clean/plans/features/az347-test-coverage/items/az351-restore-entrypoint.md +1 -1
  338. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +3 -3
  339. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +2 -3
  340. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +23 -6
  341. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +76 -0
  342. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +58 -17
  343. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +161 -0
  344. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +35 -3
  345. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +108 -1
  346. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +281 -61
  347. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/absolute-path.yaml +3 -0
  348. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/backslash-path.yaml +3 -0
  349. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/baseline-is-a-list.yaml +2 -0
  350. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/boolean-size.yaml +3 -0
  351. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/dot-segment.yaml +3 -0
  352. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/duplicate-path.yaml +4 -0
  353. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-file.yaml +0 -0
  354. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-segment.yaml +3 -0
  355. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/float-size.yaml +3 -0
  356. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/negative-size.yaml +3 -0
  357. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-over-limit-baseline.yaml +1 -0
  358. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-schema-version.yaml +1 -0
  359. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/non-string-path.yaml +3 -0
  360. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/not-yaml.yaml +2 -0
  361. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/null-size.yaml +3 -0
  362. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/parent-segment.yaml +3 -0
  363. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/string-size.yaml +3 -0
  364. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/top-level-is-a-list.yaml +2 -0
  365. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/trailing-slash.yaml +3 -0
  366. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/unknown-key.yaml +3 -0
  367. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/wrong-schema-version.yaml +2 -0
  368. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/zero-size.yaml +3 -0
  369. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/valid.yaml +4 -0
  370. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +758 -45
  371. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +4 -3
  372. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +2 -2
  373. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/cargo_lock.py +490 -0
  374. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +368 -55
  375. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +4 -2
  376. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_declared_paths.py +523 -0
  377. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_stale_lock.py +1179 -0
  378. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +122 -3
  379. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +33 -1
  380. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +0 -11
  381. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +16 -1
  382. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +1 -2
  383. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +12 -1
  384. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +133 -147
  385. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +133 -147
  386. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +1 -1
  387. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +52 -10
  388. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +23 -4
  389. package/packages/repo-controls/package.json +2 -9
  390. package/packages/repo-controls/scripts/hooks/post-merge +13 -0
  391. package/packages/repo-controls/scripts/hooks/pre-push +3 -3
  392. package/packages/repo-controls/src/azdo-push.ts +64 -36
  393. package/packages/repo-controls/src/azure-devops-governance.ts +7 -9
  394. package/packages/repo-controls/src/azure-devops-remote.ts +1 -1
  395. package/packages/repo-controls/src/cli.ts +29 -8
  396. package/packages/repo-controls/src/compliance-config.ts +410 -2
  397. package/packages/repo-controls/src/config.ts +133 -60
  398. package/packages/repo-controls/src/constants.ts +13 -27
  399. package/packages/repo-controls/src/coverage-ratchet.ts +4 -4
  400. package/packages/repo-controls/src/doctor.ts +46 -19
  401. package/packages/repo-controls/src/gitignore-block.ts +5 -29
  402. package/packages/repo-controls/src/hook-log.ts +1 -2
  403. package/packages/repo-controls/src/hook.ts +201 -45
  404. package/packages/repo-controls/src/install.ts +14 -8
  405. package/packages/repo-controls/src/integrity.ts +3 -3
  406. package/packages/repo-controls/src/lfs.ts +111 -0
  407. package/packages/repo-controls/src/promote.ts +8 -8
  408. package/packages/repo-controls/src/runtime.ts +9 -1
  409. package/packages/repo-controls/src/workflows-drift.ts +4 -5
  410. package/packages/repo-controls/src/worktree-guard.ts +3 -3
@@ -37,44 +37,61 @@ check.sh's comparison used the literal garbled string, that same clean-pass
37
37
  case would report a finding instead of passing. The restored string is the
38
38
  only one consistent with test.sh's own asserted outcome.
39
39
 
40
- **Two deviations this port does NOT resolve, only documents**, because
41
- `compliance_py`'s architecture makes check.sh's literal design unstatable
42
- here rather than merely inconvenient:
43
-
44
- 1. **No git object reads (K-41).** check.sh deliberately reads the path from
45
- the index (`:path`, pre-commit) or `HEAD` (`HEAD:path`, elsewhere) via
46
- `git cat-file`, and its own comment explains why at length: the WORKTREE
47
- file is not a safe source, because a correctly-tracked LFS pointer is
48
- smudged back to full content on disk, and a check reading the worktree
49
- would flag the very files that are doing the right thing. check.sh calls
50
- this risk "latent, not hypothetical" for the shell tree's OWN prior
51
- design, which read the worktree and was replaced because of it.
52
-
53
- `compliance_py` has exactly one file that calls `git` or resolves a root
54
- — `cli.py` — and every check, this one included, is handed a `Context`
55
- and a `FileSet` with no way to reach a git object store (see
56
- `core/check.py`'s docstring and `INVARIANTS.md`'s K-41 entry, verified
57
- there as `git: 1 module`). There is no established mechanism in this
58
- package for a check to read `:path`/`HEAD:path` instead of the worktree
59
- file, and none is added here. `graded` below reads the WORKTREE file
60
- `ctx.path(rel)` resolves to, which means it inherits the exact risk
61
- check.sh's comment names — a large file whose LFS pointer HAS been
62
- smudged back to full content by an active `git-lfs` filter would be
63
- misreported as a violation. check.sh's own measurement on the checkout it
64
- was written against found no case of this actually happening (one sampled
65
- LFS-tracked file was the same byte count in the worktree as in `HEAD`),
66
- so the risk carries over as documented rather than as an active defect —
67
- but it is a real, named gap, not a silent one, and resolving it needs
68
- either a git-object-reading mechanism added to this package's
69
- architecture or an accepted exception for this one gate.
70
-
71
- 2. **No phase (K-43).** check.sh branches its object read on
72
- `ADL_GATE_PHASE` (index at pre-commit, `HEAD` everywhere else).
73
- `compliance_py` reads no phase anywhere — "nothing reads a phase" is
74
- K-43, and K-33 records phase-conditional behaviour as retired by
75
- construction. There is one behaviour here, not two: `graded` grades
76
- whatever the caller's `FileSet` contains, exactly like every other check
77
- in this package.
40
+ **What is graded where (K-41 stays true: the CLI supplies the facts).**
41
+ check.sh reads the path from the index (`:path`, pre-commit) or `HEAD`
42
+ (`HEAD:path`, elsewhere) via `git cat-file`, and its own comment explains why at
43
+ length: the WORKTREE file is not a safe source, because a correctly-tracked LFS
44
+ file is a pointer in Git and is smudged back to full content on disk, so a check
45
+ reading the worktree flags the very files that are doing the right thing.
46
+ check.sh called that risk "latent, not hypothetical". It was measured on
47
+ 2026-10-01 against enact-combined: `live-probes/local/chat-local/output/
48
+ evidence/probe-result-video.webm` has `git check-attr filter` = lfs, a committed
49
+ blob of 132 bytes (`git cat-file -s :path`) and a 1,170,147-byte worktree file,
50
+ and the worktree-reading version of this check reported it as a violation. No
51
+ change inside that repository can clear it: the path is tracked correctly.
52
+
53
+ This check still performs no git reads. `compliance_py` has exactly one file that
54
+ calls `git` -- `cli.py` (K-41; measured 2026-10-01: it is the only non-test
55
+ module under `src/adl_compliance` that builds a git subprocess argv) -- and a
56
+ check is handed a `Context` and a `FileSet` with no way to reach an object store. What
57
+ changed is that the CLI now measures the fact and hands it down: this class sets
58
+ `reads_committed_sizes`, and when a selected row does, `cli.committed_blob_sizes`
59
+ runs two git processes however many paths there are (`ls-files --stage -z`, then
60
+ ONE `cat-file --batch-check`) and `Context.committed_sizes` maps each tracked
61
+ path to the size of the blob in the index. `graded` then grades:
62
+
63
+ * a path WITH a committed size, by that size alone, against `THRESHOLD`. A
64
+ committed pointer is ~132 bytes, so it is silent whatever the worktree
65
+ holds; a committed blob over the threshold is reported with the COMMITTED
66
+ size, whatever the worktree holds and whether or not the worktree file still
67
+ exists (an unstaged deletion leaves the blob stored). There is no pointer
68
+ comparison on this path: a real pointer is far under the threshold, so a
69
+ stored blob over it is not one, whatever its first line says.
70
+ * a path WITHOUT one, by its worktree file, exactly as this check always did,
71
+ pointer comparison included. A path has no committed size when it is
72
+ untracked or new, a gitlink, unmerged, in a root with no git repository, or
73
+ when the run is `--exhaustive` -- a snapshot whose bytes the caller vouches
74
+ ARE the candidate commit, for which `cli.py` does not ask whichever
75
+ repository might enclose it. A missing fact is never "small": a big file with
76
+ no committed size is still reported. The gap that remains is the mirror of
77
+ the one closed: a smudged LFS pointer at a path with no committed size would
78
+ still be misreported, and in a git repository that can only be a path not
79
+ yet in the index.
80
+
81
+ "Stored" is the INDEX entry, not `HEAD`: for a clean checkout they are the same
82
+ blob, and while staging it is the blob about to be committed -- check.sh's
83
+ `:path`. An edit not yet staged is therefore not graded for a tracked path (a
84
+ small committed file grown past the threshold in the worktree is reported once
85
+ `git add` stores it, not before).
86
+
87
+ **No phase (K-43).** check.sh branches its object read on
88
+ `ADL_GATE_PHASE` (index at pre-commit, `HEAD` everywhere else).
89
+ `compliance_py` reads no phase anywhere -- "nothing reads a phase" is
90
+ K-43, and K-33 records phase-conditional behaviour as retired by
91
+ construction. There is one behaviour here, not two: the facts come from the
92
+ index in every run that has a git repository, and `graded` grades whatever
93
+ the caller's `FileSet` contains, exactly like every other check in this
94
+ package.
78
95
 
79
96
  `.gitattributes` matching is scoped to the repository-root file only, using
80
97
  "last matching pattern wins" (`core.scope.matches`, the same rule real
@@ -83,23 +100,123 @@ check.sh's `git check-attr` resolves the full multi-directory and global
83
100
  attribute stack; this does not, and every case `test.sh` exercises uses a
84
101
  single root-level file, so this is enough to prove the branch, not a claim
85
102
  of full `check-attr` parity.
103
+
104
+ **The ratchet register (2026-10-01, Tarun: "add a ratchet", "ratchets go under
105
+ compliance/ folder").** A repository that already carries blobs over the threshold
106
+ records them in `<compliance>/ratchets/LFS-001-large-blobs.yaml` --
107
+ `schema_version: 1` and `over_limit_baseline: {<repo-relative path>: <size in
108
+ bytes>}` -- and the gate holds each at its recorded size. It is the repository's
109
+ OWN debt, so it is a consumer input (`inputs`), never packaged data, the same
110
+ reasoning as LAY-004's register. Three rules, all over the one question `_assess`
111
+ answers for every path in the set and every entry in the register:
112
+
113
+ LFS-002 over the threshold with no entry (the finding this gate always had).
114
+ LFS-003 over its own recorded size; names both sizes.
115
+ LFS-004 an entry that is no longer required -- its file is not in the tree, is
116
+ at or under the threshold, or is stored as an LFS pointer -- so the
117
+ register can only shrink. Adding an entry declares new debt; the repair
118
+ for LFS-003 never offers to raise one.
119
+
120
+ A register that EXISTS but cannot be used (invalid YAML, a repeated path, a size
121
+ that is not a positive integer, an unknown key, a path that is not a normalised
122
+ repository-relative one) is could-not-run, never ignored. `register` is a
123
+ `widening_inputs` member: it only ever ADDS an allowance, so no file, an empty
124
+ baseline, or a `compliance` tree declared absent (`""`) all mean "nothing is
125
+ ratcheted" and grade exactly as before. KNOWN GAP, measured and not closed here:
126
+ a `compliance` tree that is UNDECLARED (absent from the map, not `""`) is
127
+ could-not-run, because `runner.resolve_inputs` expands every input before it
128
+ reaches the widening branch; the message names what to declare. Before the register
129
+ existed that case graded normally, and both repositories in this estate declare the
130
+ tree.
131
+
132
+ Selection has no gap: the row's scope is `**` (less fixtures), so a change to the
133
+ register selects the gate with no `<compliance>` scope entry -- which would make
134
+ the row could-not-run in a repository that declares no such tree.
135
+
136
+ **Why LFS-004 is not gated on an exhaustive run.** LAY-004's DIR-003 grades
137
+ absence from a set, so a narrower set inflates it, and the obvious guard is to fire
138
+ only when the caller vouches the set is the whole tree. That fact is the runner's
139
+ `exhaustive` argument and `Context` does not carry it, so a check cannot read it.
140
+ This gate does not need to: it never infers staleness from a path being absent from
141
+ the SET. `structural` probes each entry's own path with the same `_assess` the set's
142
+ paths get, so a file the set simply does not name, but which is still over the
143
+ threshold, is not stale (a test pins that for both values of `exhaustive`). The real
144
+ pre-commit path always grades the whole staged snapshot with `--exhaustive`
145
+ (`src/hook.ts`, `withStagedIndexSnapshot`), so a narrowed run exists only as a
146
+ manual `--files`. What that leaves open: on such a run an entry for a TRACKED path
147
+ the set does not name is judged from the worktree alone, since `committed_sizes`
148
+ covers only the given paths, so an unstaged deletion or shrink of it reads as stale
149
+ until it is staged. The mirror error is also possible there -- an entry kept alive by
150
+ a smudged worktree copy of a file Git now stores as a pointer -- and only delays its
151
+ removal. Neither lets a blob over the threshold through.
86
152
  """
87
153
 
88
154
  from __future__ import annotations
89
155
 
90
156
  from collections.abc import Iterable
91
157
  from pathlib import Path
92
- from typing import ClassVar
158
+ from typing import Annotated, ClassVar, Literal
159
+
160
+ import yaml
161
+ from pydantic import Field, field_validator
93
162
 
94
163
  from ....core import scope
95
164
  from ....core.check import Check
96
165
  from ....core.context import Context, FileSet
166
+ from ....core.errors import CouldNotRun, SchemaInvalid
97
167
  from ....core.finding import Report
168
+ from ....core.models import StrictModel
169
+
170
+
171
+ class Register(StrictModel):
172
+ """The repository's recorded debt: every blob it already carries over the
173
+ threshold, with the size it had when that was recorded."""
174
+
175
+ schema_version: Literal[1]
176
+ """Locked, not just typed: a future bump must change this literal, which makes
177
+ it a deliberate, schema-revealing edit rather than a silent one."""
178
+
179
+ over_limit_baseline: dict[str, Annotated[int, Field(gt=0)]]
180
+ """Repository-relative file path -> size in bytes. Required (an empty map is a
181
+ register with no debt, a missing key is a typo), and a size is a positive
182
+ integer: a string, float or boolean is refused, not coerced."""
183
+
184
+ @field_validator("over_limit_baseline")
185
+ @classmethod
186
+ def _paths_are_normalised(cls, value: dict[str, int]) -> dict[str, int]:
187
+ for path in value:
188
+ if "\\" in path or any(part in ("", ".", "..") for part in path.split("/")):
189
+ raise ValueError(f"{path!r} is not a normalised repository-relative file path")
190
+ return value
191
+
192
+
193
+ class UniqueKeyLoader(yaml.SafeLoader):
194
+ """`yaml.safe_load`, except that a repeated mapping key is an error.
195
+
196
+ PyYAML keeps the LAST of a repeated key without a word. In a register that
197
+ only ever shrinks that is a silent drop: lowering an entry by adding a second
198
+ line, with the old higher one left in place, would be ignored."""
199
+
200
+ def construct_mapping(self, node: yaml.MappingNode, deep: bool = False) -> dict[object, object]:
201
+ seen: set[object] = set()
202
+ for key_node, _ in node.value:
203
+ key = self.construct_object(key_node, deep=True)
204
+ try:
205
+ if key in seen:
206
+ raise yaml.constructor.ConstructorError(
207
+ None, None, f"found a duplicate key {key!r}", key_node.start_mark
208
+ )
209
+ seen.add(key)
210
+ except TypeError:
211
+ break # unhashable: the base class refuses it below, with its own message
212
+ return super().construct_mapping(node, deep=deep)
98
213
 
99
214
 
100
215
  class Integrity(Check):
101
216
  id: ClassVar[str] = "LFS-001"
102
217
  rule: ClassVar[str] = "LFS-002"
218
+ GREW: ClassVar[str] = "LFS-003"
219
+ STALE: ClassVar[str] = "LFS-004"
103
220
 
104
221
  THRESHOLD: ClassVar[int] = 1024 * 1024
105
222
  """check.sh: `threshold=$((1024 * 1024))`. A blob strictly larger fails."""
@@ -112,34 +229,137 @@ class Integrity(Check):
112
229
  GITATTRIBUTES: ClassVar[str] = ".gitattributes"
113
230
  FILTER_LFS: ClassVar[str] = "filter=lfs"
114
231
 
232
+ reads_committed_sizes: ClassVar[bool] = True
233
+
234
+ # CONSUMER-OWNED: a ratchet baseline IS the repository's own recorded debt
235
+ # (see LAY-004's `register`), so it is read from the repository's declared
236
+ # `compliance` tree and never shipped. Optional on purpose -- see
237
+ # `widening_inputs`: an absent file, or a repository that declares no such
238
+ # tree, means nothing is ratcheted and every blob over the threshold is
239
+ # reported as before.
240
+ inputs: ClassVar[dict[str, str]] = {
241
+ "register": "<compliance>/ratchets/LFS-001-large-blobs.yaml",
242
+ }
243
+
244
+ # The register only ever ADDS an allowance, so leaving it out can only produce
245
+ # MORE findings, never fewer. Requiring the tree would push an owner into
246
+ # declaring a directory they may not have. Read with `.get()`, never assumed.
247
+ widening_inputs: ClassVar[frozenset[str]] = frozenset({"register"})
248
+
249
+ def structural(self, ctx: Context) -> Iterable[Report]:
250
+ # LFS-004 probes each ENTRY's own path, the same question `graded` asks of
251
+ # every path in the set, so it never reads absence from the set. An entry
252
+ # for a file the set simply does not name is not stale. See the module
253
+ # docstring, "Why LFS-004 is not gated on an exhaustive run".
254
+ for rel, _recorded in sorted(self._register(ctx).items()):
255
+ size, why = self._assess(ctx, rel)
256
+ if size is None:
257
+ yield self.report(
258
+ rel,
259
+ f"ratchet entry for {rel} is no longer required: {why}",
260
+ f"delete {rel} from over_limit_baseline in {self._shown(ctx)}",
261
+ rule=self.STALE,
262
+ )
263
+
115
264
  def graded(self, ctx: Context, files: FileSet) -> Iterable[Report]:
265
+ recorded = self._register(ctx)
116
266
  for rel in files:
117
- target = ctx.path(rel)
118
- if not target.is_file():
119
- # check.sh: a path `cat-file --batch-check` answers `missing`
120
- # for -- deleted from the index, or never tracked -- is not a
121
- # blob entering the repository, so there is nothing to
122
- # enforce (its own comment on the `blob` type test).
267
+ size, _why = self._assess(ctx, rel)
268
+ if size is None:
123
269
  continue
270
+ allowed = recorded.get(rel)
271
+ if allowed is None:
272
+ yield self._violation(rel, size)
273
+ elif size > allowed:
274
+ yield self._grew(rel, size, allowed)
124
275
 
125
- size = target.stat().st_size
126
- if size <= self.THRESHOLD:
127
- continue
276
+ def _assess(self, ctx: Context, rel: str) -> tuple[int | None, str]:
277
+ """`(size, "")` when `rel` is a blob entering Git over the threshold,
278
+ otherwise `(None, why not)`. The one question asked of every path in the
279
+ set and of every register entry, so the two can never disagree."""
280
+ stored = ctx.committed_sizes.get(rel)
281
+ if stored is not None:
282
+ # Git has a blob for this path, and its size is what enters the
283
+ # repository -- the worktree file is not (a smudged LFS file is
284
+ # the full content on disk and a ~132-byte pointer in Git). Graded
285
+ # whether or not the worktree file still exists: an unstaged
286
+ # deletion leaves the blob stored. No pointer comparison here: a
287
+ # real pointer is far under the threshold, so a stored blob over it
288
+ # is not one, whatever its first line says.
289
+ if stored > self.THRESHOLD:
290
+ return stored, ""
291
+ return None, (
292
+ f"Git stores {stored} bytes for it, at or under the {self.THRESHOLD}-byte threshold"
293
+ )
128
294
 
129
- if self._tracked_by_lfs(ctx, rel) and self._first_line(target) == self.POINTER:
130
- continue
295
+ target = ctx.path(rel)
296
+ if not target.is_file():
297
+ # check.sh: a path `cat-file --batch-check` answers `missing`
298
+ # for -- deleted from the index, or never tracked -- is not a
299
+ # blob entering the repository, so there is nothing to
300
+ # enforce (its own comment on the `blob` type test).
301
+ return None, "it is not a file in the tree"
131
302
 
132
- # check.sh: both conditions are required, not either one -- a
133
- # `.gitattributes` rule alone does not excuse content that was
134
- # never actually converted to a pointer, and a pointer-shaped
135
- # first line alone does not excuse a path with no rule tracking
136
- # it. See "attribute-without-conversion" in this gate's fixtures.
137
- yield self.report(
138
- rel,
139
- f"{rel} is a {size}-byte blob entering Git without the LFS filter",
140
- f"add a .gitattributes rule matching {rel} to filter=lfs, run "
141
- f"'git lfs track' for that pattern, then re-add {rel}",
142
- )
303
+ size = target.stat().st_size
304
+ if size <= self.THRESHOLD:
305
+ return None, f"it is {size} bytes, at or under the {self.THRESHOLD}-byte threshold"
306
+
307
+ if self._tracked_by_lfs(ctx, rel) and self._first_line(target) == self.POINTER:
308
+ return None, "it is an LFS pointer under a matching .gitattributes rule"
309
+
310
+ # check.sh: both conditions are required, not either one -- a
311
+ # `.gitattributes` rule alone does not excuse content that was
312
+ # never actually converted to a pointer, and a pointer-shaped
313
+ # first line alone does not excuse a path with no rule tracking
314
+ # it. See "attribute-without-conversion" in this gate's fixtures.
315
+ return size, ""
316
+
317
+ def _violation(self, rel: str, size: int) -> Report:
318
+ return self.report(
319
+ rel,
320
+ f"{rel} is a {size}-byte blob entering Git without the LFS filter",
321
+ f"add a .gitattributes rule matching {rel} to filter=lfs, run "
322
+ f"'git lfs track' for that pattern, then re-add {rel}",
323
+ )
324
+
325
+ def _grew(self, rel: str, size: int, recorded: int) -> Report:
326
+ return self.report(
327
+ rel,
328
+ f"{rel} is a {size}-byte blob entering Git without the LFS filter, "
329
+ f"over its ratchet entry of {recorded} bytes",
330
+ f"shrink {rel} to at most {recorded} bytes, or move it to LFS (add a "
331
+ f".gitattributes rule matching {rel} to filter=lfs, run 'git lfs track' for "
332
+ f"that pattern, then re-add {rel}); the register only shrinks, so do not "
333
+ "raise its entry",
334
+ rule=self.GREW,
335
+ )
336
+
337
+ # ------------------------------------------------------------ the register
338
+
339
+ def _register(self, ctx: Context) -> dict[str, int]:
340
+ """The repository's recorded debt, or `{}` when it records none.
341
+
342
+ Absent (no file, or the input dropped because the tree is undeclared) is
343
+ `{}`: nothing is ratcheted, which grades STRICTER. A register that EXISTS
344
+ but cannot be used is could-not-run, never ignored -- ignoring it would
345
+ grade every ratcheted blob as fresh debt, or drop an allowance unseen."""
346
+ target = ctx.inputs.get("register")
347
+ if target is None or not target.exists():
348
+ return {}
349
+ shown = self._shown(ctx)
350
+ if not target.is_file():
351
+ raise CouldNotRun(f"LFS-001 ratchet register {shown} exists but is not a file")
352
+ body = self.text(ctx, target)
353
+ try:
354
+ loaded = yaml.load(body, Loader=UniqueKeyLoader) # noqa: S506 - a SafeLoader
355
+ return dict(self._validate(loaded, Register, shown).over_limit_baseline)
356
+ except yaml.YAMLError as exc:
357
+ raise CouldNotRun(f"LFS-001 ratchet register {shown} is not valid YAML: {exc}") from exc
358
+ except SchemaInvalid as exc:
359
+ raise CouldNotRun(f"LFS-001 ratchet register is unusable: {exc.detail}") from exc
360
+
361
+ def _shown(self, ctx: Context) -> str:
362
+ return ctx.relative(ctx.inputs["register"])
143
363
 
144
364
  # ------------------------------------------------------------- reading
145
365
 
@@ -0,0 +1,3 @@
1
+ schema_version: 1
2
+ over_limit_baseline:
3
+ "./a.png": 2000000
@@ -0,0 +1,4 @@
1
+ schema_version: 1
2
+ over_limit_baseline:
3
+ "a.png": 2000000
4
+ "a.png": 9000000
@@ -0,0 +1,3 @@
1
+ schema_version: 1
2
+ over_limit_baseline:
3
+ "a.png": 2000000.5
@@ -0,0 +1,3 @@
1
+ schema_version: 1
2
+ over_limit_baseline:
3
+ "a.png": '2000000'
@@ -0,0 +1,4 @@
1
+ schema_version: 1
2
+ over_limit_baseline:
3
+ photo.png: 2000000
4
+ "assets/large file.bin": 1500000