@amsterdamdatalabs/adl-agent-control-darwin-arm64 0.1.4

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 (741) hide show
  1. package/bin/adl +4 -0
  2. package/bin/cursor-settings +14 -0
  3. package/bin/default-agent-file +14 -0
  4. package/bin/git +670 -0
  5. package/bin/git-ado +425 -0
  6. package/bin/global-agents +14 -0
  7. package/bin/global-surface-sweep +14 -0
  8. package/bin/health-check +38 -0
  9. package/bin/kimi-hooks +14 -0
  10. package/bin/lean-ctx-observe-strip +361 -0
  11. package/bin/lib/bun-compile-build.sh +34 -0
  12. package/bin/lib/lean-ctx-observe-hooks.sh +634 -0
  13. package/bin/managed-settings +14 -0
  14. package/bin/opencode-hooks +14 -0
  15. package/bin/reconcile +2648 -0
  16. package/bin/scratch-reap +14 -0
  17. package/bin/shell-path-policy +64 -0
  18. package/bin/surface-policy +14 -0
  19. package/bin/sync-and-reconcile +215 -0
  20. package/bin/update-azure-agent-pool +29 -0
  21. package/bin/validate-manifest +171 -0
  22. package/bin/vscode-settings +14 -0
  23. package/package.json +44 -0
  24. package/packages/agent-hooks/README.md +411 -0
  25. package/packages/agent-hooks/assets/hooks.json +97 -0
  26. package/packages/agent-hooks/assets/opencode-plugin.template.ts +224 -0
  27. package/packages/agent-hooks/bunfig.toml +27 -0
  28. package/packages/agent-hooks/deploy-profile.json +53 -0
  29. package/packages/agent-hooks/deploy-profile.schema.json +120 -0
  30. package/packages/agent-hooks/package.json +23 -0
  31. package/packages/agent-hooks/src/cli/args.ts +99 -0
  32. package/packages/agent-hooks/src/cli/doctor.ts +241 -0
  33. package/packages/agent-hooks/src/cli/rules.ts +133 -0
  34. package/packages/agent-hooks/src/deploy/deploy.ts +181 -0
  35. package/packages/agent-hooks/src/deploy/doctor.ts +158 -0
  36. package/packages/agent-hooks/src/deploy/index.ts +17 -0
  37. package/packages/agent-hooks/src/deploy/json-merge.ts +115 -0
  38. package/packages/agent-hooks/src/deploy/legacy-lock.ts +213 -0
  39. package/packages/agent-hooks/src/deploy/list.ts +117 -0
  40. package/packages/agent-hooks/src/deploy/lock.ts +65 -0
  41. package/packages/agent-hooks/src/deploy/opencode-template.ts +74 -0
  42. package/packages/agent-hooks/src/deploy/profile.ts +117 -0
  43. package/packages/agent-hooks/src/deploy/render.ts +162 -0
  44. package/packages/agent-hooks/src/deploy/source.ts +84 -0
  45. package/packages/agent-hooks/src/gating/config.ts +514 -0
  46. package/packages/agent-hooks/src/gating/root.ts +117 -0
  47. package/packages/agent-hooks/src/hooks/briefing/handler.ts +22 -0
  48. package/packages/agent-hooks/src/hooks/briefing/index.ts +320 -0
  49. package/packages/agent-hooks/src/hooks/contract.ts +112 -0
  50. package/packages/agent-hooks/src/hooks/crg/handler.ts +22 -0
  51. package/packages/agent-hooks/src/hooks/crg/index.ts +209 -0
  52. package/packages/agent-hooks/src/hooks/lean-ctx/handler.ts +22 -0
  53. package/packages/agent-hooks/src/hooks/lean-ctx/index.ts +173 -0
  54. package/packages/agent-hooks/src/hooks/lean-ctx/mapping.ts +121 -0
  55. package/packages/agent-hooks/src/hooks/lean-ctx/scope-rewrite.ts +207 -0
  56. package/packages/agent-hooks/src/hooks/log.ts +233 -0
  57. package/packages/agent-hooks/src/hooks/user-prompt-submit/config.ts +58 -0
  58. package/packages/agent-hooks/src/hooks/user-prompt-submit/constants.ts +149 -0
  59. package/packages/agent-hooks/src/hooks/user-prompt-submit/handler.ts +72 -0
  60. package/packages/agent-hooks/src/hooks/user-prompt-submit/index.ts +203 -0
  61. package/packages/agent-hooks/src/hooks/user-prompt-submit/match.ts +212 -0
  62. package/packages/agent-hooks/src/hooks/user-prompt-submit/skill-roots.ts +73 -0
  63. package/packages/agent-hooks/src/hooks/user-prompt-submit/skills.ts +98 -0
  64. package/packages/agent-hooks/src/hooks/user-prompt-submit/tokenizer.ts +115 -0
  65. package/packages/agent-hooks/src/hooks/user-prompt-submit/vector.ts +174 -0
  66. package/packages/agent-hooks/src/hosts/impl/claude.ts +47 -0
  67. package/packages/agent-hooks/src/hosts/impl/codex.ts +47 -0
  68. package/packages/agent-hooks/src/hosts/impl/cursor.ts +40 -0
  69. package/packages/agent-hooks/src/hosts/impl/kimi.ts +47 -0
  70. package/packages/agent-hooks/src/hosts/impl/opencode.ts +54 -0
  71. package/packages/agent-hooks/src/hosts/registry.ts +29 -0
  72. package/packages/agent-hooks/src/hosts/spec.ts +113 -0
  73. package/packages/agent-hooks/src/lean-ctx/env.ts +106 -0
  74. package/packages/agent-hooks/src/lean-ctx/mcp.ts +140 -0
  75. package/packages/agent-hooks/src/lib/spawn-with-timeout.ts +120 -0
  76. package/packages/agent-hooks/src/log/writer.ts +230 -0
  77. package/packages/agent-hooks/src/main.ts +269 -0
  78. package/packages/agent-hooks/src/pre-tool-use/handler.ts +549 -0
  79. package/packages/agent-hooks/src/rules/engine.ts +293 -0
  80. package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +51 -0
  81. package/packages/agent-hooks/src/rules/impl/adl-git-credential-bypass.ts +320 -0
  82. package/packages/agent-hooks/src/rules/impl/adl-git-identity.ts +249 -0
  83. package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +258 -0
  84. package/packages/agent-hooks/src/rules/impl/adl-human-azdo-bypass.ts +731 -0
  85. package/packages/agent-hooks/src/rules/impl/adl-identity.ts +128 -0
  86. package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +179 -0
  87. package/packages/agent-hooks/src/rules/impl/adl-pr-complete-pending.ts +65 -0
  88. package/packages/agent-hooks/src/rules/impl/adl-pr-review-role.ts +156 -0
  89. package/packages/agent-hooks/src/rules/impl/adl-pr-role.ts +121 -0
  90. package/packages/agent-hooks/src/rules/impl/adl-session-required.ts +403 -0
  91. package/packages/agent-hooks/src/rules/impl/adl-token-minting-role.ts +92 -0
  92. package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +74 -0
  93. package/packages/agent-hooks/src/rules/impl/advisory-coverage.ts +43 -0
  94. package/packages/agent-hooks/src/rules/impl/advisory-finder.ts +62 -0
  95. package/packages/agent-hooks/src/rules/impl/agent-secrets-stay-unread.ts +173 -0
  96. package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +508 -0
  97. package/packages/agent-hooks/src/rules/impl/fs-canonical-checkout.ts +86 -0
  98. package/packages/agent-hooks/src/rules/impl/fs-git-internals.ts +75 -0
  99. package/packages/agent-hooks/src/rules/impl/fs-mv.ts +66 -0
  100. package/packages/agent-hooks/src/rules/impl/fs-rm.ts +83 -0
  101. package/packages/agent-hooks/src/rules/impl/fs-trash.ts +140 -0
  102. package/packages/agent-hooks/src/rules/impl/git-core.ts +101 -0
  103. package/packages/agent-hooks/src/rules/impl/git-helpers.ts +408 -0
  104. package/packages/agent-hooks/src/rules/impl/git-history.ts +77 -0
  105. package/packages/agent-hooks/src/rules/impl/git-paths.ts +139 -0
  106. package/packages/agent-hooks/src/rules/impl/git-plumbing.ts +167 -0
  107. package/packages/agent-hooks/src/rules/impl/git-protected-tree.ts +132 -0
  108. package/packages/agent-hooks/src/rules/impl/git-transitions.ts +292 -0
  109. package/packages/agent-hooks/src/rules/impl/git-verify.ts +95 -0
  110. package/packages/agent-hooks/src/rules/impl/git-worktree.ts +265 -0
  111. package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +76 -0
  112. package/packages/agent-hooks/src/rules/impl/messages.ts +128 -0
  113. package/packages/agent-hooks/src/rules/impl/parse-uncertain.ts +143 -0
  114. package/packages/agent-hooks/src/rules/impl/pr-completion.ts +35 -0
  115. package/packages/agent-hooks/src/rules/impl/shell-remote-script-exec.ts +63 -0
  116. package/packages/agent-hooks/src/rules/impl/tool-azure-devops.ts +283 -0
  117. package/packages/agent-hooks/src/rules/impl/tool-bun-test.ts +81 -0
  118. package/packages/agent-hooks/src/rules/impl/tool-cargo.ts +66 -0
  119. package/packages/agent-hooks/src/rules/impl/tool-chmod-hook.ts +42 -0
  120. package/packages/agent-hooks/src/rules/impl/tool-find.ts +82 -0
  121. package/packages/agent-hooks/src/rules/impl/tool-frontend.ts +83 -0
  122. package/packages/agent-hooks/src/rules/impl/tool-grep.ts +93 -0
  123. package/packages/agent-hooks/src/rules/impl/tool-lean-ctx-global.ts +594 -0
  124. package/packages/agent-hooks/src/rules/impl/tool-native-search.ts +77 -0
  125. package/packages/agent-hooks/src/rules/ports.ts +178 -0
  126. package/packages/agent-hooks/src/rules/registry.ts +233 -0
  127. package/packages/agent-hooks/src/rules/shell/git-identity.ts +1415 -0
  128. package/packages/agent-hooks/src/rules/shell/git-internals.ts +186 -0
  129. package/packages/agent-hooks/src/rules/shell/invocation.ts +1083 -0
  130. package/packages/agent-hooks/src/rules/shell/piped-script.ts +201 -0
  131. package/packages/agent-hooks/src/rules/shell/prefixes.ts +214 -0
  132. package/packages/agent-hooks/src/rules/shell/protected-carrier-writes.ts +108 -0
  133. package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +149 -0
  134. package/packages/agent-hooks/src/rules/shell/split.ts +179 -0
  135. package/packages/agent-hooks/src/rules/shell/substitution.ts +394 -0
  136. package/packages/agent-hooks/src/rules/shell/token.ts +180 -0
  137. package/packages/agent-hooks/src/rules/shell/xargs.ts +81 -0
  138. package/packages/agent-hooks/src/rules/spec.ts +152 -0
  139. package/packages/agent-hooks/src/surface-policy.ts +37 -0
  140. package/packages/agent-hooks/tsconfig.json +23 -0
  141. package/packages/agent-settings/assets/GLOBAL-AGENTS.md +107 -0
  142. package/packages/agent-settings/assets/agents/architect.toml +30 -0
  143. package/packages/agent-settings/assets/agents/code-reviewer.toml +27 -0
  144. package/packages/agent-settings/assets/agents/critic.toml +35 -0
  145. package/packages/agent-settings/assets/agents/executor.toml +28 -0
  146. package/packages/agent-settings/assets/agents/explore.toml +25 -0
  147. package/packages/agent-settings/assets/agents/planner.toml +29 -0
  148. package/packages/agent-settings/assets/lean-ctx/config.toml +39 -0
  149. package/packages/agent-settings/assets/lean-ctx/gitignore +6 -0
  150. package/packages/agent-settings/assets/lean-ctx/layout.toml +5 -0
  151. package/packages/agent-settings/assets/mcp.json +20 -0
  152. package/packages/agent-settings/managed/README.md +331 -0
  153. package/packages/agent-settings/managed/claude-managed-settings.json +150 -0
  154. package/packages/agent-settings/managed/codex-requirements.toml +105 -0
  155. package/packages/agent-settings/protected.json +470 -0
  156. package/packages/agent-settings/src/deploy/agent-render.ts +94 -0
  157. package/packages/agent-settings/src/deploy/agent-toml.ts +76 -0
  158. package/packages/agent-settings/src/deploy/agents-deploy.ts +129 -0
  159. package/packages/agent-settings/src/deploy/doctor.ts +201 -0
  160. package/packages/agent-settings/src/deploy/index.ts +33 -0
  161. package/packages/agent-settings/src/deploy/json-pretty.ts +66 -0
  162. package/packages/agent-settings/src/deploy/lean-ctx-deploy.ts +138 -0
  163. package/packages/agent-settings/src/deploy/legacy-lock.ts +286 -0
  164. package/packages/agent-settings/src/deploy/list.ts +135 -0
  165. package/packages/agent-settings/src/deploy/lock.ts +112 -0
  166. package/packages/agent-settings/src/deploy/mcp-deploy.ts +175 -0
  167. package/packages/agent-settings/src/deploy/mcp-inspect.ts +56 -0
  168. package/packages/agent-settings/src/deploy/mcp-merge.ts +164 -0
  169. package/packages/agent-settings/src/deploy/mcp-render.ts +80 -0
  170. package/packages/agent-settings/src/deploy/mcp-source.ts +43 -0
  171. package/packages/agent-settings/src/deploy/profile.ts +296 -0
  172. package/packages/agent-settings/src/deploy/settings.ts +65 -0
  173. package/packages/agent-settings/src/global-agents.ts +230 -0
  174. package/packages/agent-settings/src/global-surface-sweep.ts +2179 -0
  175. package/packages/agent-settings/src/kimi-hooks.ts +455 -0
  176. package/packages/agent-settings/src/opencode-hooks.ts +76 -0
  177. package/packages/agent-settings/src/surface-policy.ts +441 -0
  178. package/packages/agent-settings/surface-policy.json +20 -0
  179. package/packages/agent-skills/assets/code-review/SKILL.md +100 -0
  180. package/packages/agent-skills/assets/codebase-design/SKILL.md +98 -0
  181. package/packages/agent-skills/assets/codebase-design/references/DEEPENING.md +37 -0
  182. package/packages/agent-skills/assets/codebase-design/references/DESIGN-IT-TWICE.md +44 -0
  183. package/packages/agent-skills/assets/codebase-design/references/TESTABILITY.md +29 -0
  184. package/packages/agent-skills/assets/debug-issue/SKILL.md +40 -0
  185. package/packages/agent-skills/assets/diagnosing-bugs/SKILL.md +100 -0
  186. package/packages/agent-skills/assets/diagnosing-bugs/references/FEEDBACK-LOOP-TACTICS.md +34 -0
  187. package/packages/agent-skills/assets/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  188. package/packages/agent-skills/assets/domain-modeling/SKILL.md +86 -0
  189. package/packages/agent-skills/assets/domain-modeling/references/ADR-FORMAT.md +47 -0
  190. package/packages/agent-skills/assets/domain-modeling/references/CONTEXT-FORMAT.md +60 -0
  191. package/packages/agent-skills/assets/explore-codebase/SKILL.md +41 -0
  192. package/packages/agent-skills/assets/handoff/SKILL.md +28 -0
  193. package/packages/agent-skills/assets/implement/SKILL.md +28 -0
  194. package/packages/agent-skills/assets/refactor-safely/SKILL.md +44 -0
  195. package/packages/agent-skills/assets/review-changes/SKILL.md +45 -0
  196. package/packages/agent-skills/assets/tdd/SKILL.md +49 -0
  197. package/packages/agent-skills/assets/tdd/references/mocking.md +59 -0
  198. package/packages/agent-skills/assets/tdd/references/tests.md +77 -0
  199. package/packages/agent-skills/assets/testing/SKILL.md +54 -0
  200. package/packages/agent-skills/assets/to-feature/SKILL.md +91 -0
  201. package/packages/agent-skills/assets/to-feature/references/FEATURE-SPEC-TEMPLATE.md +88 -0
  202. package/packages/agent-skills/assets/to-workitems/SKILL.md +90 -0
  203. package/packages/agent-skills/assets/to-workitems/references/AZURE-DEVOPS-HIERARCHY.md +118 -0
  204. package/packages/agent-skills/assets/to-workitems/references/TICKET-TEMPLATES.md +70 -0
  205. package/packages/agent-skills/assets/wayfinder/SKILL.md +100 -0
  206. package/packages/agent-skills/assets/wayfinder/references/TEMPLATES.md +35 -0
  207. package/packages/agent-skills/assets/wayfinder/references/TICKET-TYPES.md +8 -0
  208. package/packages/agent-skills/deploy-profile.json +9 -0
  209. package/packages/agent-skills/deploy-profile.schema.json +45 -0
  210. package/packages/agent-skills/dist/deploy.d.ts +27 -0
  211. package/packages/agent-skills/dist/deploy.d.ts.map +1 -0
  212. package/packages/agent-skills/dist/deploy.js +186 -0
  213. package/packages/agent-skills/dist/deploy.js.map +1 -0
  214. package/packages/agent-skills/dist/doctor.d.ts +24 -0
  215. package/packages/agent-skills/dist/doctor.d.ts.map +1 -0
  216. package/packages/agent-skills/dist/doctor.js +141 -0
  217. package/packages/agent-skills/dist/doctor.js.map +1 -0
  218. package/packages/agent-skills/dist/fs-utils.d.ts +8 -0
  219. package/packages/agent-skills/dist/fs-utils.d.ts.map +1 -0
  220. package/packages/agent-skills/dist/fs-utils.js +40 -0
  221. package/packages/agent-skills/dist/fs-utils.js.map +1 -0
  222. package/packages/agent-skills/dist/index.d.ts +8 -0
  223. package/packages/agent-skills/dist/index.d.ts.map +1 -0
  224. package/packages/agent-skills/dist/index.js +8 -0
  225. package/packages/agent-skills/dist/index.js.map +1 -0
  226. package/packages/agent-skills/dist/legacy-lock.d.ts +44 -0
  227. package/packages/agent-skills/dist/legacy-lock.d.ts.map +1 -0
  228. package/packages/agent-skills/dist/legacy-lock.js +121 -0
  229. package/packages/agent-skills/dist/legacy-lock.js.map +1 -0
  230. package/packages/agent-skills/dist/list.d.ts +23 -0
  231. package/packages/agent-skills/dist/list.d.ts.map +1 -0
  232. package/packages/agent-skills/dist/list.js +75 -0
  233. package/packages/agent-skills/dist/list.js.map +1 -0
  234. package/packages/agent-skills/dist/manifest.d.ts +15 -0
  235. package/packages/agent-skills/dist/manifest.d.ts.map +1 -0
  236. package/packages/agent-skills/dist/manifest.js +57 -0
  237. package/packages/agent-skills/dist/manifest.js.map +1 -0
  238. package/packages/agent-skills/dist/profile.d.ts +41 -0
  239. package/packages/agent-skills/dist/profile.d.ts.map +1 -0
  240. package/packages/agent-skills/dist/profile.js +86 -0
  241. package/packages/agent-skills/dist/profile.js.map +1 -0
  242. package/packages/agent-skills/dist/skill-config.d.ts +24 -0
  243. package/packages/agent-skills/dist/skill-config.d.ts.map +1 -0
  244. package/packages/agent-skills/dist/skill-config.js +68 -0
  245. package/packages/agent-skills/dist/skill-config.js.map +1 -0
  246. package/packages/agent-skills/dist/skill-meta.d.ts +17 -0
  247. package/packages/agent-skills/dist/skill-meta.d.ts.map +1 -0
  248. package/packages/agent-skills/dist/skill-meta.js +67 -0
  249. package/packages/agent-skills/dist/skill-meta.js.map +1 -0
  250. package/packages/agent-skills/package.json +31 -0
  251. package/packages/agent-skills/src/deploy.ts +222 -0
  252. package/packages/agent-skills/src/doctor.ts +178 -0
  253. package/packages/agent-skills/src/fs-utils.ts +40 -0
  254. package/packages/agent-skills/src/index.ts +29 -0
  255. package/packages/agent-skills/src/legacy-lock.ts +152 -0
  256. package/packages/agent-skills/src/list.ts +94 -0
  257. package/packages/agent-skills/src/manifest.ts +66 -0
  258. package/packages/agent-skills/src/profile.ts +128 -0
  259. package/packages/agent-skills/src/skill-config.ts +75 -0
  260. package/packages/agent-skills/src/skill-meta.ts +78 -0
  261. package/packages/agent-skills/tsconfig.build.json +13 -0
  262. package/packages/agent-skills/tsconfig.json +23 -0
  263. package/packages/azdo/README.md +111 -0
  264. package/packages/azdo/package.json +21 -0
  265. package/packages/azdo/src/azdo-pl.ts +275 -0
  266. package/packages/azdo/src/azdo-pr-review.ts +160 -0
  267. package/packages/azdo/src/azdo-pr.ts +289 -0
  268. package/packages/azdo/src/azdo-repo-doctor.ts +839 -0
  269. package/packages/azdo/src/azdo-wit.ts +145 -0
  270. package/packages/azdo/src/cli.ts +251 -0
  271. package/packages/azdo/src/lib/agent-identity.ts +198 -0
  272. package/packages/azdo/src/lib/agent-token.ts +167 -0
  273. package/packages/azdo/src/lib/client.ts +259 -0
  274. package/packages/azdo/src/lib/graph-identity.ts +153 -0
  275. package/packages/azdo/src/lib/validate-pr-metadata.ts +57 -0
  276. package/packages/azdo/src/mcp-server.ts +209 -0
  277. package/packages/azdo/src/tool-dispatch.ts +204 -0
  278. package/packages/azdo/tsconfig.json +13 -0
  279. package/packages/fleet/jobs/git-maintain/src/main.ts +588 -0
  280. package/packages/fleet/manifest.json +207 -0
  281. package/packages/fleet/manifest.schema.json +283 -0
  282. package/packages/fleet/src/default-agent-file.ts +144 -0
  283. package/packages/fleet/src/install-adl-package.ts +178 -0
  284. package/packages/fleet/src/install-embedding-model.ts +412 -0
  285. package/packages/fleet/src/launch-agents.ts +649 -0
  286. package/packages/fleet/src/managed-settings.ts +278 -0
  287. package/packages/fleet/src/scratch-reap.ts +601 -0
  288. package/packages/fleet/src/vscode-settings.ts +705 -0
  289. package/packages/fleet/systemd/adl-azure-agent-update.service +13 -0
  290. package/packages/fleet/systemd/adl-azure-agent-update.timer +10 -0
  291. package/packages/repo-controls/AGENTS.md +96 -0
  292. package/packages/repo-controls/CLAUDE.md +1 -0
  293. package/packages/repo-controls/LICENSE +20 -0
  294. package/packages/repo-controls/README.md +493 -0
  295. package/packages/repo-controls/assets/enable-integration-auto-complete.mjs +79 -0
  296. package/packages/repo-controls/assets/promote.ts +371 -0
  297. package/packages/repo-controls/assets/version-bump.sh +189 -0
  298. package/packages/repo-controls/azure-pipelines.yml +274 -0
  299. package/packages/repo-controls/bin/adl-repo-controls.ts +10 -0
  300. package/packages/repo-controls/bunfig.toml +58 -0
  301. package/packages/repo-controls/package/adl-compliance/AGENTS.md +163 -0
  302. package/packages/repo-controls/package/adl-compliance/CLAUDE.md +1 -0
  303. package/packages/repo-controls/package/adl-compliance/conftest.py +78 -0
  304. package/packages/repo-controls/package/adl-compliance/pyproject.toml +31 -0
  305. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/__init__.py +50 -0
  306. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +98 -0
  307. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/__init__.py +1 -0
  308. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/__init__.py +12 -0
  309. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/check.py +210 -0
  310. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-bad-status/docs/architecture/overview.md +8 -0
  311. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-bad-status/docs/decisions/adr-901-proposed.md +10 -0
  312. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-broken-backlink/docs/decisions/adr-902-dangling.md +11 -0
  313. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-clean/docs/architecture/overview.md +8 -0
  314. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-clean/docs/decisions/adr-900-example.md +10 -0
  315. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-frontmatter-mismatch/.plans/b_committed/26-08-08-lifecycle-fixture.md +3 -0
  316. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-frontmatter-mismatch/.specs/demo/lifecycle.md +7 -0
  317. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-frontmatter-mismatch/docs/decisions/adr-903-frontmatter-mismatch.md +11 -0
  318. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-inactive-plan/.plans/c_done/26-08-08-completed-fixture.md +3 -0
  319. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-inactive-plan/.specs/demo/lifecycle.md +7 -0
  320. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-inactive-plan/docs/decisions/adr-904-completed-plan.md +11 -0
  321. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +127 -0
  322. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/__init__.py +7 -0
  323. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/check.py +91 -0
  324. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/AGENTS.md +1 -0
  325. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/CLAUDE.md +1 -0
  326. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/architecture/declared.txt +1 -0
  327. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/compliance/declared.txt +1 -0
  328. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/decisions/declared.txt +1 -0
  329. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/index.md +1 -0
  330. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/operations/declared.txt +1 -0
  331. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/research/declared.txt +1 -0
  332. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/stray-root-file.md +1 -0
  333. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/totally-made-up/nonsense.md +1 -0
  334. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +106 -0
  335. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/__init__.py +7 -0
  336. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +291 -0
  337. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/clean/backend/clean.rs +1 -0
  338. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/excluded/frontend/mobile/src/i18n/locales/zh-CN/strings.ts +1 -0
  339. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/violation/backend/escaped.rs +2 -0
  340. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/violation/backend/raw.rs +1 -0
  341. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/violation/backend//346/226/207/344/273/266.rs +1 -0
  342. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +193 -0
  343. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/__init__.py +12 -0
  344. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/check.py +140 -0
  345. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/fixtures/index-updated-clean/docs/architecture/foo.md +7 -0
  346. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/fixtures/index-updated-clean/docs/architecture/index.md +10 -0
  347. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/fixtures/index-updated-violation/docs/architecture/foo.md +7 -0
  348. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/fixtures/index-updated-violation/docs/architecture/index.md +9 -0
  349. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/test_check.py +98 -0
  350. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/__init__.py +12 -0
  351. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +378 -0
  352. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +192 -0
  353. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-clean/docs/index.md +14 -0
  354. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-clean/docs/one.md +7 -0
  355. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-clean/docs/two.md +7 -0
  356. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-clean/docs-knowledge-indexes.yaml +20 -0
  357. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-duplicate/docs/index.md +15 -0
  358. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-duplicate/docs/one.md +7 -0
  359. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-duplicate/docs/two.md +7 -0
  360. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-duplicate/docs-knowledge-indexes.yaml +16 -0
  361. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-missing-entry/docs/index.md +13 -0
  362. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-missing-entry/docs/one.md +7 -0
  363. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-missing-entry/docs/two.md +7 -0
  364. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-missing-entry/docs-knowledge-indexes.yaml +16 -0
  365. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +102 -0
  366. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/__init__.py +12 -0
  367. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/check.py +387 -0
  368. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-bad-date/plans/LEDGER.md +5 -0
  369. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-clean/plans/LEDGER.md +6 -0
  370. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-empty-table/plans/LEDGER.md +4 -0
  371. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-long-event/plans/LEDGER.md +5 -0
  372. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-violation/plans/LEDGER.md +5 -0
  373. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +427 -0
  374. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/__init__.py +11 -0
  375. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/check.py +84 -0
  376. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/fixtures/markdown-structure-bad-fence/docs/bad-fence.md +2 -0
  377. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/fixtures/markdown-structure-bad-fence/docs/valid.md +5 -0
  378. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/fixtures/markdown-structure-bad-frontmatter/docs/bad-front-matter.md +2 -0
  379. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/fixtures/markdown-structure-bad-frontmatter/docs/valid.md +5 -0
  380. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/fixtures/markdown-structure-clean/docs/valid.md +7 -0
  381. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/test_check.py +126 -0
  382. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/__init__.py +12 -0
  383. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +210 -0
  384. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +119 -0
  385. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +17 -0
  386. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +8 -0
  387. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs/architecture/bad-status.md +17 -0
  388. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +8 -0
  389. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +49 -0
  390. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +159 -0
  391. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/__init__.py +12 -0
  392. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/check.py +578 -0
  393. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/architecture/backend/crate-overview.md +8 -0
  394. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/architecture/team/team-overview.md +8 -0
  395. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/compliance/controls/control-matrix.md +12 -0
  396. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/compliance/controls/control-matrix.yaml +10 -0
  397. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/research/benchmarks/note.md +24 -0
  398. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/backend/crate-overview.md +8 -0
  399. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/product/stable-delivery.md +10 -0
  400. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/product/stable-recommendation.md +12 -0
  401. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/product/target-narration.md +10 -0
  402. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/team/team-overview.md +8 -0
  403. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/compliance/controls/control-matrix.md +8 -0
  404. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/compliance/controls/control-matrix.yaml +17 -0
  405. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/research/benchmarks/bad-research.md +8 -0
  406. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +461 -0
  407. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/__init__.py +1 -0
  408. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/__init__.py +12 -0
  409. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/check.py +124 -0
  410. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/.workflows/AGENTS.md +1 -0
  411. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/.workflows/CLAUDE.md +1 -0
  412. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/AGENTS.md +3 -0
  413. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/CLAUDE.md +2 -0
  414. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/INVARIANTS.md +3 -0
  415. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/bad-pointer/AGENTS.md +3 -0
  416. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/bad-pointer/CLAUDE.md +1 -0
  417. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/docs/AGENTS.md +1 -0
  418. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/docs/CLAUDE.md +1 -0
  419. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/missing-pair/AGENTS.md +3 -0
  420. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/owned/AGENTS.md +1 -0
  421. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/owned/CLAUDE.md +2 -0
  422. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/test_check.py +116 -0
  423. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/ci_paths/__init__.py +13 -0
  424. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/ci_paths/check.py +380 -0
  425. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/ci_paths/fixtures/redeclared-workflows-tree/automation/pipelines/pr-validation.yaml +1 -0
  426. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/ci_paths/test_check.py +274 -0
  427. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +12 -0
  428. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +227 -0
  429. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
  430. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +6 -0
  431. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/fresh/fresh.ts +1 -0
  432. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub1/only.ts +1 -0
  433. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub10/only.ts +1 -0
  434. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub11/only.ts +1 -0
  435. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub2/only.ts +1 -0
  436. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub3/only.ts +1 -0
  437. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub4/only.ts +1 -0
  438. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub5/only.ts +1 -0
  439. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub6/only.ts +1 -0
  440. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub7/only.ts +1 -0
  441. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub8/only.ts +1 -0
  442. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/many/sub9/only.ts +1 -0
  443. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/services/i18n/locales/de/common.json +1 -0
  444. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
  445. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/frontend/packages/desktop/src/vendored-crate/Cargo.toml +2 -0
  446. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +6 -0
  447. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/fresh/fresh.ts +1 -0
  448. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub1/only.ts +1 -0
  449. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub10/only.ts +1 -0
  450. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub11/only.ts +1 -0
  451. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub2/only.ts +1 -0
  452. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub3/only.ts +1 -0
  453. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub4/only.ts +1 -0
  454. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub5/only.ts +1 -0
  455. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub6/only.ts +1 -0
  456. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub7/only.ts +1 -0
  457. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub8/only.ts +1 -0
  458. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/many/sub9/only.ts +1 -0
  459. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
  460. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +6 -0
  461. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +138 -0
  462. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/__init__.py +12 -0
  463. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +240 -0
  464. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/fixtures/markdown-trees-clean/.plans/a_new/plan.md +7 -0
  465. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/fixtures/markdown-trees-clean/backend/AGENTS.md +4 -0
  466. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/fixtures/markdown-trees-clean/docs/page.md +7 -0
  467. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/fixtures/markdown-trees-stray/backend/notes.md +4 -0
  468. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/fixtures/markdown-trees-stray/docs/page.md +8 -0
  469. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +220 -0
  470. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/__init__.py +5 -0
  471. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +225 -0
  472. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/fixtures/open-work-cap-clean/plans/GAPS-AND-FINDINGS.md +5 -0
  473. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/fixtures/open-work-cap-clean/plans/features/az601-clean/spec.md +10 -0
  474. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +330 -0
  475. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/__init__.py +12 -0
  476. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +240 -0
  477. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/agent/crates/enact-providers/src/snapshots/README.md +1 -0
  478. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/backend/crates/enact-app/assets/builtin-assistants/avatars/assistant.jpg +1 -0
  479. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/backend/crates/enact-assets/assets/logos/tools/coding/tool.png +1 -0
  480. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/backend/crates/enact-session/src/backend/codex_init_prompt.md +1 -0
  481. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/mobile/assets/images/icon.png +1 -0
  482. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/packages/desktop/src/renderer/assets/logos/brand/app.png +1 -0
  483. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/packages/desktop/src/renderer/assets/themes/default-theme.png +1 -0
  484. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/public/pwa/icon-192.png +1 -0
  485. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/resources/product.png +1 -0
  486. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-stray/apps/legacy/file.ts +1 -0
  487. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-stray/backend/crates/enact-session/src/backend/README.md +1 -0
  488. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-stray/frontend/unapproved/screenshot.png +1 -0
  489. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +230 -0
  490. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plan_metadata.py +53 -0
  491. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/__init__.py +7 -0
  492. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/check.py +438 -0
  493. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-clean/plans/AGENTS.md +1 -0
  494. 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 +9 -0
  495. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-clean/plans/features/az347-test-coverage/spec.md +12 -0
  496. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-clean/plans/templates/feature.md +1 -0
  497. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-violation/plans/features/az347-test-coverage/items/az351-restore-entrypoint.md +9 -0
  498. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-violation/plans/features/az347-test-coverage/spec.md +12 -0
  499. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +461 -0
  500. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/__init__.py +11 -0
  501. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/check.py +62 -0
  502. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/NotAMigration.sql +1 -0
  503. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/0001_long_prefix.sql +1 -0
  504. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/001_init.sql +1 -0
  505. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/002_add_index.sql +1 -0
  506. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/003-dashed-slug.sql +1 -0
  507. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/004_MixedCase.sql +1 -0
  508. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/005_trailing space.sql +1 -0
  509. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/01_short_prefix.sql +1 -0
  510. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/migrations/not-a-migration.sql +1 -0
  511. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/test_check.py +116 -0
  512. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/__init__.py +11 -0
  513. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +188 -0
  514. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/.plans/c_done/26-07-27-history.md +3 -0
  515. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/docs/README.md +8 -0
  516. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/docs/architecture/product/links.md +20 -0
  517. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/docs/architecture/product/route-target.md +8 -0
  518. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/.plans/c_done/26-07-27-history.md +3 -0
  519. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/docs/README.md +8 -0
  520. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/docs/architecture/product/links.md +20 -0
  521. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/docs/architecture/product/route-target.md +8 -0
  522. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/test_check.py +166 -0
  523. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/__init__.py +11 -0
  524. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +135 -0
  525. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.agents/declared.txt +1 -0
  526. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.changeset/declared.txt +1 -0
  527. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.claude/declared.txt +1 -0
  528. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.code-review-graph/declared.txt +1 -0
  529. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.code-review-graph_old/declared.txt +1 -0
  530. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.codex/declared.txt +1 -0
  531. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.cursor/declared.txt +1 -0
  532. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.cursorrules +1 -0
  533. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.dockerignore +1 -0
  534. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.docs/declared.txt +1 -0
  535. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.donors/declared.txt +1 -0
  536. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.gitattributes +1 -0
  537. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.kimi-code/declared.txt +1 -0
  538. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.lfsconfig +1 -0
  539. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.mcp.json +1 -0
  540. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.opencode/declared.txt +1 -0
  541. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.workflows/declared.txt +1 -0
  542. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/AGENTS.md +1 -0
  543. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/CHANGELOG.md +1 -0
  544. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/CLAUDE-INVARIANTS.md +1 -0
  545. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/CLAUDE.md +1 -0
  546. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/INDEPENDENT-VERIFICATION.md +1 -0
  547. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/INVARIANTS.md +1 -0
  548. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/LICENSE +1 -0
  549. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/NOTICE +1 -0
  550. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/README.md +1 -0
  551. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/RELEASE.md +1 -0
  552. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/VERSION +1 -0
  553. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/backend/declared.txt +1 -0
  554. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/compliance/declared.txt +1 -0
  555. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/dev/declared.txt +1 -0
  556. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/docker/declared.txt +1 -0
  557. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/docs/declared.txt +1 -0
  558. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/frontend/declared.txt +1 -0
  559. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/infra/declared.txt +1 -0
  560. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/justfile +1 -0
  561. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/opencode.jsonc +1 -0
  562. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/rule-tests/undeclared.txt +1 -0
  563. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/rules/undeclared.txt +1 -0
  564. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/unapproved-root/undeclared.txt +1 -0
  565. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/undeclared-root-file.txt +1 -0
  566. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +122 -0
  567. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/__init__.py +12 -0
  568. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +290 -0
  569. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/.changeset/some-change.md +3 -0
  570. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/.plans/AGENTS.md +3 -0
  571. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/.specs/AGENTS.md +3 -0
  572. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/.workflows/AGENTS.md +3 -0
  573. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/AGENTS.md +3 -0
  574. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/CHANGELOG.md +3 -0
  575. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/CLAUDE.md +3 -0
  576. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/INDEPENDENT-VERIFICATION.md +3 -0
  577. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/INVARIANTS.md +3 -0
  578. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/README.md +3 -0
  579. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/RELEASE.md +3 -0
  580. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/STRAY.md +3 -0
  581. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/docs/AGENTS.md +3 -0
  582. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/docs/architecture/note.md +3 -0
  583. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/frontend/README.md +3 -0
  584. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-missing-guide/.workflows/AGENTS.md +1 -0
  585. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-missing-guide/AGENTS.md +1 -0
  586. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-missing-guide/README.md +1 -0
  587. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-missing-guide/docs/overview.md +1 -0
  588. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-missing-guide/plans/AGENTS.md +1 -0
  589. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +329 -0
  590. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/__init__.py +12 -0
  591. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +127 -0
  592. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/a/b/c/d/at-limit.sh +3 -0
  593. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/a/b/c/d/e/too-deep.sh +3 -0
  594. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-01.sh +3 -0
  595. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-02.sh +3 -0
  596. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-03.sh +3 -0
  597. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-04.sh +3 -0
  598. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-05.sh +3 -0
  599. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-06.sh +3 -0
  600. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-07.sh +3 -0
  601. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-08.sh +3 -0
  602. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-09.sh +3 -0
  603. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-10.sh +3 -0
  604. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-11.sh +3 -0
  605. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-12.sh +3 -0
  606. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-13.sh +3 -0
  607. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-14.sh +3 -0
  608. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-15.sh +3 -0
  609. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/fixtures/scripts-layout/.workflows/scripts/direct-16.sh +3 -0
  610. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +163 -0
  611. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/__init__.py +1 -0
  612. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/__init__.py +11 -0
  613. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +169 -0
  614. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/attribute-without-conversion/.gitattributes +1 -0
  615. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/attribute-without-conversion/large file.bin +3 -0
  616. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/clean/.gitattributes +1 -0
  617. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/clean/large file.bin +3 -0
  618. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/clean/small.txt +1 -0
  619. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/missing-filter/large file.bin +0 -0
  620. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/unmatched-extension/.gitattributes +1 -0
  621. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/unmatched-extension/payload.dat +0 -0
  622. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +133 -0
  623. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/__init__.py +1 -0
  624. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/__init__.py +12 -0
  625. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/check.py +129 -0
  626. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/fixtures/disjoint/gate-registry.yaml +13 -0
  627. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/fixtures/empty/gate-registry.yaml +7 -0
  628. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/fixtures/overlapping/gate-registry.yaml +13 -0
  629. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/test_check.py +109 -0
  630. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/__init__.py +1 -0
  631. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/__init__.py +11 -0
  632. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/check.py +149 -0
  633. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/fixtures/clean/docs/readme.md +4 -0
  634. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/fixtures/relevant/VERSION +1 -0
  635. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/test_check.py +151 -0
  636. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/__init__.py +11 -0
  637. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/check.py +202 -0
  638. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/.workflows/changesets/package.json +5 -0
  639. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/.workflows/package.json +5 -0
  640. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/CHANGELOG.md +5 -0
  641. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/VERSION +1 -0
  642. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/.workflows/changesets/package.json +5 -0
  643. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/.workflows/package.json +5 -0
  644. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/CHANGELOG.md +5 -0
  645. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/VERSION +1 -0
  646. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/test_check.py +162 -0
  647. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/__init__.py +1 -0
  648. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/__init__.py +12 -0
  649. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/check.py +103 -0
  650. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/compliance_py/checks/git-bad.sh +2 -0
  651. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/compliance_py/checks/git-note.sh +3 -0
  652. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/compliance_py/checks/good.sh +2 -0
  653. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/compliance_py/checks/grep-bad.sh +2 -0
  654. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/compliance_py/checks/grep-note.sh +3 -0
  655. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/compliance_py/checks/grep-trailing.sh +2 -0
  656. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/compliance_py/checks/notes.md +1 -0
  657. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/elsewhere/loose-git.sh +6 -0
  658. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/elsewhere/loose-grep.sh +4 -0
  659. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/test_check.py +117 -0
  660. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/__init__.py +13 -0
  661. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +265 -0
  662. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/fixtures/ignored-paths/keep.log +1 -0
  663. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/fixtures/ignored-paths/src/main.rs +1 -0
  664. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +180 -0
  665. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/__init__.py +12 -0
  666. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/check.py +84 -0
  667. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/fixtures/license-declared-clean/LICENSE +10 -0
  668. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/fixtures/license-declared-mismatch/LICENSE +3 -0
  669. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/fixtures/license-declared-missing/README.md +1 -0
  670. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/test_check.py +66 -0
  671. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/__init__.py +11 -0
  672. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +167 -0
  673. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/Cargo.lock +7 -0
  674. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/Cargo.toml +4 -0
  675. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/rust-toolchain.toml +3 -0
  676. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/src/main.rs +1 -0
  677. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/frontend/bun.lock +1 -0
  678. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/Cargo.lock +7 -0
  679. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/Cargo.toml +4 -0
  680. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/rust-toolchain.toml +3 -0
  681. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/src/main.rs +1 -0
  682. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/frontend/bun.lock +0 -0
  683. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +109 -0
  684. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +483 -0
  685. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/__init__.py +1 -0
  686. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/ast_grep.py +199 -0
  687. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/batch.py +52 -0
  688. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +303 -0
  689. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +106 -0
  690. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +99 -0
  691. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/errors.py +32 -0
  692. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/finding.py +65 -0
  693. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/models.py +40 -0
  694. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/receipt.py +63 -0
  695. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/scope.py +82 -0
  696. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/verdict.py +161 -0
  697. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/__init__.py +1 -0
  698. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +131 -0
  699. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.toml +30 -0
  700. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +65 -0
  701. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +791 -0
  702. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.schema.yaml +176 -0
  703. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +791 -0
  704. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/grants-registry.yaml +112 -0
  705. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/grants.py +129 -0
  706. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +281 -0
  707. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +250 -0
  708. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/severity-policy.yaml +114 -0
  709. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/providers/__init__.py +11 -0
  710. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +371 -0
  711. package/packages/repo-controls/package/adl-compliance/uv.lock +199 -0
  712. package/packages/repo-controls/package.json +33 -0
  713. package/packages/repo-controls/scripts/hooks/commit-msg +63 -0
  714. package/packages/repo-controls/scripts/hooks/lib/hook-log.sh +62 -0
  715. package/packages/repo-controls/scripts/hooks/post-checkout +15 -0
  716. package/packages/repo-controls/scripts/hooks/post-commit +18 -0
  717. package/packages/repo-controls/scripts/hooks/pre-commit +82 -0
  718. package/packages/repo-controls/scripts/hooks/pre-push +144 -0
  719. package/packages/repo-controls/src/azdo-push.ts +463 -0
  720. package/packages/repo-controls/src/azure-devops-governance.ts +248 -0
  721. package/packages/repo-controls/src/azure-devops-remote.ts +61 -0
  722. package/packages/repo-controls/src/cli.ts +188 -0
  723. package/packages/repo-controls/src/compliance-config.ts +200 -0
  724. package/packages/repo-controls/src/config.ts +690 -0
  725. package/packages/repo-controls/src/constants.ts +97 -0
  726. package/packages/repo-controls/src/coverage-ratchet.ts +153 -0
  727. package/packages/repo-controls/src/doc-freshness.ts +172 -0
  728. package/packages/repo-controls/src/doctor.ts +304 -0
  729. package/packages/repo-controls/src/findings-ratchet.ts +163 -0
  730. package/packages/repo-controls/src/gitignore-block.ts +253 -0
  731. package/packages/repo-controls/src/hook-log.ts +72 -0
  732. package/packages/repo-controls/src/hook.ts +694 -0
  733. package/packages/repo-controls/src/install.ts +506 -0
  734. package/packages/repo-controls/src/integrity.ts +104 -0
  735. package/packages/repo-controls/src/promote.ts +25 -0
  736. package/packages/repo-controls/src/runtime.ts +110 -0
  737. package/packages/repo-controls/src/workflows-drift.ts +106 -0
  738. package/packages/repo-controls/src/worktree-guard.ts +272 -0
  739. package/packages/repo-controls/src/worktree-limit.ts +11 -0
  740. package/packages/repo-controls/tsconfig.json +14 -0
  741. package/packages/repo-controls/workflows/scripts/release/verify-npm-artifact.ts +119 -0
