@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.30 → 0.1.33

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 (199) hide show
  1. package/bin/adl +2 -2
  2. package/bin/health-check +2 -2
  3. package/bin/reconcile +41 -21
  4. package/bin/setup +2 -1
  5. package/package.json +1 -1
  6. package/packages/agent-hooks/README.md +77 -8
  7. package/packages/agent-hooks/assets/opencode-plugin.template.ts +2 -6
  8. package/packages/agent-hooks/src/deploy/opencode-template.ts +5 -3
  9. package/packages/agent-hooks/src/hooks/crg/background.ts +7 -4
  10. package/packages/agent-hooks/src/hooks/log.ts +12 -12
  11. package/packages/agent-hooks/src/log/writer.ts +170 -24
  12. package/packages/agent-hooks/src/main.ts +1 -1
  13. package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +5 -4
  14. package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +1 -1
  15. package/packages/agent-hooks/src/rules/shell/invocation.ts +2 -1
  16. package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +19 -5
  17. package/packages/agent-settings/assets/GLOBAL-AGENTS.md +1 -1
  18. package/packages/agent-skills/assets/agent-search-tool-audit/SKILL.md +24 -2
  19. package/packages/agent-skills/assets/agent-search-tool-audit/scripts/audit.sh +19 -45
  20. package/packages/agent-skills/assets/diagnosing-bugs/SKILL.md +9 -0
  21. package/packages/agent-skills/assets/diagnosing-bugs/scripts/hitl-loop.template.sh +1 -12
  22. package/packages/azdo/src/lib/commit-types.ts +8 -0
  23. package/packages/azdo/src/lib/validate-pr-metadata.ts +4 -1
  24. package/packages/fleet/manifest.json +2 -1
  25. package/packages/fleet/src/repo-maintain.ts +5 -2
  26. package/packages/repo-controls/AGENTS.md +8 -5
  27. package/packages/repo-controls/README.md +348 -58
  28. package/packages/repo-controls/assets/GLOBAL-INVARIANTS.md +21 -0
  29. package/packages/repo-controls/assets/promote.ts +7 -85
  30. package/packages/repo-controls/assets/reconcile-guard.sh +1 -14
  31. package/packages/repo-controls/assets/scaffold/docs/AGENTS.md +25 -0
  32. package/packages/repo-controls/assets/scaffold/docs/CLAUDE.md +1 -0
  33. package/packages/repo-controls/assets/scaffold/docs/decisions/index.md +17 -0
  34. package/packages/repo-controls/assets/scaffold/docs/notes.md +20 -0
  35. package/packages/repo-controls/assets/scaffold/plans/AGENTS.md +28 -0
  36. package/packages/repo-controls/assets/scaffold/plans/CLAUDE.md +1 -0
  37. package/packages/repo-controls/assets/scaffold/plans/GAPS-AND-FINDINGS.md +12 -0
  38. package/packages/repo-controls/assets/scaffold/plans/LEDGER.md +8 -0
  39. package/packages/repo-controls/assets/scaffold/plans/features/.gitkeep +0 -0
  40. package/packages/repo-controls/assets/scaffold/root/AGENTS.md +22 -0
  41. package/packages/repo-controls/assets/scaffold/root/CLAUDE.md +1 -0
  42. package/packages/repo-controls/assets/scaffold/workflows/AGENTS.md +16 -0
  43. package/packages/repo-controls/assets/scaffold/workflows/CLAUDE.md +1 -0
  44. package/packages/repo-controls/assets/scaffold/workflows/pipelines/.gitkeep +0 -0
  45. package/packages/repo-controls/assets/scaffold/workflows/scripts/.gitkeep +0 -0
  46. package/packages/repo-controls/assets/version-bump.sh +7 -48
  47. package/packages/repo-controls/package/adl-compliance/AGENTS.md +25 -7
  48. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +6 -4
  49. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/check.py +1 -1
  50. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +1 -1
  51. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +7 -42
  52. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/excluded/web/i18n/locales/zh-CN/strings.ts +1 -0
  53. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +10 -44
  54. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/ui-contract.md +1 -1
  55. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/UI-CONTRACT.md +1 -1
  56. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/test_check.py +1 -1
  57. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/check.py +1 -7
  58. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/test_check.py +12 -3
  59. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +15 -23
  60. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +0 -136
  61. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +18 -0
  62. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +2 -2
  63. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +0 -7
  64. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/check.py +2 -4
  65. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/guides/stable-delivery.md +10 -0
  66. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/guides/stable-recommendation.md +12 -0
  67. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/guides/target-narration.md +10 -0
  68. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +6 -7
  69. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/ci_paths/test_check.py +3 -3
  70. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +10 -12
  71. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +1 -1
  72. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/web/src/renderer/solo/item.ts +1 -0
  73. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/web/src/a.ts +1 -0
  74. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/web/src/b.ts +1 -0
  75. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +1 -1
  76. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/fresh/fresh.ts +1 -0
  77. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub1/only.ts +1 -0
  78. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub10/only.ts +1 -0
  79. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub11/only.ts +1 -0
  80. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub2/only.ts +1 -0
  81. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub3/only.ts +1 -0
  82. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub4/only.ts +1 -0
  83. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub5/only.ts +1 -0
  84. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub6/only.ts +1 -0
  85. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub7/only.ts +1 -0
  86. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub8/only.ts +1 -0
  87. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/many/sub9/only.ts +1 -0
  88. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/services/i18n/locales/de/common.json +1 -0
  89. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/renderer/solo/item.ts +1 -0
  90. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/web/src/vendored-crate/Cargo.toml +2 -0
  91. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/grants.yaml +1 -1
  92. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/web/src/renderer/solo/item.ts +1 -0
  93. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/grants.yaml +1 -1
  94. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/web/src/a.ts +1 -0
  95. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/web/src/b.ts +1 -0
  96. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/web/src/c.ts +1 -0
  97. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/grants.yaml +2 -2
  98. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/web/src/renderer/solo/item.ts +1 -0
  99. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +1 -1
  100. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/fresh/fresh.ts +1 -0
  101. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub1/only.ts +1 -0
  102. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub10/only.ts +1 -0
  103. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub11/only.ts +1 -0
  104. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub2/only.ts +1 -0
  105. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub3/only.ts +1 -0
  106. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub4/only.ts +1 -0
  107. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub5/only.ts +1 -0
  108. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub6/only.ts +1 -0
  109. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub7/only.ts +1 -0
  110. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub8/only.ts +1 -0
  111. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/many/sub9/only.ts +1 -0
  112. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/web/src/renderer/solo/item.ts +1 -0
  113. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/web/src/renderer/solo/item.ts +1 -0
  114. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +46 -54
  115. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +16 -76
  116. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +35 -32
  117. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +46 -213
  118. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/README.md +1 -0
  119. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +76 -194
  120. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/check.py +18 -2
  121. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +49 -0
  122. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +1 -1
  123. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/docs/architecture/guides/links.md +20 -0
  124. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/docs/architecture/guides/route-target.md +8 -0
  125. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/docs/architecture/guides/links.md +20 -0
  126. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/docs/architecture/guides/route-target.md +8 -0
  127. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/test_check.py +4 -4
  128. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +3 -3
  129. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.notes/declared.txt +1 -0
  130. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +8 -1
  131. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +15 -135
  132. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +98 -50
  133. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +1 -1
  134. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +1 -1
  135. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +1 -1
  136. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +14 -10
  137. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/__init__.py +3 -10
  138. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/base.py +42 -0
  139. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/test_check.py +82 -49
  140. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/test_scope.py +71 -0
  141. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/legacy_search/__init__.py +7 -0
  142. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/legacy_search/check.py +15 -0
  143. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/legacy_search/test_check.py +32 -0
  144. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/cargo_lock.py +1 -1
  145. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +56 -124
  146. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/Cargo.lock +7 -0
  147. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/Cargo.toml +4 -0
  148. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/bun.lock +1 -0
  149. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/package.json +1 -0
  150. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/rust-toolchain.toml +3 -0
  151. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/src/main.rs +1 -0
  152. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/Cargo.lock +7 -0
  153. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/Cargo.toml +4 -0
  154. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/bun.lock +0 -0
  155. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/package.json +1 -0
  156. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/rust-toolchain.toml +3 -0
  157. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/src/main.rs +1 -0
  158. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +8 -37
  159. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_declared_paths.py +95 -130
  160. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_root_lockfiles.py +101 -0
  161. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_stale_lock.py +25 -13
  162. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/no_multiline_comments/__init__.py +7 -0
  163. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/no_multiline_comments/check.py +124 -0
  164. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/no_multiline_comments/fixtures/valid-register.yaml +4 -0
  165. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/no_multiline_comments/scanner.py +217 -0
  166. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/no_multiline_comments/test_check.py +391 -0
  167. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/vcs_in_scripts/__init__.py +7 -0
  168. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/vcs_in_scripts/check.py +16 -0
  169. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/vcs_in_scripts/test_check.py +32 -0
  170. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +12 -1
  171. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/ast_grep.py +2 -3
  172. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +3 -0
  173. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +1 -1
  174. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/declarations.py +24 -0
  175. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/receipt.py +2 -2
  176. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/scripts.py +120 -0
  177. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +1 -1
  178. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.toml +4 -4
  179. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +93 -99
  180. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +93 -99
  181. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +1 -1
  182. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +6 -47
  183. package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +54 -8
  184. package/packages/repo-controls/scripts/hooks/commit-msg +1 -1
  185. package/packages/repo-controls/scripts/hooks/pre-commit +12 -2
  186. package/packages/repo-controls/scripts/hooks/pre-push +27 -19
  187. package/packages/repo-controls/src/cli.ts +22 -3
  188. package/packages/repo-controls/src/compliance-config.ts +132 -65
  189. package/packages/repo-controls/src/config.ts +62 -52
  190. package/packages/repo-controls/src/constants.ts +9 -0
  191. package/packages/repo-controls/src/coverage-ratchet.ts +19 -4
  192. package/packages/repo-controls/src/doctor.ts +20 -30
  193. package/packages/repo-controls/src/findings-ratchet.ts +14 -0
  194. package/packages/repo-controls/src/gitignore-block.ts +3 -13
  195. package/packages/repo-controls/src/hook-log.ts +7 -10
  196. package/packages/repo-controls/src/hook.ts +127 -83
  197. package/packages/repo-controls/src/install-compliance.ts +112 -0
  198. package/packages/repo-controls/src/install.ts +133 -30
  199. package/packages/repo-controls/src/integrity.ts +5 -18
