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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (413) hide show
  1. package/bin/adl +2 -2
  2. package/bin/git +17 -18
  3. package/bin/git-ado +27 -26
  4. package/bin/git-defaults +173 -0
  5. package/bin/health-check +8 -1
  6. package/bin/kimi-hooks +1 -1
  7. package/bin/lib/adl-package.sh +257 -0
  8. package/bin/lib/bun-compile-build.sh +1 -1
  9. package/bin/lib/fleet-host.sh +62 -0
  10. package/bin/lib/lean-ctx-observe-hooks.sh +9 -9
  11. package/bin/reconcile +693 -470
  12. package/bin/reconcile-host +121 -0
  13. package/bin/setup +219 -0
  14. package/bin/shell-path-policy +15 -5
  15. package/bin/sync-and-reconcile +79 -68
  16. package/bin/validate-manifest +46 -51
  17. package/package.json +2 -12
  18. package/packages/agent-hooks/README.md +14 -9
  19. package/packages/agent-hooks/assets/hooks.json +0 -20
  20. package/packages/agent-hooks/package.json +1 -2
  21. package/packages/agent-hooks/src/cli/args.ts +1 -1
  22. package/packages/agent-hooks/src/cli/doctor.ts +6 -58
  23. package/packages/agent-hooks/src/deploy/deploy.ts +12 -41
  24. package/packages/agent-hooks/src/deploy/doctor.ts +8 -11
  25. package/packages/agent-hooks/src/deploy/index.ts +14 -14
  26. package/packages/agent-hooks/src/deploy/json-merge.ts +7 -8
  27. package/packages/agent-hooks/src/deploy/legacy-lock.ts +2 -2
  28. package/packages/agent-hooks/src/deploy/list.ts +1 -1
  29. package/packages/agent-hooks/src/deploy/lock.ts +31 -12
  30. package/packages/agent-hooks/src/deploy/profile.ts +3 -4
  31. package/packages/agent-hooks/src/deploy/source.ts +1 -1
  32. package/packages/agent-hooks/src/gating/config.ts +10 -24
  33. package/packages/agent-hooks/src/gating/root.ts +3 -3
  34. package/packages/agent-hooks/src/hooks/briefing/handler.ts +2 -2
  35. package/packages/agent-hooks/src/hooks/briefing/index.ts +27 -287
  36. package/packages/agent-hooks/src/hooks/contract.ts +17 -17
  37. package/packages/agent-hooks/src/hooks/crg/background.ts +27 -0
  38. package/packages/agent-hooks/src/hooks/crg/index.ts +7 -6
  39. package/packages/agent-hooks/src/hooks/log.ts +8 -10
  40. package/packages/agent-hooks/src/hooks/user-prompt-submit/match.ts +1 -1
  41. package/packages/agent-hooks/src/hooks/user-prompt-submit/tokenizer.ts +1 -1
  42. package/packages/agent-hooks/src/hooks/user-prompt-submit/vector.ts +6 -5
  43. package/packages/agent-hooks/src/hosts/registry.ts +1 -1
  44. package/packages/agent-hooks/src/log/adl-dir.ts +44 -0
  45. package/packages/agent-hooks/src/log/writer.ts +16 -2
  46. package/packages/agent-hooks/src/main.ts +7 -41
  47. package/packages/agent-hooks/src/pre-tool-use/handler.ts +71 -82
  48. package/packages/agent-hooks/src/rules/engine.ts +13 -17
  49. package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +3 -3
  50. package/packages/agent-hooks/src/rules/impl/adl-git-credential-bypass.ts +12 -14
  51. package/packages/agent-hooks/src/rules/impl/adl-git-identity.ts +28 -28
  52. package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +8 -9
  53. package/packages/agent-hooks/src/rules/impl/adl-human-azdo-bypass.ts +56 -59
  54. package/packages/agent-hooks/src/rules/impl/adl-identity.ts +16 -23
  55. package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +19 -16
  56. package/packages/agent-hooks/src/rules/impl/adl-pr-complete-pending.ts +2 -2
  57. package/packages/agent-hooks/src/rules/impl/adl-pr-review-role.ts +9 -12
  58. package/packages/agent-hooks/src/rules/impl/adl-pr-role.ts +5 -7
  59. package/packages/agent-hooks/src/rules/impl/adl-run-required.ts +411 -0
  60. package/packages/agent-hooks/src/rules/impl/adl-token-minting-role.ts +4 -5
  61. package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +6 -7
  62. package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +77 -70
  63. package/packages/agent-hooks/src/rules/impl/deny-allowlist.ts +159 -0
  64. package/packages/agent-hooks/src/rules/impl/fs-trash.ts +2 -2
  65. package/packages/agent-hooks/src/rules/impl/git-helpers.ts +21 -23
  66. package/packages/agent-hooks/src/rules/impl/git-worktree.ts +14 -28
  67. package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +3 -3
  68. package/packages/agent-hooks/src/rules/impl/messages.ts +1 -1
  69. package/packages/agent-hooks/src/rules/impl/pr-completion.ts +1 -1
  70. package/packages/agent-hooks/src/rules/impl/tool-azure-devops.ts +35 -46
  71. package/packages/agent-hooks/src/rules/impl/tool-find.ts +34 -7
  72. package/packages/agent-hooks/src/rules/impl/tool-grep.ts +34 -12
  73. package/packages/agent-hooks/src/rules/impl/tool-native-search.ts +52 -9
  74. package/packages/agent-hooks/src/rules/ports.ts +5 -7
  75. package/packages/agent-hooks/src/rules/registry.ts +4 -6
  76. package/packages/agent-hooks/src/rules/shell/git-identity.ts +86 -101
  77. package/packages/agent-hooks/src/rules/shell/git-internals.ts +1 -1
  78. package/packages/agent-hooks/src/rules/shell/invocation.ts +24 -118
  79. package/packages/agent-hooks/src/rules/shell/piped-script.ts +1 -1
  80. package/packages/agent-hooks/src/rules/shell/prefixes.ts +1 -1
  81. package/packages/agent-hooks/src/rules/shell/protected-carrier-writes.ts +11 -10
  82. package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +26 -26
  83. package/packages/agent-hooks/src/rules/shell/substitution.ts +1 -1
  84. package/packages/agent-hooks/src/rules/shell/xargs.ts +2 -2
  85. package/packages/agent-hooks/src/rules/spec.ts +2 -2
  86. package/packages/agent-settings/README.md +287 -0
  87. package/packages/agent-settings/assets/GLOBAL-AGENTS.md +18 -18
  88. package/packages/agent-settings/assets/agents/architect.toml +2 -0
  89. package/packages/agent-settings/assets/agents/code-reviewer.toml +2 -0
  90. package/packages/agent-settings/assets/agents/executor.toml +2 -0
  91. package/packages/agent-settings/assets/agents/explore.toml +2 -0
  92. package/packages/agent-settings/assets/agents/planner.toml +2 -0
  93. package/packages/agent-settings/assets/mcp.json +0 -4
  94. package/packages/agent-settings/deploy-profile.json +139 -0
  95. package/packages/agent-settings/deploy-profile.schema.json +147 -0
  96. package/packages/agent-settings/managed/README.md +29 -30
  97. package/packages/agent-settings/managed/codex-requirements.toml +9 -9
  98. package/packages/agent-settings/package.json +20 -0
  99. package/packages/agent-settings/src/deploy/agent-render.ts +2 -2
  100. package/packages/agent-settings/src/deploy/agent-toml.ts +1 -1
  101. package/packages/agent-settings/src/deploy/agents-deploy.ts +17 -3
  102. package/packages/agent-settings/src/deploy/doctor.ts +3 -83
  103. package/packages/agent-settings/src/deploy/index.ts +6 -33
  104. package/packages/agent-settings/src/deploy/legacy-lock.ts +6 -6
  105. package/packages/agent-settings/src/deploy/list.ts +5 -19
  106. package/packages/agent-settings/src/deploy/lock.ts +8 -18
  107. package/packages/agent-settings/src/deploy/mcp-deploy.ts +10 -5
  108. package/packages/agent-settings/src/deploy/mcp-merge.ts +22 -3
  109. package/packages/agent-settings/src/deploy/mcp-source.ts +1 -1
  110. package/packages/agent-settings/src/deploy/profile.ts +11 -35
  111. package/packages/agent-settings/src/deploy/retire-lean-ctx.ts +184 -0
  112. package/packages/agent-settings/src/deploy/settings.ts +17 -22
  113. package/packages/agent-settings/src/global-surface-sweep.ts +5 -17
  114. package/packages/agent-settings/src/kimi-hooks.ts +339 -192
  115. package/packages/agent-settings/src/opencode-hooks.ts +1 -1
  116. package/packages/agent-settings/tsconfig.json +23 -0
  117. package/packages/agent-skills/assets/agent-search-tool-audit/SKILL.md +120 -0
  118. package/packages/agent-skills/assets/agent-search-tool-audit/scripts/audit.sh +276 -0
  119. package/packages/agent-skills/assets/debug-issue/SKILL.md +8 -7
  120. package/packages/agent-skills/assets/explore-codebase/SKILL.md +13 -13
  121. package/packages/agent-skills/assets/refactor-safely/SKILL.md +12 -11
  122. package/packages/agent-skills/assets/review-changes/SKILL.md +7 -7
  123. package/packages/agent-skills/assets/testing/references/e2e.md +37 -0
  124. package/packages/agent-skills/assets/testing/references/integration.md +37 -0
  125. package/packages/agent-skills/assets/testing/references/unit.md +32 -0
  126. package/packages/agent-skills/dist/deploy.d.ts +2 -0
  127. package/packages/agent-skills/dist/deploy.d.ts.map +1 -1
  128. package/packages/agent-skills/dist/deploy.js +27 -1
  129. package/packages/agent-skills/dist/deploy.js.map +1 -1
  130. package/packages/agent-skills/dist/doctor.d.ts +0 -2
  131. package/packages/agent-skills/dist/doctor.d.ts.map +1 -1
  132. package/packages/agent-skills/dist/doctor.js +1 -1
  133. package/packages/agent-skills/dist/doctor.js.map +1 -1
  134. package/packages/agent-skills/dist/fs-utils.d.ts +0 -1
  135. package/packages/agent-skills/dist/fs-utils.d.ts.map +1 -1
  136. package/packages/agent-skills/dist/fs-utils.js +1 -1
  137. package/packages/agent-skills/dist/fs-utils.js.map +1 -1
  138. package/packages/agent-skills/package.json +1 -1
  139. package/packages/agent-skills/src/deploy.ts +29 -1
  140. package/packages/agent-skills/src/doctor.ts +1 -1
  141. package/packages/agent-skills/src/fs-utils.ts +1 -1
  142. package/packages/azdo/README.md +10 -9
  143. package/packages/azdo/package.json +2 -5
  144. package/packages/azdo/src/azdo-pl.ts +2 -54
  145. package/packages/azdo/src/azdo-pr-review.ts +4 -4
  146. package/packages/azdo/src/azdo-repo-doctor.ts +101 -52
  147. package/packages/azdo/src/azdo-wit.ts +41 -2
  148. package/packages/azdo/src/lib/agent-identity.ts +12 -14
  149. package/packages/azdo/src/lib/agent-token.ts +2 -2
  150. package/packages/azdo/src/lib/client.ts +0 -5
  151. package/packages/azdo/src/lib/graph-identity.ts +4 -4
  152. package/packages/azdo/src/workflow-rules-matrix.csv +85 -0
  153. package/packages/azdo/src/workflow-rules.ts +128 -0
  154. package/packages/fleet/manifest.json +38 -33
  155. package/packages/fleet/manifest.schema.json +67 -65
  156. package/packages/fleet/src/default-agent-file.ts +3 -3
  157. package/packages/fleet/src/install-adl-package.ts +73 -15
  158. package/packages/fleet/src/install-embedding-model.ts +14 -14
  159. package/packages/fleet/src/managed-settings.ts +7 -7
  160. package/packages/fleet/src/repo-maintain.ts +439 -0
  161. package/packages/fleet/src/scratch-reap.ts +6 -6
  162. package/packages/fleet/src/vscode-settings.ts +5 -5
  163. package/packages/repo-controls/README.md +141 -43
  164. package/packages/repo-controls/assets/promote.ts +4 -4
  165. package/packages/repo-controls/assets/reconcile-guard.sh +10 -46
  166. package/packages/repo-controls/assets/version-bump.sh +31 -84
  167. package/packages/repo-controls/bunfig.toml +6 -7
  168. package/packages/repo-controls/package/adl-compliance/AGENTS.md +5 -6
  169. package/packages/repo-controls/package/adl-compliance/conftest.py +3 -1
  170. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +4 -16
  171. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +9 -2
  172. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/notes.md +1 -0
  173. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +11 -0
  174. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/__init__.py +7 -0
  175. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/check.py +266 -0
  176. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/c.md +1 -0
  177. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/d.md +1 -0
  178. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.hidden.md +1 -0
  179. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/a.md +1 -0
  180. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/b.md +1 -0
  181. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/data.csv +1 -0
  182. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/diagram.png +1 -0
  183. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/mock.png +1 -0
  184. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/sub/nested.md +1 -0
  185. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs.md +1 -0
  186. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/grants.yaml +4 -0
  187. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p1.md +1 -0
  188. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p2.md +1 -0
  189. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p3.md +1 -0
  190. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p4.md +1 -0
  191. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p5.md +1 -0
  192. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/build.md +1 -0
  193. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/overview.md +1 -0
  194. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/install.md +1 -0
  195. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/start.md +1 -0
  196. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/grants.yaml +4 -0
  197. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-001-tenancy.md +1 -0
  198. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-002-carrier.md +1 -0
  199. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-003-cli.md +1 -0
  200. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-old.md +1 -0
  201. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-older.md +1 -0
  202. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/a.md +1 -0
  203. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/b.md +1 -0
  204. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/c.md +1 -0
  205. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/grants.yaml +4 -0
  206. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-01.md +1 -0
  207. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-02.md +1 -0
  208. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-03.md +1 -0
  209. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-04.md +1 -0
  210. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-05.md +1 -0
  211. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-06.md +1 -0
  212. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-07.md +1 -0
  213. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-08.md +1 -0
  214. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-09.md +1 -0
  215. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-10.md +1 -0
  216. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-11.md +1 -0
  217. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-12.md +1 -0
  218. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-13.md +1 -0
  219. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-14.md +1 -0
  220. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-15.md +1 -0
  221. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-16.md +1 -0
  222. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/grants.yaml +4 -0
  223. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/a.md +1 -0
  224. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/b.md +1 -0
  225. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/c.md +1 -0
  226. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/grants.yaml +4 -0
  227. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/a.md +1 -0
  228. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/b.md +1 -0
  229. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/c.md +1 -0
  230. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/grants.yaml +4 -0
  231. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/a.md +1 -0
  232. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/b.md +1 -0
  233. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/c.md +1 -0
  234. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/d.md +1 -0
  235. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/e.md +1 -0
  236. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/grants.yaml +4 -0
  237. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/a.md +1 -0
  238. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/b.md +1 -0
  239. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/c.md +1 -0
  240. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/short/only.md +1 -0
  241. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/grants.yaml +4 -0
  242. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/a.md +1 -0
  243. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/b.md +1 -0
  244. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/c.md +1 -0
  245. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/d.md +1 -0
  246. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/a.md +1 -0
  247. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/b.md +1 -0
  248. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/grants.yaml +6 -0
  249. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/a.md +1 -0
  250. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/b.md +1 -0
  251. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/c.md +1 -0
  252. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/grants.yaml +3 -0
  253. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/test_check.py +345 -0
  254. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +18 -5
  255. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +35 -0
  256. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/__init__.py +7 -0
  257. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/check.py +91 -0
  258. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/AGENTS.md +3 -0
  259. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/CLAUDE.md +3 -0
  260. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/-leading-hyphen.md +3 -0
  261. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/AGENTS.md +3 -0
  262. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/double--hyphen.md +3 -0
  263. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/getting started.md +3 -0
  264. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/nested/page-here.md +3 -0
  265. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/trailing-hyphen-.md +3 -0
  266. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/ui-contract.md +4 -0
  267. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/user_profile.md +3 -0
  268. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/UI-CONTRACT.png +2 -0
  269. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/diagram.png +1 -0
  270. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/index.md +4 -0
  271. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/notes.md +3 -0
  272. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/reference.html +1 -0
  273. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/2026-10-experiment.md +3 -0
  274. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/UI-CONTRACT.md +6 -0
  275. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs.md +5 -0
  276. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/test_check.py +194 -0
  277. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +14 -2
  278. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +5 -5
  279. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-legacy/docs/compliance/index.md +10 -0
  280. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-type/docs/compliance/index.md +10 -0
  281. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +58 -6
  282. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +0 -1
  283. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +64 -17
  284. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +60 -9
  285. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-clean/docs/notes.md +17 -0
  286. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-no-lines/docs/notes.md +13 -0
  287. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +0 -1
  288. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +0 -1
  289. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/no-type.md +9 -0
  290. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-experiment.md +10 -0
  291. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-research.md +10 -0
  292. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs-okf-profiles.yaml +5 -0
  293. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs/architecture/bad-status.md +0 -1
  294. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +0 -1
  295. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/experiment-ok.md +15 -0
  296. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-key.md +15 -0
  297. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-keys.md +16 -0
  298. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-created.md +11 -0
  299. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-description.md +11 -0
  300. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-last-update.md +11 -0
  301. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-sources.md +10 -0
  302. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-status.md +11 -0
  303. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-title.md +11 -0
  304. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/optional-keys.md +16 -0
  305. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/research-ok.md +14 -0
  306. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/created-date.md +21 -0
  307. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/research-shaped.md +19 -0
  308. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/operations/runbook.md +26 -0
  309. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +228 -2
  310. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +5 -0
  311. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +11 -2
  312. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +5 -3
  313. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +160 -44
  314. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +0 -2
  315. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/a.ts +1 -0
  316. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/b.ts +1 -0
  317. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/grants.yaml +3 -0
  318. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +0 -2
  319. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
  320. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/grants.yaml +5 -0
  321. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/a.ts +1 -0
  322. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/b.ts +1 -0
  323. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/c.ts +1 -0
  324. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/grants.yaml +4 -0
  325. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
  326. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/grants.yaml +5 -0
  327. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +0 -2
  328. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
  329. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/grants.yaml +3 -0
  330. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/register.py +127 -0
  331. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +265 -29
  332. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +75 -2
  333. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +194 -0
  334. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +56 -10
  335. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +256 -0
  336. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +40 -12
  337. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +108 -0
  338. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +1 -1
  339. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +2 -3
  340. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +23 -6
  341. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +76 -0
  342. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +58 -17
  343. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +161 -0
  344. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +35 -3
  345. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +108 -1
  346. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +281 -61
  347. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/absolute-path.yaml +3 -0
  348. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/backslash-path.yaml +3 -0
  349. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/baseline-is-a-list.yaml +2 -0
  350. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/boolean-size.yaml +3 -0
  351. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/dot-segment.yaml +3 -0
  352. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/duplicate-path.yaml +4 -0
  353. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-file.yaml +0 -0
  354. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-segment.yaml +3 -0
  355. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/float-size.yaml +3 -0
  356. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/negative-size.yaml +3 -0
  357. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-over-limit-baseline.yaml +1 -0
  358. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-schema-version.yaml +1 -0
  359. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/non-string-path.yaml +3 -0
  360. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/not-yaml.yaml +2 -0
  361. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/null-size.yaml +3 -0
  362. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/parent-segment.yaml +3 -0
  363. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/string-size.yaml +3 -0
  364. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/top-level-is-a-list.yaml +2 -0
  365. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/trailing-slash.yaml +3 -0
  366. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/unknown-key.yaml +3 -0
  367. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/wrong-schema-version.yaml +2 -0
  368. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/zero-size.yaml +3 -0
  369. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/valid.yaml +4 -0
  370. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +758 -45
  371. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +4 -3
  372. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +2 -2
  373. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/cargo_lock.py +490 -0
  374. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +368 -55
  375. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +4 -2
  376. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_declared_paths.py +523 -0
  377. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_stale_lock.py +1179 -0
  378. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +122 -3
  379. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +33 -1
  380. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +0 -11
  381. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +16 -1
  382. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +1 -2
  383. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +12 -1
  384. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +133 -147
  385. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +133 -147
  386. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +1 -1
  387. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +52 -10
  388. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +23 -4
  389. package/packages/repo-controls/package.json +2 -10
  390. package/packages/repo-controls/scripts/hooks/post-merge +13 -0
  391. package/packages/repo-controls/scripts/hooks/pre-push +3 -3
  392. package/packages/repo-controls/src/azdo-push.ts +64 -36
  393. package/packages/repo-controls/src/azure-devops-governance.ts +7 -9
  394. package/packages/repo-controls/src/azure-devops-remote.ts +1 -1
  395. package/packages/repo-controls/src/cli.ts +29 -8
  396. package/packages/repo-controls/src/compliance-config.ts +410 -2
  397. package/packages/repo-controls/src/config.ts +133 -60
  398. package/packages/repo-controls/src/constants.ts +13 -27
  399. package/packages/repo-controls/src/coverage-ratchet.ts +4 -4
  400. package/packages/repo-controls/src/doctor.ts +46 -19
  401. package/packages/repo-controls/src/gitignore-block.ts +5 -29
  402. package/packages/repo-controls/src/hook-log.ts +1 -2
  403. package/packages/repo-controls/src/hook.ts +201 -45
  404. package/packages/repo-controls/src/install.ts +14 -8
  405. package/packages/repo-controls/src/integrity.ts +3 -3
  406. package/packages/repo-controls/src/lfs.ts +111 -0
  407. package/packages/repo-controls/src/promote.ts +8 -8
  408. package/packages/repo-controls/src/runtime.ts +9 -1
  409. package/packages/repo-controls/src/workflows-drift.ts +4 -5
  410. package/packages/repo-controls/src/worktree-guard.ts +3 -3
  411. package/packages/fleet/jobs/git-maintain/src/main.ts +0 -848
  412. package/packages/fleet/systemd/adl-azure-agent-update.service +0 -13
  413. package/packages/fleet/systemd/adl-azure-agent-update.timer +0 -10
