@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,483 @@
|
|
|
1
|
+
"""The argv surface, and the ONLY module that reads the environment or calls git.
|
|
2
|
+
|
|
3
|
+
Everything below this file receives what it needs as an argument. That is the
|
|
4
|
+
whole of what "fully abstract" means here: there is exactly one place where the
|
|
5
|
+
outside world gets in, and it is this one. `grep -rn 'os.environ' src/` returns
|
|
6
|
+
these lines and nothing else.
|
|
7
|
+
|
|
8
|
+
The third term of the applicable-scope formula — *minus what git cannot see* —
|
|
9
|
+
is the CONSUMER's, and the consumer is this file. `git ls-files --cached
|
|
10
|
+
--others --exclude-standard` is called here so that gitignored paths never enter
|
|
11
|
+
a set, which is why no row needs to exclude `node_modules/` or `.scratch/`, and
|
|
12
|
+
why no check needs to know git exists (K-41).
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import subprocess
|
|
21
|
+
import sys
|
|
22
|
+
import tomllib
|
|
23
|
+
from collections.abc import Mapping, Sequence
|
|
24
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
from typing import TextIO
|
|
27
|
+
|
|
28
|
+
import yaml
|
|
29
|
+
from pydantic import ValidationError
|
|
30
|
+
|
|
31
|
+
from . import runner
|
|
32
|
+
from .core.constants import Constants
|
|
33
|
+
from .core.receipt import from_verdict
|
|
34
|
+
from .core.verdict import Outcome, Verdict
|
|
35
|
+
from .policy.registry import (
|
|
36
|
+
Registry,
|
|
37
|
+
RegistryError,
|
|
38
|
+
Row,
|
|
39
|
+
effective_trees,
|
|
40
|
+
load,
|
|
41
|
+
policy_text,
|
|
42
|
+
)
|
|
43
|
+
from .providers import PROVIDERS
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def find_root(explicit: str | None) -> Path:
|
|
47
|
+
"""The repository being graded. Resolved once, here, and passed down.
|
|
48
|
+
|
|
49
|
+
Three sources, in order, and the first that answers wins. The shell tree had
|
|
50
|
+
four mechanisms answering this and they disagreed; the point is not which
|
|
51
|
+
order is right but that the question is asked in one place.
|
|
52
|
+
"""
|
|
53
|
+
if explicit:
|
|
54
|
+
return Path(explicit).resolve()
|
|
55
|
+
from_environment = os.environ.get("ANALYSIS_PROJECT_ROOT")
|
|
56
|
+
if from_environment:
|
|
57
|
+
return Path(from_environment).resolve()
|
|
58
|
+
for candidate in (Path.cwd(), *Path.cwd().parents):
|
|
59
|
+
if (candidate / ".git").exists():
|
|
60
|
+
return candidate
|
|
61
|
+
raise SystemExit("adl-compliance: not inside a git repository, and no --root given")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def visible_files(root: Path) -> tuple[str, ...]:
|
|
65
|
+
"""Everything git can see, repository-relative. The caller's set.
|
|
66
|
+
|
|
67
|
+
`-c core.quotePath=false`, not left to the caller's ambient config
|
|
68
|
+
(Tarun, 2026-09-27, decision 3): left on git's own default (unset,
|
|
69
|
+
which behaves as quoting ON), a non-ASCII filename comes back
|
|
70
|
+
octal-escaped and double-quoted -- a filename this function returns as
|
|
71
|
+
a member of the given set, not something downstream ever unquotes. That
|
|
72
|
+
corrupted path then fails every prefix/root check this package does
|
|
73
|
+
(root-file detection, tree membership, doc-path matching), silently:
|
|
74
|
+
the file is simply invisible to those checks under its real name. This
|
|
75
|
+
must not depend on the checkout's own `core.quotePath` being set
|
|
76
|
+
correctly -- the function is not fully abstract otherwise (see the
|
|
77
|
+
module docstring's "one place the outside world gets in").
|
|
78
|
+
"""
|
|
79
|
+
completed = subprocess.run(
|
|
80
|
+
["git", "-c", "core.quotePath=false", "ls-files", "--cached", "--others", "--exclude-standard"],
|
|
81
|
+
cwd=root, capture_output=True, text=True, check=False,
|
|
82
|
+
)
|
|
83
|
+
if completed.returncode != 0:
|
|
84
|
+
raise SystemExit(f"adl-compliance: git ls-files failed: {completed.stderr.strip()}")
|
|
85
|
+
return tuple(line for line in completed.stdout.splitlines() if line)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def selected_rows(
|
|
89
|
+
registry: Registry, target: str | None, only: Sequence[str] | None = None
|
|
90
|
+
) -> list[Row]:
|
|
91
|
+
"""Rows to grade. `only` selects by gate id (`RST-001`), `domain.name` address
|
|
92
|
+
(`rust.acp-boundary`), or a whole `domain` (`layout`).
|
|
93
|
+
|
|
94
|
+
An entry matching no row is a hard error, never a silent narrowing: a selector
|
|
95
|
+
that selects nothing is indistinguishable from a clean run, so a typo'd or
|
|
96
|
+
renamed id would report success while grading absolutely nothing. That is the
|
|
97
|
+
same "selects nothing, passes quietly" failure K-13 and K-21 record for scope
|
|
98
|
+
globs and prefix filters, arriving here through the selection list instead.
|
|
99
|
+
"""
|
|
100
|
+
if only:
|
|
101
|
+
matched: dict[str, list[Row]] = {entry: [] for entry in only}
|
|
102
|
+
for row in registry.rows:
|
|
103
|
+
for entry in only:
|
|
104
|
+
if row.id == entry or row.address == entry or row.domain == entry:
|
|
105
|
+
matched[entry].append(row)
|
|
106
|
+
unmatched = sorted(entry for entry, rows in matched.items() if not rows)
|
|
107
|
+
if unmatched:
|
|
108
|
+
known = ", ".join(sorted({row.domain for row in registry.rows}))
|
|
109
|
+
raise RegistryError(
|
|
110
|
+
f"selection matches no gate: {', '.join(unmatched)} "
|
|
111
|
+
f"(expected a gate id, a domain.name address, or one of these domains: {known})"
|
|
112
|
+
)
|
|
113
|
+
chosen = {row.id for rows in matched.values() for row in rows}
|
|
114
|
+
return [row for row in registry.rows if row.id in chosen]
|
|
115
|
+
if target is None:
|
|
116
|
+
return list(registry.rows)
|
|
117
|
+
return [registry.resolve(target)]
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def read_trees_file(path: str) -> dict[str, str]:
|
|
121
|
+
"""A per-repo `[trees]` override, the same shape as the packaged
|
|
122
|
+
`policy/config.toml` — read here because this is the one module allowed to
|
|
123
|
+
read a file outside the package."""
|
|
124
|
+
try:
|
|
125
|
+
text = Path(path).read_text(encoding="utf-8")
|
|
126
|
+
except OSError as exc:
|
|
127
|
+
raise RegistryError(f"{path} could not be read: {exc}") from exc
|
|
128
|
+
try:
|
|
129
|
+
document = tomllib.loads(text)
|
|
130
|
+
except tomllib.TOMLDecodeError as exc:
|
|
131
|
+
raise RegistryError(f"{path} is not valid TOML: {exc}") from exc
|
|
132
|
+
trees = document.get("trees")
|
|
133
|
+
if not isinstance(trees, dict):
|
|
134
|
+
raise RegistryError(f"{path} has no [trees] table")
|
|
135
|
+
return trees
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def load_registry(
|
|
139
|
+
registry_file: str,
|
|
140
|
+
trees_file: str | None,
|
|
141
|
+
tree_overrides: Mapping[str, str] | None = None,
|
|
142
|
+
) -> Registry:
|
|
143
|
+
"""`policy.registry.load`'s cached, package-only path when there is no
|
|
144
|
+
override; otherwise the same parse, validated with the trees override as
|
|
145
|
+
`context`, so `EngineSpec`/`Row`'s `<tree>` resolution sees it (Task 4)."""
|
|
146
|
+
if trees_file is None and not tree_overrides:
|
|
147
|
+
return load(registry_file)
|
|
148
|
+
# A file and flags compose: the file is the base, flags win per key, which is
|
|
149
|
+
# the same precedence `[controls.compliance.trees]` has over the packaged default.
|
|
150
|
+
trees = read_trees_file(trees_file) if trees_file else {}
|
|
151
|
+
trees.update(tree_overrides or {})
|
|
152
|
+
try:
|
|
153
|
+
document = yaml.safe_load(policy_text(registry_file))
|
|
154
|
+
except yaml.YAMLError as exc:
|
|
155
|
+
raise RegistryError(f"{registry_file} is not valid YAML: {exc}") from exc
|
|
156
|
+
try:
|
|
157
|
+
return Registry.model_validate(document, context={"trees": trees})
|
|
158
|
+
except ValidationError as exc:
|
|
159
|
+
raise RegistryError(f"{registry_file} violates its schema:\n{exc}") from exc
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def report(verdict: Verdict, stream: TextIO | None = None, errors: TextIO | None = None) -> None:
|
|
163
|
+
"""Findings to stdout, advisories to stderr.
|
|
164
|
+
|
|
165
|
+
The streams default to None and are resolved HERE, not in the signature.
|
|
166
|
+
`stream=sys.stdout` as a default binds the object that existed at import
|
|
167
|
+
time, so anything that replaces the stream afterwards — a test harness, a
|
|
168
|
+
redirect, a caller wrapping the run — is silently written past.
|
|
169
|
+
"""
|
|
170
|
+
out = sys.stdout if stream is None else stream
|
|
171
|
+
err = sys.stderr if errors is None else errors
|
|
172
|
+
for advisory in verdict.advisories:
|
|
173
|
+
print(advisory.render(), file=err)
|
|
174
|
+
print(verdict.render(), file=out)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def tally(verdicts: Sequence[Verdict]) -> str:
|
|
178
|
+
"""The counts, so a log's first line says what the run actually covered."""
|
|
179
|
+
passed = sum(1 for v in verdicts if v.outcome is Outcome.CLEAN)
|
|
180
|
+
failed = sum(1 for v in verdicts if v.outcome is Outcome.FINDINGS)
|
|
181
|
+
errored = sum(1 for v in verdicts if v.outcome is Outcome.COULD_NOT_RUN)
|
|
182
|
+
return f"{len(verdicts)} row(s): {passed} pass, {failed} fail, {errored} error"
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def write_logs(directory: Path, verdicts: Sequence[Verdict]) -> tuple[Path, Path]:
|
|
186
|
+
"""Two files, because they answer two questions.
|
|
187
|
+
|
|
188
|
+
`all.log` is the sweep: one line per row, pass and fail alike, so a row that
|
|
189
|
+
was never reached stays distinguishable from one that came back clean.
|
|
190
|
+
|
|
191
|
+
`failures.log` is the work list: the same line for every non-clean row,
|
|
192
|
+
followed by its findings indented beneath it.
|
|
193
|
+
|
|
194
|
+
Both open with a `#` tally line even when there is nothing to report. An
|
|
195
|
+
empty file cannot tell "nothing failed" from "the run never happened", and
|
|
196
|
+
that is the exact confusion this estate keeps paying for.
|
|
197
|
+
"""
|
|
198
|
+
directory.mkdir(parents=True, exist_ok=True)
|
|
199
|
+
|
|
200
|
+
header = f"# {tally(verdicts)}"
|
|
201
|
+
all_path = directory / Constants.ALL_LOG
|
|
202
|
+
all_path.write_text(
|
|
203
|
+
"\n".join([header, *(v.summary() for v in verdicts)]) + "\n", encoding="utf-8"
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
failing = [v for v in verdicts if v.outcome is not Outcome.CLEAN]
|
|
207
|
+
lines = [f"# {len(failing)} of {len(verdicts)} row(s) did not pass"]
|
|
208
|
+
for verdict in failing:
|
|
209
|
+
lines.append(verdict.summary())
|
|
210
|
+
lines.extend(f" {f.render()}" for f in verdict.findings)
|
|
211
|
+
failures_path = directory / Constants.FAILURES_LOG
|
|
212
|
+
failures_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
213
|
+
|
|
214
|
+
return all_path, failures_path
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def write_receipts(directory: Path, verdicts: Sequence[Verdict], *, exhaustive: bool) -> Path:
|
|
218
|
+
"""C1: one `core.receipt.Receipt` per row, JSONL, alongside the two logs.
|
|
219
|
+
|
|
220
|
+
`exhaustive` is the one fact `write_logs` never needed and this does: it is
|
|
221
|
+
what tells `from_verdict` a zero-unit PASS apart as dead-scope (impossible,
|
|
222
|
+
and a hard error) from narrowed-and-irrelevant (a legitimate receipt). The
|
|
223
|
+
same value `main` already threads through every `runner.run` call for
|
|
224
|
+
exactly this reason.
|
|
225
|
+
"""
|
|
226
|
+
directory.mkdir(parents=True, exist_ok=True)
|
|
227
|
+
receipts_path = directory / Constants.RECEIPTS_LOG
|
|
228
|
+
lines = [
|
|
229
|
+
from_verdict(verdict, exhaustive=exhaustive).model_dump_json() for verdict in verdicts
|
|
230
|
+
]
|
|
231
|
+
receipts_path.write_text("\n".join(lines) + ("\n" if lines else ""), encoding="utf-8")
|
|
232
|
+
return receipts_path
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def main(argv: Sequence[str] | None = None) -> int:
|
|
236
|
+
parser = argparse.ArgumentParser(prog="adl-compliance")
|
|
237
|
+
parser.add_argument(
|
|
238
|
+
"target", nargs="?",
|
|
239
|
+
help="a gate id (RST-001) or address (rust.acp-boundary); omit to run every row",
|
|
240
|
+
)
|
|
241
|
+
parser.add_argument("--root", help="the repository to grade (default: the enclosing checkout)")
|
|
242
|
+
parser.add_argument(
|
|
243
|
+
"--files", metavar="LIST",
|
|
244
|
+
help="a file holding the caller's set, one repository-relative path per line. "
|
|
245
|
+
"Omit to grade everything git can see.",
|
|
246
|
+
)
|
|
247
|
+
parser.add_argument(
|
|
248
|
+
"--exhaustive", action="store_true",
|
|
249
|
+
help="declare that --files is the complete visible tree. Used for a staged "
|
|
250
|
+
"index snapshot that intentionally has no .git directory; an empty "
|
|
251
|
+
"row scope is therefore could-not-run, never an unrelated partial set.",
|
|
252
|
+
)
|
|
253
|
+
parser.add_argument(
|
|
254
|
+
"--summary", action="store_true",
|
|
255
|
+
help="one line per gate instead of every finding",
|
|
256
|
+
)
|
|
257
|
+
parser.add_argument(
|
|
258
|
+
"--log-dir", metavar="DIR",
|
|
259
|
+
help=f"write {Constants.ALL_LOG} (every row) and {Constants.FAILURES_LOG} "
|
|
260
|
+
"(non-clean rows and their findings) into DIR",
|
|
261
|
+
)
|
|
262
|
+
parser.add_argument(
|
|
263
|
+
"--only", action="append", metavar="IDS-OR-ADDRESSES",
|
|
264
|
+
help="a gate id or <domain>.<name> address, or a comma-separated list of "
|
|
265
|
+
"either; repeatable. When given, replaces target/every-row selection "
|
|
266
|
+
"with exactly the named rows.",
|
|
267
|
+
)
|
|
268
|
+
parser.add_argument(
|
|
269
|
+
"--registry-file", metavar="FILENAME", default="gate-registry.yaml",
|
|
270
|
+
help="the packaged registry document to load (default: gate-registry.yaml)",
|
|
271
|
+
)
|
|
272
|
+
parser.add_argument(
|
|
273
|
+
"--input", metavar="GATE:NAME=PATH", action="append", default=[],
|
|
274
|
+
help="override a check's named input, repository-relative (repeatable). "
|
|
275
|
+
"A check declares logical names -- `orchestrator`, `registry` -- and a "
|
|
276
|
+
"declared default is otherwise the only value, so a gate whose input "
|
|
277
|
+
"names one repository's file cannot run anywhere else.",
|
|
278
|
+
)
|
|
279
|
+
parser.add_argument(
|
|
280
|
+
"--jobs", type=int, default=0, metavar="N",
|
|
281
|
+
help="grade N rows concurrently (default: one per CPU). `--jobs 1` forces "
|
|
282
|
+
"sequential, which is what a failing run wants when a check's own "
|
|
283
|
+
"subprocess output needs reading. Output order is the registry's "
|
|
284
|
+
"either way, never completion order.",
|
|
285
|
+
)
|
|
286
|
+
parser.add_argument(
|
|
287
|
+
"--declare", metavar="NAME=VALUE", action="append", default=[],
|
|
288
|
+
help="a fact the repository states about itself, as `license=Proprietary` "
|
|
289
|
+
"(repeatable). Read from [controls.compliance] and passed through: the "
|
|
290
|
+
"package grades a repository against what it declares, it does not hold "
|
|
291
|
+
"the answer. `license` is the only name consumed today (REP-001).",
|
|
292
|
+
)
|
|
293
|
+
parser.add_argument(
|
|
294
|
+
"--tree", metavar="NAME=PATH", action="append", default=[],
|
|
295
|
+
help="override one logical tree, as `rust=backend` (repeatable). The flag "
|
|
296
|
+
"form of --trees-file, so a caller holding the mapping in its own config "
|
|
297
|
+
"need not write a temporary TOML file to pass it.",
|
|
298
|
+
)
|
|
299
|
+
parser.add_argument(
|
|
300
|
+
"--trees-file", metavar="PATH.TOML",
|
|
301
|
+
help="a [trees] table overriding the packaged policy/config.toml, per key "
|
|
302
|
+
"(a key absent from it still resolves through the packaged default)",
|
|
303
|
+
)
|
|
304
|
+
args = parser.parse_args(argv)
|
|
305
|
+
if args.exhaustive and not args.files:
|
|
306
|
+
parser.error("--exhaustive requires --files")
|
|
307
|
+
|
|
308
|
+
# NAME=PATH pairs, repository-relative. Resolved against `root` below, beside
|
|
309
|
+
# every other input, so an override and a default reach the check identically.
|
|
310
|
+
# GATE:NAME=PATH. An override belongs to one gate: a flat map reached every
|
|
311
|
+
# row and made one declaration break every other check (see
|
|
312
|
+
# `resolve_inputs`).
|
|
313
|
+
overrides: dict[str, dict[str, str]] = {}
|
|
314
|
+
global_inputs: dict[str, str] = {}
|
|
315
|
+
for pair in args.input:
|
|
316
|
+
addressed, sep, value = pair.partition("=")
|
|
317
|
+
# Two accepted forms:
|
|
318
|
+
# GATE:NAME=PATH -- per-gate override (rare; useful for tests)
|
|
319
|
+
# NAME=PATH -- global input; applies to every gate sharing the
|
|
320
|
+
# same BatchProvider. This is the common case
|
|
321
|
+
# (`[controls.compliance.inputs]` is global).
|
|
322
|
+
if ":" in addressed:
|
|
323
|
+
gate, gate_sep, name = addressed.partition(":")
|
|
324
|
+
if not sep or not gate_sep or not gate.strip() or not name.strip() or not value.strip():
|
|
325
|
+
parser.error(f"--input expects GATE:NAME=PATH or NAME=PATH, got {pair!r}")
|
|
326
|
+
overrides.setdefault(gate.strip(), {})[name.strip()] = value.strip()
|
|
327
|
+
else:
|
|
328
|
+
if not sep or not addressed.strip() or not value.strip():
|
|
329
|
+
parser.error(f"--input expects GATE:NAME=PATH or NAME=PATH, got {pair!r}")
|
|
330
|
+
global_inputs[addressed.strip()] = value.strip()
|
|
331
|
+
|
|
332
|
+
declarations: dict[str, str] = {}
|
|
333
|
+
for pair in args.declare:
|
|
334
|
+
name, sep, value = pair.partition("=")
|
|
335
|
+
if not sep or not name.strip() or not value.strip():
|
|
336
|
+
parser.error(f"--declare expects NAME=VALUE, got {pair!r}")
|
|
337
|
+
declarations[name.strip()] = value.strip()
|
|
338
|
+
|
|
339
|
+
tree_overrides: dict[str, str] = {}
|
|
340
|
+
for pair in args.tree:
|
|
341
|
+
name, sep, value = pair.partition("=")
|
|
342
|
+
# `--tree specs=` with an EMPTY path is legal and meaningful: the
|
|
343
|
+
# repository declaring it has no such tree. An undeclared tree is
|
|
344
|
+
# could-not-run, because silence could equally mean "we have one and
|
|
345
|
+
# forgot to say" -- this is the owner answering. A missing `=` or a
|
|
346
|
+
# blank NAME is still an error.
|
|
347
|
+
if not sep or not name.strip():
|
|
348
|
+
parser.error(f"--tree expects NAME=PATH, got {pair!r}")
|
|
349
|
+
tree_overrides[name.strip()] = value.strip()
|
|
350
|
+
|
|
351
|
+
only = (
|
|
352
|
+
tuple(item.strip() for group in args.only for item in group.split(",") if item.strip())
|
|
353
|
+
if args.only
|
|
354
|
+
else None
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
# The same precedence `load_registry` applies to scope patterns, through the
|
|
358
|
+
# same function, so both surfaces resolve a placeholder identically.
|
|
359
|
+
declared_trees = dict(read_trees_file(args.trees_file)) if args.trees_file else {}
|
|
360
|
+
declared_trees.update(tree_overrides)
|
|
361
|
+
resolved_trees = effective_trees(declared_trees)
|
|
362
|
+
|
|
363
|
+
root = find_root(args.root)
|
|
364
|
+
try:
|
|
365
|
+
registry = load_registry(args.registry_file, args.trees_file, tree_overrides)
|
|
366
|
+
rows = selected_rows(registry, args.target, only)
|
|
367
|
+
except RegistryError as exc:
|
|
368
|
+
print(f"adl-compliance: {exc}", file=sys.stderr)
|
|
369
|
+
return int(Outcome.COULD_NOT_RUN)
|
|
370
|
+
|
|
371
|
+
if args.files:
|
|
372
|
+
given = tuple(
|
|
373
|
+
line for line in Path(args.files).read_text(encoding="utf-8").splitlines() if line
|
|
374
|
+
)
|
|
375
|
+
exhaustive = args.exhaustive
|
|
376
|
+
universe = given if exhaustive else visible_files(root)
|
|
377
|
+
else:
|
|
378
|
+
given = visible_files(root)
|
|
379
|
+
exhaustive = True
|
|
380
|
+
universe = given
|
|
381
|
+
|
|
382
|
+
# Expand global inputs to every batch-check row. The runner sees a
|
|
383
|
+
# per-gate map; a global declaration from `[controls.compliance.inputs]`
|
|
384
|
+
# (or `--input NAME=PATH`) is a declaration that applies to every gate
|
|
385
|
+
# sharing a BatchProvider, so we materialize that here. Non-batch rows
|
|
386
|
+
# (each owning its own per-gate input surface) are NEVER seeded with
|
|
387
|
+
# global inputs — passing `ui_bases` to TS-017, for instance, fails it as
|
|
388
|
+
# an unknown input and rolls every doc/typescript/layout gate back to
|
|
389
|
+
# could-not-run. The contract is: a gate's `inputs` class attribute is
|
|
390
|
+
# the authority on what it consumes; global inputs route only to rows
|
|
391
|
+
# that consume them (i.e. BatchCheck rows whose class names them).
|
|
392
|
+
from .checks import lookup
|
|
393
|
+
from .core.check import BatchCheck
|
|
394
|
+
inputs_by_gate: dict[str, dict[str, str]] = {gate: dict(names) for gate, names in overrides.items()}
|
|
395
|
+
for row in rows:
|
|
396
|
+
try:
|
|
397
|
+
check_class = lookup(row.id)
|
|
398
|
+
except KeyError:
|
|
399
|
+
continue
|
|
400
|
+
if not issubclass(check_class, BatchCheck):
|
|
401
|
+
continue
|
|
402
|
+
gate_inputs = inputs_by_gate.setdefault(row.id, {})
|
|
403
|
+
for name, value in global_inputs.items():
|
|
404
|
+
gate_inputs.setdefault(name, value)
|
|
405
|
+
resolved_inputs_by_gate: dict[str, dict[str, Path]] | None = None
|
|
406
|
+
if inputs_by_gate:
|
|
407
|
+
resolved_inputs_by_gate = {
|
|
408
|
+
gate: {name: root / value for name, value in names.items()}
|
|
409
|
+
for gate, names in inputs_by_gate.items()
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
batch_results = runner.prepare_batches(
|
|
413
|
+
rows,
|
|
414
|
+
root,
|
|
415
|
+
given,
|
|
416
|
+
exhaustive=exhaustive,
|
|
417
|
+
universe=universe,
|
|
418
|
+
trees=resolved_trees,
|
|
419
|
+
declared_trees=declared_trees,
|
|
420
|
+
inputs=resolved_inputs_by_gate,
|
|
421
|
+
providers=PROVIDERS,
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
def grade(row: Row) -> Verdict:
|
|
425
|
+
return runner.run(
|
|
426
|
+
row, root, given, exhaustive=exhaustive, universe=universe,
|
|
427
|
+
inputs=resolved_inputs_by_gate,
|
|
428
|
+
declarations=declarations,
|
|
429
|
+
trees=resolved_trees,
|
|
430
|
+
# The UNDILUTED map -- what this repository actually declared, with
|
|
431
|
+
# no packaged defaults merged in. `trees` above is the merged one,
|
|
432
|
+
# used for scope; these two must never converge. A check's INPUT
|
|
433
|
+
# resolving against a packaged default is how TS-001 graded zero
|
|
434
|
+
# files in four repositories and reported PASS. Owner ruling: the
|
|
435
|
+
# gate runs, `adl-config.toml` decides.
|
|
436
|
+
declared_trees=declared_trees,
|
|
437
|
+
batch_results=batch_results,
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
# Threads, not processes. Nearly every check is I/O or a subprocess
|
|
441
|
+
# (`ast-grep`, `just`, `cargo`, reading files), and CPython releases the GIL
|
|
442
|
+
# for both — so threads get the parallelism without paying to pickle a Row
|
|
443
|
+
# and a FileSet to a worker, and without the import cost of a fresh
|
|
444
|
+
# interpreter per gate. A check that is genuinely CPU-bound in Python would
|
|
445
|
+
# not scale here; none is today.
|
|
446
|
+
#
|
|
447
|
+
# Results are collected in REGISTRY ORDER regardless of completion order:
|
|
448
|
+
# a gate report whose line order shifts run to run is unreadable and makes
|
|
449
|
+
# two runs impossible to diff.
|
|
450
|
+
jobs = args.jobs if args.jobs > 0 else (os.cpu_count() or 1)
|
|
451
|
+
if jobs == 1 or len(rows) < 2:
|
|
452
|
+
verdicts_by_row = [grade(row) for row in rows]
|
|
453
|
+
else:
|
|
454
|
+
with ThreadPoolExecutor(max_workers=jobs) as pool:
|
|
455
|
+
verdicts_by_row = list(pool.map(grade, rows))
|
|
456
|
+
|
|
457
|
+
verdicts: list[Verdict] = []
|
|
458
|
+
worst = Outcome.CLEAN
|
|
459
|
+
for verdict in verdicts_by_row:
|
|
460
|
+
verdicts.append(verdict)
|
|
461
|
+
if args.summary:
|
|
462
|
+
# Advisories still go to stderr: --summary narrows stdout, it does
|
|
463
|
+
# not suppress a warning nobody has seen yet.
|
|
464
|
+
for advisory in verdict.advisories:
|
|
465
|
+
print(advisory.render(), file=sys.stderr)
|
|
466
|
+
print(verdict.summary())
|
|
467
|
+
else:
|
|
468
|
+
report(verdict)
|
|
469
|
+
worst = max(worst, verdict.outcome)
|
|
470
|
+
|
|
471
|
+
if args.log_dir:
|
|
472
|
+
all_path, failures_path = write_logs(Path(args.log_dir), verdicts)
|
|
473
|
+
receipts_path = write_receipts(Path(args.log_dir), verdicts, exhaustive=exhaustive)
|
|
474
|
+
print(
|
|
475
|
+
f"adl-compliance: wrote {all_path}, {failures_path} and {receipts_path}",
|
|
476
|
+
file=sys.stderr,
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
return int(worst)
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
if __name__ == "__main__": # pragma: no cover
|
|
483
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""core."""
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"""Shared base for `engine.rule` gates: dispatch to the real `ast-grep` CLI.
|
|
2
|
+
|
|
3
|
+
Ten of the twenty-two rule-engine rows in `policy/gate-registry.yaml` have no
|
|
4
|
+
`check.sh` at all in the shell tree (`compliance_new/`) — their rule logic
|
|
5
|
+
lives entirely in an ast-grep `RuleConfig` YAML, dispatched through
|
|
6
|
+
`compliance_new/checks/framework/_rule-check.sh`'s `rule_check()`/`rule_hits()`
|
|
7
|
+
helpers. `RST-001` (`AcpBoundary`) already proved the shape a Python port of
|
|
8
|
+
that dispatch takes: shell to a packaged `sgconfig.yml`, parse the
|
|
9
|
+
`--json=stream` output, turn each match into a `Finding`. This module is that
|
|
10
|
+
shape, extracted so a single-rule gate declares data, not a subprocess call.
|
|
11
|
+
|
|
12
|
+
A concrete check declares three things and nothing else:
|
|
13
|
+
|
|
14
|
+
rule_ids the ast-grep rule id(s) in the packaged config this gate
|
|
15
|
+
grades. More than one only when a single gate is genuinely
|
|
16
|
+
graded by several rule documents together (e.g. a `.ts`
|
|
17
|
+
document and its `.tsx` sibling) — `--filter` is built as one
|
|
18
|
+
anchored alternation, so that stays one subprocess call.
|
|
19
|
+
extensions which of the GIVEN file set are this rule's subject matter.
|
|
20
|
+
This is not scope (AGENTS.md "Applicable scope"): the runner
|
|
21
|
+
already narrowed the set through the row's `engine.scope`
|
|
22
|
+
before this class ever sees it. `extensions` answers "which
|
|
23
|
+
of these files does this rule's parser apply to" — the same
|
|
24
|
+
question `language:` answers on the YAML side, and the two
|
|
25
|
+
must agree, since `.ts` is not `.tsx` (AGENTS.md "language:
|
|
26
|
+
is per parser").
|
|
27
|
+
rule (inherited from `Check`) the id reported on the Finding.
|
|
28
|
+
|
|
29
|
+
and may override `message_for`/`fix_for` to phrase a finding better than the
|
|
30
|
+
rule document's own generic `message:`/`note:` fields, without touching the
|
|
31
|
+
query itself. **The query is never reimplemented** — every subclass runs the
|
|
32
|
+
one packaged `sgconfig.yml` this class resolves via `importlib.resources`
|
|
33
|
+
(K-16, K-40): a rule YAML is read from where it already lives as package data,
|
|
34
|
+
copied in verbatim, never hand-transcribed as a Python pattern.
|
|
35
|
+
|
|
36
|
+
ast-grep is handed a FILE LIST, never a directory, and no `--globs` — the two
|
|
37
|
+
must never be mixed (AGENTS.md "Handing a set to ast-grep": `ast-grep` skips
|
|
38
|
+
glob filtering entirely for a path named on the command line). The narrowing
|
|
39
|
+
is already complete by the time `graded` runs; this only picks out the subject
|
|
40
|
+
matter.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
from __future__ import annotations
|
|
44
|
+
|
|
45
|
+
import json
|
|
46
|
+
import re
|
|
47
|
+
import subprocess
|
|
48
|
+
from collections.abc import Iterable, Iterator, Sequence
|
|
49
|
+
from contextlib import ExitStack
|
|
50
|
+
from importlib import resources
|
|
51
|
+
from typing import ClassVar
|
|
52
|
+
|
|
53
|
+
from .check import Check
|
|
54
|
+
from .context import Context, FileSet
|
|
55
|
+
from .errors import CouldNotRun
|
|
56
|
+
from .finding import Report
|
|
57
|
+
from .models import OpenModel
|
|
58
|
+
|
|
59
|
+
# A `// biome-ignore <rule>: <reason>` marker. `<reason>` is optional in the
|
|
60
|
+
# GRAMMAR (a bare marker parses) but not in what gets HONOURED — owner ruling:
|
|
61
|
+
# "if it's legitimate, own it", so group(2) is inspected for emptiness by the
|
|
62
|
+
# caller rather than being made mandatory here and rejecting the bare form
|
|
63
|
+
# outright, which would turn "not owned" into "not even a suppression".
|
|
64
|
+
_BIOME_IGNORE = re.compile(r"^\s*//\s*biome-ignore\s+(\S+)(?::\s*(.*))?\s*$")
|
|
65
|
+
_COMMENT_LINE = re.compile(r"^\s*//")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class AstGrepRange(OpenModel):
|
|
69
|
+
"""Open, like every model over ast-grep's own output: it emits `column`
|
|
70
|
+
and `byteOffset` here too, and forbidding fields this package ignores
|
|
71
|
+
would break the gate on ast-grep's next release rather than on a real
|
|
72
|
+
defect."""
|
|
73
|
+
|
|
74
|
+
line: int = 0
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class AstGrepSpan(OpenModel):
|
|
78
|
+
start: AstGrepRange = AstGrepRange()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class AstGrepMatch(OpenModel):
|
|
82
|
+
"""One `--json=stream` record. Open for the same reason as `AstGrepSpan`."""
|
|
83
|
+
|
|
84
|
+
file: str
|
|
85
|
+
ruleId: str = "" # noqa: N815 — the wire name
|
|
86
|
+
message: str = ""
|
|
87
|
+
note: str | None = None
|
|
88
|
+
range: AstGrepSpan = AstGrepSpan()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class AstGrepCheck(Check):
|
|
92
|
+
"""One or more ast-grep rule ids, graded against the given file set."""
|
|
93
|
+
|
|
94
|
+
requires: ClassVar[tuple[str, ...]] = ("ast-grep",)
|
|
95
|
+
|
|
96
|
+
rule_ids: ClassVar[tuple[str, ...]] = ()
|
|
97
|
+
"""The rule id(s) in the packaged config this gate grades. Declared, never
|
|
98
|
+
the empty default a real subclass would run with — `_scan` refuses to
|
|
99
|
+
build a filter that matches everything when this is unset (K-13: a
|
|
100
|
+
positive glob matching nothing excludes everything, and the same failure
|
|
101
|
+
mode applies to an unfiltered `--filter` matching everything)."""
|
|
102
|
+
|
|
103
|
+
extensions: ClassVar[tuple[str, ...]] = ()
|
|
104
|
+
"""Which of the GIVEN files are this rule's subject matter. Not scope —
|
|
105
|
+
the row's `engine.scope` already narrowed the set; this narrows it again
|
|
106
|
+
by file KIND, the same distinction `language:` draws on the YAML side."""
|
|
107
|
+
|
|
108
|
+
SGCONFIG_PACKAGE: ClassVar[str] = "adl_compliance.rules"
|
|
109
|
+
SGCONFIG_NAME: ClassVar[str] = "sgconfig.yml"
|
|
110
|
+
|
|
111
|
+
def graded(self, ctx: Context, files: FileSet) -> Iterable[Report]:
|
|
112
|
+
corpus = sorted(
|
|
113
|
+
path for path in files.existing(ctx.root) if path.endswith(self.extensions)
|
|
114
|
+
)
|
|
115
|
+
if not corpus:
|
|
116
|
+
return
|
|
117
|
+
for match in self._scan(ctx, corpus):
|
|
118
|
+
if self._is_owned_suppression(ctx, match):
|
|
119
|
+
continue
|
|
120
|
+
yield self.report(
|
|
121
|
+
match.file,
|
|
122
|
+
self.message_for(match),
|
|
123
|
+
self.fix_for(match),
|
|
124
|
+
rule=self.rule_for(match),
|
|
125
|
+
line=match.range.start.line + 1,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def _is_owned_suppression(self, ctx: Context, match: AstGrepMatch) -> bool:
|
|
129
|
+
"""Owner ruling on TS-013's two `enact-m5` findings: "if it's
|
|
130
|
+
legitimate, own it" / "no exception". Synthesised into one mechanism
|
|
131
|
+
for every `engine.rule` row, not one gate's patch: a match is skipped
|
|
132
|
+
only when the row DECLARES an equivalent biome rule (`engine.
|
|
133
|
+
suppression`) and the match is immediately preceded — allowing a
|
|
134
|
+
multi-line comment continuation — by a `// biome-ignore <rule>:
|
|
135
|
+
<reason>` comment naming that same rule with a non-empty reason. A
|
|
136
|
+
bare marker, a different rule, a non-adjacent comment, or no declared
|
|
137
|
+
equivalence at all honours nothing.
|
|
138
|
+
"""
|
|
139
|
+
equivalent = ctx.row.engine.suppression
|
|
140
|
+
if not equivalent:
|
|
141
|
+
return False
|
|
142
|
+
body = self.text(ctx, match.file)
|
|
143
|
+
if body is None:
|
|
144
|
+
return False
|
|
145
|
+
lines = body.splitlines()
|
|
146
|
+
index = match.range.start.line - 1 # the line immediately above the match
|
|
147
|
+
while index >= 0 and _COMMENT_LINE.match(lines[index]):
|
|
148
|
+
found = _BIOME_IGNORE.match(lines[index])
|
|
149
|
+
if found:
|
|
150
|
+
rule, reason = found.group(1), found.group(2)
|
|
151
|
+
return rule == equivalent and bool(reason and reason.strip())
|
|
152
|
+
index -= 1
|
|
153
|
+
return False
|
|
154
|
+
|
|
155
|
+
def rule_for(self, match: AstGrepMatch) -> str:
|
|
156
|
+
"""The id reported on the Finding. Defaults to this gate's own
|
|
157
|
+
`self.rule`; override for a per-ast-grep-rule-id mapping the way
|
|
158
|
+
`AcpBoundary.ACP_CODE` does when one gate spans several rule ids."""
|
|
159
|
+
return self.rule or match.ruleId
|
|
160
|
+
|
|
161
|
+
def message_for(self, match: AstGrepMatch) -> str:
|
|
162
|
+
"""The rule document's own `message:`. Override to phrase a finding
|
|
163
|
+
specific to this gate rather than the query's generic wording."""
|
|
164
|
+
return match.message
|
|
165
|
+
|
|
166
|
+
def fix_for(self, match: AstGrepMatch) -> str:
|
|
167
|
+
"""The rule document's own `note:`, or a generic fallback. Override
|
|
168
|
+
for remediation text specific to this gate."""
|
|
169
|
+
return match.note or f"fix the flagged construct per {match.ruleId}"
|
|
170
|
+
|
|
171
|
+
def _scan(self, ctx: Context, corpus: Sequence[str]) -> Iterator[AstGrepMatch]:
|
|
172
|
+
if not self.rule_ids:
|
|
173
|
+
raise CouldNotRun(f"{type(self).__name__} declares no rule_ids")
|
|
174
|
+
rule_filter = "^(" + "|".join(self.rule_ids) + ")$"
|
|
175
|
+
with ExitStack() as stack:
|
|
176
|
+
config = stack.enter_context(
|
|
177
|
+
resources.as_file(resources.files(self.SGCONFIG_PACKAGE) / self.SGCONFIG_NAME)
|
|
178
|
+
)
|
|
179
|
+
completed = subprocess.run(
|
|
180
|
+
[
|
|
181
|
+
"ast-grep", "scan", "--config", str(config),
|
|
182
|
+
"--filter", rule_filter, "--json=stream", *corpus,
|
|
183
|
+
],
|
|
184
|
+
cwd=ctx.root, capture_output=True, text=True, check=False,
|
|
185
|
+
)
|
|
186
|
+
# ast-grep's own exit status carries no verdict of its own: 0 whether
|
|
187
|
+
# or not an info/warning rule matched, and NONZERO whenever an
|
|
188
|
+
# error-severity rule matched (AGENTS.md, K-22) — so only >1 means the
|
|
189
|
+
# tool itself broke rather than a real match. A tool failure is never
|
|
190
|
+
# a finding (F-05).
|
|
191
|
+
if completed.returncode > 1:
|
|
192
|
+
raise CouldNotRun(
|
|
193
|
+
f"ast-grep exited {completed.returncode} scanning {len(corpus)} file(s): "
|
|
194
|
+
f"{completed.stderr.strip()}"
|
|
195
|
+
)
|
|
196
|
+
for line in completed.stdout.splitlines():
|
|
197
|
+
if not line.strip():
|
|
198
|
+
continue
|
|
199
|
+
yield AstGrepMatch.model_validate(json.loads(line))
|