@amsterdamdatalabs/adl-agent-control-linux-x64 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,731 @@
1
+ /**
2
+ * `adl.human-azdo-bypass` — STATUS.md 12p decisions 1/1b/1c:
3
+ * `ADL_HUMAN_AZDO=1` marks Tarun's own interactive terminal (`bin/git-ado`'s
4
+ * and `resolveAgentIdentity`'s shared human-pass-through check,
5
+ * `packages/azdo/src/lib/agent-identity.ts`'s `isMarkedHumanAzdoCaller`:
6
+ * stdin is a real TTY AND `ADL_HUMAN_AZDO === '1'`, exactly — never a
7
+ * near-miss value, never trimmed or case-insensitive). An agent must never
8
+ * set it at all: doing so from an agent surface would let a LATER command
9
+ * on the same persistent shell (where one exists) fall through git-ado's
10
+ * human pass-through with no agent identity involved, exactly the incident
11
+ * the whole standard exists to close — just aimed at the marker itself
12
+ * instead of at `ADL_AGENT_ID_AGENT`.
13
+ *
14
+ * F1 (independent review, 2026-09-29, HIGH, confirmed): a live bypass —
15
+ * `export ADL_HUMAN_AZD''O=1; unset ADL_AGENT_ID_AGENT; script -q /dev/null
16
+ * git push origin feat/x` — was ALLOWED and reached `bin/git-ado`'s human
17
+ * pass-through via a faked pty. Fixed in three parts (a/b/c below).
18
+ *
19
+ * SECOND REVIEW (2026-09-29, same night): the first F1 fix over-matched —
20
+ * `git commit -m "ADL_HUMAN_AZDO=1 is denied now"`, `git log -S
21
+ * "ADL_HUMAN_AZDO=1"`, `declare -p ADL_HUMAN_AZDO` (a READ, not a set),
22
+ * `grep -c '...'` (grep's COUNT flag, mistaken for shell `-c`), and `node -e
23
+ * "console.log('pty')"` (a bare word 'pty' in unrelated code) were all
24
+ * wrongly denied. Detection is now POSITIONAL, not "any word anywhere":
25
+ *
26
+ * (a) A setter is recognized only in a real setter POSITION — a leading
27
+ * `NAME=value` assignment before a piece's own command word, or the
28
+ * piece's OWN command word being `export`/`declare -x`/`typeset -x`/
29
+ * `printf -v`/`read`/`env NAME=value` with the name as ITS operand
30
+ * (checked against `values[0]`, the piece's actual command, never an
31
+ * unrelated word buried inside some OTHER command's arguments — a git
32
+ * commit message, a `-S`/`-m` operand, are never inspected for this at
33
+ * all). `declare`/`typeset` require the `-x` flag to be present
34
+ * (`-p`/bare prints or lists, never sets); `printf` requires `-v`;
35
+ * `export -p` (list, not set) does not count either. Word values are
36
+ * already quote/escape-resolved by `../shell/token.ts`'s `tokenize`
37
+ * before any of this runs, closing the original quote-splitting/
38
+ * backslash-escaping bypass without needing a second, looser check.
39
+ * A `-c`/`--command` argument is only re-scanned as a nested shell
40
+ * script when the piece's OWN command is a REAL shell
41
+ * (`bash`/`sh`/`zsh`/`dash`/`ksh`/`fish`) — `grep -c PATTERN`'s count
42
+ * flag is never mistaken for one.
43
+ * Interpreter one-liners (python/node/ruby/perl) are matched by their
44
+ * OWN coarse setter pattern (`os.environ[...]=`/`.setdefault(...)`,
45
+ * `process.env.X=`/`['X']=`, `$ENV{X}=`) against ONLY the `-c`/`-e`/
46
+ * `--eval` code argument's value — never a bare word anywhere in the
47
+ * command.
48
+ * (b) Clearing `ADL_AGENT_ID_AGENT` is denied in every named form: `unset
49
+ * NAME` (as an operand of `unset`, the piece's own command), `env -u
50
+ * NAME`/`--unset[=]NAME`, an empty leading assignment (`NAME=`),
51
+ * `export -n NAME`, `declare +x NAME`/`typeset +x NAME` (P2: `+x`
52
+ * removes the export attribute). `env -i`/`--ignore-environment`/bare
53
+ * `env -` clears the WHOLE environment, but is denied ONLY when the
54
+ * command it wraps is ITSELF identity-bearing (`isLikelyIdentityBearing`
55
+ * below: a network git verb, a curl/wget/httpie/xh call to Azure
56
+ * DevOps, `az`, or an `adl`/`adl-agent-id` entry point) — `env -i PATH=
57
+ * /usr/bin ls` clears the environment for a command that never needed
58
+ * an identity in the first place, and denying it would only cost a
59
+ * falsely-blocked, ordinary command for no security gain.
60
+ * Interpreter one-liners: `del os.environ[...]`/`.pop(...)`/
61
+ * `os.unsetenv(...)` (python), `delete process.env.X`/`['X']` (node),
62
+ * `delete $ENV{X}` (perl) — same "-c/-e/--eval argument only" scoping
63
+ * as the setter check.
64
+ * (c) `script`/`unbuffer`/`expect`, `socat` with a `pty` argument, `tmux`/
65
+ * `screen` starting a detached session with a command (P2:
66
+ * `new-session`/`-dm`/`-dmS`), `zsh`'s `zpty` module command, a
67
+ * python/node/ruby/perl one-liner or flag that actually loads a pty
68
+ * module (`import pty`/`pty.spawn(...)`, `require('pty'|'node-pty')`,
69
+ * `-rpty`, `-MIO::Pty` — never a bare word), launching a real terminal
70
+ * app (`open -a Terminal|iTerm...`, `open *.command`, an `osascript`
71
+ * `do script ... "Terminal"|"iTerm"`) are denied UNCONDITIONALLY — none
72
+ * has a legitimate purpose on an agent surface, and narrowing to
73
+ * "wraps an identity-bearing command" would require parsing what each
74
+ * one wraps, fragile and trivially evaded by one more layer of
75
+ * indirection. `ssh -t|-tt|-o RequestTTY=force` is the one shape
76
+ * narrowed to a loopback host (`localhost`, `127.0.0.0/8`, `::1`, the
77
+ * shorthand `0`) — forcing a PTY on a genuine remote admin session is
78
+ * ordinary usage unrelated to faking a LOCAL pty.
79
+ * All of (c) resolves the piece's REAL command first — past a leading
80
+ * `NAME=value`, and past a chain of `env`/`timeout`/`nice`/`nohup`/
81
+ * `command`/`exec` wrappers and their own flags (`resolvedCommand`,
82
+ * below) — so `env ADL_AGENT_ID_AGENT=agent-tarun nohup script -q
83
+ * /dev/null git push origin feat/x` is still caught as `script`, not
84
+ * missed because the literal first word was a wrapper.
85
+ *
86
+ * Word collection deliberately does NOT walk into here-documents, here-
87
+ * strings, or `$(...)`/backtick substitutions (out of scope for this fix);
88
+ * it only reaches one level into a REAL shell's `-c`/`--command` script
89
+ * string, depth-capped — matching this rule's own "coarse, not a precise
90
+ * parser" contract.
91
+ *
92
+ * Unconditional — this fires regardless of whether an agent identity is
93
+ * otherwise resolvable. `IDENTITY_RULE_IDS` (`../../pre-tool-use/handler.ts`)
94
+ * no longer names a baseline this rule "rides" — Tarun's rule (2026-09-29)
95
+ * removed the global identity baseline entirely (hooks run only in a repo
96
+ * with its own `adl-config.toml`, never unmanaged), so `IDENTITY_RULE_IDS`
97
+ * now serves `identity_source` LOGGING classification only, inside a
98
+ * managed repo's own normal rule pass — this rule fires the same way any
99
+ * other enabled rule does, nothing baseline-specific about it.
100
+ *
101
+ * THE PTY-FAKING-WRAPPER CLASS IS UNBOUNDED (STATUS.md 12p item 15's threat
102
+ * model; F4, fourth independent review, 2026-09-29, "bounded, then stop").
103
+ * `pieceUsesPtyFakingWrapper` recognizes a widened but still FINITE list of
104
+ * named tools (`script`/`unbuffer`/`expect`/`zpty`, `socat`, `tmux`/`screen`,
105
+ * `ssh` to a loopback host, terminal-launching `open`/`osascript`, and a
106
+ * `pty`-module reference from python/node/ruby/perl) — it is not, and
107
+ * cannot be made, a complete enumeration of every way a same-OS-user
108
+ * process can attach to or fake a controlling terminal (a custom compiled
109
+ * helper, a language runtime this list does not name, a future terminal
110
+ * emulator, a creative combination of otherwise-ordinary tools). Widening
111
+ * this list further, one reported gap at a time, has a naturally
112
+ * diminishing return: closing THIS session's known list here (this fix,
113
+ * and the two before it in this file's own history) is the last widening
114
+ * pass for the foreseeable future — the credential-level fix (removing the
115
+ * SHARED-machine TTY signal `bin/git-ado` relies on as a proxy for "is this
116
+ * a human") is the orchestrator's own, separate track with Tarun, not
117
+ * something this rule can substitute for by enumerating tools forever.
118
+ */
119
+
120
+ import type { Invocation } from '../shell/invocation.ts'
121
+ import type { Finding, MessageContext, RuleContext, RuleSpec } from '../spec.ts'
122
+ import { noParams } from '../spec.ts'
123
+ import { isMarkedHumanAzdoCaller } from '../../../../azdo/src/lib/agent-identity.ts'
124
+ import { ADL_AGENT_ID_ENV_VAR } from './adl-identity.ts'
125
+ import { ADL_AGENT_ID_BINARY_NAMES, ADL_BINARY_NAMES, HTTP_CLIENT_BINARY_NAMES, isAdoUrl } from './git-helpers.ts'
126
+ import { isNetworkGitInvocation } from '../shell/git-identity.ts'
127
+ import { skipPrefixes } from '../shell/prefixes.ts'
128
+ import { heredocBodies } from '../shell/substitution.ts'
129
+ import { splitShell } from '../shell/split.ts'
130
+ import { tokenize, tokenValue, type Token } from '../shell/token.ts'
131
+
132
+ export const RULE_ID = 'adl.human-azdo-bypass'
133
+
134
+ /**
135
+ * The exact env var name STATUS.md 12p decisions 1b/1c name. Not exported as
136
+ * a standalone string constant from `packages/azdo/src/lib/agent-identity.ts`
137
+ * (only the combined TTY+value check, `isMarkedHumanAzdoCaller`, is) — this
138
+ * is the one place in this package that spells it, rather than a second,
139
+ * independent literal duplicated across detection helpers below.
140
+ */
141
+ export const ADL_HUMAN_AZDO_ENV_VAR = 'ADL_HUMAN_AZDO'
142
+
143
+ /** `os.environ['ADL_HUMAN_AZDO'] = ...` / `os.environ.setdefault('ADL_HUMAN_AZDO', ...)` — Python. Checked against ONLY the `-c`/`-e`/`--eval` code argument (see this file's own header). */
144
+ const PYTHON_HUMAN_AZDO_SET_RE = /os\.environ\s*(?:\[\s*['"]ADL_HUMAN_AZDO['"]\s*\]|\.setdefault\(\s*['"]ADL_HUMAN_AZDO['"])\s*[=(]/
145
+ /** `process.env.ADL_HUMAN_AZDO = ...` / `process.env['ADL_HUMAN_AZDO'] = ...` — Node. */
146
+ const NODE_HUMAN_AZDO_SET_RE = /process\.env\s*(?:\.\s*ADL_HUMAN_AZDO\b|\[\s*['"]ADL_HUMAN_AZDO['"]\s*\])\s*=/
147
+ /** `$ENV{ADL_HUMAN_AZDO} = ...` — Perl. */
148
+ const PERL_HUMAN_AZDO_SET_RE = /\$ENV\{\s*['"]?ADL_HUMAN_AZDO['"]?\s*\}\s*=/
149
+
150
+ /** `del os.environ['ADL_AGENT_ID_AGENT']` / `os.environ.pop(...)` / `os.unsetenv(...)` — Python. */
151
+ const PYTHON_AGENT_ID_DELETE_RE = /\bdel\s+os\.environ\s*\[\s*['"]ADL_AGENT_ID_AGENT['"]\s*\]|\bos\.environ\.pop\(\s*['"]ADL_AGENT_ID_AGENT['"]|\bos\.unsetenv\(\s*['"]ADL_AGENT_ID_AGENT['"]/
152
+ /** `delete process.env.ADL_AGENT_ID_AGENT` / `delete process.env['ADL_AGENT_ID_AGENT']` — Node. */
153
+ const NODE_AGENT_ID_DELETE_RE = /\bdelete\s+process\.env\s*(?:\.\s*ADL_AGENT_ID_AGENT\b|\[\s*['"]ADL_AGENT_ID_AGENT['"]\s*\])/
154
+ /** `delete $ENV{ADL_AGENT_ID_AGENT}` — Perl. */
155
+ const PERL_AGENT_ID_DELETE_RE = /\bdelete\s*\$ENV\{\s*['"]?ADL_AGENT_ID_AGENT['"]?\s*\}/
156
+
157
+ /** Real shells only — a `-c`/`--command` word is re-scanned as a nested script only when the piece's OWN command is one of these (never `grep -c PATTERN`'s unrelated count flag). */
158
+ const SHELL_NAMES: ReadonlySet<string> = new Set(['sh', 'bash', 'zsh', 'dash', 'ksh', 'fish'])
159
+ /** python/node/ruby/perl — interpreters whose `-c`/`-e`/`--eval` inline code is inspected by the coarse patterns above. */
160
+ const INTERPRETER_NAMES: ReadonlySet<string> = new Set(['python', 'python2', 'python3', 'node', 'nodejs', 'ruby', 'perl'])
161
+ const AZ_NAMES: ReadonlySet<string> = new Set(['az', 'az.exe'])
162
+
163
+ /**
164
+ * P2 (independent review, 2026-09-29, "dynamic names"): a strict leading
165
+ * assignment shape (`^[A-Za-z_][A-Za-z0-9_]*=`), but permitting
166
+ * `$`/backtick/`{`/`}` in the identifier portion too —
167
+ * `ADL_HUMAN_AZ${EMPTY}DO=1` is one word after `tokenize` (confirmed
168
+ * directly), and a real shell WOULD expand `${EMPTY}` before checking
169
+ * assignment shape, so this is a genuine bypass of a strict identifier
170
+ * check, not merely cosmetic. Used only to recognize the SHAPE (so a scan
171
+ * keeps walking past it); `isNameOperandDynamic` below decides whether the
172
+ * identifier portion is actually dynamic.
173
+ */
174
+ const ASSIGNMENT_SHAPE_RE = /^[A-Za-z_][\w$`{}]*=/
175
+
176
+ function isAssignmentTo(value: string, name: string): boolean {
177
+ return value === `${name}=` || value.startsWith(`${name}=`)
178
+ }
179
+
180
+ /**
181
+ * True when `value` — a bare operand (`unset NAME`, `read NAME`, `printf -v
182
+ * NAME`) or an assignment word (`NAME=value`) — has an unresolved shell
183
+ * expansion (`$VAR`, `${VAR}`, `$(...)`, backtick) in the NAME portion
184
+ * (before the first `=`, or the whole word when there is none). We cannot
185
+ * know what such a word actually names — `v=ADL_HUMAN_AZDO; export "$v=1"`
186
+ * and `X=ADL_AGENT_ID_AGENT; unset $X` both hide the real name behind a
187
+ * variable this static scan never resolves — so any setter/clearer-shaped
188
+ * position holding one is treated as a match (P2 "dynamic names",
189
+ * fail-closed) for whichever name the caller is checking.
190
+ */
191
+ function isNameOperandDynamic(value: string): boolean {
192
+ const equals = value.indexOf('=')
193
+ const namePart = equals < 0 ? value : value.slice(0, equals)
194
+ return /[$`]/.test(namePart)
195
+ }
196
+
197
+ function basenameOf(value: string): string {
198
+ const index = value.lastIndexOf('/')
199
+ return index < 0 ? value : value.slice(index + 1)
200
+ }
201
+
202
+ /** Nested `-c`/`--command` shell script strings are re-tokenized at most this deep. */
203
+ const MAX_WORD_SCAN_DEPTH = 8
204
+
205
+ /** One piece of a command: its raw tokens (for `skipPrefixes`, which needs a real `Token[]`) alongside their already quote/escape-resolved string values. */
206
+ interface WordPiece {
207
+ readonly tokens: readonly Token[]
208
+ readonly values: readonly string[]
209
+ }
210
+
211
+ /**
212
+ * Every piece of `command` (one `WordPiece` per top-level piece), collected
213
+ * into `out`. Recurses one level into a `-c`/`--command` shell script string
214
+ * ONLY when the piece's own command is a real shell (`SHELL_NAMES`) — never
215
+ * for an unrelated `-c` flag on some other command (`grep -c`, `curl -c`,
216
+ * `ssh -c`, …). Quote concatenation and backslash escapes are already
217
+ * resolved by `tokenize`.
218
+ */
219
+ /**
220
+ * `-c`, a combined short flag ENDING in `c` (`-ic`, `-lc`, `-ec` — an
221
+ * interactive/login/errexit shell still reads its script from the SAME
222
+ * `-c` operand), or `--command[=]` — mirrors `shell/invocation.ts`'s own
223
+ * (private) `isShellCommandOption` one-line check, kept in sync
224
+ * deliberately rather than exported, to recognize a shell invoked with
225
+ * combined flags (`zsh -ic '...'`, `bash -lc '...'`, `sh -ec '...'`) the
226
+ * same way the rest of the engine already does (F2, third independent
227
+ * review, 2026-09-29 — this rule's own exact-`-c`-only check let `zsh -ic
228
+ * '...'` defeat it entirely).
229
+ */
230
+ function isShellScriptOption(value: string): boolean {
231
+ return value === '-c' || /^-[^-]*c$/.test(value) || value === '--command' || value.startsWith('--command=')
232
+ }
233
+
234
+ /**
235
+ * Every piece of `command` (one `WordPiece` per top-level piece), collected
236
+ * into `out`. Recurses one level into a `-c`-shaped shell script string
237
+ * ONLY when the piece's own RESOLVED command (past a leading assignment and
238
+ * a chain of transparent wrappers — F2: `nohup bash -c '...'`/`FOO=1 bash
239
+ * -c '...'` were invisible before, since only the piece's literal FIRST
240
+ * word was checked) is a real shell (`SHELL_NAMES`) — never for an
241
+ * unrelated `-c` flag on some other command (`grep -c`, `curl -c`, `ssh
242
+ * -c`, …). Quote concatenation and backslash escapes are already resolved
243
+ * by `tokenize`.
244
+ */
245
+ function collectWordPieces(command: string, depth: number, out: WordPiece[]): void {
246
+ if (depth > MAX_WORD_SCAN_DEPTH) return
247
+ const split = splitShell(command)
248
+ if (split.invalid) return
249
+ for (const piece of split.pieces) {
250
+ const tokenized = tokenize(piece)
251
+ if (tokenized.invalid) continue
252
+ const values = tokenized.tokens.map(tokenValue)
253
+ const wordPiece: WordPiece = { tokens: tokenized.tokens, values }
254
+ out.push(wordPiece)
255
+ const resolved = resolvedCommand(wordPiece)
256
+ if (resolved.name === undefined || !SHELL_NAMES.has(resolved.name)) continue
257
+ for (let index = resolved.argsStart; index < values.length; index += 1) {
258
+ const value = values[index] as string
259
+ if (isShellScriptOption(value) && !value.startsWith('--command=')) {
260
+ if (values[index + 1] !== undefined) collectWordPieces(values[index + 1] as string, depth + 1, out)
261
+ } else if (value.startsWith('--command=')) {
262
+ collectWordPieces(value.slice('--command='.length), depth + 1, out)
263
+ }
264
+ }
265
+ }
266
+ }
267
+
268
+ function wordPiecesFor(command: string): readonly WordPiece[] {
269
+ const out: WordPiece[] = []
270
+ collectWordPieces(command, 0, out)
271
+ return out
272
+ }
273
+
274
+ /** The `-c`/`-e`/`--eval[=]` argument value for an interpreter invocation, or null when the piece runs a script FILE (nothing inline to inspect). */
275
+ function interpreterInlineCode(args: readonly string[]): string | null {
276
+ for (let index = 0; index < args.length; index += 1) {
277
+ const value = args[index] as string
278
+ if (value === '-c' || value === '-e' || value === '--eval') return args[index + 1] ?? null
279
+ if (value.startsWith('--eval=')) return value.slice('--eval='.length)
280
+ }
281
+ return null
282
+ }
283
+
284
+ /**
285
+ * Find the REAL command a piece resolves to, and where ITS OWN arguments
286
+ * begin — past a leading `NAME=value` assignment and a chain of transparent
287
+ * wrappers (`sudo`/`env`/`timeout`/`nice`/`caffeinate`/`arch`/`exec`/`time`/
288
+ * `stdbuf`/`setsid`/`command`/`doas`/`nohup`/`gtimeout`) and THEIR OWN
289
+ * arguments (P2: "detect... by the walker's RESOLVED command"). Reuses
290
+ * `../shell/prefixes.ts`'s own `skipPrefixes` — the SAME, already-tested
291
+ * wrapper-argument-skipping logic every other rule's classification is
292
+ * built on (`shell/invocation.ts`'s `walk()` calls it too) — rather than a
293
+ * second, narrower reimplementation: an earlier version of this function
294
+ * had its own generic "skip one flag at a time" loop, which mishandled a
295
+ * wrapper's own POSITIONAL argument (`timeout 90 script ...` — `90` is
296
+ * `timeout`'s duration, not a flag, and a generic dash-flag skipper does
297
+ * not know to skip it) — `skipPrefixes` already has a specific handler for
298
+ * exactly that (`skipTimeoutFlags`).
299
+ */
300
+ function resolvedCommand(piece: WordPiece): { readonly name: string | undefined; readonly argsStart: number } {
301
+ const index = skipPrefixes(piece.tokens)
302
+ if (index >= piece.tokens.length) return { name: undefined, argsStart: index }
303
+ return { name: basenameOf(piece.values[index] as string).toLowerCase(), argsStart: index + 1 }
304
+ }
305
+
306
+ /** A network git verb, a curl/wget/httpie/xh call to Azure DevOps, `az`, or an `adl`/`adl-agent-id` entry point — the shapes `env -i`/bare `env -` is worth denying for (P1: clearing the WHOLE environment for a command that never needed an identity is harmless). Coarse, matching the same tradeoff every other check in this file makes. */
307
+ function isLikelyIdentityBearing(name: string, args: readonly string[]): boolean {
308
+ if (name === 'git' || name === 'git.exe') {
309
+ const subIndex = args.findIndex((value) => !value.startsWith('-'))
310
+ if (subIndex < 0) return false
311
+ return isNetworkGitInvocation((args[subIndex] as string).toLowerCase(), args.slice(subIndex + 1))
312
+ }
313
+ if (HTTP_CLIENT_BINARY_NAMES.has(name)) return args.some((value) => isAdoUrl(value))
314
+ if (AZ_NAMES.has(name)) return true
315
+ if (ADL_BINARY_NAMES.has(name) || ADL_AGENT_ID_BINARY_NAMES.has(name)) return true
316
+ return false
317
+ }
318
+
319
+ /**
320
+ * F3 (third independent review, 2026-09-29): a setter/clearer keyword is
321
+ * still missed when it is NOT `values[0]` — `if true; then export
322
+ * ADL_HUMAN_AZDO=1; fi` splits (on `;`) into a piece whose first word is
323
+ * the keyword `then`, not `export`; `builtin export …`/`command export …`
324
+ * explicitly invoke the builtin/external form, bypassing any shell
325
+ * function or alias named `export` but still meaning the same thing. Strip
326
+ * a leading run of these — pure syntax markers or explicit-invocation
327
+ * prefixes, none of which take a flag/operand of their own to skip past —
328
+ * to find the actual setter/clearer keyword underneath. `command` is
329
+ * ALSO one of `shell/prefixes.ts`'s own `COMMAND_PREFIXES` (so
330
+ * `resolvedCommand`'s wrapper-chain resolution already skips it too); kept
331
+ * here as well since this strip runs on plain string VALUES, before (and
332
+ * independently of) any Token-based `resolvedCommand` call.
333
+ */
334
+ const HEAD_SKIP_WORDS: ReadonlySet<string> = new Set(['then', 'do', 'else', 'elif', 'builtin', 'command'])
335
+
336
+ function afterHeadSkipWords(values: readonly string[]): readonly string[] {
337
+ let rest = values
338
+ while (rest.length > 0 && HEAD_SKIP_WORDS.has(basenameOf(rest[0] as string).toLowerCase())) {
339
+ rest = rest.slice(1)
340
+ }
341
+ return rest
342
+ }
343
+
344
+ /** True when `values` (one piece's words) sets/exports/declares/reads-into/printf-v's `ADL_HUMAN_AZDO` in a real setter POSITION, or an interpreter's inline code writes it via `os.environ`/`process.env`/`$ENV`. */
345
+ function pieceSetsHumanAzdo(values: readonly string[], heredocs: readonly string[]): boolean {
346
+ const name = ADL_HUMAN_AZDO_ENV_VAR
347
+ let index = 0
348
+ while (index < values.length && ASSIGNMENT_SHAPE_RE.test(values[index] as string)) {
349
+ const word = values[index] as string
350
+ if (isAssignmentTo(word, name) || isNameOperandDynamic(word)) return true
351
+ index += 1
352
+ }
353
+ const resolved = afterHeadSkipWords(values)
354
+ if (resolved.length === 0) return false
355
+ const head = basenameOf(resolved[0] as string).toLowerCase()
356
+ const rest = resolved.slice(1)
357
+ if (head === 'export') {
358
+ // `-f` (functions) is unrelated; `-p` (print) is deliberately NOT
359
+ // excluded here any more (F3) — `export -p ADL_HUMAN_AZDO=1` still
360
+ // carries an assignment and real bash still exports it, `-p` or not; a
361
+ // bare `export -p ADL_HUMAN_AZDO` (no `=`, a genuine list/print with no
362
+ // real effect) is a coarse, low-cost over-match this file already
363
+ // accepts elsewhere (documented "dynamic names" tradeoff, same file).
364
+ if (rest.includes('-f')) return false
365
+ return rest.some((value) => value === name || isAssignmentTo(value, name) || isNameOperandDynamic(value))
366
+ }
367
+ if (head === 'declare' || head === 'typeset' || head === 'local') {
368
+ if (!rest.some((value) => value === '-x' || /^-[a-zA-Z]*x[a-zA-Z]*$/.test(value))) return false
369
+ return rest.some((value) => value === name || isAssignmentTo(value, name) || isNameOperandDynamic(value))
370
+ }
371
+ if (head === 'read') {
372
+ const target = rest.find((value) => !value.startsWith('-'))
373
+ return target !== undefined && (target === name || isNameOperandDynamic(target))
374
+ }
375
+ if (head === 'printf') {
376
+ const vIndex = rest.indexOf('-v')
377
+ if (vIndex < 0) return false
378
+ const target = rest[vIndex + 1]
379
+ return target !== undefined && (target === name || isNameOperandDynamic(target))
380
+ }
381
+ if (head === 'env') {
382
+ for (const value of rest) {
383
+ if (value.startsWith('-')) continue
384
+ if (!ASSIGNMENT_SHAPE_RE.test(value)) break
385
+ if (isAssignmentTo(value, name) || isNameOperandDynamic(value)) return true
386
+ }
387
+ return false
388
+ }
389
+ if (INTERPRETER_NAMES.has(head)) {
390
+ // Third independent review (2026-09-29): "heredoc-fed interpreters"
391
+ // (`python3 - <<'EOF' ... EOF`) have no `-c`/`-e`/`--eval` argument at
392
+ // all — the real code is the heredoc BODY, passed in from `match()`
393
+ // (computed once from the whole command, not per-piece).
394
+ const inline = interpreterInlineCode(rest)
395
+ const candidates = inline !== null ? [inline] : heredocs
396
+ return candidates.some((code) => PYTHON_HUMAN_AZDO_SET_RE.test(code) || NODE_HUMAN_AZDO_SET_RE.test(code) || PERL_HUMAN_AZDO_SET_RE.test(code))
397
+ }
398
+ return false
399
+ }
400
+
401
+ /** True when `piece` (one piece's words) clears `ADL_AGENT_ID_AGENT` — `unset`/`env -u`/`export -n`/`declare +x`/`typeset +x` in a real clearer POSITION, an empty leading assignment, `env -i` wrapping an identity-bearing command, or an interpreter's inline code deleting it. */
402
+ function pieceClearsAgentIdentity(piece: WordPiece, heredocs: readonly string[]): boolean {
403
+ const values = piece.values
404
+ const name = ADL_AGENT_ID_ENV_VAR
405
+ let index = 0
406
+ while (index < values.length && ASSIGNMENT_SHAPE_RE.test(values[index] as string)) {
407
+ const word = values[index] as string
408
+ if (word === `${name}=`) return true
409
+ if (isNameOperandDynamic(word) && word.endsWith('=')) return true
410
+ index += 1
411
+ }
412
+ const afterKeywords = afterHeadSkipWords(values)
413
+ if (afterKeywords.length === 0) return false
414
+ const head = basenameOf(afterKeywords[0] as string).toLowerCase()
415
+ const rest = afterKeywords.slice(1)
416
+ if (head === 'unset') return rest.some((value) => value === name || isNameOperandDynamic(value))
417
+ if (head === 'export') return rest.includes('-n') && rest.some((value) => value === name || isNameOperandDynamic(value))
418
+ if (head === 'declare' || head === 'typeset' || head === 'local') return rest.includes('+x') && rest.some((value) => value === name || isNameOperandDynamic(value))
419
+ if (head === 'env') {
420
+ for (let look = 0; look < rest.length; look += 1) {
421
+ const flag = rest[look] as string
422
+ if ((flag === '-u' || flag === '--unset') && rest[look + 1] !== undefined && (rest[look + 1] === name || isNameOperandDynamic(rest[look + 1] as string))) return true
423
+ if (flag.startsWith('--unset=') && (flag.slice('--unset='.length) === name || isNameOperandDynamic(flag.slice('--unset='.length)))) return true
424
+ if (flag === '-i' || flag === '--ignore-environment' || flag === '-') {
425
+ const resolved = resolvedCommand(piece)
426
+ return resolved.name !== undefined && isLikelyIdentityBearing(resolved.name, values.slice(resolved.argsStart))
427
+ }
428
+ if (!flag.startsWith('-') && !ASSIGNMENT_SHAPE_RE.test(flag)) break
429
+ }
430
+ return false
431
+ }
432
+ if (INTERPRETER_NAMES.has(head)) {
433
+ // Third independent review (2026-09-29): heredoc-fed interpreters.
434
+ const inline = interpreterInlineCode(rest)
435
+ const candidates = inline !== null ? [inline] : heredocs
436
+ return candidates.some((code) => PYTHON_AGENT_ID_DELETE_RE.test(code) || NODE_AGENT_ID_DELETE_RE.test(code) || PERL_AGENT_ID_DELETE_RE.test(code))
437
+ }
438
+ return false
439
+ }
440
+
441
+ const LOOPBACK_EXACT: ReadonlySet<string> = new Set(['localhost', '::1', '0'])
442
+
443
+ /**
444
+ * F4 (fourth independent review, 2026-09-29): `user@host` (ssh's own
445
+ * `user@` prefix) is stripped before checking; `127.1`/`127.0.1` (partial
446
+ * IPv4 notation — every major OS resolves these to the `127.0.0.1` range)
447
+ * are accepted alongside the full four-octet form.
448
+ */
449
+ function isLoopbackHost(rawValue: string): boolean {
450
+ const value = rawValue.includes('@') ? rawValue.slice(rawValue.lastIndexOf('@') + 1) : rawValue
451
+ const lower = value.toLowerCase()
452
+ if (LOOPBACK_EXACT.has(lower)) return true
453
+ return /^127(?:\.\d{1,3}){1,3}$/.test(lower)
454
+ }
455
+
456
+ /** An unresolved shell expansion in a host-shaped position (F4: `ssh -tt $(hostname) …`) — cannot be proven non-loopback, so treated as a match (fail-closed), the same "dynamic names" tradeoff this file already makes elsewhere. */
457
+ const isDynamicHostCandidate = (value: string): boolean => /\$\(|`|\$\{/.test(value)
458
+
459
+ function sshForcesTty(args: readonly string[]): boolean {
460
+ for (let index = 0; index < args.length; index += 1) {
461
+ const value = args[index] as string
462
+ if (value === '-t' || value === '-tt' || /^-[a-zA-Z]*t{1,2}[a-zA-Z]*$/.test(value)) return true
463
+ const next = args[index + 1]
464
+ if ((value === '-o' || value === '--') && next !== undefined && /^requesttty=force$/i.test(next)) return true
465
+ if (/^-o?requesttty=force$/i.test(value.replace(/\s+/g, ''))) return true
466
+ }
467
+ return false
468
+ }
469
+
470
+ /** No legitimate use on an agent surface — see this file's own F1(c) header. `zpty` is zsh's own pty module command — invoked as `zsh -c 'zpty ...'`, this scanner's own `-c` recursion (real shells only) makes `zpty` the RESOLVED command of the nested piece, not merely an argument to `zsh`. */
471
+ const UNCONDITIONAL_PTY_WRAPPERS: ReadonlySet<string> = new Set(['script', 'unbuffer', 'expect', 'zpty'])
472
+
473
+ /** True when `args` is nothing but `--help`/`-h`/`--version`/`-V` — a string-value mirror of `shell/invocation.ts`'s own (Token-based) `isHelpOrVersionOnly`. F7 (fourth independent review, 2026-09-29): `expect --version` has no script to run at all — harmless. */
474
+ function isHelpOrVersionOnlyValues(args: readonly string[]): boolean {
475
+ let sawHelp = false
476
+ for (const arg of args) {
477
+ if (arg === '--') return false
478
+ if (!arg.startsWith('-')) return false
479
+ if (arg === '--help' || arg === '-h' || arg === '--version' || arg === '-V') {
480
+ sawHelp = true
481
+ continue
482
+ }
483
+ return false
484
+ }
485
+ return sawHelp
486
+ }
487
+
488
+ /** Every `-e CODE` occurrence (F4: `osascript` accepts MULTIPLE `-e` flags, each one a line of the same script — reading only the first, as `interpreterInlineCode` does, missed a script split across several). */
489
+ function allDashEArgs(args: readonly string[]): readonly string[] {
490
+ const values: string[] = []
491
+ for (let index = 0; index < args.length; index += 1) {
492
+ if (args[index] === '-e' && args[index + 1] !== undefined) values.push(args[index + 1] as string)
493
+ }
494
+ return values
495
+ }
496
+
497
+ const TMUX_ACTIONS: ReadonlySet<string> = new Set(['new-session', 'new', 'new-window', 'split-window', 'send-keys'])
498
+ /** Bundle IDs for `open -b <id>` — F4: the app-name check (`open -a Terminal`) has no bundle-id equivalent to match against. */
499
+ const TERMINAL_BUNDLE_IDS: ReadonlySet<string> = new Set([
500
+ 'com.apple.terminal',
501
+ 'com.googlecode.iterm2',
502
+ 'com.mitchellh.ghostty',
503
+ 'dev.warp.warp-stable',
504
+ 'net.kovidgoyal.kitty',
505
+ 'org.alacritty',
506
+ 'com.github.wez.wezterm',
507
+ ])
508
+ /** Terminal-app names `open -a`/AppleScript/JXA name by — F4: widened past Terminal/iTerm to every terminal emulator the finding named. */
509
+ const TERMINAL_APP_NAME_RE = /\b(?:terminal|iterm|ghostty|warp|kitty|alacritty|wezterm)\b/i
510
+
511
+ /** True when `piece` (one piece's words) invokes a pty-faking wrapper, resolved past a leading assignment and a chain of transparent wrappers. See this file's own F1(c) header for which shapes are unconditional vs. narrowed to a loopback host. */
512
+ function pieceUsesPtyFakingWrapper(piece: WordPiece): boolean {
513
+ const resolved = resolvedCommand(piece)
514
+ const name = resolved.name
515
+ if (name === undefined) return false
516
+ const args = piece.values.slice(resolved.argsStart)
517
+ if (UNCONDITIONAL_PTY_WRAPPERS.has(name)) return !isHelpOrVersionOnlyValues(args)
518
+ if (name === 'socat') return args.some((value) => /\bpty\b/i.test(value))
519
+ if (name === 'tmux') return args.some((value) => TMUX_ACTIONS.has(value) || value === '-dm' || value === '-dmS')
520
+ if (name === 'screen') {
521
+ if (args.some((value) => value === '-dm' || value === '-dmS')) return true
522
+ return args.includes('-d') && args.includes('-m')
523
+ }
524
+ if (name === 'ruby') {
525
+ if (args.includes('-rpty')) return true
526
+ const code = interpreterInlineCode(args)
527
+ return code !== null && /require\s+['"]pty['"]/.test(code)
528
+ }
529
+ if (name === 'perl' && args.includes('-MIO::Pty')) return true
530
+ if (INTERPRETER_NAMES.has(name)) {
531
+ const code = interpreterInlineCode(args)
532
+ if (code === null) return false
533
+ // F4: comma-form imports (`import os, pty`) and `__import__('pty')`.
534
+ if (name.startsWith('python')) {
535
+ return (
536
+ /(?:^|[\s;])import\s+(?:[\w.]+\s*,\s*)*pty\b|\bfrom\s+pty\s+import\b|\bpty\.(?:spawn|fork|openpty)\s*\(|__import__\(\s*['"]pty['"]\s*\)/.test(
537
+ code,
538
+ )
539
+ )
540
+ }
541
+ if (name.startsWith('node')) return /\brequire\(\s*['"](?:node-)?pty['"]\s*\)/.test(code)
542
+ return false
543
+ }
544
+ if (name === 'ssh') {
545
+ if (!sshForcesTty(args)) return false
546
+ if (args.some(isLoopbackHost)) return true
547
+ return args.some((value) => !value.startsWith('-') && isDynamicHostCandidate(value))
548
+ }
549
+ if (name === 'open') {
550
+ for (let index = 0; index < args.length; index += 1) {
551
+ const value = args[index] as string
552
+ // F4: combined flags (`-na` = -n new-instance + -a app) — any
553
+ // combined short-flag string containing `a`/`b` still takes the
554
+ // NEXT word as the app name / bundle id, same as the bare flag.
555
+ if (/^-[a-zA-Z]*a[a-zA-Z]*$/.test(value) && TERMINAL_APP_NAME_RE.test(args[index + 1] ?? '')) return true
556
+ if (/^-[a-zA-Z]*b[a-zA-Z]*$/.test(value) && TERMINAL_BUNDLE_IDS.has((args[index + 1] ?? '').toLowerCase())) return true
557
+ }
558
+ return args.some((value) => value.toLowerCase().endsWith('.command'))
559
+ }
560
+ if (name === 'osascript') {
561
+ const codes = allDashEArgs(args)
562
+ if (codes.length === 0) return false
563
+ const combined = codes.join('\n')
564
+ if (!TERMINAL_APP_NAME_RE.test(combined)) return false
565
+ // F4: AppleScript's `do script` and JXA's (`-l JavaScript`) `.doScript(`
566
+ // are the same operation in the two languages osascript accepts.
567
+ return /\bdo script\b/i.test(combined) || /\.\s*doScript\s*\(/i.test(combined)
568
+ }
569
+ return false
570
+ }
571
+
572
+ type BypassReason = 'sets-human-azdo' | 'clears-agent-identity' | 'pty-faking-wrapper'
573
+
574
+ export const adlHumanAzdoBypass: RuleSpec = {
575
+ id: RULE_ID,
576
+ category: 'tool',
577
+ severity: 'deny',
578
+ enabledByDefault: true,
579
+ summary:
580
+ "Deny an agent command that sets/exports/assigns ADL_HUMAN_AZDO, clears ADL_AGENT_ID_AGENT, or fakes a TTY to defeat bin/git-ado's human/agent decision (STATUS.md 12p decisions 1/1b/1c; F1).",
581
+ params: noParams,
582
+ match(inv: Invocation, ctx: RuleContext<Record<string, never>>): Finding | null {
583
+ // A tool-call payload (a real MCP call) carries no shell command text
584
+ // at all — nothing for this word-level scan to see.
585
+ if (inv.kind === 'tool-call') return null
586
+ const command = ctx.command ?? ''
587
+ if (command.trim().length === 0) return null
588
+ const pieces = wordPiecesFor(command)
589
+ // Third independent review (2026-09-29): heredoc-fed interpreters
590
+ // (`python3 - <<'EOF' ... EOF`) have no `-c`/`-e`/`--eval` argument at
591
+ // all — computed once from the whole command, not per-piece.
592
+ const heredocs = heredocBodies(command)
593
+ let reason: BypassReason | null = null
594
+ for (const piece of pieces) {
595
+ if (pieceSetsHumanAzdo(piece.values, heredocs)) {
596
+ reason = 'sets-human-azdo'
597
+ break
598
+ }
599
+ if (pieceClearsAgentIdentity(piece, heredocs)) {
600
+ reason = 'clears-agent-identity'
601
+ break
602
+ }
603
+ if (pieceUsesPtyFakingWrapper(piece)) {
604
+ reason = 'pty-faking-wrapper'
605
+ break
606
+ }
607
+ }
608
+ if (reason === null) return null
609
+ // Reuse the ONE shared human-pass-through check rather than asserting
610
+ // the same fact independently: a pre-tool-use hook invocation reads a
611
+ // JSON payload from its host, never an interactive TTY, so this can
612
+ // never legitimately be a marked-human session — `stdinIsTTY` is
613
+ // explicitly `false` here, by construction, not merely assumed.
614
+ const consideredHuman = isMarkedHumanAzdoCaller({ [ADL_HUMAN_AZDO_ENV_VAR]: ctx.env.get(ADL_HUMAN_AZDO_ENV_VAR) } as NodeJS.ProcessEnv, false)
615
+ return { ruleId: RULE_ID, severity: 'deny', detail: { consideredHuman: String(consideredHuman), reason } }
616
+ },
617
+ message(finding: Finding, ctx: MessageContext) {
618
+ const reason = (typeof finding.detail.reason === 'string' ? finding.detail.reason : 'sets-human-azdo') as BypassReason
619
+ if (reason === 'clears-agent-identity') {
620
+ const user = `clearing ${ADL_AGENT_ID_ENV_VAR} is not allowed — an agent must always carry its identity`
621
+ return {
622
+ user,
623
+ agent:
624
+ `DENIED ${user}. unset/env -u/env -i (wrapping an identity-bearing command)/an empty inline assignment/export -n/` +
625
+ `declare or typeset +x on ${ADL_AGENT_ID_ENV_VAR} removes the one thing that routes a network git command as this ` +
626
+ `agent instead of falling through to bin/git-ado's own default (F1, STATUS.md 12p). Never clear it; prefix the ` +
627
+ `command with ${ADL_AGENT_ID_ENV_VAR}=<agent> instead. Blocked: ${ctx.snippet}`,
628
+ }
629
+ }
630
+ if (reason === 'pty-faking-wrapper') {
631
+ const user =
632
+ 'faking a TTY (script/unbuffer/expect, socat/tmux/screen/zsh zpty, a pty-module interpreter one-liner, ssh -t to a loopback host, or launching a real terminal app) is not allowed'
633
+ return {
634
+ user,
635
+ agent:
636
+ `DENIED ${user}. These tools exist to make a program's isatty() check pass when nothing real is attached to it — ` +
637
+ "bin/git-ado's own human-vs-agent decision is exactly such a check, and faking it (F1, STATUS.md 12p) is how a " +
638
+ 'session with no agent identity reaches the human credential path undetected. There is no legitimate use of a ' +
639
+ `pty-faking wrapper on an agent surface; run the command directly instead. Blocked: ${ctx.snippet}`,
640
+ }
641
+ }
642
+ const user = `${ADL_HUMAN_AZDO_ENV_VAR} marks a human terminal; an agent may never set it — use ADL_AGENT_ID_AGENT=<agent>`
643
+ return {
644
+ user,
645
+ agent:
646
+ `DENIED ${user}. ${ADL_HUMAN_AZDO_ENV_VAR}=1 tells bin/git-ado this is Tarun's own interactive terminal - setting, exporting, ` +
647
+ `or assigning it from an agent surface (inline, export, env, declare/typeset -x, printf -v, read, a nested REAL shell — ` +
648
+ `quote-split or backslash-escaped included, F1 — or an interpreter's own os.environ/process.env/$ENV) would let ` +
649
+ `git-ado's human pass-through apply with no agent identity involved. Unset it (or use \`env -u ${ADL_HUMAN_AZDO_ENV_VAR}\`) ` +
650
+ `if you need it absent; prefix the command with ADL_AGENT_ID_AGENT=<agent-tarun|agent-vivek|agent-reviewer> instead. ` +
651
+ `Blocked: ${ctx.snippet}`,
652
+ }
653
+ },
654
+ corpus: {
655
+ deny: [
656
+ 'ADL_HUMAN_AZDO=1 git push origin main',
657
+ 'export ADL_HUMAN_AZDO=1',
658
+ 'export ADL_HUMAN_AZDO=1 && git push origin main',
659
+ 'env ADL_HUMAN_AZDO=1 git push origin main',
660
+ 'declare -x ADL_HUMAN_AZDO=1',
661
+ 'typeset -x ADL_HUMAN_AZDO=1',
662
+ 'export ADL_HUMAN_AZDO',
663
+ "bash -c 'export ADL_HUMAN_AZDO=1 && git push origin main'",
664
+ `python3 -c "import os; os.environ['ADL_HUMAN_AZDO'] = '1'"`,
665
+ `node -e "process.env.ADL_HUMAN_AZDO = '1'"`,
666
+ `node -e "process.env['ADL_HUMAN_AZDO'] = '1'"`,
667
+ // F1(a): shell quote-splitting / backslash-escaping cannot defeat the
668
+ // check any more — the tokenizer resolves both before matching.
669
+ `export ADL_HUMAN_AZD''O=1`,
670
+ `export ADL_HUMAN_AZ\\DO=1`,
671
+ // A bare `printf ...` line alone produces no Invocation at all
672
+ // (`printf` is in shell/invocation.ts's own `introspectionNames`, so
673
+ // `decideCommand`'s per-invocation loop never runs) — realistic usage
674
+ // always chains it with the command it is trying to unlock, which is
675
+ // also what makes the loop run at all.
676
+ `printf -v ADL_HUMAN_AZDO '1'; git push origin main`,
677
+ 'read ADL_HUMAN_AZDO',
678
+ // F1(b): clearing ADL_AGENT_ID_AGENT in any form.
679
+ 'unset ADL_AGENT_ID_AGENT',
680
+ 'unset ADL_AGENT_ID_AGENT; git push origin feat/x',
681
+ 'env -u ADL_AGENT_ID_AGENT git push origin feat/x',
682
+ 'env --unset ADL_AGENT_ID_AGENT git push origin feat/x',
683
+ 'env --unset=ADL_AGENT_ID_AGENT git push origin feat/x',
684
+ 'env -i git push origin feat/x',
685
+ 'env --ignore-environment git push origin feat/x',
686
+ 'ADL_AGENT_ID_AGENT= git push origin feat/x',
687
+ 'export -n ADL_AGENT_ID_AGENT',
688
+ 'declare +x ADL_AGENT_ID_AGENT',
689
+ // F1(c): pty-faking wrappers, unconditional.
690
+ 'script -q /dev/null git push origin feat/x',
691
+ 'unbuffer git push origin feat/x',
692
+ 'expect -c "spawn git push origin feat/x"',
693
+ "socat exec:'git push origin feat/x',pty stdio",
694
+ `python3 -c "import pty; pty.spawn(['git','push','origin','feat/x'])"`,
695
+ 'ssh -t localhost git push origin feat/x',
696
+ 'ssh -t 127.0.0.1 git push origin feat/x',
697
+ // The live F1 incident, combined.
698
+ "export ADL_HUMAN_AZD''O=1; unset ADL_AGENT_ID_AGENT; script -q /dev/null git push origin feat/x",
699
+ ],
700
+ allow: [
701
+ 'git status',
702
+ 'ADL_AGENT_ID_AGENT=agent-tarun git push origin feat/x',
703
+ // Unsetting HUMAN_AZDO is explicitly fine — only SETTING it is denied.
704
+ 'env -u ADL_HUMAN_AZDO git status',
705
+ 'unset ADL_HUMAN_AZDO',
706
+ // Unsetting an unrelated variable, or exporting one, is untouched.
707
+ 'unset SOME_OTHER_VAR',
708
+ 'export PATH=/usr/bin:$PATH',
709
+ // ssh -t to a genuine remote host: ordinary, common usage.
710
+ 'ssh -t build-host.example.com uptime',
711
+ // socat without a pty argument: unrelated.
712
+ 'socat TCP:example.com:80 -',
713
+ // A bare python/node one-liner naming neither variable: untouched.
714
+ `python3 -c "print('hello')"`,
715
+ // SECOND REVIEW (2026-09-29): the false positives that broke normal
716
+ // agent work — a mention of the name in an unrelated command's
717
+ // argument, a read (not a set), an unrelated `-c` flag mistaken for
718
+ // shell `-c`, a bare 'pty' word, and env -i clearing the WHOLE
719
+ // environment for a command that never needed an identity.
720
+ 'git commit -m "ADL_HUMAN_AZDO=1 is denied now"',
721
+ 'git log -S "ADL_HUMAN_AZDO=1"',
722
+ 'declare -p ADL_HUMAN_AZDO',
723
+ // `rg`, not `grep` — `tool.grep` denies grep outright, unrelated to
724
+ // this rule; the point here is `-c` (rg's own count flag) not being
725
+ // mistaken for shell `-c`.
726
+ "bun -e '1' && rg -c 'unset ADL_AGENT_ID_AGENT' STATUS.md",
727
+ `node -e "console.log('pty')"`,
728
+ 'env -i PATH=/usr/bin ls',
729
+ ],
730
+ },
731
+ }