@@ -0,0 +1,439 @@
1
+ /**
2
+ * Repository maintenance: the repository step of `adl reconcile`
3
+ * (`adl maintain --location DIR`). It replaces the retired git-maintain
4
+ * LaunchAgent (2026-09-30, Tarun: "one binary controlling everything").
5
+ *
6
+ * Scope is exactly ONE directory, the host's `repo_location` from the fleet
7
+ * manifest, and only its IMMEDIATE children that carry `adl-config.toml` and
8
+ * are git top-levels. Nothing else is ever touched or mentioned: every child
9
+ * is resolved (symlinks followed) and must still be a direct child of the
10
+ * location BEFORE any file inside it is stat'ed, so a symlink can never make
11
+ * this step read, fetch into or install into anything outside the location.
12
+ * A directory without the marker is not this step's business at all.
13
+ *
14
+ * Per repository, in order:
15
+ * 1. `git fetch origin --prune`;
16
+ * 2. fast-forward the local `integration` and `main` (whichever exist on
17
+ * both sides) -- only ever a true fast-forward. A branch checked out in a
18
+ * worktree (this one or another) is moved only when that worktree is
19
+ * clean (`merge --ff-only`), else WARN and skip; a branch checked out
20
+ * nowhere is moved with a compare-and-swap `update-ref`;
21
+ * 3. the safe-only local branch prune (ported from git-maintain): protected
22
+ * integration/main/master/develop and HEAD are never deleted, the KEEP
23
+ * most recent branches are kept, and only "[gone]" upstreams (-D) or
24
+ * branches merged into the baseline (-d) are deleted;
25
+ * 4. the stale-branch prune (only when `branchMaxAgeDays` is configured, from
26
+ * the manifest's `config.repo_maintain.branch_max_age_days`): every local
27
+ * branch whose TIP commit is older than that many days is deleted with
28
+ * `git branch -D` -- never integration/main/master/develop, the checked-out
29
+ * HEAD, or a branch checked out in any worktree. Each deletion is a
30
+ * `WARN repo-maintain: <repo>: deleted stale branch <name> at <sha> (last
31
+ * commit <date>)` line, which is how a deleted branch is recovered from the
32
+ * log (`git branch <name> <sha>`); a dry run lists them without deleting;
33
+ * 5. `adl install --repo <repo>` -- the existing per-repo enrolment.
34
+ *
35
+ * This runs as the device administrator, never root (the caller,
36
+ * bin/reconcile-host, drops privileges and `adl maintain --expect-user`
37
+ * refuses otherwise). It never reads, migrates or modifies enact-config.toml:
38
+ * a repo may carry both markers, and adl-config.toml alone decides scope.
39
+ *
40
+ * Reporting: plain progress lines go to `out`; every warning and failure goes
41
+ * to `err` as `WARN repo-maintain: ...` / `ERROR repo-maintain: ...` (the
42
+ * level word `adl logs` filters on). A failure never stops the other
43
+ * repositories; the run returns `ok: false` when any occurred.
44
+ */
45
+ import { spawnSync } from 'node:child_process'
46
+ import { readdirSync, realpathSync, statSync, type Dirent } from 'node:fs'
47
+ import { basename, dirname, isAbsolute, join } from 'node:path'
48
+ import { NO_AGENT_IDENTITY_MESSAGE, resolveAgentIdentity } from '../../azdo/src/lib/agent-identity.ts'
49
+
50
+ export const TCC_DENIED_MARKER = 'TCC denied'
51
+
52
+ /** The file whose presence puts a repository in this step's scope. */
53
+ const MARKER = 'adl-config.toml'
54
+
55
+ /** Branches fast-forwarded, in this order. */
56
+ const SYNCED_BRANCHES = ['integration', 'main'] as const
57
+ const PROTECTED = new Set(['integration', 'main', 'master', 'develop'])
58
+ const DEFAULT_KEEP = 3
59
+
60
+ /** Case-insensitive, by name and by realpath: never an Azure Pipelines agent install. */
61
+ const FORBIDDEN_PATH_PATTERN = /azagent|vsts\.agent/i
62
+
63
+ export interface MaintainOptions {
64
+ /** Absolute path of the host's `repo_location`. */
65
+ readonly location: string
66
+ /** The running adl binary, named in the Full Disk Access remedy. */
67
+ readonly executable: string
68
+ /** How to run `adl`: `<command> <...leadingArgs> install --repo <repo>`. */
69
+ readonly install: { readonly command: string; readonly leadingArgs: readonly string[] }
70
+ /** Most recent non-protected local branches kept by the prune. Default 3. */
71
+ readonly keep?: number
72
+ /** Report only: fetches, but never moves a ref, deletes a branch or runs install. */
73
+ readonly dryRun?: boolean
74
+ /**
75
+ * Delete local branches whose tip commit is older than this many days (a
76
+ * positive whole number). Unset: no age-based deletion. The manifest's
77
+ * `config.repo_maintain.branch_max_age_days`, never an environment variable.
78
+ */
79
+ readonly branchMaxAgeDays?: number
80
+ /** The clock, injectable for tests. Default: the current time. */
81
+ readonly now?: () => Date
82
+ /** Environment for identity resolution and every child. Default process.env. */
83
+ readonly env?: NodeJS.ProcessEnv
84
+ readonly out?: (line: string) => void
85
+ readonly err?: (line: string) => void
86
+ }
87
+
88
+ export interface MaintainResult {
89
+ readonly ok: boolean
90
+ readonly repositories: number
91
+ readonly failures: readonly string[]
92
+ }
93
+
94
+ /**
95
+ * Lines explaining why `root` could not be listed. EPERM from readdir is what
96
+ * macOS privacy protection (TCC) returns -- plain permission bits give EACCES
97
+ * -- so it names the exact binary the owner must grant Full Disk Access.
98
+ */
99
+ export function listFailureLines(root: string, error: unknown, executable: string): readonly string[] {
100
+ const message = error instanceof Error ? error.message : String(error)
101
+ const code = (error as { code?: unknown } | null)?.code
102
+ if (code === 'ENOTDIR') return [`${root}: ${message}`]
103
+ const lines = [`${root}: cannot list: ${message}`]
104
+ if (code === 'EPERM') lines.push(tccDeniedLine(root, executable))
105
+ return lines
106
+ }
107
+
108
+ /** The one Full Disk Access hint, for a refused readdir and for a git child refused the same way. */
109
+ function tccDeniedLine(path: string, executable: string): string {
110
+ return (
111
+ `${path}: ${TCC_DENIED_MARKER}: macOS privacy protection blocked ${executable}; ` +
112
+ `one-time fix: System Settings › Privacy & Security › Full Disk Access › + › add ${executable}`
113
+ )
114
+ }
115
+
116
+ interface GitResult {
117
+ readonly ok: boolean
118
+ readonly stdout: string
119
+ readonly stderr: string
120
+ }
121
+
122
+ function errorCode(error: unknown): string | undefined {
123
+ const code = (error as { code?: unknown } | null)?.code
124
+ return typeof code === 'string' ? code : undefined
125
+ }
126
+
127
+ function lines(output: string): string[] {
128
+ return output.split('\n').filter((line) => line.length > 0)
129
+ }
130
+
131
+ function isForbiddenAzurePipelinesPath(path: string): boolean {
132
+ if (FORBIDDEN_PATH_PATTERN.test(path)) return true
133
+ try {
134
+ return FORBIDDEN_PATH_PATTERN.test(realpathSync(path))
135
+ } catch {
136
+ return false
137
+ }
138
+ }
139
+
140
+ export function maintainRepositories(options: MaintainOptions): MaintainResult {
141
+ const env = options.env ?? process.env
142
+ const keep = options.keep ?? DEFAULT_KEEP
143
+ const dry = options.dryRun ?? false
144
+ const out = options.out ?? ((line: string) => void process.stdout.write(`${line}\n`))
145
+ const errOut = options.err ?? ((line: string) => void process.stderr.write(`${line}\n`))
146
+ const info = (message: string): void => out(`repo-maintain: ${message}`)
147
+ const warn = (message: string): void => errOut(`WARN repo-maintain: ${message}`)
148
+ const failures: string[] = []
149
+ const fail = (message: string, subject: string): void => {
150
+ errOut(`ERROR repo-maintain: ${message}`)
151
+ failures.push(subject)
152
+ }
153
+
154
+ let identityEnv: NodeJS.ProcessEnv = {}
155
+ const childEnv = (): NodeJS.ProcessEnv => ({ ...env, ...identityEnv })
156
+ const git = (repo: string, ...args: string[]): GitResult => {
157
+ const result = spawnSync('git', ['-C', repo, ...args], { encoding: 'utf8', env: childEnv() })
158
+ if (result.error !== undefined) throw result.error
159
+ return { ok: result.status === 0, stdout: result.stdout, stderr: result.stderr ?? '' }
160
+ }
161
+
162
+ const maxAgeDays = options.branchMaxAgeDays
163
+ if (maxAgeDays !== undefined && (!Number.isInteger(maxAgeDays) || maxAgeDays < 1)) {
164
+ fail(`branch max age must be a positive whole number of days: ${maxAgeDays}`, 'branch-max-age-days')
165
+ return { ok: false, repositories: 0, failures }
166
+ }
167
+ const now = options.now ?? ((): Date => new Date())
168
+
169
+ const { location } = options
170
+ if (!isAbsolute(location)) {
171
+ fail(`location must be an absolute path: ${location}`, location)
172
+ return { ok: false, repositories: 0, failures }
173
+ }
174
+ if (isForbiddenAzurePipelinesPath(location)) {
175
+ fail(`${location}: refusing an Azure Pipelines agent path`, location)
176
+ return { ok: false, repositories: 0, failures }
177
+ }
178
+
179
+ // Resolve the Azure DevOps agent identity ONCE, before touching any repo
180
+ // (F6): this job runs with no TTY and no ADL_AGENT_ID_AGENT, and bin/git-ado
181
+ // fails closed without one. A real resolution error is fatal; "nothing
182
+ // configured" is only fatal for Azure DevOps remotes, which are skipped
183
+ // loudly below rather than fetched with no identity.
184
+ let agent: string | undefined
185
+ try {
186
+ agent = resolveAgentIdentity(env).agent
187
+ } catch (error) {
188
+ const message = error instanceof Error ? error.message : String(error)
189
+ if (message !== NO_AGENT_IDENTITY_MESSAGE) {
190
+ fail(`cannot resolve an Azure DevOps agent identity: ${message}`, 'identity')
191
+ return { ok: false, repositories: 0, failures }
192
+ }
193
+ warn(
194
+ 'no Azure DevOps agent identity resolved (no ADL_AGENT_ID_AGENT, no default-agent file): ' +
195
+ 'Azure DevOps repos will be skipped this run, not silently fetched with no identity',
196
+ )
197
+ }
198
+ if (agent !== undefined) identityEnv = { ADL_AGENT_ID_AGENT: agent }
199
+
200
+ info(`start location=${location} keep=${keep} dry=${dry ? 1 : 0}${maxAgeDays === undefined ? '' : ` branch_max_age_days=${maxAgeDays}`}`)
201
+
202
+ let entries: Dirent[]
203
+ let locationReal: string
204
+ try {
205
+ locationReal = realpathSync(location)
206
+ entries = readdirSync(locationReal, { withFileTypes: true })
207
+ } catch (error) {
208
+ for (const line of listFailureLines(location, error, options.executable)) errOut(`ERROR repo-maintain: ${line}`)
209
+ failures.push(location)
210
+ return { ok: false, repositories: 0, failures }
211
+ }
212
+
213
+ const seen = new Set<string>()
214
+ let repositories = 0
215
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
216
+ // Files and other non-directories (a symlink is the one kind resolved below).
217
+ if (!entry.isDirectory() && !entry.isSymbolicLink()) continue
218
+ const candidate = join(locationReal, entry.name)
219
+
220
+ // 1. Resolve, then scope-check, BEFORE looking inside. A broken symlink
221
+ // points nowhere and so carries no marker; any other failure to
222
+ // resolve is reported, because it may hide an in-scope repository.
223
+ let real: string
224
+ try {
225
+ real = realpathSync(candidate)
226
+ } catch (error) {
227
+ if (errorCode(error) === 'ENOENT') continue
228
+ fail(`${candidate}: cannot resolve: ${error instanceof Error ? error.message : String(error)}`, candidate)
229
+ continue
230
+ }
231
+ if (dirname(real) !== locationReal) continue
232
+ if (seen.has(real)) continue
233
+
234
+ // 2. The marker decides scope. Not there: not this step's business, and
235
+ // silent. Anything other than "not there" is a named failure.
236
+ try {
237
+ if (!statSync(join(real, MARKER)).isFile()) continue
238
+ } catch (error) {
239
+ const code = errorCode(error)
240
+ if (code === 'ENOENT' || code === 'ENOTDIR') continue
241
+ fail(`${real}: cannot read ${MARKER}: ${error instanceof Error ? error.message : String(error)}`, real)
242
+ continue
243
+ }
244
+ seen.add(real)
245
+
246
+ // 3. In scope from here on. enact-config.toml may sit beside the marker; it is never read.
247
+ const toplevel = gitToplevelState(real)
248
+ if (toplevel === 'failed') continue
249
+ if (toplevel === 'not-toplevel') {
250
+ warn(`${real}: ${MARKER} but not a git top-level; skipped`)
251
+ continue
252
+ }
253
+ repositories += 1
254
+ maintainRepo(real)
255
+ }
256
+
257
+ info(`done (${repositories} repositories, ${failures.length} failed)`)
258
+ return { ok: failures.length === 0, repositories, failures }
259
+
260
+ /**
261
+ * 'not-toplevel' only on git's own "not a git repository" answer (exit 128) or
262
+ * a toplevel that is a different directory. Anything else (spawn error, other
263
+ * exit status, unresolvable toplevel) is reported here as a failure naming the
264
+ * directory, and the repo is not maintained: it may hide an in-scope repository.
265
+ */
266
+ function gitToplevelState(directory: string): 'toplevel' | 'not-toplevel' | 'failed' {
267
+ const command = 'git rev-parse --show-toplevel'
268
+ const top = spawnSync('git', ['-C', directory, 'rev-parse', '--show-toplevel'], { encoding: 'utf8', env: childEnv() })
269
+ if (top.error !== undefined) {
270
+ fail(`${directory}: cannot run ${command}: ${top.error.message}`, directory)
271
+ return 'failed'
272
+ }
273
+ const stderr = (top.stderr ?? '').trim()
274
+ if (top.status === 128 && stderr.includes('not a git repository')) return 'not-toplevel'
275
+ if (top.status !== 0) {
276
+ const shown = stderr.split('\n').slice(0, 3).join(' | ')
277
+ fail(`${directory}: ${command} exited ${top.status ?? `by signal ${top.signal}`}: ${shown}`, directory)
278
+ // git's "Operation not permitted" is TCC refusing the files to this job's responsible process (adl).
279
+ if (stderr.includes('Operation not permitted')) errOut(`ERROR repo-maintain: ${tccDeniedLine(directory, options.executable)}`)
280
+ return 'failed'
281
+ }
282
+ try {
283
+ return realpathSync(top.stdout.trim()) === directory ? 'toplevel' : 'not-toplevel'
284
+ } catch (error) {
285
+ fail(`${directory}: cannot resolve git toplevel ${top.stdout.trim()}: ${error instanceof Error ? error.message : String(error)}`, directory)
286
+ return 'failed'
287
+ }
288
+ }
289
+
290
+ function baselineFor(repo: string): string {
291
+ for (const branch of ['integration', 'main', 'master']) {
292
+ if (git(repo, 'show-ref', '--verify', '--quiet', `refs/remotes/origin/${branch}`).ok) return branch
293
+ }
294
+ return ''
295
+ }
296
+
297
+ function maintainRepo(repo: string): void {
298
+ const name = basename(repo)
299
+
300
+ // An Azure DevOps remote needs an agent identity; without one the fetch
301
+ // would only fail (or be refused) far from the cause.
302
+ if (agent === undefined) {
303
+ const url = git(repo, 'remote', 'get-url', 'origin')
304
+ if (url.ok && /^https:\/\/[^/]*dev\.azure\.com\//.test(url.stdout.trim())) {
305
+ fail(`${name}: skipping: Azure DevOps remote but no agent identity resolved (see the start-of-run warning)`, repo)
306
+ return
307
+ }
308
+ }
309
+
310
+ const head = git(repo, 'symbolic-ref', '--short', '-q', 'HEAD')
311
+ const current = head.ok ? head.stdout.trim() : '(detached)'
312
+
313
+ // 1. fetch + prune. Report what git SAID, never a guess at what it meant.
314
+ const fetched = git(repo, 'fetch', 'origin', '--prune', '--quiet')
315
+ if (!fetched.ok) {
316
+ const reason = fetched.stderr.trim().split('\n').pop() || 'no stderr from git'
317
+ fail(`${name}: fetch failed, skipping repo: ${reason}`, repo)
318
+ return
319
+ }
320
+
321
+ // 2. fast-forward integration and main.
322
+ for (const branch of SYNCED_BRANCHES) fastForward(repo, name, branch)
323
+
324
+ // 3. guarded prune.
325
+ prune(repo, name, current)
326
+
327
+ // 4. stale-branch prune: by the tip commit's age.
328
+ if (maxAgeDays !== undefined) pruneStale(repo, name, current, maxAgeDays)
329
+
330
+ // 5. the per-repo enrolment.
331
+ const argv = [...options.install.leadingArgs, 'install', '--repo', repo]
332
+ const shown = `adl install --repo ${repo}`
333
+ if (dry) {
334
+ info(`${name}: [dry] would run ${shown}`)
335
+ return
336
+ }
337
+ const result = spawnSync(options.install.command, argv, { encoding: 'utf8', env: childEnv() })
338
+ if (result.error !== undefined) {
339
+ fail(`${name}: could not run ${options.install.command}: ${result.error.message}`, repo)
340
+ } else if (result.status !== 0) {
341
+ fail(`${name}: ${shown} exited ${result.status}: ${(result.stderr ?? '').trim()}`, repo)
342
+ } else {
343
+ info(`${name}: ${shown}: ok`)
344
+ }
345
+ }
346
+
347
+ function fastForward(repo: string, name: string, branch: string): void {
348
+ const local = `refs/heads/${branch}`
349
+ const remote = `refs/remotes/origin/${branch}`
350
+ if (!git(repo, 'show-ref', '--verify', '--quiet', local).ok) return
351
+ if (!git(repo, 'show-ref', '--verify', '--quiet', remote).ok) return
352
+ const localSha = git(repo, 'rev-parse', local).stdout.trim()
353
+ const remoteSha = git(repo, 'rev-parse', remote).stdout.trim()
354
+ if (localSha === remoteSha) return
355
+ if (!git(repo, 'merge-base', '--is-ancestor', local, remote).ok) {
356
+ // Not a fast-forward (local has commits origin lacks). Never moved.
357
+ if (!git(repo, 'merge-base', '--is-ancestor', remote, local).ok) {
358
+ warn(`${name}: ${branch} has diverged from origin/${branch}; not moved`)
359
+ }
360
+ return
361
+ }
362
+ // Where is it checked out, if anywhere? (`%(worktreepath)` covers this
363
+ // worktree and every linked one.)
364
+ const worktree = git(repo, 'for-each-ref', local, '--format=%(worktreepath)').stdout.trim()
365
+ if (worktree !== '') {
366
+ if (git(worktree, 'status', '--porcelain').stdout.trim() !== '') {
367
+ warn(`${name}: ${branch} checked out but dirty; skipped fast-forward`)
368
+ } else if (dry) {
369
+ info(`${name}: [dry] would fast-forward ${branch} (checked out)`)
370
+ } else if (git(worktree, 'merge', '--ff-only', `origin/${branch}`, '--quiet').ok) {
371
+ info(`${name}: ${branch} fast-forwarded (checked out)`)
372
+ } else {
373
+ fail(`${name}: ${branch} could not be fast-forwarded (checked out)`, repo)
374
+ }
375
+ return
376
+ }
377
+ if (dry) {
378
+ info(`${name}: [dry] would fast-forward ${branch} (background)`)
379
+ } else if (git(repo, 'update-ref', '-m', `adl maintain: fast-forward ${branch}`, local, remoteSha, localSha).ok) {
380
+ info(`${name}: ${branch} ref fast-forwarded (background)`)
381
+ } else {
382
+ fail(`${name}: ${branch} ref could not be fast-forwarded (background)`, repo)
383
+ }
384
+ }
385
+
386
+ function pruneStale(repo: string, name: string, current: string, days: number): void {
387
+ const cutoff = now().getTime() / 1000 - days * 86_400
388
+ // %1f (unit separator) cannot appear in a ref name, unlike `|`.
389
+ const format = '%(refname:short)%1f%(objectname)%1f%(committerdate:unix)%1f%(worktreepath)'
390
+ for (const line of lines(git(repo, 'for-each-ref', 'refs/heads/', `--format=${format}`).stdout)) {
391
+ const [branch = '', sha = '', committed = '', worktree = ''] = line.split('\x1f')
392
+ if (branch === '' || PROTECTED.has(branch) || branch === current) continue
393
+ const tip = Number(committed)
394
+ if (!Number.isFinite(tip) || tip >= cutoff) continue
395
+ // A branch checked out in any worktree (the main one included) is in use.
396
+ if (worktree !== '') {
397
+ info(`${name}: kept stale branch ${branch} (checked out in ${worktree})`)
398
+ continue
399
+ }
400
+ const described = `stale branch ${branch} at ${sha} (last commit ${new Date(tip * 1000).toISOString().slice(0, 10)})`
401
+ if (dry) info(`${name}: [dry] would delete ${described}`)
402
+ else if (git(repo, 'branch', '-D', branch).ok) warn(`${name}: deleted ${described}`)
403
+ else warn(`${name}: could not delete ${described}`)
404
+ }
405
+ }
406
+
407
+ function prune(repo: string, name: string, current: string): void {
408
+ const base = baselineFor(repo)
409
+ const keptRecent = new Set(
410
+ lines(git(repo, 'for-each-ref', '--sort=-committerdate', 'refs/heads/', '--format=%(refname:short)').stdout)
411
+ .filter((branch) => !PROTECTED.has(branch) && branch !== current)
412
+ .slice(0, keep),
413
+ )
414
+ const merged =
415
+ base === ''
416
+ ? new Set<string>()
417
+ : new Set(lines(git(repo, 'branch', '--merged', `origin/${base}`, '--format=%(refname:short)').stdout))
418
+
419
+ for (const line of lines(git(repo, 'for-each-ref', 'refs/heads/', '--format=%(refname:short)|%(upstream:track)').stdout)) {
420
+ const separator = line.indexOf('|')
421
+ const branch = line.slice(0, separator)
422
+ const track = line.slice(separator + 1)
423
+ if (PROTECTED.has(branch) || branch === current || keptRecent.has(branch)) continue
424
+
425
+ if (track.includes('[gone]')) {
426
+ // remote branch deleted after merge -> proven safe
427
+ if (dry) info(`${name}: [dry] would delete (upstream gone) ${branch}`)
428
+ else if (git(repo, 'branch', '-D', branch).ok) info(`${name}: deleted (upstream gone) ${branch}`)
429
+ else warn(`${name}: could not delete (upstream gone) ${branch}`)
430
+ } else if (base !== '' && merged.has(branch)) {
431
+ if (dry) info(`${name}: [dry] would delete (merged into ${base}) ${branch}`)
432
+ else if (git(repo, 'branch', '-d', branch).ok) info(`${name}: deleted (merged into ${base}) ${branch}`)
433
+ else info(`${name}: kept (${branch}: -d refused)`)
434
+ } else {
435
+ info(`${name}: kept (unconfirmed merged) ${branch}`)
436
+ }
437
+ }
438
+ }
439
+ }
@@ -20,7 +20,7 @@
20
20
  * `git worktree prune` is not a substitute for any of this. It only clears