@@ -11,8 +11,9 @@ third rule that makes this check unlike any other ported so far:
11
11
  DIR-003 is why this gate has no way to point it at one tree. A narrower set
12
12
  makes every unreachable entry look stale, so narrowing INFLATES the answer
13
13
  rather than reducing it: measured on this row, 7 findings over the registered
14
- trees against 92 when pointed at one crate. That is also why the row declares
15
- tree-scoped globs and why `runner.run(exhaustive=...)` matters here more than
14
+ trees against 92 when pointed at one crate. That is also why the row's scope is
15
+ the whole repository (`**`, no exclusion: what a repository exempts it declares
16
+ in the register and the ceilings) and why `runner.run(exhaustive=...)` matters here more than
16
17
  anywhere else — an empty intersection is a dead scope, not a clean tree.
17
18
 
18
19
  Children means FILES. A directory holding ten subdirectories and no files of
@@ -33,7 +34,7 @@ gates must read as one family):
33
34
  `page_cap` resolves its limit: each entry must be a repo-relative path
34
35
  and a base-10 positive integer; any malformed entry is could-not-run
35
36
  naming the config key and the entry. NO ceilings declared means nothing
36
- to enforce — the gate is inert and the register is not even read.
37
+ to enforce, though the register is still read and validated.
37
38
  2. The register records STATE only — the consumer-owned