@@ -0,0 +1,508 @@
1
+ /**
2
+ * Editing the files that wire the host's hooks or un-manage this repo.
3
+ *
4
+ * Handoff 5, rule 5: deny Write/Edit/MultiEdit/NotebookEdit on
5
+ * `.claude/settings.json`, `.claude/settings.local.json`,
6
+ * `.codex/config.toml`, or `adl-config.toml`. These are the files that
7
+ * either install the hook into the host (`.claude/settings.json`,
8
+ * `.codex/config.toml`, including the `.local.json` overrides) or arm the
9
+ * gate in this repo (`adl-config.toml`'s `[hooks] enabled = false`
10
+ * silently no-ops every kind — see `main.ts`'s `runHook`). Editing any
11
+ * of them is a way to switch the gate off without anyone noticing.
12
+ *
13
+ * Decision 13 (STATUS.md 12p, 2026-09-29): the managed-
14
+ * hooks lock is off, so these per-repo carrier files are now the ONLY
15
+ * enforcement layer for the hosts that read them — three more joined the
16
+ * set for exactly that reason: `.codex/hooks.json`, `.cursor/hooks.json`,
17
+ * and `.opencode/plugins/adl-repo.ts` (the generated OpenCode plugin IS
18
+ * its own carrier; there is no separate settings file for that host).
19
+ * Measured against the real engine before this fix: Write
20
+ * `.codex/hooks.json` / Edit `.cursor/hooks.json` / Write
21
+ * `.opencode/plugins/adl-repo.ts` all had `blocked: false`, while the
22
+ * original four's own control case (`.claude/settings.json`) already had
23
+ * `blocked: true`.
24
+ *
25
+ * The list is hard-coded here on purpose. `adl-config.toml`'s own
26
+ * `[hooks] enabled` already lets a repo switch the whole hook system
27
+ * off; allowing `[rules."agent.tamper-protection"] enabled = false` in
28
+ * the same file is the same switch wearing a different hat. A repo that
29
+ * legitimately needs a different allowlist should patch this file in a
30
+ * PR, not in a session.
31
+ *
32
+ * The file names match against the FULL path and against the basename so
33
+ * `Write .claude/settings.json` AND `Write /Users/x/repo/.claude/settings.json`
34
+ * both fire, but `Write .claude/SETTINGS.json.bak` does NOT (the
35
+ * case-sensitive suffix check rejects it).
36
+ *
37
+ * Shell-write coverage (STATUS.md 12p, decision 13 follow-up, 2026-09-29):
38
+ * the tool-call gate above never saw a shell command at all — `echo x >
39
+ * .cursor/hooks.json`, `tee`, `mv`/`cp`/`install`/`ln -sf`, `sed -i`/
40
+ * `perl -pi`, `truncate`, `trash`/`rm`/`unlink`/`shred`, and `dd of=` were
41
+ * every one of them `{blocked: false}` against all seven protected files,
42
+ * measured directly against the real engine before this fix. Closed via
43
+ * three additional match() branches:
44
+ * - `inv.kind === 'protected-carrier-write'` — the generic-command half
45
+ * (redirection/tee/mv/cp/install/ln/sed/perl/truncate/trash/rm/unlink/
46
+ * shred/dd), classified by `shell/protected-carrier-writes.ts` and wired
47
+ * into `shell/invocation.ts`'s `walk()` exactly like `git-internals-write`
48
+ * — which is what makes nested `bash -c`/`sh -c` covered for free (that
49
+ * detection runs on every walked piece, top-level or nested).
50
+ * - `inv.kind === 'git'` with subcommand `rm`, or `checkout`/`restore`/
51
+ * `reset` with a protected path after `--` — `git rm`/`checkout --`/etc.
52
+ * on one of these files IS already blocked today by generic, target-
53
+ * independent rules (`git.rm` bans every `git rm`; `git.checkout-dashdash`
54
+ * bans every `git checkout --`), but neither is protecting THESE files
55
+ * specifically and neither would survive being disabled on its own —
56
+ * this rule (AGENT_RULES, evaluated before GIT_RULES — see registry.ts)
57
+ * now claims the protected-path case with its own message before either
58
+ * generic rule gets a turn.
59
+ * - A coarse textual check on `ctx.command` (the same pattern as
60
+ * `adl.human-azdo-bypass`'s `os.environ`/`process.env` detection) for an
61
+ * interpreter one-liner writing a protected path — `python3 -c
62
+ * "open('.codex/hooks.json','w')..."`, `node -e
63
+ * "fs.writeFileSync('.cursor/hooks.json', ...)"`. Not a parser: a
64
+ * write-shaped call plus a protected path's text anywhere in the command
65
+ * is enough to deny, same tradeoff `adl.human-azdo-bypass` already makes.
66
+ *
67
+ * A write whose target is a dynamic command substitution
68
+ * (`$(git rev-parse --show-toplevel)/…`) is not this rule's to classify at
69
+ * all — `shell/invocation.ts`'s existing, target-agnostic
70
+ * `unresolvableRedirectionWriteTargets`/`unresolvableOperandWriteTargets`
71
+ * checks already fail closed on ANY dynamic write target via
72
+ * `parse.uncertain`, protected carrier or not.
73
+ */
74
+ import type { Token } from '../shell/token.ts'
75
+ import { tokenValue } from '../shell/token.ts'
76
+ import type { Invocation } from '../shell/invocation.ts'
77
+ import { PROTECTED_CARRIER_PATHS, protectedCarrierDirMatch, protectedCarrierMatch } from '../shell/protected-carriers.ts'
78
+ import { mcpToolName } from './mcp-tool.ts'
79
+ import type { Finding, MessageContext, RuleContext, RuleSpec } from '../spec.ts'
80
+ import { noParams } from '../spec.ts'
81
+
82
+ /** The tool name a host actually sends, past an `mcp__<server>__` prefix (e.g. `mcp__lean_ctx__ctx_patch` → `ctx_patch`) — unprefixed names (Claude/Codex/Kimi/Cursor/OpenCode's own tool names) pass through unchanged. */
83
+ function logicalToolName(tool: string): string {
84
+ if (!tool.startsWith('mcp__')) return tool
85
+ return mcpToolName(tool) ?? tool
86
+ }
87
+
88
+ /**
89
+ * Tools whose `input.file_path` / `input.notebook_path` / `input.path` /
90
+ * `input.filePath` decides what the edit targets — matched case-insensitively
91
+ * (F4, independent review, 2026-09-29): OpenCode's own plugin
92
+ * (`.opencode/plugins/adl-repo.ts`'s `tool.execute.before`) sends its OWN
93
+ * lowercase tool names (`edit`, `write`), not Claude/Codex/Kimi's
94
+ * capitalized ones, and its `tool_input` (`output.args`) carries the target
95
+ * as camelCase `filePath`, not `file_path`.
96
+ */
97
+ /**
98
+ * P2 (independent review, 2026-09-29): widened beyond Claude/Codex/Kimi's
99
+ * own capitalized names — one normalized (lowercase) list covering every
100
+ * edit-tool spelling a supported host actually sends:
101
+ * - `strreplace`/`str_replace_editor`/`edit_file`/`str_replace`/
102
+ * `replace_in_file`/`create_file`/`write_file` — Cursor's own matcher
103
+ * regex names every one of these (`deploy-profile.json`'s
104
+ * `surfaces[].matchers` entry for cursor, line ~33) as an alias its
105
+ * generated carrier maps onto `Write`; this rule reads the SAME source
106
+ * list rather than a second, hand-copied one.
107
+ * - `delete` — Cursor's own delete-file tool.
108
+ * - `writefile`/`strreplacefile` — Kimi's own tool names (`WriteFile`/
109
+ * `StrReplaceFile`), lower-cased same as every other host's.
110
+ * - `ctx_patch`/`ctx_edit` — the lean-ctx MCP server's own edit tools
111
+ * (`mcp__lean_ctx__ctx_patch`/`ctx_edit`); their target field is `path`,
112
+ * already read below alongside `file_path`/`notebook_path`/`filePath`.
113
+ * `apply_patch` stays a SEPARATE branch (its own patch-header parsing, not
114
+ * a `file_path`-shaped field) — see `applyPatchTarget`.
115
+ */
116
+ const EDIT_TOOL_NAMES = new Set([
117
+ 'write',
118
+ 'edit',
119
+ 'multiedit',
120
+ 'notebookedit',
121
+ 'patch',
122
+ 'strreplace',
123
+ 'str_replace_editor',
124
+ 'edit_file',
125
+ 'str_replace',
126
+ 'replace_in_file',
127
+ 'create_file',
128
+ 'write_file',
129
+ 'delete',
130
+ 'writefile',
131
+ 'strreplacefile',
132
+ 'ctx_patch',
133
+ 'ctx_edit',
134
+ ])
135
+
136
+ function readStringField(input: Readonly<Record<string, unknown>>, key: string): string {
137
+ const value = input[key]
138
+ return typeof value === 'string' ? value : ''
139
+ }
140
+
141
+ /**
142
+ * Codex's `apply_patch` (F4): its patch body lives in `input.command`
143
+ * (`handler.ts`'s `toDecideInput` special-cases this tool to a `tool-call`
144
+ * precisely so it reaches here instead of being walked as shell text), and
145
+ * the path it targets is named in a `*** Add File:`/`*** Update File:`/
146
+ * `*** Delete File:`/`*** Move to:` header — never a `file_path`-shaped
147
+ * field. Coarse (no real patch parser): any one of those headers naming a
148
+ * protected path is enough to deny.
149
+ */
150
+ const PATCH_HEADER_RE = /^\*\*\* (?:Add File|Update File|Delete File|Move to): (.+)$/gm
151
+
152
+ function applyPatchTarget(patchBody: string): string | null {
153
+ for (const match of patchBody.matchAll(PATCH_HEADER_RE)) {
154
+ const path = (match[1] ?? '').trim()
155
+ if (protectedCarrierMatch(path) !== null) return path
156
+ }
157
+ return null
158
+ }
159
+
160
+ function toolCallTarget(inv: Invocation & { kind: 'tool-call' }): string | null {
161
+ const name = logicalToolName(inv.tool).toLowerCase()
162
+ // apply_patch / OpenCode's own `patch` tool: the patch body is
163
+ // `input.command` (Codex) or `input.patchText` (OpenCode's own field
164
+ // name for the same shape, P2) — never a `file_path`-shaped field.
165
+ if (name === 'apply_patch' || name === 'patch') {
166
+ const body = readStringField(inv.input, 'command') + readStringField(inv.input, 'patchText')
167
+ if (body.length > 0) return applyPatchTarget(body)
168
+ }
169
+ if (!EDIT_TOOL_NAMES.has(name)) return null
170
+ // F8 (fourth independent review, 2026-09-29): Cursor's real `edit_file`
171
+ // schema names its path argument `target_file` (confirmed via Cursor's
172
+ // own published tool schema/system-prompt documentation).
173
+ const filePath =
174
+ readStringField(inv.input, 'file_path') + readStringField(inv.input, 'notebook_path') + readStringField(inv.input, 'filePath') + readStringField(inv.input, 'target_file')
175
+ const path = readStringField(inv.input, 'path')
176
+ for (const candidate of [filePath, path]) {
177
+ if (candidate.length === 0) continue
178
+ if (protectedCarrierMatch(candidate) !== null) return candidate
179
+ }
180
+ return null
181
+ }
182
+
183
+ /** The path operands after a `--` in `rest` (git's own pathspec separator). */
184
+ function pathsAfterDashDash(rest: readonly Token[]): readonly string[] {
185
+ const index = rest.findIndex((token) => tokenValue(token) === '--')
186
+ return index < 0 ? [] : rest.slice(index + 1).map(tokenValue)
187
+ }
188
+
189
+ /** The non-option operands (`--` itself excluded) — used for the no-`--` positional path forms below. */
190
+ function nonOptionValues(rest: readonly Token[]): readonly string[] {
191
+ return rest.map(tokenValue).filter((value) => value !== '--' && (!value.startsWith('-') || value === '-'))
192
+ }
193
+
194
+ /**
195
+ * `git checkout` ALWAYS restores the WORKTREE for a named path — there is no
196
+ * staged-only variant (that is `git restore --staged`'s job) — so every
197
+ * shape is checked: `git checkout -- <path>` and, P1 (second independent
198
+ * review, 2026-09-29), the equally real `git checkout <rev> <path>` form
199
+ * with no `--` at all (>= 2 non-option operands; the LAST one is the path).
200
+ */
201
+ function checkoutTarget(rest: readonly Token[]): string | null {
202
+ const afterDashDash = pathsAfterDashDash(rest)
203
+ if (afterDashDash.length > 0) {
204
+ for (const value of afterDashDash) {
205
+ if (protectedCarrierMatch(value) !== null) return value
206
+ }
207
+ return null
208
+ }
209
+ const operands = nonOptionValues(rest)
210
+ if (operands.length < 2) return null
211
+ const path = operands[operands.length - 1] as string
212
+ return protectedCarrierMatch(path) !== null ? path : null
213
+ }
214
+
215
+ /**
216
+ * `git restore` touches the WORKTREE by default; `--staged`/`-S` makes it an
217
+ * index-only unstage UNLESS `--worktree`/`-W` is ALSO given (both flags
218
+ * together restore both). P1 (second independent review, 2026-09-29): a
219
+ * plain `git restore --staged -- <path>` must be ALLOWED — it never
220
+ * touches the file this rule exists to protect from being overwritten.
221
+ */
222
+ function restoreTouchesWorktree(rest: readonly Token[]): boolean {
223
+ const values = rest.map(tokenValue)
224
+ const staged = values.some((value) => value === '--staged' || value === '-S')
225
+ if (!staged) return true
226
+ return values.some((value) => value === '--worktree' || value === '-W')
227
+ }
228
+
229
+ function restoreTarget(rest: readonly Token[]): string | null {
230
+ if (!restoreTouchesWorktree(rest)) return null
231
+ const afterDashDash = pathsAfterDashDash(rest)
232
+ const candidates = afterDashDash.length > 0 ? afterDashDash : nonOptionValues(rest)
233
+ for (const value of candidates) {
234
+ if (protectedCarrierMatch(value) !== null) return value
235
+ }
236
+ return null
237
+ }
238
+
239
+ /**
240
+ * `git reset [<tree>] [--] <paths>...` only ever updates the INDEX for
241
+ * those paths — never the worktree — regardless of any flag other than
242
+ * `--hard`/`--merge`/`--keep`, none of which accepts a pathspec in real
243
+ * git (a bare `git reset --hard` with no path at all is `git.reset`'s own
244
+ * unconditional deny to catch, not this rule's — there is no specific
245
+ * carrier PATH for this function to find there). P1 (second independent
246
+ * review, 2026-09-29): `git reset -- <path>` and `git reset HEAD --
247
+ * <path>` must be ALLOWED — they only unstage.
248
+ */
249
+ function resetTouchesWorktree(rest: readonly Token[]): boolean {
250
+ return rest.some((token) => {
251
+ const value = tokenValue(token)
252
+ return value === '--hard' || value === '--merge' || value === '--keep'
253
+ })
254
+ }
255
+
256
+ function resetTarget(rest: readonly Token[]): string | null {
257
+ if (!resetTouchesWorktree(rest)) return null
258
+ for (const value of pathsAfterDashDash(rest)) {
259
+ if (protectedCarrierMatch(value) !== null) return value
260
+ }
261
+ return null
262
+ }
263
+
264
+ /** `git rm <protected>` (any form), or `git checkout|restore|reset` in a WORKTREE-changing form naming `<protected>`. */
265
+ /** `git rm`/`git mv`: every non-option operand is a candidate (for `mv`, moving a carrier away OR overwriting one with something else are both tamper). */
266
+ function anyOperandTarget(rest: readonly Token[]): string | null {
267
+ for (const token of rest) {
268
+ const value = tokenValue(token)
269
+ if (value === '--' || value.startsWith('-')) continue
270
+ // F5 (fourth independent review, 2026-09-29): `git mv .claude
271
+ // .claude-old` moves the WHOLE carrier directory away — file-level
272
+ // `protectedCarrierMatch` alone never saw this.
273
+ const hit = protectedCarrierMatch(value) ?? protectedCarrierDirMatch(value)
274
+ if (hit !== null) return value
275
+ }
276
+ return null
277
+ }
278
+
279
+ function gitTarget(inv: Invocation & { kind: 'git' }): string | null {
280
+ // P2 (independent review, 2026-09-29): `git mv` of a carrier (either
281
+ // operand — moving it away, or overwriting it with something else).
282
+ if (inv.subcommand === 'rm' || inv.subcommand === 'mv') return anyOperandTarget(inv.rest)
283
+ if (inv.subcommand === 'checkout') return checkoutTarget(inv.rest)
284
+ if (inv.subcommand === 'restore') return restoreTarget(inv.rest)
285
+ if (inv.subcommand === 'reset') return resetTarget(inv.rest)
286
+ // P2: `git checkout-index` writes working-tree files from the index for
287
+ // named paths — the plumbing sibling of `git checkout -- <path>`. `-a`/
288
+ // `--all` (every staged file, no specific path named) is a known,
289
+ // documented gap — not handled here.
290
+ if (inv.subcommand === 'checkout-index') return anyOperandTarget(inv.rest)
291
+ return null
292
+ }
293
+
294
+ /**
295
+ * `git apply`/the standalone `patch` utility (P2, independent review,
296
+ * 2026-09-29): the path a patch actually modifies lives INSIDE the patch
297
+ * file's own headers, not (usually) as a command-line operand at all —
298
+ * `git apply some.patch` names the PATCH FILE, never its target. Coarse,
299
+ * whole-command (same tradeoff `interpreterTarget`/`coarsePathMention`
300
+ * already make elsewhere in this file): a protected path's text ANYWHERE
301
+ * on the line is enough to deny — reading the patch file's own content to
302
+ * parse its `--- a/<path>`/`+++ b/<path>` headers is out of scope for a
303
+ * static, pre-execution hook (it would need to read the file from disk,
304
+ * which this hook does not do for any other check either).
305
+ */
306
+ /** `git apply` flags that inspect a patch without applying anything (F7, fourth independent review, 2026-09-29). */
307
+ const DRY_RUN_GIT_APPLY_FLAGS: ReadonlySet<string> = new Set(['--check', '--stat', '--numstat', '--summary'])
308
+
309
+ function coarsePathMention(command: string): string | null {
310
+ for (const protectedPath of PROTECTED_CARRIER_PATHS) {
311
+ if (command.includes(protectedPath)) return protectedPath
312
+ const base = protectedPath.slice(protectedPath.lastIndexOf('/') + 1)
313
+ if (command.includes(base)) return protectedPath
314
+ }
315
+ return null
316
+ }
317
+
318
+ /**
319
+ * Live false positive (third independent review, 2026-09-29): the OLD check
320
+ * paired "some write call anywhere in the command" (`WRITE_CALL_RE.test`)
321
+ * with "a carrier path anywhere in the command text" (`coarsePathMention`)
322
+ * — two UNCORRELATED checks. A heredoc-fed `python3 - <<'EOF'` writing an
323
+ * unrelated file (e.g. `STATUS.md`) whose own written TEXT merely mentioned
324
+ * `.codex/config.toml` (a docstring, a log line, a commit message) was
325
+ * wrongly denied — the mention and the write had nothing to do with each
326
+ * other.
327
+ *
328
+ * Replaced with CORRELATED detection: each pattern below captures the
329
+ * WRITE-CALL'S OWN TARGET ARGUMENT specifically (group 1) — `open(TARGET,
330
+ * 'w'|'a'|'x'…)`, `Path(TARGET).write_text/write_bytes(...)`,
331
+ * `os.remove/unlink(TARGET)`, `os.rename(SRC, TARGET)`,
332
+ * `shutil.move/copy/copy2/copyfile(SRC, TARGET)`,
333
+ * `fs.writeFileSync|appendFileSync|rmSync|unlinkSync|copyFileSync|truncateSync(TARGET, …)`,
334
+ * `fs.renameSync(SRC, TARGET)`, `Bun.write(TARGET, …)`, `File.write(TARGET,
335
+ * …)` (Ruby), `open(FH, '>'|'>>', TARGET)` (Perl 3-arg open) — a carrier
336
+ * path is only a match when it appears THERE. `writeCallTargets` extracts
337
+ * every captured target; `targetNamesCarrierPath` decides each one: a
338
+ * quoted string literal (or f-string) is checked directly
339
+ * (`protectedCarrierMatch`); a bare, unresolvable identifier/expression is
340
+ * fail-closed ONLY when that EXACT identifier is separately assigned a
341
+ * carrier-path string literal earlier in the same code (`p = '.codex/
342
+ * config.toml'; open(p, 'w')`) — an unrelated variable, or one assigned
343
+ * something else, is not a match. A capture that is a more complex
344
+ * expression (neither a literal nor a bare identifier — string
345
+ * concatenation, a function call, …) cannot be correlated at all and is
346
+ * left alone (allowed), the same "cannot resolve, so cannot deny" stance
347
+ * `adl.session-required-for-writes`'s own destination classification takes
348
+ * for an unresolved git push remote.
349
+ *
350
+ * `ARG` allows one level of nested parens (`os.path.join(a, b)` as a
351
+ * target) but otherwise stops at the next comma/paren — coarse, matching
352
+ * every other regex-based check in this file, not a real expression parser.
353
+ */
354
+ const ARG = `((?:[^,()]|\\([^()]*\\))+)`
355
+ /** `fs.X(...)`, `require('fs').X(...)`, or `require('fs').promises.X(...)` (no literal `fs.` substring exists in the `require(...)` forms — `'fs')` breaks it — so all three are matched explicitly rather than relying on a bare `fs\.` prefix). Required (not optional) for the async, non-Sync names below — `rename`/`unlink`/`rm` are common-enough verbs that an UNqualified bare call risks a real collision with an unrelated same-named function. */
356
+ const FS_QUALIFIED_PREFIX = `(?:\\bfs|require\\(\\s*['"]fs['"]\\s*\\))\\s*\\.\\s*(?:promises\\s*\\.\\s*)?`
357
+ /** The SAME prefix, but OPTIONAL — F6 (fourth independent review, 2026-09-29): `const { writeFileSync } = require('fs'); writeFileSync(...)` calls it BARE, with no qualifying prefix on the call site itself. Only for the `*Sync` names, distinctive enough on their own that an unqualified bare call is still almost certainly this Node API. */
358
+ const FS_SYNC_OPTIONAL_PREFIX = `(?:${FS_QUALIFIED_PREFIX})?`
359
+ const WRITE_TARGET_PATTERNS: readonly RegExp[] = [
360
+ new RegExp(`\\bopen\\s*\\(\\s*${ARG}\\s*,\\s*['"][wax]`, 'g'),
361
+ new RegExp(`\\bPath\\s*\\(\\s*${ARG}\\s*\\)\\s*\\.\\s*write_(?:text|bytes)\\s*\\(`, 'g'),
362
+ new RegExp(`\\bos\\.(?:remove|unlink)\\s*\\(\\s*${ARG}\\s*\\)`, 'g'),
363
+ new RegExp(`\\bos\\.rename\\s*\\(\\s*${ARG}\\s*,\\s*${ARG}\\s*\\)`, 'g'),
364
+ new RegExp(`\\bshutil\\.(?:move|copy2?|copyfile)\\s*\\(\\s*${ARG}\\s*,\\s*${ARG}\\s*\\)`, 'g'),
365
+ new RegExp(`${FS_SYNC_OPTIONAL_PREFIX}(?:writeFileSync|appendFileSync|rmSync|unlinkSync|copyFileSync|truncateSync)\\s*\\(\\s*${ARG}`, 'g'),
366
+ new RegExp(`${FS_SYNC_OPTIONAL_PREFIX}renameSync\\s*\\(\\s*${ARG}\\s*,\\s*${ARG}`, 'g'),
367
+ // F6: the async (non-Sync) forms, prefix REQUIRED.
368
+ new RegExp(`${FS_QUALIFIED_PREFIX}(?:writeFile|appendFile|rm|unlink|copyFile)\\s*\\(\\s*${ARG}`, 'g'),
369
+ new RegExp(`${FS_QUALIFIED_PREFIX}rename\\s*\\(\\s*${ARG}\\s*,\\s*${ARG}`, 'g'),
370
+ new RegExp(`\\bBun\\.write\\s*\\(\\s*${ARG}`, 'g'),
371
+ new RegExp(`\\bFile\\.write\\s*\\(\\s*${ARG}`, 'g'),
372
+ new RegExp(`\\bopen\\s*\\(\\s*${ARG}\\s*,\\s*['"]>{1,2}['"]\\s*,\\s*${ARG}\\s*\\)`, 'g'),
373
+ ]
374
+ /** Position (from the end) of the TARGET capture group for each pattern above, in the same order — `os.rename`/`shutil.*`/the async `rename`/perl `open` capture 2 groups (source, target); every other pattern captures 1 (the target itself). */
375
+ const TARGET_IS_LAST_GROUP: readonly boolean[] = [false, false, false, true, true, false, true, false, true, false, false, true]
376
+
377
+ function writeCallTargets(command: string): readonly string[] {
378
+ const targets: string[] = []
379
+ for (let index = 0; index < WRITE_TARGET_PATTERNS.length; index += 1) {
380
+ const pattern = WRITE_TARGET_PATTERNS[index] as RegExp
381
+ const takeLast = TARGET_IS_LAST_GROUP[index]
382
+ for (const match of command.matchAll(pattern)) {
383
+ const value = takeLast ? match[2] : match[1]
384
+ if (value !== undefined) targets.push(value.trim())
385
+ }
386
+ }
387
+ return targets
388
+ }
389
+
390
+ const QUOTED_LITERAL_RE = /^f?(['"])([\s\S]*)\1$/
391
+ const BARE_IDENTIFIER_RE = /^[A-Za-z_]\w*$/
392
+
393
+ /** Whether `target` (a captured write-call argument) names a protected carrier — directly (a quoted literal) or, fail-closed, via a same-code assignment to a carrier-path literal when `target` is an unresolvable bare identifier. */
394
+ function targetNamesCarrierPath(target: string, command: string): string | null {
395
+ const literal = QUOTED_LITERAL_RE.exec(target)
396
+ if (literal !== null) return protectedCarrierMatch(literal[2] ?? '')
397
+ if (!BARE_IDENTIFIER_RE.test(target)) return null
398
+ const escaped = target.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
399
+ const assignment = new RegExp(`\\b${escaped}\\s*=\\s*f?(['"])([\\s\\S]*?)\\1`).exec(command)
400
+ if (assignment === null) return null
401
+ return protectedCarrierMatch(assignment[2] ?? '')
402
+ }
403
+
404
+ function interpreterTarget(command: string): string | null {
405
+ for (const target of writeCallTargets(command)) {
406
+ const hit = targetNamesCarrierPath(target, command)
407
+ if (hit !== null) return hit
408
+ }
409
+ return null
410
+ }
411
+
412
+ export const agentTamperProtection: RuleSpec = {
413
+ id: 'agent.tamper-protection',
414
+ category: 'tool-call',
415
+ severity: 'deny',
416
+ enabledByDefault: true,
417
+ summary: 'Deny edits (tool, shell write, or git rewrite) to the host hook config or the repo gate marker.',
418
+ params: noParams,
419
+ match(inv: Invocation, ctx: RuleContext<Record<string, never>>): Finding | null {
420
+ if (inv.kind === 'tool-call') {
421
+ const target = toolCallTarget(inv)
422
+ return target === null ? null : { ruleId: 'agent.tamper-protection', severity: 'deny', detail: { path: target, via: 'tool-call' } }
423
+ }
424
+ if (inv.kind === 'protected-carrier-write') {
425
+ // `targets` is never empty here: shell/invocation.ts only ever emits
426
+ // this kind when `protectedCarrierWriteTargets(...).length > 0`.
427
+ return { ruleId: 'agent.tamper-protection', severity: 'deny', detail: { path: inv.targets[0] ?? '', via: 'shell', command: inv.name || 'a redirection' } }
428
+ }
429
+ if (inv.kind === 'git') {
430
+ const target = gitTarget(inv)
431
+ if (target !== null) {
432
+ return { ruleId: 'agent.tamper-protection', severity: 'deny', detail: { path: target, via: 'git', command: `git ${inv.subcommand}` } }
433
+ }
434
+ // P2: `git apply` — coarse, whole-command (see `coarsePathMention`'s
435
+ // own doc for why: the target path is inside the patch's own
436
+ // headers, not an operand `gitTarget`'s per-operand scan would see).
437
+ // F7 (fourth independent review, 2026-09-29): a dry-run/inspection
438
+ // flag applies NOTHING — `git apply --check/--stat/--numstat/
439
+ // --summary` never touches the working tree, so naming a carrier is
440
+ // harmless.
441
+ if (inv.subcommand === 'apply' && !inv.rest.some((token) => DRY_RUN_GIT_APPLY_FLAGS.has(tokenValue(token)))) {
442
+ const hit = coarsePathMention(ctx.command ?? '')
443
+ if (hit !== null) return { ruleId: 'agent.tamper-protection', severity: 'deny', detail: { path: hit, via: 'git', command: 'git apply' } }
444
+ }
445
+ return null
446
+ }
447
+ // P2: the standalone `patch` utility — same coarse, whole-command
448
+ // reasoning as `git apply` above.
449
+ if (inv.kind === 'command' && inv.name === 'patch') {
450
+ const hit = coarsePathMention(ctx.command ?? '')
451
+ if (hit !== null) return { ruleId: 'agent.tamper-protection', severity: 'deny', detail: { path: hit, via: 'shell', command: 'patch' } }
452
+ }
453
+ const interpreter = interpreterTarget(ctx.command ?? '')
454
+ if (interpreter !== null) {
455
+ return { ruleId: 'agent.tamper-protection', severity: 'deny', detail: { path: interpreter, via: 'interpreter' } }
456
+ }
457
+ return null
458
+ },
459
+ message(finding: Finding, ctx: MessageContext) {
460
+ const path = typeof finding.detail.path === 'string' ? finding.detail.path : 'this file'
461
+ const via = typeof finding.detail.via === 'string' ? finding.detail.via : 'tool-call'
462
+ const command = typeof finding.detail.command === 'string' ? finding.detail.command : ''
463
+ const verb =
464
+ via === 'shell'
465
+ ? `${command} writing`
466
+ : via === 'git'
467
+ ? `${command} rewriting`
468
+ : via === 'interpreter'
469
+ ? 'an interpreter one-liner writing'
470
+ : 'editing'
471
+ return {
472
+ user: `Blocked ${via === 'tool-call' ? 'editing' : verb} ${path}. This file wires the host's hooks or un-manages this repo; ask the user to change it.`,
473
+ agent:
474
+ `DENIED ${verb} ${path}. This file is one of the tamper-protected files: ` +
475
+ '`.claude/settings.json`, `.claude/settings.local.json`, `.codex/config.toml`, ' +
476
+ '`.codex/hooks.json`, `.cursor/hooks.json`, `.opencode/plugins/adl-repo.ts`, ' +
477
+ "`~/.kimi-code/config.toml`, or `adl-config.toml`. The first six install or override a " +
478
+ "host's own hook contract (directly, or — for `.opencode/plugins/adl-repo.ts` — as the " +
479
+ 'generated plugin THAT IS the carrier; `~/.kimi-code/config.toml` is Kimi\'s own single, ' +
480
+ "globally-installed carrier — Kimi has no per-repo one); `adl-config.toml` is the repo's " +
481
+ "own gate marker (`[hooks] enabled = false` silently no-ops every hook kind — see " +
482
+ '`main.ts`). Editing, overwriting, moving over, truncating, ' +
483
+ 'deleting, or rewriting any of them — by a tool call, a shell write, or a git checkout/ ' +
484
+ 'restore/reset/rm — is a way to switch the gate off without anyone noticing, the ONLY ' +
485
+ 'enforcement layer for the hosts that read them (decision 13: the managed-hooks lock is ' +
486
+ `off). If a legitimate change is needed, file a PR or ask the user to make it themselves. ` +
487
+ `Blocked call: ${ctx.snippet}`,
488
+ }
489
+ },
490
+ corpus: {
491
+ // Tool-call and shell-command shapes are both exercised directly by
492
+ // `tests/unit/rules-agent-tamper-protection.test.ts` (through
493
+ // `decide({kind:'tool-call'})` and `decideCommand`); this corpus only
494
+ // has to prove reads stay allowed and unrelated commands don't trip it.
495
+ deny: [],
496
+ allow: [
497
+ 'ls -la .claude',
498
+ 'cat .claude/settings.json',
499
+ 'cat adl-config.toml',
500
+ 'rg "enabled" .claude/',
501
+ 'cat .codex/hooks.json',
502
+ 'cat .cursor/hooks.json',
503
+ 'cat .opencode/plugins/adl-repo.ts',
504
+ 'jq . .codex/hooks.json',
505
+ 'sed -n "1,5p" .codex/hooks.json',
506
+ ],
507
+ },
508
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * `~/enact-vps` — the canonical checkout — is off-limits to agents.
3
+ *
4
+ * Owner decision, 2026-09-15. It is the tree the fleet reconciler builds every
5
+ * global binary from (`/Library/LaunchDaemons/com.adl.global-tools.plist` →
6
+ * `--repo /Users/ranahome/enact-vps`), and
7
+ * `/usr/local/libexec/adl-global-tools-sync` refuses the ENTIRE
8
+ * reconciliation while that tree is dirty (labels/binary confirmed already
9
+ * renamed fleet-side: `packages/fleet/README.md` documents
10
+ * `com.adl.global-tools`; this comment had drifted):
11
+ *
12
+ * canonical checkout is dirty; refusing pull and reconciliation
13
+ *
14
+ * So a single stray write there does not inconvenience one repo — it silently
15
+ * stops every machine in the fleet from updating, with no signal beyond a line
16
+ * in a log nobody reads. That had been happening for an unknown number of
17
+ * cycles before it was found.
18
+ *
19
+ * Nothing needs to touch that path to ship: agents work in a clone and push to
20
+ * `main`, and the reconciler does its own `git pull --ff-only origin main`.
21
+ *
22
+ * WHY THIS LAYER. `~/.claude/settings.json` cannot express it. Permission rules
23
+ * match Bash by command PREFIX (`Bash(git *)`), never by path, so
24
+ * `rg foo ~/enact-vps` is invisible to them — and a hand-added `permissions.deny`
25
+ * entry is itself a global-surface-sweep candidate, so it would be removed
26
+ * again later. Path-aware denial exists only here.
27
+ *
28
+ * The classifier carries the path (see `shell/invocation.ts`'s `denied-path`):
29
+ * `cat`/`ls` and the other read-only consumers return `[]` from classification
30
+ * and are invisible to rules, and `read-only` carries only a name, so without
31
+ * that kind there would be nothing for this rule to inspect.
32
+ */
33
+
34
+ import type { Invocation } from '../shell/invocation.ts'
35
+ import type { Finding, MessageContext, RuleSpec } from '../spec.ts'
36
+ import { noParams } from '../spec.ts'
37
+ import { detailString } from './messages.ts'
38
+
39
+ export const fsCanonicalCheckout: RuleSpec = {
40
+ id: 'fs.canonical-checkout',
41
+ category: 'filesystem',
42
+ severity: 'deny',
43
+ enabledByDefault: true,
44
+ summary: 'Deny any command reaching into ~/enact-vps, the canonical checkout the fleet builds from.',
45
+ params: noParams,
46
+ match(inv: Invocation): Finding | null {
47
+ if (inv.kind !== 'denied-path') return null
48
+ return { ruleId: 'fs.canonical-checkout', severity: 'deny', detail: { path: inv.path, name: inv.name } }
49
+ },
50
+ message(finding: Finding, ctx: MessageContext) {
51
+ const path = detailString(finding, 'path')
52
+ return {
53
+ user: `Blocked: ${path} is inside ~/enact-vps, the canonical checkout. Work in a clone and push to main — the reconciler pulls from origin itself.`,
54
+ agent:
55
+ `DENIED ${path}. That is inside ~/enact-vps, the canonical checkout the fleet reconciler builds every ` +
56
+ 'global binary from. It refuses the whole reconciliation while that tree is dirty ("canonical checkout ' +
57
+ 'is dirty; refusing pull and reconciliation"), so a stray write there stops every machine updating.\n' +
58
+ 'Nothing needs to touch it to ship: work in a clone (e.g. ~/Documents/enact-vps-m5), commit, and push to ' +
59
+ '`main`. The reconciler runs its own `git pull --ff-only origin main` before building, so your change ' +
60
+ 'reaches /usr/local/bin without that path ever being written by an agent.\n' +
61
+ `Blocked command: ${ctx.snippet}`,
62
+ }
63
+ },
64
+ corpus: {
65
+ // $HOME is /Users/tester in the rule fixtures (test/fixtures/decide.ts).
66
+ deny: [
67
+ 'cat /Users/tester/enact-vps/adl-config.toml',
68
+ 'rg TODO /Users/tester/enact-vps/adl-hook/src',
69
+ 'ls /Users/tester/enact-vps',
70
+ 'cp /Users/tester/enact-vps/x.ts /tmp/x.ts',
71
+ 'ls -la && cat /Users/tester/enact-vps/adl-config.toml',
72
+ 'echo hi; cat /Users/tester/enact-vps/adl-config.toml',
73
+ ],
74
+ allow: [
75
+ // A clone whose name merely starts with the denied one is a different repo.
76
+ 'cat /Users/tester/enact-vps-m5/adl-config.toml',
77
+ 'rg TODO /Users/tester/enact-vps-m5/adl-hook/src',
78
+ // Same name, different place.
79
+ 'cat /Users/tester/Documents/enact-vps/adl-config.toml',
80
+ // The word is not the path.
81
+ 'echo "see enact-vps for details"',
82
+ 'rg TODO src/',
83
+ 'ls -la',
84
+ ],
85
+ },
86
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Filesystem writes into `.git` — the non-plumbing half of "manual git
3
+ * surgery".
4
+ *
5
+ * Added after an incident: an agent denied `git rebase --abort` trashed
6
+ * `.git/rebase-merge` and rewrote HEAD by hand. `fs.trash` refused only
7
+ * `.git` itself; `mv`, `cp`, `tee`, `>`, `sed -i`, `perl -pi`, `truncate`,
8
+ * `chmod`, `ln -sf`, `rsync` into `.git` were never inspected at all. The
9
+ * detection (which verbs, which operand is the written path) lives in
10
+ * shell/git-internals.ts; this rule only denies what it classified. Reading
11
+ * `.git/*` is never classified and stays allowed.
12
+ */
13
+
14
+ import type { Invocation } from '../shell/invocation.ts'
15
+ import type { Finding, MessageContext, RuleSpec } from '../spec.ts'
16
+ import { noParams } from '../spec.ts'
17
+ import { detailString, gitAgentTail } from './messages.ts'
18
+
19
+ export const fsGitInternals: RuleSpec = {
20
+ id: 'fs.git-internals',
21
+ category: 'filesystem',
22
+ severity: 'deny',
23
+ enabledByDefault: true,
24
+ summary: 'Deny any filesystem write (rm/trash/mv/cp/ln/rsync/truncate/redirect/tee/sed -i/perl -i/chmod/find -delete) into a .git directory or gitdir file.',
25
+ params: noParams,
26
+ match(inv: Invocation): Finding | null {
27
+ if (inv.kind !== 'git-internals-write') return null
28
+ return {
29
+ ruleId: 'fs.git-internals',
30
+ severity: 'deny',
31
+ detail: { command: inv.name || 'a redirection', target: inv.targets[0] ?? '' },
32
+ }
33
+ },
34
+ message(finding: Finding, ctx: MessageContext) {
35
+ const command = detailString(finding, 'command')
36
+ const target = detailString(finding, 'target')
37
+ return {
38
+ user: `Blocked ${command} writing inside .git (${target}). Hand-editing git internals can corrupt the repository; use git's own commands, or do it yourself.`,
39
+ agent:
40
+ `DENIED ${command} writing inside .git (${target}). Deleting, moving, overwriting, truncating, ` +
41
+ 're-permissioning, or in-place editing anything in a .git directory (refs, HEAD, the index, ' +
42
+ 'rebase-merge/rebase-apply, MERGE_HEAD, objects, a worktree or submodule gitdir file) bypasses every ' +
43
+ "safety check git has and can leave the repository corrupt or silently lose commits. Reading .git " +
44
+ `is fine (cat, ls, grep). ${gitAgentTail(ctx.snippet)}`,
45
+ }
46
+ },
47
+ corpus: {
48
+ deny: [
49
+ 'trash .git/rebase-merge',
50
+ 'rm -rf .git/rebase-merge',
51
+ 'mv .git/rebase-merge ~/.Trash/',
52
+ 'cp -f /tmp/HEAD .git/HEAD',
53
+ 'echo ref: refs/heads/main > .git/HEAD',
54
+ 'echo abc | tee .git/ORIG_HEAD',
55
+ "sed -i 's/feat/main/' .git/HEAD",
56
+ "perl -pi -e 's/feat/main/' .git/HEAD",
57
+ 'truncate -s 0 .git/index',
58
+ 'ln -sf refs/heads/main .git/HEAD',
59
+ 'rsync -a --delete backup/ .git/',
60
+ 'chmod 000 .git/index',
61
+ 'find .git/rebase-merge -delete',
62
+ 'cd repo && trash sub/.git/rebase-apply',
63
+ "bash <<'EOF'\nrm -rf .git\nEOF",
64
+ "sh <<EOF\nrm -rf .git\nEOF",
65
+ ],
66
+ allow: [
67
+ 'cat .git/HEAD',
68
+ 'ls -la .git/rebase-merge',
69
+ "sed -n '1,5p' .git/config",
70
+ 'cp .git/config /tmp/git-config',
71
+ 'trash .gitignore',
72
+ "cat <<'EOF' > notes.md\nrm -rf .git\nEOF",
73
+ ],
74
+ },
75
+ }