21
21
  * metadata for worktrees whose directory has ALREADY been deleted.
22
22
  *
23
- * Invoked by reconcile's six-hourly pass (bin/reconcile), gated on
23
+ * Invoked by reconcile's 12-hourly pass (bin/reconcile), gated on
24
24
  * config.scratch_reap.enabled and the per-device scratch_repos list. Devices
25
25
  * that declare no scratch_repos are never touched — a developer machine's
26
26
  * scratch worktrees are working state, not fleet state.
@@ -34,12 +34,12 @@ import { defaultAgentFilePath, type FleetPlatform } from './default-agent-file.t
34
34
  // apps/cli/src/commands/mcp.ts's own cross-package import of packages/azdo:
35
35
  // this workspace has no node_modules/@adl/* symlinks without `bun install`.
36
36
  // packages/azdo/src/lib/agent-identity.ts is now THE one place the
37
- // default-agent file is READ from (STATUS.md 12p,
38
- // W1); this package's own default-agent-file.ts keeps only the WRITE side
39
- // (`reconcileDefaultAgentFile`) plus the path computation both sides need.
37
+ // default-agent file is READ from; this package's own default-agent-file.ts
38
+ // keeps only the WRITE side (`reconcileDefaultAgentFile`) plus the path
39
+ // computation both sides need.
40
40
  import { NO_AGENT_IDENTITY_MESSAGE, resolveAgentIdentity } from '../../azdo/src/lib/agent-identity.ts'
