@amsterdamdatalabs/adl-agent-control-darwin-arm64 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/adl +4 -0
- package/bin/cursor-settings +14 -0
- package/bin/default-agent-file +14 -0
- package/bin/git +670 -0
- package/bin/git-ado +425 -0
- package/bin/global-agents +14 -0
- package/bin/global-surface-sweep +14 -0
- package/bin/health-check +38 -0
- package/bin/kimi-hooks +14 -0
- package/bin/lean-ctx-observe-strip +361 -0
- package/bin/lib/bun-compile-build.sh +34 -0
- package/bin/lib/lean-ctx-observe-hooks.sh +634 -0
- package/bin/managed-settings +14 -0
- package/bin/opencode-hooks +14 -0
- package/bin/reconcile +2648 -0
- package/bin/scratch-reap +14 -0
- package/bin/shell-path-policy +64 -0
- package/bin/surface-policy +14 -0
- package/bin/sync-and-reconcile +215 -0
- package/bin/update-azure-agent-pool +29 -0
- package/bin/validate-manifest +171 -0
- package/bin/vscode-settings +14 -0
- package/package.json +44 -0
- package/packages/agent-hooks/README.md +411 -0
- package/packages/agent-hooks/assets/hooks.json +97 -0
- package/packages/agent-hooks/assets/opencode-plugin.template.ts +224 -0
- package/packages/agent-hooks/bunfig.toml +27 -0
- package/packages/agent-hooks/deploy-profile.json +53 -0
- package/packages/agent-hooks/deploy-profile.schema.json +120 -0
- package/packages/agent-hooks/package.json +23 -0
- package/packages/agent-hooks/src/cli/args.ts +99 -0
- package/packages/agent-hooks/src/cli/doctor.ts +241 -0
- package/packages/agent-hooks/src/cli/rules.ts +133 -0
- package/packages/agent-hooks/src/deploy/deploy.ts +181 -0
- package/packages/agent-hooks/src/deploy/doctor.ts +158 -0
- package/packages/agent-hooks/src/deploy/index.ts +17 -0
- package/packages/agent-hooks/src/deploy/json-merge.ts +115 -0
- package/packages/agent-hooks/src/deploy/legacy-lock.ts +213 -0
- package/packages/agent-hooks/src/deploy/list.ts +117 -0
- package/packages/agent-hooks/src/deploy/lock.ts +65 -0
- package/packages/agent-hooks/src/deploy/opencode-template.ts +74 -0
- package/packages/agent-hooks/src/deploy/profile.ts +117 -0
- package/packages/agent-hooks/src/deploy/render.ts +162 -0
- package/packages/agent-hooks/src/deploy/source.ts +84 -0
- package/packages/agent-hooks/src/gating/config.ts +514 -0
- package/packages/agent-hooks/src/gating/root.ts +117 -0
- package/packages/agent-hooks/src/hooks/briefing/handler.ts +22 -0
- package/packages/agent-hooks/src/hooks/briefing/index.ts +320 -0
- package/packages/agent-hooks/src/hooks/contract.ts +112 -0
- package/packages/agent-hooks/src/hooks/crg/handler.ts +22 -0
- package/packages/agent-hooks/src/hooks/crg/index.ts +209 -0
- package/packages/agent-hooks/src/hooks/lean-ctx/handler.ts +22 -0
- package/packages/agent-hooks/src/hooks/lean-ctx/index.ts +173 -0
- package/packages/agent-hooks/src/hooks/lean-ctx/mapping.ts +121 -0
- package/packages/agent-hooks/src/hooks/lean-ctx/scope-rewrite.ts +207 -0
- package/packages/agent-hooks/src/hooks/log.ts +233 -0
- package/packages/agent-hooks/src/hooks/user-prompt-submit/config.ts +58 -0
- package/packages/agent-hooks/src/hooks/user-prompt-submit/constants.ts +149 -0
- package/packages/agent-hooks/src/hooks/user-prompt-submit/handler.ts +72 -0
- package/packages/agent-hooks/src/hooks/user-prompt-submit/index.ts +203 -0
- package/packages/agent-hooks/src/hooks/user-prompt-submit/match.ts +212 -0
- package/packages/agent-hooks/src/hooks/user-prompt-submit/skill-roots.ts +73 -0
- package/packages/agent-hooks/src/hooks/user-prompt-submit/skills.ts +98 -0
- package/packages/agent-hooks/src/hooks/user-prompt-submit/tokenizer.ts +115 -0
- package/packages/agent-hooks/src/hooks/user-prompt-submit/vector.ts +174 -0
- package/packages/agent-hooks/src/hosts/impl/claude.ts +47 -0
- package/packages/agent-hooks/src/hosts/impl/codex.ts +47 -0
- package/packages/agent-hooks/src/hosts/impl/cursor.ts +40 -0
- package/packages/agent-hooks/src/hosts/impl/kimi.ts +47 -0
- package/packages/agent-hooks/src/hosts/impl/opencode.ts +54 -0
- package/packages/agent-hooks/src/hosts/registry.ts +29 -0
- package/packages/agent-hooks/src/hosts/spec.ts +113 -0
- package/packages/agent-hooks/src/lean-ctx/env.ts +106 -0
- package/packages/agent-hooks/src/lean-ctx/mcp.ts +140 -0
- package/packages/agent-hooks/src/lib/spawn-with-timeout.ts +120 -0
- package/packages/agent-hooks/src/log/writer.ts +230 -0
- package/packages/agent-hooks/src/main.ts +269 -0
- package/packages/agent-hooks/src/pre-tool-use/handler.ts +549 -0
- package/packages/agent-hooks/src/rules/engine.ts +293 -0
- package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +51 -0
- package/packages/agent-hooks/src/rules/impl/adl-git-credential-bypass.ts +320 -0
- package/packages/agent-hooks/src/rules/impl/adl-git-identity.ts +249 -0
- package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +258 -0
- package/packages/agent-hooks/src/rules/impl/adl-human-azdo-bypass.ts +731 -0
- package/packages/agent-hooks/src/rules/impl/adl-identity.ts +128 -0
- package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +179 -0
- package/packages/agent-hooks/src/rules/impl/adl-pr-complete-pending.ts +65 -0
- package/packages/agent-hooks/src/rules/impl/adl-pr-review-role.ts +156 -0
- package/packages/agent-hooks/src/rules/impl/adl-pr-role.ts +121 -0
- package/packages/agent-hooks/src/rules/impl/adl-session-required.ts +403 -0
- package/packages/agent-hooks/src/rules/impl/adl-token-minting-role.ts +92 -0
- package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +74 -0
- package/packages/agent-hooks/src/rules/impl/advisory-coverage.ts +43 -0
- package/packages/agent-hooks/src/rules/impl/advisory-finder.ts +62 -0
- package/packages/agent-hooks/src/rules/impl/agent-secrets-stay-unread.ts +173 -0
- package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +508 -0
- package/packages/agent-hooks/src/rules/impl/fs-canonical-checkout.ts +86 -0
- package/packages/agent-hooks/src/rules/impl/fs-git-internals.ts +75 -0
- package/packages/agent-hooks/src/rules/impl/fs-mv.ts +66 -0
- package/packages/agent-hooks/src/rules/impl/fs-rm.ts +83 -0
- package/packages/agent-hooks/src/rules/impl/fs-trash.ts +140 -0
- package/packages/agent-hooks/src/rules/impl/git-core.ts +101 -0
- package/packages/agent-hooks/src/rules/impl/git-helpers.ts +408 -0
- package/packages/agent-hooks/src/rules/impl/git-history.ts +77 -0
- package/packages/agent-hooks/src/rules/impl/git-paths.ts +139 -0
- package/packages/agent-hooks/src/rules/impl/git-plumbing.ts +167 -0
- package/packages/agent-hooks/src/rules/impl/git-protected-tree.ts +132 -0
- package/packages/agent-hooks/src/rules/impl/git-transitions.ts +292 -0
- package/packages/agent-hooks/src/rules/impl/git-verify.ts +95 -0
- package/packages/agent-hooks/src/rules/impl/git-worktree.ts +265 -0
- package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +76 -0
- package/packages/agent-hooks/src/rules/impl/messages.ts +128 -0
- package/packages/agent-hooks/src/rules/impl/parse-uncertain.ts +143 -0
- package/packages/agent-hooks/src/rules/impl/pr-completion.ts +35 -0
- package/packages/agent-hooks/src/rules/impl/shell-remote-script-exec.ts +63 -0
- package/packages/agent-hooks/src/rules/impl/tool-azure-devops.ts +283 -0
- package/packages/agent-hooks/src/rules/impl/tool-bun-test.ts +81 -0
- package/packages/agent-hooks/src/rules/impl/tool-cargo.ts +66 -0
- package/packages/agent-hooks/src/rules/impl/tool-chmod-hook.ts +42 -0
- package/packages/agent-hooks/src/rules/impl/tool-find.ts +82 -0
- package/packages/agent-hooks/src/rules/impl/tool-frontend.ts +83 -0
- package/packages/agent-hooks/src/rules/impl/tool-grep.ts +93 -0
- package/packages/agent-hooks/src/rules/impl/tool-lean-ctx-global.ts +594 -0
- package/packages/agent-hooks/src/rules/impl/tool-native-search.ts +77 -0
- package/packages/agent-hooks/src/rules/ports.ts +178 -0
- package/packages/agent-hooks/src/rules/registry.ts +233 -0
- package/packages/agent-hooks/src/rules/shell/git-identity.ts +1415 -0
- package/packages/agent-hooks/src/rules/shell/git-internals.ts +186 -0
- package/packages/agent-hooks/src/rules/shell/invocation.ts +1083 -0
- package/packages/agent-hooks/src/rules/shell/piped-script.ts +201 -0
- package/packages/agent-hooks/src/rules/shell/prefixes.ts +214 -0
- package/packages/agent-hooks/src/rules/shell/protected-carrier-writes.ts +108 -0
- package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +149 -0
- package/packages/agent-hooks/src/rules/shell/split.ts +179 -0
- package/packages/agent-hooks/src/rules/shell/substitution.ts +394 -0
- package/packages/agent-hooks/src/rules/shell/token.ts +180 -0
- package/packages/agent-hooks/src/rules/shell/xargs.ts +81 -0
- package/packages/agent-hooks/src/rules/spec.ts +152 -0
- package/packages/agent-hooks/src/surface-policy.ts +37 -0
- package/packages/agent-hooks/tsconfig.json +23 -0
- package/packages/agent-settings/assets/GLOBAL-AGENTS.md +107 -0
- package/packages/agent-settings/assets/agents/architect.toml +30 -0
- package/packages/agent-settings/assets/agents/code-reviewer.toml +27 -0
- package/packages/agent-settings/assets/agents/critic.toml +35 -0
- package/packages/agent-settings/assets/agents/executor.toml +28 -0
- package/packages/agent-settings/assets/agents/explore.toml +25 -0
- package/packages/agent-settings/assets/agents/planner.toml +29 -0
- package/packages/agent-settings/assets/lean-ctx/config.toml +39 -0
- package/packages/agent-settings/assets/lean-ctx/gitignore +6 -0
- package/packages/agent-settings/assets/lean-ctx/layout.toml +5 -0
- package/packages/agent-settings/assets/mcp.json +20 -0
- package/packages/agent-settings/managed/README.md +331 -0
- package/packages/agent-settings/managed/claude-managed-settings.json +150 -0
- package/packages/agent-settings/managed/codex-requirements.toml +105 -0
- package/packages/agent-settings/protected.json +470 -0
- package/packages/agent-settings/src/deploy/agent-render.ts +94 -0
- package/packages/agent-settings/src/deploy/agent-toml.ts +76 -0
- package/packages/agent-settings/src/deploy/agents-deploy.ts +129 -0
- package/packages/agent-settings/src/deploy/doctor.ts +201 -0
- package/packages/agent-settings/src/deploy/index.ts +33 -0
- package/packages/agent-settings/src/deploy/json-pretty.ts +66 -0
- package/packages/agent-settings/src/deploy/lean-ctx-deploy.ts +138 -0
- package/packages/agent-settings/src/deploy/legacy-lock.ts +286 -0
- package/packages/agent-settings/src/deploy/list.ts +135 -0
- package/packages/agent-settings/src/deploy/lock.ts +112 -0
- package/packages/agent-settings/src/deploy/mcp-deploy.ts +175 -0
- package/packages/agent-settings/src/deploy/mcp-inspect.ts +56 -0
- package/packages/agent-settings/src/deploy/mcp-merge.ts +164 -0
- package/packages/agent-settings/src/deploy/mcp-render.ts +80 -0
- package/packages/agent-settings/src/deploy/mcp-source.ts +43 -0
- package/packages/agent-settings/src/deploy/profile.ts +296 -0
- package/packages/agent-settings/src/deploy/settings.ts +65 -0
- package/packages/agent-settings/src/global-agents.ts +230 -0
- package/packages/agent-settings/src/global-surface-sweep.ts +2179 -0
- package/packages/agent-settings/src/kimi-hooks.ts +455 -0
- package/packages/agent-settings/src/opencode-hooks.ts +76 -0
- package/packages/agent-settings/src/surface-policy.ts +441 -0
- package/packages/agent-settings/surface-policy.json +20 -0
- package/packages/agent-skills/assets/code-review/SKILL.md +100 -0
- package/packages/agent-skills/assets/codebase-design/SKILL.md +98 -0
- package/packages/agent-skills/assets/codebase-design/references/DEEPENING.md +37 -0
- package/packages/agent-skills/assets/codebase-design/references/DESIGN-IT-TWICE.md +44 -0
- package/packages/agent-skills/assets/codebase-design/references/TESTABILITY.md +29 -0
- package/packages/agent-skills/assets/debug-issue/SKILL.md +40 -0
- package/packages/agent-skills/assets/diagnosing-bugs/SKILL.md +100 -0
- package/packages/agent-skills/assets/diagnosing-bugs/references/FEEDBACK-LOOP-TACTICS.md +34 -0
- package/packages/agent-skills/assets/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/packages/agent-skills/assets/domain-modeling/SKILL.md +86 -0
- package/packages/agent-skills/assets/domain-modeling/references/ADR-FORMAT.md +47 -0
- package/packages/agent-skills/assets/domain-modeling/references/CONTEXT-FORMAT.md +60 -0
- package/packages/agent-skills/assets/explore-codebase/SKILL.md +41 -0
- package/packages/agent-skills/assets/handoff/SKILL.md +28 -0
- package/packages/agent-skills/assets/implement/SKILL.md +28 -0
- package/packages/agent-skills/assets/refactor-safely/SKILL.md +44 -0
- package/packages/agent-skills/assets/review-changes/SKILL.md +45 -0
- package/packages/agent-skills/assets/tdd/SKILL.md +49 -0
- package/packages/agent-skills/assets/tdd/references/mocking.md +59 -0
- package/packages/agent-skills/assets/tdd/references/tests.md +77 -0
- package/packages/agent-skills/assets/testing/SKILL.md +54 -0
- package/packages/agent-skills/assets/to-feature/SKILL.md +91 -0
- package/packages/agent-skills/assets/to-feature/references/FEATURE-SPEC-TEMPLATE.md +88 -0
- package/packages/agent-skills/assets/to-workitems/SKILL.md +90 -0
- package/packages/agent-skills/assets/to-workitems/references/AZURE-DEVOPS-HIERARCHY.md +118 -0
- package/packages/agent-skills/assets/to-workitems/references/TICKET-TEMPLATES.md +70 -0
- package/packages/agent-skills/assets/wayfinder/SKILL.md +100 -0
- package/packages/agent-skills/assets/wayfinder/references/TEMPLATES.md +35 -0
- package/packages/agent-skills/assets/wayfinder/references/TICKET-TYPES.md +8 -0
- package/packages/agent-skills/deploy-profile.json +9 -0
- package/packages/agent-skills/deploy-profile.schema.json +45 -0
- package/packages/agent-skills/dist/deploy.d.ts +27 -0
- package/packages/agent-skills/dist/deploy.d.ts.map +1 -0
- package/packages/agent-skills/dist/deploy.js +186 -0
- package/packages/agent-skills/dist/deploy.js.map +1 -0
- package/packages/agent-skills/dist/doctor.d.ts +24 -0
- package/packages/agent-skills/dist/doctor.d.ts.map +1 -0
- package/packages/agent-skills/dist/doctor.js +141 -0
- package/packages/agent-skills/dist/doctor.js.map +1 -0
- package/packages/agent-skills/dist/fs-utils.d.ts +8 -0
- package/packages/agent-skills/dist/fs-utils.d.ts.map +1 -0
- package/packages/agent-skills/dist/fs-utils.js +40 -0
- package/packages/agent-skills/dist/fs-utils.js.map +1 -0
- package/packages/agent-skills/dist/index.d.ts +8 -0
- package/packages/agent-skills/dist/index.d.ts.map +1 -0
- package/packages/agent-skills/dist/index.js +8 -0
- package/packages/agent-skills/dist/index.js.map +1 -0
- package/packages/agent-skills/dist/legacy-lock.d.ts +44 -0
- package/packages/agent-skills/dist/legacy-lock.d.ts.map +1 -0
- package/packages/agent-skills/dist/legacy-lock.js +121 -0
- package/packages/agent-skills/dist/legacy-lock.js.map +1 -0
- package/packages/agent-skills/dist/list.d.ts +23 -0
- package/packages/agent-skills/dist/list.d.ts.map +1 -0
- package/packages/agent-skills/dist/list.js +75 -0
- package/packages/agent-skills/dist/list.js.map +1 -0
- package/packages/agent-skills/dist/manifest.d.ts +15 -0
- package/packages/agent-skills/dist/manifest.d.ts.map +1 -0
- package/packages/agent-skills/dist/manifest.js +57 -0
- package/packages/agent-skills/dist/manifest.js.map +1 -0
- package/packages/agent-skills/dist/profile.d.ts +41 -0
- package/packages/agent-skills/dist/profile.d.ts.map +1 -0
- package/packages/agent-skills/dist/profile.js +86 -0
- package/packages/agent-skills/dist/profile.js.map +1 -0
- package/packages/agent-skills/dist/skill-config.d.ts +24 -0
- package/packages/agent-skills/dist/skill-config.d.ts.map +1 -0
- package/packages/agent-skills/dist/skill-config.js +68 -0
- package/packages/agent-skills/dist/skill-config.js.map +1 -0
- package/packages/agent-skills/dist/skill-meta.d.ts +17 -0
- package/packages/agent-skills/dist/skill-meta.d.ts.map +1 -0
- package/packages/agent-skills/dist/skill-meta.js +67 -0
- package/packages/agent-skills/dist/skill-meta.js.map +1 -0
- package/packages/agent-skills/package.json +31 -0
- package/packages/agent-skills/src/deploy.ts +222 -0
- package/packages/agent-skills/src/doctor.ts +178 -0
- package/packages/agent-skills/src/fs-utils.ts +40 -0
- package/packages/agent-skills/src/index.ts +29 -0
- package/packages/agent-skills/src/legacy-lock.ts +152 -0
- package/packages/agent-skills/src/list.ts +94 -0
- package/packages/agent-skills/src/manifest.ts +66 -0
- package/packages/agent-skills/src/profile.ts +128 -0
- package/packages/agent-skills/src/skill-config.ts +75 -0
- package/packages/agent-skills/src/skill-meta.ts +78 -0
- package/packages/agent-skills/tsconfig.build.json +13 -0
- package/packages/agent-skills/tsconfig.json +23 -0
- package/packages/azdo/README.md +111 -0
- package/packages/azdo/package.json +21 -0
- package/packages/azdo/src/azdo-pl.ts +275 -0
- package/packages/azdo/src/azdo-pr-review.ts +160 -0
- package/packages/azdo/src/azdo-pr.ts +289 -0
- package/packages/azdo/src/azdo-repo-doctor.ts +839 -0
- package/packages/azdo/src/azdo-wit.ts +145 -0
- package/packages/azdo/src/cli.ts +251 -0
- package/packages/azdo/src/lib/agent-identity.ts +198 -0
- package/packages/azdo/src/lib/agent-token.ts +167 -0
- package/packages/azdo/src/lib/client.ts +259 -0
- package/packages/azdo/src/lib/graph-identity.ts +153 -0
- package/packages/azdo/src/lib/validate-pr-metadata.ts +57 -0
- package/packages/azdo/src/mcp-server.ts +209 -0
- package/packages/azdo/src/tool-dispatch.ts +204 -0
- package/packages/azdo/tsconfig.json +13 -0
- package/packages/fleet/jobs/git-maintain/src/main.ts +588 -0
- package/packages/fleet/manifest.json +207 -0
- package/packages/fleet/manifest.schema.json +283 -0
- package/packages/fleet/src/default-agent-file.ts +144 -0
- package/packages/fleet/src/install-adl-package.ts +178 -0
- package/packages/fleet/src/install-embedding-model.ts +412 -0
- package/packages/fleet/src/launch-agents.ts +649 -0
- package/packages/fleet/src/managed-settings.ts +278 -0
- package/packages/fleet/src/scratch-reap.ts +601 -0
- package/packages/fleet/src/vscode-settings.ts +705 -0
- package/packages/fleet/systemd/adl-azure-agent-update.service +13 -0
- package/packages/fleet/systemd/adl-azure-agent-update.timer +10 -0
- package/packages/repo-controls/AGENTS.md +96 -0
- package/packages/repo-controls/CLAUDE.md +1 -0
- package/packages/repo-controls/LICENSE +20 -0
- package/packages/repo-controls/README.md +493 -0
- package/packages/repo-controls/assets/enable-integration-auto-complete.mjs +79 -0
- package/packages/repo-controls/assets/promote.ts +371 -0
- package/packages/repo-controls/assets/version-bump.sh +189 -0
- package/packages/repo-controls/azure-pipelines.yml +274 -0
- package/packages/repo-controls/bin/adl-repo-controls.ts +10 -0
- package/packages/repo-controls/bunfig.toml +58 -0
- package/packages/repo-controls/package/adl-compliance/AGENTS.md +163 -0
- package/packages/repo-controls/package/adl-compliance/CLAUDE.md +1 -0
- package/packages/repo-controls/package/adl-compliance/conftest.py +78 -0
- package/packages/repo-controls/package/adl-compliance/pyproject.toml +31 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/__init__.py +50 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +98 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/__init__.py +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/check.py +210 -0
- 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
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/fixtures/adr-lifecycle-clean/docs/architecture/overview.md +8 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +127 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/check.py +91 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/AGENTS.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/CLAUDE.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/architecture/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/compliance/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/decisions/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/index.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/operations/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/research/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/stray-root-file.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/totally-made-up/nonsense.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +106 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +291 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/clean/backend/clean.rs +1 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/violation/backend/escaped.rs +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/fixtures/violation/backend/raw.rs +1 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +193 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/check.py +140 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/fixtures/index-updated-clean/docs/architecture/foo.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/fixtures/index-updated-clean/docs/architecture/index.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/fixtures/index-updated-violation/docs/architecture/foo.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/fixtures/index-updated-violation/docs/architecture/index.md +9 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/index_updated/test_check.py +98 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +378 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +192 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-clean/docs/index.md +14 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-clean/docs/one.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-clean/docs/two.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-clean/docs-knowledge-indexes.yaml +20 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-duplicate/docs/index.md +15 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-duplicate/docs/one.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-duplicate/docs/two.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-duplicate/docs-knowledge-indexes.yaml +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-missing-entry/docs/index.md +13 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-missing-entry/docs/one.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-missing-entry/docs/two.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-missing-entry/docs-knowledge-indexes.yaml +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +102 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/check.py +387 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-bad-date/plans/LEDGER.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-clean/plans/LEDGER.md +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-empty-table/plans/LEDGER.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-long-event/plans/LEDGER.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/fixtures/ledger-violation/plans/LEDGER.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +427 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/__init__.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/check.py +84 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/fixtures/markdown-structure-bad-fence/docs/valid.md +5 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/fixtures/markdown-structure-bad-frontmatter/docs/valid.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/fixtures/markdown-structure-clean/docs/valid.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/markdown_ast/test_check.py +126 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +210 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +119 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +17 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +8 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +49 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +159 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/check.py +578 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/architecture/backend/crate-overview.md +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/architecture/team/team-overview.md +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/compliance/controls/control-matrix.md +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/compliance/controls/control-matrix.yaml +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-clean/docs/research/benchmarks/note.md +24 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/backend/crate-overview.md +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/product/stable-delivery.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/product/stable-recommendation.md +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/product/target-narration.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/architecture/team/team-overview.md +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/compliance/controls/control-matrix.md +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/compliance/controls/control-matrix.yaml +17 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/fixtures/semantics-violations/docs/research/benchmarks/bad-research.md +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +461 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/__init__.py +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/check.py +124 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/.workflows/AGENTS.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/.workflows/CLAUDE.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/CLAUDE.md +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/INVARIANTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/bad-pointer/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/bad-pointer/CLAUDE.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/docs/AGENTS.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/docs/CLAUDE.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/missing-pair/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/owned/AGENTS.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/fixtures/owned/CLAUDE.md +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/agents_layout/test_check.py +116 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/ci_paths/__init__.py +13 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/ci_paths/check.py +380 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/ci_paths/test_check.py +274 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +227 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +6 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +6 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +138 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +240 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/fixtures/markdown-trees-clean/backend/AGENTS.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/fixtures/markdown-trees-clean/docs/page.md +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/fixtures/markdown-trees-stray/backend/notes.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/fixtures/markdown-trees-stray/docs/page.md +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +220 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/__init__.py +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +225 -0
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +330 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +240 -0
- 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
- 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
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/mobile/assets/images/icon.png +1 -0
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/public/pwa/icon-192.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-allowed/frontend/resources/product.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-stray/apps/legacy/file.ts +1 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/fixtures/placement-stray/frontend/unapproved/screenshot.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +230 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plan_metadata.py +53 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/check.py +438 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-clean/plans/AGENTS.md +1 -0
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-clean/plans/templates/feature.md +1 -0
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +461 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/__init__.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/check.py +62 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/fixtures/migration-filenames/backend/crates/demo/NotAMigration.sql +1 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/profile_data/test_check.py +116 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/__init__.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +188 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/docs/README.md +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-broken/docs/architecture/product/links.md +20 -0
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/docs/README.md +8 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/fixtures/link-targets-clean/docs/architecture/product/links.md +20 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/test_check.py +166 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/__init__.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +135 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.agents/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.changeset/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.claude/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.code-review-graph/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.code-review-graph_old/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.codex/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.cursor/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.cursorrules +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.dockerignore +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.docs/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.donors/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.gitattributes +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.kimi-code/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.lfsconfig +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.mcp.json +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.opencode/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/.workflows/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/AGENTS.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/CHANGELOG.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/CLAUDE-INVARIANTS.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/CLAUDE.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/INDEPENDENT-VERIFICATION.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/INVARIANTS.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/LICENSE +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/NOTICE +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/README.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/RELEASE.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/VERSION +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/backend/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/compliance/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/dev/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/docker/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/docs/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/frontend/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/infra/declared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/justfile +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/opencode.jsonc +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/rule-tests/undeclared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/rules/undeclared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/unapproved-root/undeclared.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/fixtures/undeclared-root-file.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +122 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +290 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/.plans/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/.specs/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/.workflows/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/CHANGELOG.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/CLAUDE.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/INDEPENDENT-VERIFICATION.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/INVARIANTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/README.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/RELEASE.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/STRAY.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/docs/AGENTS.md +3 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-clean/frontend/README.md +3 -0
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-missing-guide/AGENTS.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/fixtures/root-markdown-missing-guide/README.md +1 -0
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +329 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +127 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +163 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/__init__.py +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/__init__.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +169 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/attribute-without-conversion/.gitattributes +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/attribute-without-conversion/large file.bin +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/clean/.gitattributes +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/clean/large file.bin +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/clean/small.txt +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/missing-filter/large file.bin +0 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/unmatched-extension/.gitattributes +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/unmatched-extension/payload.dat +0 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +133 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/__init__.py +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/check.py +129 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/fixtures/disjoint/gate-registry.yaml +13 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/fixtures/empty/gate-registry.yaml +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/fixtures/overlapping/gate-registry.yaml +13 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/pipeline/phase_disjoint/test_check.py +109 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/__init__.py +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/__init__.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/check.py +149 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/fixtures/clean/docs/readme.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/fixtures/relevant/VERSION +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/changeset_plan/test_check.py +151 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/__init__.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/check.py +202 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/.workflows/changesets/package.json +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/.workflows/package.json +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/CHANGELOG.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/aligned/VERSION +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/.workflows/changesets/package.json +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/.workflows/package.json +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/CHANGELOG.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/fixtures/mismatched/VERSION +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/release/version_release/test_check.py +162 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/__init__.py +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/check.py +103 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/elsewhere/loose-git.sh +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/fixtures/no-banned-commands/elsewhere/loose-grep.sh +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/banned_commands/test_check.py +117 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/__init__.py +13 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +265 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/fixtures/ignored-paths/keep.log +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/fixtures/ignored-paths/src/main.rs +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +180 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/__init__.py +12 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/check.py +84 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/fixtures/license-declared-clean/LICENSE +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/fixtures/license-declared-mismatch/LICENSE +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/fixtures/license-declared-missing/README.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/license_declared/test_check.py +66 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/__init__.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +167 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/Cargo.lock +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/Cargo.toml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/rust-toolchain.toml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/backend/src/main.rs +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/clean/frontend/bun.lock +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/Cargo.lock +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/Cargo.toml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/rust-toolchain.toml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/backend/src/main.rs +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/fixtures/empty-bun-lock/frontend/bun.lock +0 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +109 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +483 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/__init__.py +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/ast_grep.py +199 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/batch.py +52 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +303 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +106 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +99 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/errors.py +32 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/finding.py +65 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/models.py +40 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/receipt.py +63 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/scope.py +82 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/verdict.py +161 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/__init__.py +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +131 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.toml +30 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +65 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +791 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.schema.yaml +176 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +791 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/grants-registry.yaml +112 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/grants.py +129 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +281 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +250 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/severity-policy.yaml +114 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/providers/__init__.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +371 -0
- package/packages/repo-controls/package/adl-compliance/uv.lock +199 -0
- package/packages/repo-controls/package.json +33 -0
- package/packages/repo-controls/scripts/hooks/commit-msg +63 -0
- package/packages/repo-controls/scripts/hooks/lib/hook-log.sh +62 -0
- package/packages/repo-controls/scripts/hooks/post-checkout +15 -0
- package/packages/repo-controls/scripts/hooks/post-commit +18 -0
- package/packages/repo-controls/scripts/hooks/pre-commit +82 -0
- package/packages/repo-controls/scripts/hooks/pre-push +144 -0
- package/packages/repo-controls/src/azdo-push.ts +463 -0
- package/packages/repo-controls/src/azure-devops-governance.ts +248 -0
- package/packages/repo-controls/src/azure-devops-remote.ts +61 -0
- package/packages/repo-controls/src/cli.ts +188 -0
- package/packages/repo-controls/src/compliance-config.ts +200 -0
- package/packages/repo-controls/src/config.ts +690 -0
- package/packages/repo-controls/src/constants.ts +97 -0
- package/packages/repo-controls/src/coverage-ratchet.ts +153 -0
- package/packages/repo-controls/src/doc-freshness.ts +172 -0
- package/packages/repo-controls/src/doctor.ts +304 -0
- package/packages/repo-controls/src/findings-ratchet.ts +163 -0
- package/packages/repo-controls/src/gitignore-block.ts +253 -0
- package/packages/repo-controls/src/hook-log.ts +72 -0
- package/packages/repo-controls/src/hook.ts +694 -0
- package/packages/repo-controls/src/install.ts +506 -0
- package/packages/repo-controls/src/integrity.ts +104 -0
- package/packages/repo-controls/src/promote.ts +25 -0
- package/packages/repo-controls/src/runtime.ts +110 -0
- package/packages/repo-controls/src/workflows-drift.ts +106 -0
- package/packages/repo-controls/src/worktree-guard.ts +272 -0
- package/packages/repo-controls/src/worktree-limit.ts +11 -0
- package/packages/repo-controls/tsconfig.json +14 -0
- package/packages/repo-controls/workflows/scripts/release/verify-npm-artifact.ts +119 -0
|
@@ -0,0 +1,690 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { join } from 'node:path'
|
|
3
|
+
import { CONFIG_REL, INSTALL_HINT } from './constants.ts'
|
|
4
|
+
import { MERGE_STRATEGIES, type MergeStrategy } from './promote.ts'
|
|
5
|
+
|
|
6
|
+
export interface StaticCheck {
|
|
7
|
+
label: string
|
|
8
|
+
run: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* There is NO schema version in the config file, deliberately.
|
|
13
|
+
*
|
|
14
|
+
* A `version = N` line in every repository is a second copy of a fact the installed
|
|
15
|
+
* package already owns, free to disagree with it — and it did: a file written in the
|
|
16
|
+
* new shape kept declaring the old one, so readers graded it against the wrong rules
|
|
17
|
+
* and reported five type errors about keys that had been deliberately removed. A
|
|
18
|
+
* per-repo copy is also editable, which makes a schema claim a user preference.
|
|
19
|
+
*
|
|
20
|
+
* The schema is whatever the installed binary writes. The single central record of
|
|
21
|
+
* which one that is lives in `.workflows/repo-controls.lock.json` as the package
|
|
22
|
+
* version, and `doctor` compares it against the running binary.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* What a repository's coverage summary IS, and how that repository makes one.
|
|
27
|
+
*
|
|
28
|
+
* The gate validates the artifact; it never produces it. `produce` is recorded
|
|
29
|
+
* so the repository states its own command in one place rather than in a
|
|
30
|
+
* justfile, a package.json script and a pipeline step that can disagree — the
|
|
31
|
+
* gate reads it to tell a human what to run, not to run it.
|
|
32
|
+
*
|
|
33
|
+
* Everything here was a hardcoded literal in the bundled coverage scripts,
|
|
34
|
+
* where `sourceRoots` alone appeared in nine places across five files. A
|
|
35
|
+
* repository whose trees are named anything else was graded against
|
|
36
|
+
* enact-m5's, which is why this moved into config.
|
|
37
|
+
*/
|
|
38
|
+
export interface CoverageConfig {
|
|
39
|
+
summary: string
|
|
40
|
+
produce: string
|
|
41
|
+
sourceRoots: string[]
|
|
42
|
+
srcTestRatioGlobs: string[]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A findings ratchet's floor, and the repo-owned commands that measure it.
|
|
47
|
+
*
|
|
48
|
+
* NO TOOL NAME IS EVER WRITTEN HERE, deliberately (owner correction,
|
|
49
|
+
* 2026-09-15: "the REPO declares what they will use for linting and dead
|
|
50
|
+
* code"). `counters` is a name -> command map the repository authors itself
|
|
51
|
+
* — `lint = "just check-biome-lint"` in enact-m5, `lint = "cargo clippy
|
|
52
|
+
* --message-format=json | ..."` in a Rust repo, `dead-code = "ruff check
|
|
53
|
+
* --output-format=json | ..."` in a Python one. The package knows only the
|
|
54
|
+
* name and the command, the same division `pre_push.static_checks` already
|
|
55
|
+
* draws for a repo-authored shell command it never interprets.
|
|
56
|
+
*
|
|
57
|
+
* The command's OUTPUT is the one place a contract exists, and it names no
|
|
58
|
+
* tool either: one repository-relative path per line on stdout, one line
|
|
59
|
+
* per finding location, for a counter that ran to completion. Exit 0 means
|
|
60
|
+
* "ran; stdout is a valid (possibly empty) path list"; any other exit is
|
|
61
|
+
* the counter failing to run at all, never zero findings and never a pass
|
|
62
|
+
* (`findings-ratchet.ts`'s own header states this in
|
|
63
|
+
* full). `floor` is a repository-relative path, not resolved through the
|
|
64
|
+
* Python compliance package's `<compliance>` tree placeholder — this gate
|
|
65
|
+
* is TypeScript, outside that package, and reads the path directly.
|
|
66
|
+
*/
|
|
67
|
+
export interface FindingsConfig {
|
|
68
|
+
floor: string
|
|
69
|
+
counters: Record<string, string>
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface RepoControlsConfig {
|
|
73
|
+
branches: { protected: string[]; prefixes: string[] }
|
|
74
|
+
preCommit: { staticChecks: StaticCheck[]; stagedCoverage: boolean; docFreshness: boolean; compliance: boolean }
|
|
75
|
+
commitMsg: { staticChecks: StaticCheck[] }
|
|
76
|
+
release: { source: string; target: string; mergeStrategy: MergeStrategy; preBump: string[] }
|
|
77
|
+
postCommit: { staticChecks: StaticCheck[] }
|
|
78
|
+
prePush: {
|
|
79
|
+
coverageRatchet: boolean
|
|
80
|
+
findingsRatchet: boolean
|
|
81
|
+
staticChecks: StaticCheck[]
|
|
82
|
+
exportLinks: string[]
|
|
83
|
+
remote: string
|
|
84
|
+
}
|
|
85
|
+
coverage: CoverageConfig
|
|
86
|
+
findings: FindingsConfig
|
|
87
|
+
integrity: { watched: string[] }
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Seeded by `install` as the `[controls]` table of the shared `adl-config.toml`
|
|
92
|
+
* (repo root) when that table is missing; user-owned afterwards. This text is
|
|
93
|
+
* also the exact byte span `install`/`uninstall` append/splice — see
|
|
94
|
+
* `extractTableSpan`/`removeTableSpan` — so it must start with the
|
|
95
|
+
* `[controls]` header line and never contain another line starting with `[`.
|
|
96
|
+
*/
|
|
97
|
+
/**
|
|
98
|
+
* The `[controls]` attributes `install` SCAFFOLDS, each independently.
|
|
99
|
+
*
|
|
100
|
+
* Install wires the hooks; it does not arm a gate. Only the three attributes below
|
|
101
|
+
* are written, and only when absent — an attribute already in the file is never
|
|
102
|
+
* rewritten, reordered or reformatted, whatever its value. Everything else
|
|
103
|
+
* (`pre_commit.*`, `pre_push.coverage_ratchet`, `pre_push.findings_ratchet`,
|
|
104
|
+
* `pre_push.static_checks`) is omitted and defaults to off, so a first install
|
|
105
|
+
* changes what no `git push` or `git commit` does until somebody opts in.
|
|
106
|
+
*
|
|
107
|
+
* `branches` and `pre_push.remote` are seeded rather than omitted because they are
|
|
108
|
+
* not gates — they are the vocabulary the gates are phrased in — and because
|
|
109
|
+
* `pre-push` reads their env vars with `${VAR:?}`, which aborts on an empty value.
|
|
110
|
+
* "No branch policy" therefore cannot be spelled as an empty list.
|
|
111
|
+
*
|
|
112
|
+
* Granularity is the top-level key inside `[controls]`: an inline table is one
|
|
113
|
+
* attribute, because editing inside one means rewriting bytes the user owns.
|
|
114
|
+
*/
|
|
115
|
+
export interface SeededAttribute {
|
|
116
|
+
key: string
|
|
117
|
+
text: string
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export const SEEDED_ATTRIBUTES: SeededAttribute[] = [
|
|
121
|
+
{
|
|
122
|
+
key: 'branches',
|
|
123
|
+
text: `
|
|
124
|
+
# pre-push refuses to push while one of these branches is checked out; prefixes: <prefix>/<kebab>.
|
|
125
|
+
branches = { protected = ["main", "integration"], prefixes = ["feat", "fix", "docs", "chore"] }
|
|
126
|
+
`,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
key: 'pre_push',
|
|
130
|
+
text: `
|
|
131
|
+
# Remote that pre-push and azdo-push push to and read status from.
|
|
132
|
+
#
|
|
133
|
+
# Every gate is OFF until its key is added here: installing wires the hooks and arms
|
|
134
|
+
# nothing. Opt in by adding pre_commit (static_checks, staged_coverage, doc_freshness) or the
|
|
135
|
+
# remaining pre_push keys (coverage_ratchet, findings_ratchet, static_checks). README,
|
|
136
|
+
# "Configuration", lists each one. Deliberately no example assignments in this comment — commented TOML
|
|
137
|
+
# is indistinguishable from a real setting to find-and-replace, in an editor or a script.
|
|
138
|
+
pre_push = { remote = "origin" }
|
|
139
|
+
`,
|
|
140
|
+
},
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Seeded by `install` as the `[controls]` table of the shared `adl-config.toml`
|
|
145
|
+
* when that table is missing; user-owned afterwards. When the table already exists,
|
|
146
|
+
* install scaffolds only the individual `SEEDED_ATTRIBUTES` it lacks. This text is
|
|
147
|
+
* also the exact byte span `install`/`uninstall` append/splice — see
|
|
148
|
+
* `extractTableSpan`/`removeTableSpan` — so it must start with the `[controls]`
|
|
149
|
+
* header line and never contain another line starting with `[`.
|
|
150
|
+
*/
|
|
151
|
+
export const DEFAULT_CONFIG_TEXT = `[controls]${SEEDED_ATTRIBUTES.map((a) => a.text).join('')}`
|
|
152
|
+
|
|
153
|
+
const escapeRegExp = (text: string): string => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Every table this package writes and splices as its own independent unit.
|
|
157
|
+
*
|
|
158
|
+
* `controls.compliance` is deliberately nested under `controls` rather than being a
|
|
159
|
+
* root-level `[compliance]`: `adl hook` rejects the whole shared document on an
|
|
160
|
+
* unrecognized ROOT key, so a root `[compliance]` turned every one of its runs into
|
|
161
|
+
* a decode error in any repo carrying it. Nesting keeps this package's config inside
|
|
162
|
+
* the one root key it already owns, which needs no coordination with the other two
|
|
163
|
+
* tools — the same "no tool parses another tool's table" rule the file is built on.
|
|
164
|
+
*/
|
|
165
|
+
export const OWNED_TABLES = ['controls', 'controls.compliance'] as const
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Locates a table's exact byte span in a shared `adl-config.toml`: from the line
|
|
169
|
+
* matching `^\[<tableName>\]\s*$` to the next line starting with `[` at column 0
|
|
170
|
+
* that is neither `[<tableName>]` nor a dotted sub-table `[<tableName>.*]` of it
|
|
171
|
+
* (so `[controls.compliance]` through `[controls.compliance.trees]` splice as one
|
|
172
|
+
* span) — except that a sub-table listed in `OWNED_TABLES` terminates the span
|
|
173
|
+
* instead, so parent and child stay independently spliceable. Known limitation: a
|
|
174
|
+
* hand-edited block containing a multi-line string whose content starts a line with
|
|
175
|
+
* `[` would confuse this — this tool never writes such content itself.
|
|
176
|
+
*/
|
|
177
|
+
function findTableSpan(text: string, tableName: string): { start: number; end: number } | null {
|
|
178
|
+
const starts: number[] = [0]
|
|
179
|
+
for (let i = 0; i < text.length; i++) if (text[i] === '\n') starts.push(i + 1)
|
|
180
|
+
const lines = text.split('\n').slice(0, starts.length)
|
|
181
|
+
const lineStart = (index: number): number => starts[index] ?? text.length
|
|
182
|
+
|
|
183
|
+
const escaped = escapeRegExp(tableName)
|
|
184
|
+
const headerRe = new RegExp(`^\\[${escaped}\\]\\s*$`)
|
|
185
|
+
const subTableRe = new RegExp(`^\\[${escaped}\\.`)
|
|
186
|
+
// A dotted sub-table that this package manages as its own independent span
|
|
187
|
+
// (`[controls.compliance]` living inside `[controls]`) must TERMINATE the parent's
|
|
188
|
+
// span rather than be swallowed by it. Without this, appending compliance to a repo
|
|
189
|
+
// that already has `[controls]` would change `[controls]`'s own recorded bytes, and
|
|
190
|
+
// the next install would read that as drift and refuse — an upgrade path that fails
|
|
191
|
+
// on every already-installed repo.
|
|
192
|
+
const nestedRes = OWNED_TABLES.filter((name) => name !== tableName && name.startsWith(`${tableName}.`)).map(
|
|
193
|
+
(name) => new RegExp(`^\\[${escapeRegExp(name)}\\]\\s*$|^\\[${escapeRegExp(name)}\\.`),
|
|
194
|
+
)
|
|
195
|
+
const isSeparatelyOwned = (line: string): boolean => nestedRes.some((re) => re.test(line))
|
|
196
|
+
const isSameTableLine = (line: string): boolean => (headerRe.test(line) || subTableRe.test(line)) && !isSeparatelyOwned(line)
|
|
197
|
+
|
|
198
|
+
const startLine = lines.findIndex((line) => headerRe.test(line))
|
|
199
|
+
if (startLine === -1) return null
|
|
200
|
+
|
|
201
|
+
let endLine = starts.length
|
|
202
|
+
for (let index = startLine + 1; index < starts.length; index++) {
|
|
203
|
+
const line = lines[index] ?? ''
|
|
204
|
+
if (/^\[/.test(line) && !isSameTableLine(line)) {
|
|
205
|
+
endLine = index
|
|
206
|
+
break
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Trim blank lines immediately before the boundary: they separate this table from
|
|
210
|
+
// whatever follows (or end-of-file), not content the table itself owns — so appending
|
|
211
|
+
// another table afterwards never retroactively changes this table's own byte span.
|
|
212
|
+
let contentEnd = endLine
|
|
213
|
+
while (contentEnd > startLine + 1 && (lines[contentEnd - 1] ?? '').trim() === '') contentEnd--
|
|
214
|
+
return { start: lineStart(startLine), end: contentEnd < starts.length ? lineStart(contentEnd) : text.length }
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** The exact bytes of a table's span (header through its last line, including dotted sub-tables), or `null` if absent. */
|
|
218
|
+
export function extractTableSpan(text: string, tableName: string): string | null {
|
|
219
|
+
const span = findTableSpan(text, tableName)
|
|
220
|
+
return span === null ? null : text.slice(span.start, span.end)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* `text` with `addition` inserted at the END of a table's span — after its last line,
|
|
225
|
+
* before whatever follows. Used to scaffold a single missing attribute into a table
|
|
226
|
+
* this package did not create: every existing byte, including comments, ordering and
|
|
227
|
+
* formatting, is preserved exactly, because nothing is parsed and re-serialized.
|
|
228
|
+
* Returns `text` unchanged when the table is absent.
|
|
229
|
+
*/
|
|
230
|
+
export function appendToTableSpan(text: string, tableName: string, addition: string): string {
|
|
231
|
+
const span = findTableSpan(text, tableName)
|
|
232
|
+
if (span === null) return text
|
|
233
|
+
const before = text.slice(0, span.end)
|
|
234
|
+
const separator = before.endsWith('\n') ? '' : '\n'
|
|
235
|
+
return `${before}${separator}${addition}${text.slice(span.end)}`
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Keys this package once wrote and now owns the removal of. `version` was a per-repo
|
|
240
|
+
* copy of a fact the installed package already owns; it drifted, and a stale copy made
|
|
241
|
+
* every reader grade the file against the wrong rules. Install strips it, because it
|
|
242
|
+
* was never a user setting to preserve.
|
|
243
|
+
*/
|
|
244
|
+
export const RETIRED_ATTRIBUTES = ['version'] as const
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* `text` with `key`'s assignment line removed from inside a table's span, along with a
|
|
248
|
+
* blank line left immediately after it. Every other byte is untouched — nothing is
|
|
249
|
+
* parsed and re-serialized. Returns `text` unchanged when the table or key is absent.
|
|
250
|
+
*/
|
|
251
|
+
export function removeFromTableSpan(text: string, tableName: string, key: string): string {
|
|
252
|
+
const span = findTableSpan(text, tableName)
|
|
253
|
+
if (span === null) return text
|
|
254
|
+
const body = text.slice(span.start, span.end)
|
|
255
|
+
const assignment = new RegExp(`^${escapeRegExp(key)}\\s*=.*\\n(\\n)?`, 'm')
|
|
256
|
+
if (!assignment.test(body)) return text
|
|
257
|
+
return text.slice(0, span.start) + body.replace(assignment, '') + text.slice(span.end)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/** `text` with a table's span removed (a no-op if there is none); other tables are untouched. */
|
|
261
|
+
export function removeTableSpan(text: string, tableName: string): string {
|
|
262
|
+
const span = findTableSpan(text, tableName)
|
|
263
|
+
if (span === null) return text
|
|
264
|
+
let before = text.slice(0, span.start)
|
|
265
|
+
const after = text.slice(span.end)
|
|
266
|
+
if (before.endsWith('\n\n')) before = before.slice(0, -1)
|
|
267
|
+
return before + after
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** The exact bytes of the `[controls]` table, or `null` if absent. */
|
|
271
|
+
export function extractControlsSpan(text: string): string | null {
|
|
272
|
+
return extractTableSpan(text, 'controls')
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const BRANCH_RE = /^[a-z0-9][a-z0-9/-]*$/
|
|
276
|
+
const PREFIX_RE = /^[a-z0-9][a-z0-9-]*$/
|
|
277
|
+
const LABEL_RE = /^[a-z0-9][a-z0-9-]*$/
|
|
278
|
+
const REMOTE_RE = /^\S+$/
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Where the ratchet looks when a repository does not say otherwise.
|
|
282
|
+
*
|
|
283
|
+
* This was a literal in five places (`coverage/paths.ts`, `command.ts`,
|
|
284
|
+
* `full.ts`, `check-floors.ts`, `doctor.ts`), which is why enact-extensions —
|
|
285
|
+
* tracking `.coverage/summary.json` and gitignoring `coverage/` — could not
|
|
286
|
+
* push at all. The non-JavaScript override is retained as an executable case
|
|
287
|
+
* in `tests/config.test.ts`.
|
|
288
|
+
*/
|
|
289
|
+
const DEFAULT_COVERAGE_SUMMARY = 'coverage/coverage-summary.json'
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Where a findings ratchet's floor lives when a repository does not say
|
|
293
|
+
* otherwise: `compliance/ratchets/`, the estate's settled location for a
|
|
294
|
+
* consumer-owned number that may fall (owner ruling 2026-09-15, "grants are
|
|
295
|
+
* basically ratchets" — `LAY-004`'s `compliance/ratchets/
|
|
296
|
+
* LAY-004-over-limit-directory.yaml` is the same convention for a Python
|
|
297
|
+
* compliance-package row). This gate is not a registry row, so the file is
|
|
298
|
+
* named by SUBJECT rather than a `<GATE-ID>-<name>` this package has no id
|
|
299
|
+
* for — see `findings-ratchet.ts`'s own header.
|
|
300
|
+
*/
|
|
301
|
+
const DEFAULT_FINDINGS_FLOOR = 'compliance/ratchets/static-analysis-findings.yaml'
|
|
302
|
+
|
|
303
|
+
export type Table = Record<string, unknown>
|
|
304
|
+
export const isTable = (value: unknown): value is Table => typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
305
|
+
|
|
306
|
+
export class Problems {
|
|
307
|
+
readonly list: string[]
|
|
308
|
+
constructor() {
|
|
309
|
+
this.list = []
|
|
310
|
+
}
|
|
311
|
+
add(message: string): void {
|
|
312
|
+
this.list.push(message)
|
|
313
|
+
}
|
|
314
|
+
unknownKeys(table: Table, known: string[], prefix: string): void {
|
|
315
|
+
for (const key of Object.keys(table)) if (!known.includes(key)) this.add(`unknown key: ${prefix}${key}`)
|
|
316
|
+
}
|
|
317
|
+
table(parent: Table, key: string, known: string[]): Table {
|
|
318
|
+
const value = parent[key]
|
|
319
|
+
if (!isTable(value)) {
|
|
320
|
+
this.add(`${key} must be a table`)
|
|
321
|
+
return {}
|
|
322
|
+
}
|
|
323
|
+
this.unknownKeys(value, known, `${key}.`)
|
|
324
|
+
return value
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* A table this package SEEDS but does not require. Absent means "every control in
|
|
328
|
+
* it is off", never an error — installing wires the hooks and arms nothing, so a
|
|
329
|
+
* repository that never opted into a control simply has no key for it. Present but
|
|
330
|
+
* the wrong type is still a hard error, and unknown keys inside it still are too.
|
|
331
|
+
*/
|
|
332
|
+
optionalTable(parent: Table, key: string, known: string[]): Table {
|
|
333
|
+
if (parent[key] === undefined) return {}
|
|
334
|
+
return this.table(parent, key, known)
|
|
335
|
+
}
|
|
336
|
+
/** Absent is the documented default; present-but-not-a-boolean is still an error. */
|
|
337
|
+
optionalBool(table: Table, key: string, name: string, fallback: boolean): boolean {
|
|
338
|
+
if (table[key] === undefined) return fallback
|
|
339
|
+
return this.bool(table, key, name)
|
|
340
|
+
}
|
|
341
|
+
bool(table: Table, key: string, name: string): boolean {
|
|
342
|
+
const value = table[key]
|
|
343
|
+
if (typeof value !== 'boolean') this.add(`${name} must be a boolean`)
|
|
344
|
+
return value === true
|
|
345
|
+
}
|
|
346
|
+
string(table: Table, key: string, name: string, pattern: RegExp): string {
|
|
347
|
+
const value = table[key]
|
|
348
|
+
if (typeof value !== 'string') {
|
|
349
|
+
this.add(`${name} must be a string`)
|
|
350
|
+
return ''
|
|
351
|
+
}
|
|
352
|
+
if (!pattern.test(value)) this.add(`${name} must match ${pattern.source}`)
|
|
353
|
+
return value
|
|
354
|
+
}
|
|
355
|
+
names(table: Table, key: string, name: string, pattern: RegExp): string[] {
|
|
356
|
+
const value = table[key]
|
|
357
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== 'string')) {
|
|
358
|
+
this.add(`${name} must be an array of strings`)
|
|
359
|
+
return []
|
|
360
|
+
}
|
|
361
|
+
if (value.length === 0) this.add(`${name} must not be empty`)
|
|
362
|
+
value.forEach((item: string, index) => {
|
|
363
|
+
if (!pattern.test(item)) this.add(`${name}[${index}] must match ${pattern.source}`)
|
|
364
|
+
})
|
|
365
|
+
return value as string[]
|
|
366
|
+
}
|
|
367
|
+
/** Absent means "take the default"; present but wrong-typed is still a problem. */
|
|
368
|
+
optionalString(table: Table, key: string, name: string, fallback: string): string {
|
|
369
|
+
const value = table[key]
|
|
370
|
+
if (value === undefined) return fallback
|
|
371
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
372
|
+
this.add(`${name} must be a non-empty string`)
|
|
373
|
+
return fallback
|
|
374
|
+
}
|
|
375
|
+
return value
|
|
376
|
+
}
|
|
377
|
+
/** As above, for a list. An explicitly empty list is a problem, not a default:
|
|
378
|
+
* writing `[]` reads as "grade nothing", which is never what anyone means. */
|
|
379
|
+
optionalNames(table: Table, key: string, name: string, fallback: string[]): string[] {
|
|
380
|
+
const value = table[key]
|
|
381
|
+
if (value === undefined) return fallback
|
|
382
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== 'string')) {
|
|
383
|
+
this.add(`${name} must be an array of strings`)
|
|
384
|
+
return fallback
|
|
385
|
+
}
|
|
386
|
+
if (value.length === 0) {
|
|
387
|
+
this.add(`${name} must not be empty`)
|
|
388
|
+
return fallback
|
|
389
|
+
}
|
|
390
|
+
return value as string[]
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export function parseConfig(text: string): RepoControlsConfig {
|
|
395
|
+
let raw: unknown
|
|
396
|
+
try {
|
|
397
|
+
raw = Bun.TOML.parse(text)
|
|
398
|
+
} catch (error) {
|
|
399
|
+
throw new Error(`${CONFIG_REL} is not valid TOML: ${(error as Error).message}`)
|
|
400
|
+
}
|
|
401
|
+
const root = raw as Table
|
|
402
|
+
// Root carries other tools' tables ([hooks]/[rules]/[repo] from adl hook, [skills] from
|
|
403
|
+
// adl-extensions, a bare tool-agnostic `version`) — opaque bytes this package never inspects.
|
|
404
|
+
if (!isTable(root.controls)) throw new Error(`${CONFIG_REL} has no [controls] table — ${INSTALL_HINT}`)
|
|
405
|
+
const controls = root.controls
|
|
406
|
+
|
|
407
|
+
const problems = new Problems()
|
|
408
|
+
// `compliance` is accepted and ignored here: it is this package's config too, but it
|
|
409
|
+
// has its own schema and its own strict decoder in `compliance-config.ts`. Listing it
|
|
410
|
+
// keeps a typo elsewhere in `[controls]` failing loud without this decoder having to
|
|
411
|
+
// know anything about the compliance schema.
|
|
412
|
+
problems.unknownKeys(controls, ['branches', 'pre_commit', 'pre_push', 'commit_msg', 'post_commit', 'compliance', 'coverage', 'findings', 'integrity', 'release'], '')
|
|
413
|
+
|
|
414
|
+
const branches = problems.table(controls, 'branches', ['protected', 'prefixes'])
|
|
415
|
+
// `branches` and `pre_push.remote` are REQUIRED: install always seeds them, and
|
|
416
|
+
// `pre-push` reads their env vars with `${VAR:?}`, which aborts on an empty value —
|
|
417
|
+
// so "no branch policy" cannot be spelled as an empty list. Everything else is
|
|
418
|
+
// optional and defaults to off.
|
|
419
|
+
const preCommit = problems.optionalTable(controls, 'pre_commit', ['static_checks', 'staged_coverage', 'doc_freshness', 'compliance'])
|
|
420
|
+
const prePush = problems.table(controls, 'pre_push', ['coverage_ratchet', 'findings_ratchet', 'static_checks', 'export_links', 'remote'])
|
|
421
|
+
// Optional, and every field defaults, so a repository that never writes this
|
|
422
|
+
// table behaves exactly as before. `pre_push.coverage_ratchet` stays where it
|
|
423
|
+
// is: that key says WHETHER the gate is armed, this table says WHAT it grades.
|
|
424
|
+
// WHAT the commit gate protects, on top of the wiring files the package names
|
|
425
|
+
// itself. Declared rather than packaged because `knip.json` and `biome.json`
|
|
426
|
+
// are one ecosystem's vocabulary: a package naming them would standardise that
|
|
427
|
+
// ecosystem, which is the coupling removed from this package on 2026-09-16.
|
|
428
|
+
//
|
|
429
|
+
// Absent means only the wiring files are protected. That is deliberately NOT
|
|
430
|
+
// could-not-run, unlike a tree: the wiring set is always meaningful and always
|
|
431
|
+
// enforced, so absence shrinks the protected set visibly rather than turning a
|
|
432
|
+
// gate into a silent pass.
|
|
433
|
+
const integrity = problems.optionalTable(controls, 'integrity', ['watched'])
|
|
434
|
+
|
|
435
|
+
const coverage = problems.optionalTable(controls, 'coverage', [
|
|
436
|
+
'summary',
|
|
437
|
+
'produce',
|
|
438
|
+
'source_roots',
|
|
439
|
+
'src_test_ratio_globs',
|
|
440
|
+
])
|
|
441
|
+
// Same split as `coverage` above: `pre_push.findings_ratchet` says WHETHER,
|
|
442
|
+
// this table says WHAT and WHERE. `counters` names no tool: each key is a
|
|
443
|
+
// repository-chosen counter name, each value the repository's own command
|
|
444
|
+
// for it — the same shape `pre_push.static_checks` already uses for an
|
|
445
|
+
// opaque, repo-authored shell command this package never interprets.
|
|
446
|
+
const findings = problems.optionalTable(controls, 'findings', ['floor', 'counters'])
|
|
447
|
+
// Every hook gets the same seam. `post_commit` in particular is not
|
|
448
|
+
// decoration: a producer that defers work from pre-commit has nowhere to
|
|
449
|
+
// land it without one.
|
|
450
|
+
const commitMsg = problems.optionalTable(controls, 'commit_msg', ['static_checks'])
|
|
451
|
+
const postCommit = problems.optionalTable(controls, 'post_commit', ['static_checks'])
|
|
452
|
+
// Which branch is promoted to which. No default pair: defaulting to
|
|
453
|
+
// integration -> main would put one repository's branch names back into
|
|
454
|
+
// this package by the back door.
|
|
455
|
+
const release = problems.optionalTable(controls, 'release', ['source', 'target', 'merge_strategy', 'pre_bump'])
|
|
456
|
+
const releaseMergeStrategy = problems.optionalString(release, 'merge_strategy', 'release.merge_strategy', 'squash')
|
|
457
|
+
if (!Object.hasOwn(MERGE_STRATEGIES, releaseMergeStrategy)) {
|
|
458
|
+
problems.add(`release.merge_strategy must be one of ${Object.keys(MERGE_STRATEGIES).join(', ')}`)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const config: RepoControlsConfig = {
|
|
462
|
+
branches: {
|
|
463
|
+
protected: problems.names(branches, 'protected', 'branches.protected', BRANCH_RE),
|
|
464
|
+
prefixes: problems.names(branches, 'prefixes', 'branches.prefixes', PREFIX_RE),
|
|
465
|
+
},
|
|
466
|
+
preCommit: {
|
|
467
|
+
// The repository declares WHAT runs at commit and WHICH hook it runs in.
|
|
468
|
+
// Same shape as `pre_push.static_checks`; this package never interprets
|
|
469
|
+
// the command and names no tool.
|
|
470
|
+
staticChecks: preCommit.static_checks === undefined ? [] : parseStaticChecks(preCommit.static_checks, problems, 'pre_commit.static_checks'),
|
|
471
|
+
stagedCoverage: problems.optionalBool(preCommit, 'staged_coverage', 'pre_commit.staged_coverage', false),
|
|
472
|
+
docFreshness: problems.optionalBool(preCommit, 'doc_freshness', 'pre_commit.doc_freshness', false),
|
|
473
|
+
compliance: problems.optionalBool(preCommit, 'compliance', 'pre_commit.compliance', false),
|
|
474
|
+
},
|
|
475
|
+
prePush: {
|
|
476
|
+
coverageRatchet: problems.optionalBool(prePush, 'coverage_ratchet', 'pre_push.coverage_ratchet', false),
|
|
477
|
+
findingsRatchet: problems.optionalBool(prePush, 'findings_ratchet', 'pre_push.findings_ratchet', false),
|
|
478
|
+
staticChecks: prePush.static_checks === undefined ? [] : parseStaticChecks(prePush.static_checks, problems, 'pre_push.static_checks'),
|
|
479
|
+
// Untracked paths the HEAD export needs, e.g. a dependency directory.
|
|
480
|
+
// The hook used to hardcode `node_modules`, which assumed JavaScript in a
|
|
481
|
+
// package that is language agnostic.
|
|
482
|
+
exportLinks: parseExportLinks(prePush.export_links, problems),
|
|
483
|
+
remote: problems.string(prePush, 'remote', 'pre_push.remote', REMOTE_RE),
|
|
484
|
+
},
|
|
485
|
+
integrity: { watched: parseWatched(integrity.watched, problems) },
|
|
486
|
+
coverage: {
|
|
487
|
+
summary: problems.optionalString(coverage, 'summary', 'coverage.summary', DEFAULT_COVERAGE_SUMMARY),
|
|
488
|
+
produce: problems.optionalString(coverage, 'produce', 'coverage.produce', ''),
|
|
489
|
+
sourceRoots: problems.optionalNames(coverage, 'source_roots', 'coverage.source_roots', []),
|
|
490
|
+
srcTestRatioGlobs: problems.optionalNames(
|
|
491
|
+
coverage,
|
|
492
|
+
'src_test_ratio_globs',
|
|
493
|
+
'coverage.src_test_ratio_globs',
|
|
494
|
+
[],
|
|
495
|
+
),
|
|
496
|
+
},
|
|
497
|
+
commitMsg: {
|
|
498
|
+
staticChecks: commitMsg.static_checks === undefined ? [] : parseStaticChecks(commitMsg.static_checks, problems, 'commit_msg.static_checks'),
|
|
499
|
+
},
|
|
500
|
+
release: {
|
|
501
|
+
source: problems.optionalString(release, 'source', 'release.source', ''),
|
|
502
|
+
target: problems.optionalString(release, 'target', 'release.target', ''),
|
|
503
|
+
// The MCP server's PR tool admits only Squash, and that enum is the
|
|
504
|
+
// standard. A repository deviating declares it here.
|
|
505
|
+
mergeStrategy: releaseMergeStrategy as MergeStrategy,
|
|
506
|
+
// Ordered, repo-relative scripts `version-bump.sh` runs from the repo
|
|
507
|
+
// root before the bump commit — see `parsePreBump`'s own docstring for
|
|
508
|
+
// what "repository-relative" is checked to mean here; existence on
|
|
509
|
+
// disk is checked by `version-bump.sh` itself, which is the only place
|
|
510
|
+
// that knows the repo root at run time.
|
|
511
|
+
preBump: parsePreBump(release.pre_bump, problems),
|
|
512
|
+
},
|
|
513
|
+
postCommit: {
|
|
514
|
+
staticChecks: postCommit.static_checks === undefined ? [] : parseStaticChecks(postCommit.static_checks, problems, 'post_commit.static_checks'),
|
|
515
|
+
},
|
|
516
|
+
findings: {
|
|
517
|
+
floor: problems.optionalString(findings, 'floor', 'findings.floor', DEFAULT_FINDINGS_FLOOR),
|
|
518
|
+
counters: findings.counters === undefined ? {} : parseCounters(findings.counters, problems),
|
|
519
|
+
},
|
|
520
|
+
}
|
|
521
|
+
if (problems.list.length > 0) {
|
|
522
|
+
throw new Error(`${CONFIG_REL} is invalid:\n - ${problems.list.join('\n - ')}`)
|
|
523
|
+
}
|
|
524
|
+
return config
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Repository-relative paths to link into the HEAD export.
|
|
529
|
+
*
|
|
530
|
+
* Refuses absolute paths and `..` segments: the target is resolved against the
|
|
531
|
+
* repository root and the link is created inside a temp directory, so either
|
|
532
|
+
* would reach outside both.
|
|
533
|
+
*/
|
|
534
|
+
/**
|
|
535
|
+
* `[controls.integrity].watched` — repository-relative patterns, `*` and `**`.
|
|
536
|
+
*
|
|
537
|
+
* Rejected with a named reason rather than dropped: a pattern nobody can match
|
|
538
|
+
* protects nothing, and a protected-file list that silently shrinks is worse
|
|
539
|
+
* than one that refuses to load.
|
|
540
|
+
*/
|
|
541
|
+
function parseWatched(value: unknown, problems: Problems): string[] {
|
|
542
|
+
if (value === undefined) return []
|
|
543
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string')) {
|
|
544
|
+
problems.add('integrity.watched must be an array of strings')
|
|
545
|
+
return []
|
|
546
|
+
}
|
|
547
|
+
const watched: string[] = []
|
|
548
|
+
for (const entry of value as string[]) {
|
|
549
|
+
if (entry === '' || entry.startsWith('/') || entry.split('/').includes('..')) {
|
|
550
|
+
problems.add(`integrity.watched entry must be a repository-relative path: ${entry}`)
|
|
551
|
+
continue
|
|
552
|
+
}
|
|
553
|
+
watched.push(entry)
|
|
554
|
+
}
|
|
555
|
+
return watched
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
function parseExportLinks(value: unknown, problems: Problems): string[] {
|
|
559
|
+
if (value === undefined) return []
|
|
560
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string')) {
|
|
561
|
+
problems.add('pre_push.export_links must be an array of strings')
|
|
562
|
+
return []
|
|
563
|
+
}
|
|
564
|
+
const links: string[] = []
|
|
565
|
+
for (const entry of value as string[]) {
|
|
566
|
+
if (entry === '' || entry.startsWith('/') || entry.split('/').includes('..')) {
|
|
567
|
+
problems.add(`pre_push.export_links entry must be a repository-relative path: ${entry}`)
|
|
568
|
+
continue
|
|
569
|
+
}
|
|
570
|
+
links.push(entry)
|
|
571
|
+
}
|
|
572
|
+
return links
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* `[controls.release].pre_bump` — ordered, repository-relative script paths
|
|
577
|
+
* `version-bump.sh` runs from the repo root before the bump commit, one
|
|
578
|
+
* multi-language repo's escape hatch out of the single npm-`package.json`
|
|
579
|
+
* assumption baked into the rest of `[controls.release]` (e.g.
|
|
580
|
+
* agent-identities' Go version constant). Absent means no scripts and the
|
|
581
|
+
* bump commit stays byte-identical to the behaviour before this key existed.
|
|
582
|
+
*
|
|
583
|
+
* Only SHAPE is checked here (array of strings, repository-relative, no `..`
|
|
584
|
+
* escape) — the same two checks `parseWatched`/`parseExportLinks` already
|
|
585
|
+
* apply to every other repo-relative list this package parses. Whether each
|
|
586
|
+
* path actually exists on disk is NOT checked here: `parseConfig` takes raw
|
|
587
|
+
* text with no repository to check against (`monorepo-config-parses.test.ts`
|
|
588
|
+
* parses arbitrary siblings' text this way) — existence is `version-bump.sh`'s
|
|
589
|
+
* own job, the one place that both reads this list and knows the repo root.
|
|
590
|
+
*/
|
|
591
|
+
function parsePreBump(value: unknown, problems: Problems): string[] {
|
|
592
|
+
if (value === undefined) return []
|
|
593
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string')) {
|
|
594
|
+
problems.add('release.pre_bump must be an array of strings')
|
|
595
|
+
return []
|
|
596
|
+
}
|
|
597
|
+
const scripts: string[] = []
|
|
598
|
+
for (const entry of value as string[]) {
|
|
599
|
+
if (entry === '' || entry.startsWith('/') || entry.split('/').includes('..')) {
|
|
600
|
+
problems.add(`release.pre_bump entry must be a repository-relative path: ${entry}`)
|
|
601
|
+
continue
|
|
602
|
+
}
|
|
603
|
+
scripts.push(entry)
|
|
604
|
+
}
|
|
605
|
+
return scripts
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
function parseStaticChecks(value: unknown, problems: Problems, table: string): StaticCheck[] {
|
|
609
|
+
if (!Array.isArray(value)) {
|
|
610
|
+
problems.add(`${table} must be an array`)
|
|
611
|
+
return []
|
|
612
|
+
}
|
|
613
|
+
return value.map((entry: unknown, index) => {
|
|
614
|
+
const name = `${table}[${index}]`
|
|
615
|
+
if (!isTable(entry)) {
|
|
616
|
+
problems.add(`${name} must be a table`)
|
|
617
|
+
return { label: '', run: '' }
|
|
618
|
+
}
|
|
619
|
+
problems.unknownKeys(entry, ['label', 'run'], `${name}.`)
|
|
620
|
+
const label = typeof entry.label === 'string' ? entry.label : ''
|
|
621
|
+
const run = typeof entry.run === 'string' ? entry.run : ''
|
|
622
|
+
if (!LABEL_RE.test(label)) problems.add(`${name}.label must match ${LABEL_RE.source}`)
|
|
623
|
+
if (run.trim() === '' || /[\t\r\n]/.test(run)) problems.add(`${name}.run must be a non-empty single-line command`)
|
|
624
|
+
return { label, run }
|
|
625
|
+
})
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* `[controls.findings.counters]`: a repository-chosen name -> repository-owned
|
|
630
|
+
* command map, an inline table rather than `static_checks`' array of tables
|
|
631
|
+
* because each name must be unique (a TOML table enforces that for free) and
|
|
632
|
+
* is also the floor file's own key — see `FindingsConfig`'s docstring.
|
|
633
|
+
*/
|
|
634
|
+
function parseCounters(value: unknown, problems: Problems): Record<string, string> {
|
|
635
|
+
if (!isTable(value)) {
|
|
636
|
+
problems.add('findings.counters must be a table')
|
|
637
|
+
return {}
|
|
638
|
+
}
|
|
639
|
+
const counters: Record<string, string> = {}
|
|
640
|
+
for (const [name, raw] of Object.entries(value)) {
|
|
641
|
+
if (!LABEL_RE.test(name)) {
|
|
642
|
+
problems.add(`findings.counters key must match ${LABEL_RE.source}: ${name}`)
|
|
643
|
+
continue
|
|
644
|
+
}
|
|
645
|
+
const command = typeof raw === 'string' ? raw : ''
|
|
646
|
+
if (command.trim() === '' || /[\t\r\n]/.test(command)) {
|
|
647
|
+
problems.add(`findings.counters.${name} must be a non-empty single-line command`)
|
|
648
|
+
continue
|
|
649
|
+
}
|
|
650
|
+
counters[name] = command
|
|
651
|
+
}
|
|
652
|
+
return counters
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
export function loadConfig(repo: string): RepoControlsConfig {
|
|
656
|
+
const path = join(repo, CONFIG_REL)
|
|
657
|
+
if (!existsSync(path)) throw new Error(`${CONFIG_REL} is missing — ${INSTALL_HINT}`)
|
|
658
|
+
return parseConfig(readFileSync(path, 'utf8'))
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/** The environment contract between this CLI and the package-owned hook scripts. */
|
|
662
|
+
export function configEnv(repo: string, config: RepoControlsConfig): Record<string, string> {
|
|
663
|
+
const env: Record<string, string> = {
|
|
664
|
+
ADL_REPO_CONTROLS_ROOT: repo,
|
|
665
|
+
ADL_REPO_CONTROLS_PROTECTED_BRANCHES: config.branches.protected.join('|'),
|
|
666
|
+
ADL_REPO_CONTROLS_BRANCH_PREFIXES: config.branches.prefixes.join('|'),
|
|
667
|
+
ADL_REPO_CONTROLS_COVERAGE_RATCHET: config.prePush.coverageRatchet ? '1' : '0',
|
|
668
|
+
ADL_REPO_CONTROLS_FINDINGS_RATCHET: config.prePush.findingsRatchet ? '1' : '0',
|
|
669
|
+
ADL_REPO_CONTROLS_EXPORT_LINKS: config.prePush.exportLinks.join('\n'),
|
|
670
|
+
ADL_REPO_CONTROLS_STATIC_CHECKS: config.prePush.staticChecks.map((check) => `${check.label}\t${check.run}`).join('\n'),
|
|
671
|
+
ADL_REPO_CONTROLS_REMOTE: config.prePush.remote,
|
|
672
|
+
// The coverage artifact and the repository's own shape. Empty means "the
|
|
673
|
+
// bundled script's own default" — a repo that declares nothing keeps the
|
|
674
|
+
// behaviour it had before this table existed.
|
|
675
|
+
ADL_REPO_CONTROLS_COVERAGE_SUMMARY: config.coverage.summary,
|
|
676
|
+
ADL_REPO_CONTROLS_COVERAGE_PRODUCE: config.coverage.produce,
|
|
677
|
+
ADL_REPO_CONTROLS_COVERAGE_SOURCE_ROOTS: config.coverage.sourceRoots.join('|'),
|
|
678
|
+
ADL_REPO_CONTROLS_COVERAGE_SRC_TEST_GLOBS: config.coverage.srcTestRatioGlobs.join('|'),
|
|
679
|
+
// Where the findings ratchet's floor is, and the repo's own named
|
|
680
|
+
// counter commands — same `name\tcommand` shape as `_STATIC_CHECKS`,
|
|
681
|
+
// and empty when the repo declared none, so this gate runs nothing.
|
|
682
|
+
ADL_REPO_CONTROLS_FINDINGS_FLOOR: config.findings.floor,
|
|
683
|
+
ADL_REPO_CONTROLS_FINDINGS_COUNTERS: Object.entries(config.findings.counters)
|
|
684
|
+
.map(([name, command]) => `${name}\t${command}`)
|
|
685
|
+
.join('\n'),
|
|
686
|
+
}
|
|
687
|
+
// enact-m5's pre-commit honours ADL_SKIP_STAGED_COVERAGE=1; disabled config sets it.
|
|
688
|
+
if (!config.preCommit.stagedCoverage) env.ADL_SKIP_STAGED_COVERAGE = '1'
|
|
689
|
+
return env
|
|
690
|
+
}
|