38
39
  `<compliance>/ratchets/LAY-004-over-limit-directory.yaml` (the estate's
39
40
  settled location for a consumer-owned ratchet number), holding
@@ -104,10 +105,10 @@ class DirectoryRatchet(Check):
104
105
 
105
106
  # CONSUMER-OWNED, not package data. This shipped as a `resources` entry
106
107
  # (`grants.yaml`) holding one donor repository's entire directory shape:
107
- # 88 of its 104 lines named `<rust>/crates/enact-*`,
108
- # `<typescript>/packages/desktop/src/renderer/*` and `infra/stacks/*`. None of
109
- # the four repositories in this estate has any of those trees, so the gate
110
- # raised could-not-run on its FIRST registered tree for every one of them.
108
+ # 88 of its 104 lines named that repository's own crate, application and
109
+ # infrastructure directories. None of the other repositories in this estate
110
+ # has any of those trees, so the gate raised could-not-run on its FIRST
111
+ # registered tree for every one of them.
111
112
  #
112
113
  # The old docstring defended the file as "not a consumer path". That is
113
114
  # backwards: a ratchet baseline IS the consumer's own state by definition —
@@ -140,13 +141,10 @@ class DirectoryRatchet(Check):
140
141
 
141
142
  def graded(self, ctx: Context, files: FileSet) -> Iterable[Report]:
142
143
  ceilings = self._ceilings(ctx)
144
+ ratchet = self._register(ctx)
143
145
  if not ceilings:
144
- # Nothing configured is nothing to enforce: the gate is inert,
145
- # and the register is not read (its entries could only ever
146
- # REMOVE findings).
147
146
  return
148
147
 
149
- ratchet = self._register(ctx)
150
148
  over_children: dict[str, int] = {}
151
149
  single_file: dict[str, str] = {}
152
150
  if ratchet is not None:
@@ -188,7 +186,7 @@ class DirectoryRatchet(Check):
188
186
  declaration (`[controls.compliance.directory-ratchet].max_children`).
189
187
 
190
188
  Absent is `{}`: no table declared, nothing to enforce — the gate is
191
- inert and the register is not read. Each entry must be
189
+ inert (the register is still read and validated). Each entry must be
192
190
  `<path>:<positive int>` with ASCII digits (paths carry slashes,
193
191
  letters, dashes, underscores and dots — never a comma or a colon,
194
192
  which are the list and entry separators); ANY malformed entry is
@@ -1,4 +1,4 @@
1
1
  schema_version: 2
2
2
  over_children_baseline: {}
3
3
  single_file_baseline:
4
- frontend/packages/desktop/src/renderer/solo: item.ts
4
+ web/src/renderer/solo: item.ts
@@ -1,4 +1,4 @@
1
1
  schema_version: 2
2
2
  over_children_baseline: {}
3
3
  single_file_baseline:
4
- frontend/packages/desktop/src/renderer/solo: item.ts
4
+ web/src/renderer/solo: item.ts
@@ -2,4 +2,4 @@ schema_version: 2
2
2
  over_children_baseline:
3
3
  infra/stacks: 5
4
4
  single_file_baseline:
5
- frontend/packages/desktop/src/renderer/solo: item.ts
5
+ web/src/renderer/solo: item.ts
@@ -1,4 +1,4 @@
1
1
  schema_version: 2
2
2
  over_children_baseline:
3
- frontend/packages/desktop/src: 3
3
+ web/src: 3
4
4
  single_file_baseline: {}
@@ -1,5 +1,5 @@
1
1
  schema_version: 2
2
2
  over_children_baseline:
3
- frontend/packages/desktop/src/renderer/gone: 4
3
+ web/src/renderer/gone: 4
4
4
  single_file_baseline:
5
- frontend/packages/desktop/src/renderer/solo: item.ts
5
+ web/src/renderer/solo: item.ts
@@ -1,4 +1,4 @@
1
1
  schema_version: 2
2
2
  over_children_baseline: {}
3
3
  single_file_baseline:
4
- frontend/packages/desktop/src/renderer/solo: item.ts
4
+ web/src/renderer/solo: item.ts
@@ -6,9 +6,8 @@ principle (v3 for this gate): `directory-ratchet-clean` (one baselined
6
6
  single-file directory, nothing else), `directory-ratchet-unbaselined` (an
7
7
  unbaselined single-file directory, plus a control: eleven single-file
8
8
  subdirectories of a parent that itself holds zero direct files),
9
- `directory-ratchet-excluded` (the row's own `!` exclusions under test, run
10
- twice against the same files through two Row variants that differ by exactly
11
- those two patterns), `directory-ratchet-missing-tree` (a ceiling-configured
9
+ `directory-ratchet-excluded` (a locale directory and a vendored crate, which the
10
+ row used to exclude and now grades: PBI 598 deleted every row exclusion), `directory-ratchet-missing-tree` (a ceiling-configured
12
11
  tree with no directory — advisory, not failure),
13
12
  `directory-ratchet-stale-entry` (DIR-003's kept reach: a baseline entry under
14
13
  a live tree whose directory was deleted), `directory-ratchet-unusable-register`
@@ -80,7 +79,7 @@ def run(
80
79
 
81
80
 
82
81
  def test_a_fully_baselined_tree_passes() -> None:
83
- verdict = run("directory-ratchet-clean", ceilings="frontend/packages/desktop/src:10")
82
+ verdict = run("directory-ratchet-clean", ceilings="web/src:10")
84
83
  assert verdict.outcome is Outcome.CLEAN, verdict.render()
85
84
  assert not verdict.findings
86
85
  assert not verdict.advisories
@@ -90,8 +89,7 @@ def test_no_ceilings_configured_means_nothing_to_enforce() -> None:
90
89
  """The generic principle's config half: no `[controls.compliance.directory-
91
90
  ratchet]` table, no ceilings declared — the gate has NOTHING to enforce
92
91
  and passes clean even with a three-file directory on disk whose register
93
- would exempt it (proving the register is not even read: its entry could
94
- only ever REMOVE findings)."""
92
+ would exempt it (a VALID register is read and changes nothing here)."""
95
93
  verdict = run("directory-ratchet-no-ceilings")
96
94
  assert verdict.outcome is Outcome.CLEAN, verdict.render()
97
95
  assert not verdict.findings
@@ -104,7 +102,7 @@ def test_a_baseline_entry_exempts_its_directory_up_to_the_recorded_count() -> No
104
102
  entry forgives the directory up to the count recorded (growing past it
105
103
  is DIR-002, reported separately)."""
106
104
  verdict = run(
107
- "directory-ratchet-no-ceilings", ceilings="frontend/packages/desktop/src:2"
105
+ "directory-ratchet-no-ceilings", ceilings="web/src:2"
108
106
  )
109
107
  assert verdict.outcome is Outcome.CLEAN, verdict.render()
110
108
  assert not verdict.findings
@@ -118,23 +116,23 @@ def test_an_over_ceiling_directory_with_no_register_is_dir_001() -> None:
118
116
  verdict = runner.run(
119
117
  ROW, directory, corpus_files(directory),
120
118
  inputs={ROW.id: {"register": directory / "does-not-exist.yaml"}},
121
- declarations={DirectoryRatchet.CEILINGS_DECLARATION: "frontend/packages/desktop/src:2"},
119
+ declarations={DirectoryRatchet.CEILINGS_DECLARATION: "web/src:2"},
122
120
  )
123
121
  assert verdict.outcome is Outcome.FINDINGS
124
122
  findings = [f for f in verdict.findings if f.rule == "DIR-001"]
125
123
  assert len(findings) == 1, tuple(f.render() for f in verdict.findings)
126
- assert findings[0].path == "frontend/packages/desktop/src"
124
+ assert findings[0].path == "web/src"
127
125
  assert findings[0].message == "3 direct children (max 2), no ratchet entry"
128
126
 
129
127
 
130
128
  def test_a_malformed_ceilings_declaration_is_could_not_run() -> None:
131
- for bad in ("frontend/packages/desktop/src:banana", "frontend/packages/desktop/src:0"):
129
+ for bad in ("web/src:banana", "web/src:0"):
132
130
  verdict = run("directory-ratchet-clean", ceilings=bad)
133
131
  assert verdict.outcome is Outcome.COULD_NOT_RUN, bad
134
132
  assert "directory-ratchet" in verdict.message
135
- assert "frontend/packages/desktop/src" in verdict.message
133
+ assert "web/src" in verdict.message
136
134
  # An entry with no ceiling half at all:
137
- verdict = run("directory-ratchet-clean", ceilings="frontend/packages/desktop/src")
135
+ verdict = run("directory-ratchet-clean", ceilings="web/src")
138
136
  assert verdict.outcome is Outcome.COULD_NOT_RUN
139
137
  assert "directory-ratchet" in verdict.message
140
138
 
@@ -146,7 +144,7 @@ def test_a_register_recording_zero_state_is_a_load_failure() -> None:
146
144
  as a load failure, never as a silent empty pass."""
147
145
  verdict = run(
148
146
  "directory-ratchet-empty-register",
149
- ceilings="frontend/packages/desktop/src:2",
147
+ ceilings="web/src:2",
150
148
  )
151
149
  assert verdict.outcome is Outcome.COULD_NOT_RUN
152
150
  assert "a register grading nothing" in verdict.message
@@ -156,56 +154,39 @@ def test_a_register_recording_zero_state_is_a_load_failure() -> None:
156
154
 
157
155
 
158
156
  def test_an_unbaselined_single_file_directory_is_reported() -> None:
159
- verdict = run("directory-ratchet-unbaselined", ceilings="frontend/packages/desktop/src:10")
157
+ verdict = run("directory-ratchet-unbaselined", ceilings="web/src:10")
160
158
  assert verdict.outcome is Outcome.FINDINGS
161
159
  paths = {f.path for f in verdict.findings if f.rule == "DIR-001"}
162
- assert "frontend/packages/desktop/src/renderer/fresh" in paths
163
- assert "frontend/packages/desktop/src/renderer/solo" not in paths
160
+ assert "web/src/renderer/fresh" in paths
161
+ assert "web/src/renderer/solo" not in paths
164
162
 
165
163
 
166
164
  def test_a_subdirectory_alone_never_trips_the_rule() -> None:
167
165
  """`many` holds eleven subdirectories and zero direct files of its own, so it
168
166
  needs no baseline entry; each subdirectory holds exactly one file and IS
169
167
  reported. Both halves matter, or this corpus is silent by accident."""
170
- verdict = run("directory-ratchet-unbaselined", ceilings="frontend/packages/desktop/src:10")
168
+ verdict = run("directory-ratchet-unbaselined", ceilings="web/src:10")
171
169
  paths = {f.path for f in verdict.findings if f.rule == "DIR-001"}
172
- assert "frontend/packages/desktop/src/renderer/many" not in paths
173
- assert "frontend/packages/desktop/src/renderer/many/sub1" in paths
170
+ assert "web/src/renderer/many" not in paths
171
+ assert "web/src/renderer/many/sub1" in paths
174
172
 
175
173
 
176
- def test_the_row_exclusions_silence_locales_and_vendored_cargo() -> None:
177
- verdict = run("directory-ratchet-excluded", ceilings="frontend/packages/desktop/src:20")
178
- assert verdict.outcome is Outcome.FINDINGS
179
- paths = {f.path for f in verdict.findings}
180
- assert not any("locales" in p for p in paths)
181
- assert not any("vendored-crate" in p for p in paths)
182
- assert "frontend/packages/desktop/src/renderer/fresh" in {
183
- f.path for f in verdict.findings if f.rule == "DIR-001"
184
- }
185
-
186
-
187
- def test_falsifiability_without_the_row_exclusions() -> None:
188
- """The same corpus, read through a Row differing by exactly the two `!`
189
- patterns. Without this, the rejections above would pass just as well
190
- against a row whose exclusions never matched anything."""
191
- unscoped = tuple(
192
- pattern for pattern in ROW.engine.scope
193
- if not (pattern.startswith("!") and ("locales" in pattern or "Cargo.toml" in pattern))
194
- )
195
- assert len(unscoped) == len(ROW.engine.scope) - 2
196
-
197
- verdict = run("directory-ratchet-excluded", scope=unscoped, ceilings="frontend/packages/desktop/src:20")
174
+ def test_the_row_excludes_nothing_so_locales_and_vendored_cargo_are_graded() -> None:
175
+ """PBI 598: the ratchet is repo-wide with no hardcoded exclusion, locale and vendored dirs included."""
176
+ assert ROW.engine.scope == ("**",)
177
+ verdict = run("directory-ratchet-excluded", ceilings="web/src:20")
198
178
  assert verdict.outcome is Outcome.FINDINGS
199
179
  paths = {f.path for f in verdict.findings if f.rule == "DIR-001"}
200
- assert any("locales" in p for p in paths)
201
- assert any("vendored-crate" in p for p in paths)
180
+ assert any("locales" in p for p in paths), paths
181
+ assert any("vendored-crate" in p for p in paths), paths
182
+ assert "web/src/renderer/fresh" in paths
202
183
 
203
184
 
204
185
  def test_the_ratchet_register_is_not_a_grant_catalogue() -> None:
205
186
  """`structural_grant = True` forces the allowance to 0 regardless of the
206
187
  row's own `grants:` field. Passing the register's size as the allowance is
207
188
  the trap: a failing gate would report green."""
208
- verdict = run("directory-ratchet-unbaselined", ceilings="frontend/packages/desktop/src:10")
189
+ verdict = run("directory-ratchet-unbaselined", ceilings="web/src:10")
209
190
  assert verdict.granted == 0
210
191
  assert verdict.outcome is Outcome.FINDINGS
211
192
 
@@ -222,12 +203,12 @@ def test_an_absent_register_enforces_the_ceilings_bare() -> None:
222
203
  verdict = runner.run(
223
204
  ROW, directory, corpus_files(directory),
224
205
  inputs={ROW.id: {"register": directory / "does-not-exist.yaml"}},
225
- declarations={DirectoryRatchet.CEILINGS_DECLARATION: "frontend/packages/desktop/src:10"},
206
+ declarations={DirectoryRatchet.CEILINGS_DECLARATION: "web/src:10"},
226
207
  )
227
208
  assert verdict.outcome is Outcome.FINDINGS
228
209
  findings = [f for f in verdict.findings if f.rule == "DIR-001"]
229
210
  assert {f.path for f in findings} == {
230
- "frontend/packages/desktop/src/renderer/solo",
211
+ "web/src/renderer/solo",
231
212
  }
232
213
 
233
214
 
@@ -241,7 +222,7 @@ def test_an_absent_register_with_an_empty_scope_is_still_the_runners_dead_scope(
241
222
  ROW, directory, (),
242
223
  exhaustive=True,
243
224
  inputs={ROW.id: {"register": directory / "does-not-exist.yaml"}},
244
- declarations={DirectoryRatchet.CEILINGS_DECLARATION: "frontend/packages/desktop/src:10"},
225
+ declarations={DirectoryRatchet.CEILINGS_DECLARATION: "web/src:10"},
245
226
  )
246
227
  assert verdict.outcome is Outcome.COULD_NOT_RUN
247
228
  assert "matches no file on disk" in verdict.message
@@ -253,18 +234,29 @@ def test_a_register_that_exists_but_is_unusable_is_could_not_run() -> None:
253
234
  enforcement, UNUSABLE is not. A register that exists but cannot be parsed
254
235
  may be mid-edit; grading it as "no baselines" would silently drop every
255
236
  exemption it names."""
256
- verdict = run("directory-ratchet-unusable-register", ceilings="frontend/packages/desktop/src:10")
237
+ verdict = run("directory-ratchet-unusable-register", ceilings="web/src:10")
257
238
  assert verdict.outcome is Outcome.COULD_NOT_RUN
258
239
  assert "unusable" in verdict.message
259
240
 
260
241
 
242
+ def test_an_unusable_register_is_could_not_run_even_with_no_ceilings_declared() -> None:
243
+ verdict = run("directory-ratchet-unusable-register")
244
+ assert verdict.outcome is Outcome.COULD_NOT_RUN, verdict.render()
245
+ assert "unusable" in verdict.message
246
+
247
+
248
+ def test_a_register_recording_zero_state_is_a_load_failure_with_no_ceilings_declared() -> None:
249
+ verdict = run("directory-ratchet-empty-register")
250
+ assert verdict.outcome is Outcome.COULD_NOT_RUN, verdict.render()
251
+
252
+
261
253
  def test_a_configured_tree_that_is_gone_is_an_advisory_not_a_failure() -> None:
262
254
  """Generic principle, the cleanup half: a tree the CONFIGURATION names
263
255
  but the repository no longer has is cleanup, not a defect. One advisory
264
256
  names what is unaccounted; the remaining trees are graded normally."""
265
257
  verdict = run(
266
258
  "directory-ratchet-missing-tree",
267
- ceilings="frontend/packages/desktop/src:10,infra:10",
259
+ ceilings="web/src:10,infra:10",
268
260
  )
269
261
  assert verdict.outcome is Outcome.CLEAN, verdict.render()
270
262
  assert not verdict.findings
@@ -281,10 +273,10 @@ def test_a_baseline_entry_for_a_deleted_directory_is_still_reported_stale() -> N
281
273
  repository deleted, is DIR-003 exactly as before. Cleanup of the CONTENT
282
274
  is free; cleanup of the REGISTER is the owner's edit, and the gate still
283
275
  says so."""
284
- verdict = run("directory-ratchet-stale-entry", ceilings="frontend/packages/desktop/src:10")
276
+ verdict = run("directory-ratchet-stale-entry", ceilings="web/src:10")
285
277
  assert verdict.outcome is Outcome.FINDINGS
286
278
  stale = {f.path for f in verdict.findings if f.rule == "DIR-003"}
287
- assert "frontend/packages/desktop/src/renderer/gone" in stale
279
+ assert "web/src/renderer/gone" in stale
288
280
 
289
281
 
290
282
  def test_the_register_is_not_packaged_data() -> None:
@@ -309,9 +301,9 @@ def test_a_baselines_only_register_is_valid() -> None:
309
301
  ratchet = Ratchet.model_validate(
310
302
  {
311
303
  "schema_version": 2,
312
- "over_children_baseline": {"frontend/packages/desktop/src/renderer": 12},
304
+ "over_children_baseline": {"web/src/renderer": 12},
313
305
  "single_file_baseline": {
314
- "frontend/packages/desktop/src/renderer/solo": "item.ts"
306
+ "web/src/renderer/solo": "item.ts"
315
307
  },
316
308
  }
317
309
  )
@@ -331,7 +323,7 @@ def test_a_register_carrying_max_children_is_refused() -> None:
331
323
  Ratchet.model_validate(
332
324
  {
333
325
  "schema_version": 2,
334
- "max_children": {"frontend/packages/desktop/src": 10},
326
+ "max_children": {"web/src": 10},
335
327
  "over_children_baseline": {},
336
328
  "single_file_baseline": {},
337
329
  }