41
41
 
42
- export type Mode = 'plan' | 'apply'
42
+ type Mode = 'plan' | 'apply'
43
43
 
44
44
  export type GitResult = { ok: boolean; stdout: string; stderr: string }
45
45
  export type Git = (args: string[], cwd: string) => GitResult
@@ -530,7 +530,7 @@ function usage(): never {
530
530
  process.exit(2)
531
531
  }
532
532
 
533
- export function main(argv: string[]): number {
533
+ function main(argv: string[]): number {
534
534
  const repos: string[] = []
535
535
  let mode: Mode = 'plan'
536
536
  let idleDays = 1
@@ -21,7 +21,7 @@
21
21
  * format and default/named-profile directory shape, under its own
22
22
  * `Application Support`/`.config` folder name (`Cursor` instead of `Code`) —
23
23
  * this is the standard, well-known Cursor Application Support location
24
- * (docs/operations/research-2026-09-27-worktree-controls-per-surface.md confirms
24
+ * (docs/research/research-2026-09-27-worktree-controls-per-surface.md confirms
25
25
  * `~/.cursor/worktrees/<repo>/` for worktree storage and that
26
26
  * `cursor.worktreeMaxCount` lives in "the regular Cursor settings.json (user
27
27
  * or workspace scope, VS Code-style)", but does not separately spell out the
@@ -51,14 +51,14 @@ import { basename, dirname, isAbsolute, join } from 'node:path'
51
51
  export type VscodePlatform = 'mac' | 'linux'
52
52
 
53
53
  /** A managed setting's value: VS Code's two owned keys are boolean; Cursor's `worktreeMaxCount` is numeric. */
54
- export type SettingValue = boolean | number
54
+ type SettingValue = boolean | number
55
55
 
56
56
  export const REQUIRED_VSCODE_SETTINGS = {
57
57
  'git.detectWorktrees': true,
58
58
  'scm.alwaysShowRepositories': true,
59
59
  } as const
60
60
 
61
- export const APPLY_TO_ALL_PROFILES_SETTING = 'workbench.settings.applyToAllProfiles'
61
+ const APPLY_TO_ALL_PROFILES_SETTING = 'workbench.settings.applyToAllProfiles'
62
62
 
63
63
  /**
64
64
  * `cursor.worktreeMaxCount` — docs/operations/worktree-guard.md L0. Deployed as a
@@ -75,7 +75,7 @@ export const REQUIRED_CURSOR_SETTINGS = {
75
75
  'cursor.worktreeMaxCount': 3,
76
76
  } as const
77
77
 
78
- export interface EditorSettingsSpec {
78
+ interface EditorSettingsSpec {
79
79
  readonly requiredSettings: Readonly<Record<string, SettingValue>>
80
80
  /** VS Code only: the setting id that collects a profile-wide apply-to-all list. Omit for editors with no confirmed equivalent (Cursor). */
81
81
  readonly applyToAllProfilesSetting?: string
@@ -90,7 +90,7 @@ const CURSOR_SPEC: EditorSettingsSpec = {
90
90
  requiredSettings: REQUIRED_CURSOR_SETTINGS,
91
91
  }
92
92
 
93
- export interface VscodeSettingsFileResult {
93
+ interface VscodeSettingsFileResult {
94
94
  readonly path: string
95
95
  readonly changed: boolean
96
96
  readonly missing: boolean