@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,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* decide(): the single entry point that turns a shell command or tool call
|
|
3
|
+
* into a `Decision`, by running the enabled rule corpus against it.
|
|
4
|
+
*
|
|
5
|
+
* Ported from enact-repo-controls's `src/rules/engine.ts`. Fail-closed by
|
|
6
|
+
* construction: `invocations()` (shell/invocation.ts) never throws on
|
|
7
|
+
* unparseable input, it returns an `uncertain` Invocation, and `parse.uncertain`
|
|
8
|
+
* (impl/parse-uncertain.ts) denies it like any other rule — there is no
|
|
9
|
+
* separate "parse error" code path to forget to wire up.
|
|
10
|
+
*
|
|
11
|
+
* HARDCUT from the reference: `resolveHost`/`readHostFlag`/`MISSING_HOST_EXIT_CODE`
|
|
12
|
+
* moved to `../hosts/spec.ts` (per this package's target layout — host
|
|
13
|
+
* resolution is a hosts/ concern, not an engine one). `EngineContext` takes
|
|
14
|
+
* `RulesConfig` + a separate `RepoSection` from `../gating/config.ts` instead
|
|
15
|
+
* of the reference's `EffectiveConfig` (which also carries paths, host-merge
|
|
16
|
+
* config, test config, and surfaces-audit config adl hook has no use for —
|
|
17
|
+
* see `../gating/config.ts`'s header for why `RepoSection` is a sibling
|
|
18
|
+
* argument here rather than nested inside `RulesConfig`). `buildEngineContext`
|
|
19
|
+
* uses `../gating/config.ts`'s `isRuleEnabled` (`RuleEnabledResult`, not the
|
|
20
|
+
* reference's `kernel/result.ts` `Result<T, ControlsError>`).
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import type { AgentSection, ConfigDecodeIssue, RepoSection, RulesConfig } from '../gating/config.ts'
|
|
24
|
+
import { isRuleEnabled } from '../gating/config.ts'
|
|
25
|
+
import type { AgentPort, EnvPort, RepoIndexPort } from './ports.ts'
|
|
26
|
+
import { noAgent } from './ports.ts'
|
|
27
|
+
import type { AnyRuleSpec, Finding, MessageContext, RuleId } from './spec.ts'
|
|
28
|
+
import { DEFAULT_CLASSIFY_CONFIG, invocations } from './shell/invocation.ts'
|
|
29
|
+
import type { ClassifyConfig, Invocation } from './shell/invocation.ts'
|
|
30
|
+
import { resolveFromEnvOrFile } from './impl/adl-identity.ts'
|
|
31
|
+
import { RULE_ID, gitIdentityDenyMessage, gitIdentityNeedsIdentityMessage } from './impl/adl-git-identity.ts'
|
|
32
|
+
import { rewriteGitNetworkCommands } from './shell/git-identity.ts'
|
|
33
|
+
import { loadSurfacePolicy } from '../surface-policy.ts'
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The fail-closed exit code for a pre-tool-use decision that could not be
|
|
37
|
+
* rendered as a plain allow — carried over from the reference's
|
|
38
|
+
* `MISSING_HOST_EXIT_CODE` (there, also the missing-`--host` exit code; here
|
|
39
|
+
* `--host` handling is `main.ts`'s own concern, so this constant is scoped to
|
|
40
|
+
* "the engine could not build a context, or a decision could not be decided"
|
|
41
|
+
* and to Kimi's real deny contract, which independently also uses exit code
|
|
42
|
+
* 2 — see `../hosts/impl/kimi.ts` and `../pre-tool-use/handler.ts`.
|
|
43
|
+
*/
|
|
44
|
+
export const FAIL_CLOSED_EXIT_CODE = 2
|
|
45
|
+
|
|
46
|
+
export interface EngineContext {
|
|
47
|
+
readonly config: RulesConfig
|
|
48
|
+
readonly repo: RepoSection
|
|
49
|
+
readonly agent: AgentSection
|
|
50
|
+
readonly rules: ReadonlyMap<RuleId, AnyRuleSpec>
|
|
51
|
+
/** Precomputed once per config load, not per decide() call — see buildEngineContext. */
|
|
52
|
+
readonly enabled: ReadonlySet<RuleId>
|
|
53
|
+
readonly index: RepoIndexPort
|
|
54
|
+
readonly env: EnvPort
|
|
55
|
+
/** The agent identity that produced the call being decided — see `spec.ts`'s `RuleContext.agent`. */
|
|
56
|
+
readonly agentId: AgentPort
|
|
57
|
+
/** The repository root the hook is running against — see `spec.ts`'s `RuleContext.root`. Empty when unknown. */
|
|
58
|
+
readonly root: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type BuildEngineContextResult =
|
|
62
|
+
| { readonly ok: true; readonly value: EngineContext }
|
|
63
|
+
| { readonly ok: false; readonly issue: ConfigDecodeIssue }
|
|
64
|
+
|
|
65
|
+
/** Resolve which rules are enabled once, so `decide()` never has to consult `isRuleEnabled` per call. */
|
|
66
|
+
export function buildEngineContext(
|
|
67
|
+
config: RulesConfig,
|
|
68
|
+
repo: RepoSection,
|
|
69
|
+
rules: ReadonlyMap<RuleId, AnyRuleSpec>,
|
|
70
|
+
index: RepoIndexPort,
|
|
71
|
+
env: EnvPort,
|
|
72
|
+
agentId: AgentPort = noAgent,
|
|
73
|
+
agent: AgentSection = { user: '', protectedBranches: ['main', 'integration'] },
|
|
74
|
+
/** The repository root — see `EngineContext.root`. Optional, appended last, so every existing call site keeps compiling. */
|
|
75
|
+
root = '',
|
|
76
|
+
): BuildEngineContextResult {
|
|
77
|
+
const enabled = new Set<RuleId>()
|
|
78
|
+
for (const rule of rules.values()) {
|
|
79
|
+
const resolved = isRuleEnabled(config, rule.id, rule.category, rule.enabledByDefault)
|
|
80
|
+
if (!resolved.ok) return resolved
|
|
81
|
+
if (resolved.enabled) enabled.add(rule.id)
|
|
82
|
+
}
|
|
83
|
+
return { ok: true, value: { config, repo, agent, rules, enabled, index, env, agentId, root } }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export type DecideInput =
|
|
87
|
+
| { readonly kind: 'command'; readonly command: string }
|
|
88
|
+
| { readonly kind: 'tool-call'; readonly tool: string; readonly input: Readonly<Record<string, unknown>> }
|
|
89
|
+
|
|
90
|
+
export interface DenyDecision {
|
|
91
|
+
readonly blocked: true
|
|
92
|
+
readonly ruleId: RuleId
|
|
93
|
+
readonly userMessage: string
|
|
94
|
+
readonly agentMessage: string
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface AdviceDecision {
|
|
98
|
+
readonly blocked: false
|
|
99
|
+
readonly advice?: { readonly ruleId: RuleId; readonly userMessage: string; readonly agentMessage: string }
|
|
100
|
+
/**
|
|
101
|
+
* Set when a non-blocked command was rewritten to carry the session
|
|
102
|
+
* identity into its network git invocations (`adl.git-identity`,
|
|
103
|
+
* docs/architecture/cli-design.md §1a "Route, don't block"): the command to
|
|
104
|
+
* run instead of the one the agent sent. The pre-tool-use handler renders
|
|
105
|
+
* it per host (updatedInput / updated_input) or, on hosts whose hook
|
|
106
|
+
* contract cannot carry it, denies the call instead of running it
|
|
107
|
+
* unrewritten.
|
|
108
|
+
*/
|
|
109
|
+
readonly rewrite?: { readonly ruleId: RuleId; readonly command: string }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export type Decision = DenyDecision | AdviceDecision
|
|
113
|
+
|
|
114
|
+
/** Whitespace-collapsed and length-capped, exactly as the reference's deny.mjs built its log/message snippet. */
|
|
115
|
+
export function buildSnippet(command: string): string {
|
|
116
|
+
const collapsed = command.split(/\s+/).join(' ')
|
|
117
|
+
return collapsed.length > 220 ? `${collapsed.slice(0, 217)}...` : collapsed
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* `~/enact-vps` is the canonical checkout the fleet reconciler builds from, and
|
|
122
|
+
* it refuses to run while that tree is dirty — so an agent writing there stops
|
|
123
|
+
* every machine updating. Agents work in a clone and push to `main`; the
|
|
124
|
+
* reconciler pulls it itself. See impl/fs-canonical-checkout.ts.
|
|
125
|
+
*
|
|
126
|
+
* The list itself is declared once in
|
|
127
|
+
* `packages/agent-settings/surface-policy.json` and inlined into the compiled
|
|
128
|
+
* binary by `bun build --compile` — the repo is absent on machines that only
|
|
129
|
+
* carry /usr/local/bin, so this must never become a runtime file read.
|
|
130
|
+
*
|
|
131
|
+
* Handoff 5 (rule 4) extends the list with two security paths that are NOT
|
|
132
|
+
* the surface-policy fleet's to manage: `~/.config/enact/` and `/etc/enact/`,
|
|
133
|
+
* where every per-vault file lives. Hard-coded here so the rule set survives
|
|
134
|
+
* a surface-policy edit, not configurable from `adl-config.toml` — a
|
|
135
|
+
* security rule the repo can switch off is one the agent can route around.
|
|
136
|
+
*/
|
|
137
|
+
function classifyConfigFor(repo: RepoSection, home: string): ClassifyConfig {
|
|
138
|
+
const root = home.replace(/\/+$/, '')
|
|
139
|
+
const surface = loadSurfacePolicy().deny.paths.flatMap((name) => (root ? [`${root}/${name}`, `~/${name}`] : [`~/${name}`]))
|
|
140
|
+
// No trailing slash on the tree entries — the shell classifier checks
|
|
141
|
+
// `path.startsWith('${tree}/')`, so a tree ending in `/` would require a
|
|
142
|
+
// double slash in the path to match. The handoff's `deny.paths` list
|
|
143
|
+
// (`enact-vps` etc.) follows the same no-trailing-slash convention.
|
|
144
|
+
// `/etc/enact/` is absolute on every machine, so it doesn't need a `~`
|
|
145
|
+
// expansion; `~/.config/enact/` needs both spellings because the
|
|
146
|
+
// classifier compares literal tokens and does not expand `~`.
|
|
147
|
+
// adl roots plus the legacy enact roots, which still hold vault files on
|
|
148
|
+
// machines not yet cut over.
|
|
149
|
+
const vaultRoots = root
|
|
150
|
+
? [`${root}/.config/adl`, '~/.config/adl', '/etc/adl', `${root}/.config/enact`, '~/.config/enact', '/etc/enact']
|
|
151
|
+
: ['~/.config/adl', '/etc/adl', '~/.config/enact', '/etc/enact']
|
|
152
|
+
return {
|
|
153
|
+
...DEFAULT_CLASSIFY_CONFIG,
|
|
154
|
+
trustedScriptPrefixes: repo.trustedScriptPrefixes,
|
|
155
|
+
deniedTrees: [...surface, ...vaultRoots],
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function messageContextFor(command: string): MessageContext {
|
|
160
|
+
return { command, snippet: buildSnippet(command) }
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** `Blocked uninspectable shell input (...)` — shared with parse.uncertain.ts's own message() for the same reason. */
|
|
164
|
+
function missingCommandDecision(command: string): DenyDecision {
|
|
165
|
+
const ctx = messageContextFor(command)
|
|
166
|
+
return {
|
|
167
|
+
blocked: true,
|
|
168
|
+
ruleId: 'parse.uncertain',
|
|
169
|
+
userMessage: `Blocked uninspectable shell input (missing shell command). The hook fails closed; simplify the command and retry.`,
|
|
170
|
+
agentMessage: `DENIED missing shell command. The hook cannot prove that this shell input is safe. Remove the dynamic or unparsed shell construct and retry. Blocked command: ${ctx.snippet}`,
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Try every enabled rule, in registry order, against one Invocation; the first Finding wins. */
|
|
175
|
+
function firstFinding(inv: Invocation, ctx: EngineContext, command: string): { readonly rule: AnyRuleSpec; readonly finding: Finding } | null {
|
|
176
|
+
for (const rule of ctx.rules.values()) {
|
|
177
|
+
if (!ctx.enabled.has(rule.id)) continue
|
|
178
|
+
const finding = rule.match(inv, { params: {}, repo: ctx.repo, index: ctx.index, env: ctx.env, agent: ctx.agentId, agentConfig: ctx.agent, command, root: ctx.root })
|
|
179
|
+
if (finding) return { rule, finding }
|
|
180
|
+
}
|
|
181
|
+
return null
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function decideCommand(command: string, ctx: EngineContext): Decision {
|
|
185
|
+
if (!command.trim()) return missingCommandDecision(command)
|
|
186
|
+
|
|
187
|
+
const invs = invocations(command, classifyConfigFor(ctx.repo, ctx.env.home() || ''))
|
|
188
|
+
const msgCtx = messageContextFor(command)
|
|
189
|
+
|
|
190
|
+
let deny: { readonly rule: AnyRuleSpec; readonly finding: Finding } | null = null
|
|
191
|
+
let advice: { readonly rule: AnyRuleSpec; readonly finding: Finding } | null = null
|
|
192
|
+
for (const inv of invs) {
|
|
193
|
+
const found = firstFinding(inv, ctx, command)
|
|
194
|
+
if (!found) continue
|
|
195
|
+
if (found.finding.severity === 'deny') {
|
|
196
|
+
deny = found
|
|
197
|
+
break
|
|
198
|
+
}
|
|
199
|
+
if (!advice) advice = found
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (deny) {
|
|
203
|
+
const message = deny.rule.message(deny.finding, msgCtx)
|
|
204
|
+
return { blocked: true, ruleId: deny.rule.id, userMessage: message.user, agentMessage: message.agent }
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// adl.git-identity's REWRITE stage (docs/architecture/cli-design.md §1a;
|
|
208
|
+
// widened by STATUS.md 12p, "The standard", to
|
|
209
|
+
// every identity-bearing command class, not only network git): every rule
|
|
210
|
+
// passed — carry the resolved identity (steps 2-3: session env, else the
|
|
211
|
+
// machine default-agent file) into every identity-bearing invocation in
|
|
212
|
+
// the command. A VALID inline override (step 1) is honoured as-is
|
|
213
|
+
// (`kind: 'unchanged'`, handled inside `rewriteGitNetworkCommands` itself,
|
|
214
|
+
// independent of whether a fallback resolved at all); an invalid/empty
|
|
215
|
+
// inline override, or a sudo/doas wrapper, is denied here as a net (the
|
|
216
|
+
// rule can be disabled per-repo; an unsafe identity is never the rule's to
|
|
217
|
+
// see).
|
|
218
|
+
//
|
|
219
|
+
// H3 (STATUS.md 12p): `needs-identity` (an
|
|
220
|
+
// identity-bearing command with no inline override and no resolvable
|
|
221
|
+
// fallback) USED to fall through here unhandled, relying entirely on
|
|
222
|
+
// `adl.session-required-for-writes` having already denied the SAME
|
|
223
|
+
// command earlier in the rule pass — a separate classification (the
|
|
224
|
+
// shared shell/invocation.ts walker) that can be disabled per repo
|
|
225
|
+
// (`[rules."adl.session-required-for-writes"] enabled = false`) or simply
|
|
226
|
+
// not recognize a shape this scanner does. Either way, nothing else here
|
|
227
|
+
// stands between an unidentified network git command and a plain allow.
|
|
228
|
+
// The engine now denies it directly instead of trusting another rule to
|
|
229
|
+
// have already covered the same ground.
|
|
230
|
+
// L4 (STATUS.md 12p): resolve the fallback
|
|
231
|
+
// identity — which can read the REAL machine default-agent file
|
|
232
|
+
// (`resolveFromEnvOrFile`) — ONLY when the command actually has an
|
|
233
|
+
// identity-bearing piece that would use it. A probe scan with
|
|
234
|
+
// `fallback: null` is fallback-INDEPENDENT for every outcome except
|
|
235
|
+
// `needs-identity`: every `deny` reason but `unsafe-identity` fires the
|
|
236
|
+
// same regardless of the fallback's value (and `unsafe-identity` itself
|
|
237
|
+
// can only ever be reached once a fallback DOES resolve, so a null-probe
|
|
238
|
+
// never reports it), and `unchanged` means no piece needed one at all —
|
|
239
|
+
// so anything other than `unchanged` is worth a real resolution (both to
|
|
240
|
+
// decide `needs-identity` for certain, and so `deny`'s own message can
|
|
241
|
+
// name the resolved identity as a hint). Most commands reaching this
|
|
242
|
+
// point (ls, cat, git status, an unrelated tool, …) are not
|
|
243
|
+
// identity-bearing at all and, with this ordering, never touch the
|
|
244
|
+
// filesystem for this.
|
|
245
|
+
const probe = rewriteGitNetworkCommands(command, null)
|
|
246
|
+
let fallback: string | null = null
|
|
247
|
+
let outcome = probe
|
|
248
|
+
if (probe.kind !== 'unchanged') {
|
|
249
|
+
const resolution = resolveFromEnvOrFile(ctx.env)
|
|
250
|
+
fallback = resolution.ok ? resolution.agent : null
|
|
251
|
+
outcome = rewriteGitNetworkCommands(command, fallback)
|
|
252
|
+
}
|
|
253
|
+
if (outcome.kind === 'needs-identity') {
|
|
254
|
+
const message = gitIdentityNeedsIdentityMessage(msgCtx)
|
|
255
|
+
return { blocked: true, ruleId: RULE_ID, userMessage: message.user, agentMessage: message.agent }
|
|
256
|
+
}
|
|
257
|
+
if (outcome.kind === 'deny') {
|
|
258
|
+
const message = gitIdentityDenyMessage(outcome.reason, msgCtx, fallback ?? undefined)
|
|
259
|
+
return { blocked: true, ruleId: RULE_ID, userMessage: message.user, agentMessage: message.agent }
|
|
260
|
+
}
|
|
261
|
+
if (outcome.kind === 'rewrite') {
|
|
262
|
+
const rewrite = { ruleId: RULE_ID, command: outcome.command }
|
|
263
|
+
if (advice) {
|
|
264
|
+
const message = advice.rule.message(advice.finding, msgCtx)
|
|
265
|
+
return { blocked: false, advice: { ruleId: advice.rule.id, userMessage: message.user, agentMessage: message.agent }, rewrite }
|
|
266
|
+
}
|
|
267
|
+
return { blocked: false, rewrite }
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (advice) {
|
|
271
|
+
const message = advice.rule.message(advice.finding, msgCtx)
|
|
272
|
+
return { blocked: false, advice: { ruleId: advice.rule.id, userMessage: message.user, agentMessage: message.agent } }
|
|
273
|
+
}
|
|
274
|
+
return { blocked: false }
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function decideToolCall(tool: string, input: Readonly<Record<string, unknown>>, ctx: EngineContext): Decision {
|
|
278
|
+
const inv = { kind: 'tool-call' as const, tool, input }
|
|
279
|
+
const found = firstFinding(inv, ctx, `${tool} ${JSON.stringify(input)}`)
|
|
280
|
+
if (!found) return { blocked: false }
|
|
281
|
+
const msgCtx: MessageContext = { command: `${tool} ${JSON.stringify(input)}`, snippet: buildSnippet(tool) }
|
|
282
|
+
const message = found.rule.message(found.finding, msgCtx)
|
|
283
|
+
if (found.finding.severity === 'deny') {
|
|
284
|
+
return { blocked: true, ruleId: found.rule.id, userMessage: message.user, agentMessage: message.agent }
|
|
285
|
+
}
|
|
286
|
+
return { blocked: false, advice: { ruleId: found.rule.id, userMessage: message.user, agentMessage: message.agent } }
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** decide(command|toolcall, ctx) → Decision. Fail closed: an unparseable command denies (via parse.uncertain). */
|
|
290
|
+
export function decide(input: DecideInput, ctx: EngineContext): Decision {
|
|
291
|
+
if (input.kind === 'command') return decideCommand(input.command, ctx)
|
|
292
|
+
return decideToolCall(input.tool, input.input, ctx)
|
|
293
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `adl.build-run-denied` — docs/operations/agent-permissions.md row 12 (build run):
|
|
3
|
+
* denied for EVERY identity, unconditionally — "pipelines run on their own
|
|
4
|
+
* triggers". Unlike the other role rules in this package, this one does not
|
|
5
|
+
* branch on `ADL_AGENT_ID_AGENT` at all: the matrix's own hook-action column
|
|
6
|
+
* shows ❌ for both `agent-tarun`/`agent-vivek` and `agent-reviewer`, so there
|
|
7
|
+
* is no identity this tool is allowed for. With no identity at all,
|
|
8
|
+
* `adl.session-required-for-writes` (registered ahead of this rule) reports
|
|
9
|
+
* first with its own, more specific "no session" message; this rule is what
|
|
10
|
+
* fires once an identity IS present, which is the case that rule leaves
|
|
11
|
+
* alone.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { Invocation } from '../shell/invocation.ts'
|
|
15
|
+
import type { Finding, MessageContext, RuleSpec } from '../spec.ts'
|
|
16
|
+
import { noParams } from '../spec.ts'
|
|
17
|
+
import { detailString } from './messages.ts'
|
|
18
|
+
import { mcpToolName } from './mcp-tool.ts'
|
|
19
|
+
import { toolCallFor } from './adl-mcp-cli.ts'
|
|
20
|
+
|
|
21
|
+
const RULE_ID = 'adl.build-run-denied'
|
|
22
|
+
|
|
23
|
+
export const adlBuildRunDenied: RuleSpec = {
|
|
24
|
+
id: RULE_ID,
|
|
25
|
+
category: 'tool-call',
|
|
26
|
+
severity: 'deny',
|
|
27
|
+
enabledByDefault: true,
|
|
28
|
+
summary: 'Deny build_run for every identity (docs/operations/agent-permissions.md row 12) — the MCP tool AND its adl mcp cli equivalent (M4).',
|
|
29
|
+
params: noParams,
|
|
30
|
+
match(inv: Invocation): Finding | null {
|
|
31
|
+
// M4 (STATUS.md 12p): also catch `adl mcp cli build-run` — same tool, same deny.
|
|
32
|
+
const call = toolCallFor(inv)
|
|
33
|
+
if (call === null) return null
|
|
34
|
+
if (mcpToolName(call.tool) !== 'build_run') return null
|
|
35
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { tool: call.tool } }
|
|
36
|
+
},
|
|
37
|
+
message(finding: Finding, ctx: MessageContext) {
|
|
38
|
+
const tool = detailString(finding, 'tool')
|
|
39
|
+
const user = 'pipelines run on their own triggers'
|
|
40
|
+
return {
|
|
41
|
+
user,
|
|
42
|
+
agent:
|
|
43
|
+
`DENIED ${tool}: ${user}. No agent identity may queue a build — use build_list_or_get to inspect an ` +
|
|
44
|
+
`already-running or already-queued build instead. Blocked: ${ctx.snippet}`,
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
corpus: {
|
|
48
|
+
deny: [],
|
|
49
|
+
allow: ['ls -la', 'git status'],
|
|
50
|
+
},
|
|
51
|
+
}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `adl.git-credential-bypass` — H2 (STATUS.md 12p): deny, for agents, every
|
|
3
|
+
* shell shape that reaches Azure DevOps credentials or bypasses
|
|
4
|
+
* `bin/git-ado`'s routing entirely, without touching any of the specific
|
|
5
|
+
* verbs `adl.session-required-for-writes`/`adl.git-identity` already police:
|
|
6
|
+
*
|
|
7
|
+
* - An absolute git binary other than the managed front controller
|
|
8
|
+
* `/usr/local/bin/git` (that IS the path `bin/git-ado` installs itself
|
|
9
|
+
* at — see `../shell/invocation.ts`'s `binary` field on the `'git'`
|
|
10
|
+
* Invocation). Any OTHER absolute path (`/usr/bin/git`, a homebrew git,
|
|
11
|
+
* …) runs the real git binary directly, with no identity routing at
|
|
12
|
+
* all — a bare `git` (resolved via `$PATH`, the normal case) is
|
|
13
|
+
* untouched.
|
|
14
|
+
* - `git remote update` — fetches every configured remote, the same
|
|
15
|
+
* network operation as `git fetch`, but not a verb
|
|
16
|
+
* `adl.session-required-for-writes`'s `NETWORK_GIT_VERBS` recognizes.
|
|
17
|
+
* - `git submodule update/sync/foreach` — `update`/`sync` can fetch a
|
|
18
|
+
* submodule's own remote; `foreach` runs an arbitrary shell command once
|
|
19
|
+
* per submodule, unauditable by this hook.
|
|
20
|
+
* - `git credential fill/approve/reject` — reads, stores or discards a
|
|
21
|
+
* credential directly, sidestepping the front controller entirely.
|
|
22
|
+
*
|
|
23
|
+
* `security find-generic-password`/`find-internet-password` naming Azure
|
|
24
|
+
* DevOps (the fifth H2 item — a macOS Keychain read, not a git operation at
|
|
25
|
+
* all) is `adl.security-keychain-ado` below, in the same file since it
|
|
26
|
+
* shares `namesAzureDevops`, but registered as its own `category: 'tool'`
|
|
27
|
+
* rule: `tests/unit/rules-git-deny-guidance.test.ts` requires every
|
|
28
|
+
* `category: 'git'` deny to carry the git-specific "don't route around this
|
|
29
|
+
* with plumbing" guidance, which does not apply to a keychain read.
|
|
30
|
+
*
|
|
31
|
+
* `git -c alias.*` is NOT a blanket deny (regression risk: this repo's own
|
|
32
|
+
* git-alias resolution, `../shell/invocation.ts`'s `configuredGitAlias`, is
|
|
33
|
+
* an intentional, heavily-tested feature — `tests/unit/rules-git-worktree.
|
|
34
|
+
* test.ts`'s dozens of `git -c alias.wt=worktree`-shaped corpus entries SEE
|
|
35
|
+
* THROUGH a non-network inline alias on purpose). Two narrower, resolved
|
|
36
|
+
* pieces of that space ARE covered, R9 correcting this header's stale
|
|
37
|
+
* "BLOCKED" note (STATUS.md 12p):
|
|
38
|
+
* - a SELF-referential inline `-c alias.<verb>=<value>`/`--config-env`
|
|
39
|
+
* naming the LITERAL subcommand this invocation runs, where `<value>`'s
|
|
40
|
+
* own verb is network/credential — `adl.git-identity`'s own
|
|
41
|
+
* `network-alias-redefinition` reason (`../shell/git-identity.ts`), not
|
|
42
|
+
* this rule.
|
|
43
|
+
* - R4 (re-review 2026-09-28 night): a REPO-CONFIGURED alias (`.git/config`,
|
|
44
|
+
* invisible to the walker's own inline/env-var-only resolution) whose
|
|
45
|
+
* value's verb is network/credential — `repo-alias-network-verb` below,
|
|
46
|
+
* resolved via the injectable `ctx.index.configuredAlias` port
|
|
47
|
+
* (`git config --get alias.<verb>` in the command's own cwd) so tests
|
|
48
|
+
* stay hermetic. Still narrower than a blanket deny: a non-network
|
|
49
|
+
* repo-configured alias (`git st` → `alias.st=status`) is untouched.
|
|
50
|
+
*
|
|
51
|
+
* R4 also adds three more front-controller bypasses here, all sharing the
|
|
52
|
+
* same reasoning: `/usr/local/bin/git` (`bin/git-ado`) routes on the
|
|
53
|
+
* LITERAL verb/binary an agent typed — it does not resolve `PATH`
|
|
54
|
+
* overrides, `command -p`'s own default `$PATH`, or `xcrun`'s tool
|
|
55
|
+
* resolution, any of which can select a DIFFERENT `git` binary than the
|
|
56
|
+
* managed front controller while still LOOKING like an ordinary `git`
|
|
57
|
+
* invocation to this hook's own classifier:
|
|
58
|
+
* - `PATH=`/`export PATH=` combined with a `git` invocation on the same
|
|
59
|
+
* line (`path-override-git`).
|
|
60
|
+
* - `command -p git …`, which explicitly uses the system default `$PATH`
|
|
61
|
+
* (`command-dash-p-git`).
|
|
62
|
+
* - `xcrun git …`, Xcode's own tool locator (`xcrun-git`).
|
|
63
|
+
* And a fifth: `git credential-<helper>` (or the standalone
|
|
64
|
+
* `git-credential-<helper>` binary git itself resolves that spelling to) —
|
|
65
|
+
* `credential-helper-binary` — invokes the platform credential HELPER
|
|
66
|
+
* directly, one layer below the `git credential fill/approve/reject`
|
|
67
|
+
* protocol commands this file already denies.
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
import type { Invocation } from '../shell/invocation.ts'
|
|
71
|
+
import type { Token } from '../shell/token.ts'
|
|
72
|
+
import { tokenValue } from '../shell/token.ts'
|
|
73
|
+
import type { Finding, MessageContext, RuleContext, RuleSpec } from '../spec.ts'
|
|
74
|
+
import { noParams } from '../spec.ts'
|
|
75
|
+
import { isAdoUrl } from './git-helpers.ts'
|
|
76
|
+
import { detailString, gitAgentTail } from './messages.ts'
|
|
77
|
+
import { networkAliasVerb } from '../shell/git-identity.ts'
|
|
78
|
+
|
|
79
|
+
export const RULE_ID = 'adl.git-credential-bypass'
|
|
80
|
+
export const SECURITY_RULE_ID = 'adl.security-keychain-ado'
|
|
81
|
+
|
|
82
|
+
/** The one absolute git path `bin/git-ado` installs itself at — see the module doc. */
|
|
83
|
+
const MANAGED_GIT_BINARY = '/usr/local/bin/git'
|
|
84
|
+
|
|
85
|
+
/** The first non-flag operand of `rest` — git's own `--` ends flag parsing early, same convention every other rule in this family uses. */
|
|
86
|
+
function firstOperand(rest: readonly Token[]): string | null {
|
|
87
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
88
|
+
const value = tokenValue(rest[index] as Token)
|
|
89
|
+
if (value === '--') {
|
|
90
|
+
const next = rest[index + 1]
|
|
91
|
+
return next !== undefined ? tokenValue(next).toLowerCase() : null
|
|
92
|
+
}
|
|
93
|
+
if (!value.startsWith('-')) return value.toLowerCase()
|
|
94
|
+
}
|
|
95
|
+
return null
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const SUBMODULE_NETWORK_SUBCOMMANDS: ReadonlySet<string> = new Set(['update', 'sync', 'foreach'])
|
|
99
|
+
const CREDENTIAL_HELPER_SUBCOMMANDS: ReadonlySet<string> = new Set(['fill', 'approve', 'reject'])
|
|
100
|
+
|
|
101
|
+
/** `find-generic-password`, `find-internet-password`, or any other `find-*-password` subcommand `security` accepts. */
|
|
102
|
+
const FIND_PASSWORD_RE = /^find-[a-z]+-password$/i
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Whether ANY argument names Azure DevOps — not just an explicit URL
|
|
106
|
+
* (`isAdoUrl`, for `https://dev.azure.com/...`), since a keychain service/
|
|
107
|
+
* account label is prose, not a URL: `"Azure DevOps"`, `azure-devops-pat`,
|
|
108
|
+
* `dev.azure.com`, `visualstudio.com`. Kept to those specific substrings
|
|
109
|
+
* (not a bare `ado`) to avoid a false positive on an unrelated service whose
|
|
110
|
+
* name happens to contain those three letters.
|
|
111
|
+
*/
|
|
112
|
+
function namesAzureDevops(values: readonly string[]): boolean {
|
|
113
|
+
return values.some((value) => {
|
|
114
|
+
const lower = value.toLowerCase()
|
|
115
|
+
return isAdoUrl(value) || lower.includes('azure') || lower.includes('devops') || lower.includes('visualstudio')
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function securityFindsAdoPassword(inv: Invocation & { kind: 'command' }): boolean {
|
|
120
|
+
const values = inv.args.map((token) => tokenValue(token))
|
|
121
|
+
if (!values.some((value) => FIND_PASSWORD_RE.test(value))) return false
|
|
122
|
+
return namesAzureDevops(values)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** `git credential-<helper>` as a git subcommand, or the standalone `git-credential-<helper>` binary git itself resolves that spelling to. */
|
|
126
|
+
const CREDENTIAL_HELPER_BINARY_PREFIX = 'credential-'
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* `credential-cache` is git's OWN transient, in-memory helper (a daemon
|
|
130
|
+
* that holds a credential for a short-lived window and exits — `git
|
|
131
|
+
* credential-cache exit` merely stops it); it never reads or writes a
|
|
132
|
+
* platform secret store the way `credential-osxkeychain`/`credential-
|
|
133
|
+
* manager`/… do, and this exact allow case predates R4 (H2's own corpus).
|
|
134
|
+
* Excluded from the deny by name rather than widened into a blanket
|
|
135
|
+
* "every credential-* helper", to avoid regressing that settled behaviour.
|
|
136
|
+
*/
|
|
137
|
+
const CREDENTIAL_HELPER_ALLOWED_NAMES: ReadonlySet<string> = new Set(['cache'])
|
|
138
|
+
|
|
139
|
+
function isDeniedCredentialHelper(subcommandOrName: string): boolean {
|
|
140
|
+
if (!subcommandOrName.startsWith(CREDENTIAL_HELPER_BINARY_PREFIX)) return false
|
|
141
|
+
return !CREDENTIAL_HELPER_ALLOWED_NAMES.has(subcommandOrName.slice(CREDENTIAL_HELPER_BINARY_PREFIX.length))
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Git's own real subcommand vocabulary (porcelain and common plumbing),
|
|
146
|
+
* lower-cased — R4 (STATUS.md 12p): gates the repo-
|
|
147
|
+
* configured-alias lookup (`ctx.index.configuredAlias`) to an UNKNOWN verb
|
|
148
|
+
* only, per this finding's own text ("resolve unknown git verbs"), so an
|
|
149
|
+
* ordinary `git status`/`git log`/… never pays for a `git config --get`
|
|
150
|
+
* shell-out. Not exhaustive — an obscure real git verb missing here only
|
|
151
|
+
* costs one harmless extra (correctness-preserving) lookup that resolves to
|
|
152
|
+
* nothing, never a false deny.
|
|
153
|
+
*/
|
|
154
|
+
const KNOWN_GIT_VERBS: ReadonlySet<string> = new Set([
|
|
155
|
+
'add', 'am', 'apply', 'archive', 'bisect', 'blame', 'branch', 'bundle', 'checkout', 'cherry-pick',
|
|
156
|
+
'clean', 'clone', 'commit', 'config', 'credential', 'describe', 'diff', 'difftool', 'fetch', 'format-patch',
|
|
157
|
+
'fsck', 'gc', 'grep', 'help', 'init', 'instaweb', 'log', 'ls-files', 'ls-remote', 'maintenance',
|
|
158
|
+
'merge', 'mergetool', 'mv', 'notes', 'pull', 'push', 'rebase', 'reflog', 'remote', 'request-pull',
|
|
159
|
+
'reset', 'restore', 'revert', 'rev-parse', 'rm', 'send-email', 'shortlog', 'show', 'sparse-checkout', 'stash',
|
|
160
|
+
'status', 'submodule', 'switch', 'tag', 'verify-commit', 'verify-tag', 'version', 'whatchanged', 'worktree',
|
|
161
|
+
])
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* `PATH=`/`export PATH=` anywhere in `command`, co-occurring with a `git`
|
|
165
|
+
* invocation this rule is already deciding — coarse (whole-command, not
|
|
166
|
+
* piece-scoped) by design, matching R3's own precedent elsewhere in this
|
|
167
|
+
* package: a PATH override ahead of `git` ANYWHERE on the line is suspicious
|
|
168
|
+
* enough on its own that over-denial costs nothing legitimate.
|
|
169
|
+
*/
|
|
170
|
+
function pathOverridePresent(command: string): boolean {
|
|
171
|
+
return /(?:^|[\s;&|(])(?:export\s+)?PATH=/.test(command)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** `command -p git …` — `-p` makes `command` search the system default `$PATH`, bypassing any override AND the managed front controller alike. */
|
|
175
|
+
function commandDashPPresent(command: string): boolean {
|
|
176
|
+
return /\bcommand\s+(?:-\S+\s+)*-p\b/.test(command)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** `xcrun git …` — Xcode's own tool locator, independent of `$PATH`. */
|
|
180
|
+
function xcrunGitPresent(command: string): boolean {
|
|
181
|
+
return /\bxcrun\s+git\b/i.test(command)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export const adlGitCredentialBypass: RuleSpec = {
|
|
185
|
+
id: RULE_ID,
|
|
186
|
+
category: 'git',
|
|
187
|
+
severity: 'deny',
|
|
188
|
+
enabledByDefault: true,
|
|
189
|
+
summary: 'Deny an absolute non-managed git binary, git remote update, git submodule update/sync/foreach, git credential fill/approve/reject, a direct credential-helper binary, a PATH/command -p/xcrun bypass, and a repo-configured alias to a network verb.',
|
|
190
|
+
params: noParams,
|
|
191
|
+
match(inv: Invocation, ctx: RuleContext<Record<string, never>>): Finding | null {
|
|
192
|
+
if (inv.kind === 'command') {
|
|
193
|
+
const name = inv.name.toLowerCase()
|
|
194
|
+
if (name.startsWith('git-') && isDeniedCredentialHelper(name.slice('git-'.length))) {
|
|
195
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'credential-helper-binary', helper: inv.name } }
|
|
196
|
+
}
|
|
197
|
+
return null
|
|
198
|
+
}
|
|
199
|
+
if (inv.kind !== 'git') return null
|
|
200
|
+
if (inv.binary !== undefined && inv.binary.startsWith('/') && inv.binary !== MANAGED_GIT_BINARY) {
|
|
201
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'absolute-git-binary', binary: inv.binary } }
|
|
202
|
+
}
|
|
203
|
+
if (inv.subcommand === 'remote' && firstOperand(inv.rest) === 'update') {
|
|
204
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'git-remote-update' } }
|
|
205
|
+
}
|
|
206
|
+
if (inv.subcommand === 'submodule' && SUBMODULE_NETWORK_SUBCOMMANDS.has(firstOperand(inv.rest) ?? '')) {
|
|
207
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'git-submodule-network' } }
|
|
208
|
+
}
|
|
209
|
+
if (inv.subcommand === 'credential' && CREDENTIAL_HELPER_SUBCOMMANDS.has(firstOperand(inv.rest) ?? '')) {
|
|
210
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'git-credential-helper' } }
|
|
211
|
+
}
|
|
212
|
+
if (isDeniedCredentialHelper(inv.subcommand)) {
|
|
213
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'credential-helper-binary', helper: inv.subcommand } }
|
|
214
|
+
}
|
|
215
|
+
const command = ctx.command ?? ''
|
|
216
|
+
if (pathOverridePresent(command)) {
|
|
217
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'path-override-git' } }
|
|
218
|
+
}
|
|
219
|
+
if (commandDashPPresent(command)) {
|
|
220
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'command-dash-p-git' } }
|
|
221
|
+
}
|
|
222
|
+
if (xcrunGitPresent(command)) {
|
|
223
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'xcrun-git' } }
|
|
224
|
+
}
|
|
225
|
+
if (!KNOWN_GIT_VERBS.has(inv.subcommand)) {
|
|
226
|
+
const alias = ctx.index.configuredAlias?.(inv.subcommand) ?? null
|
|
227
|
+
if (alias !== null && networkAliasVerb(alias)) {
|
|
228
|
+
return { ruleId: RULE_ID, severity: 'deny', detail: { reason: 'repo-alias-network-verb', alias: inv.subcommand } }
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return null
|
|
232
|
+
},
|
|
233
|
+
message(finding: Finding, ctx: MessageContext) {
|
|
234
|
+
const reason = detailString(finding, 'reason')
|
|
235
|
+
const specific =
|
|
236
|
+
reason === 'absolute-git-binary'
|
|
237
|
+
? `Blocked an absolute git binary (${finding.detail.binary ?? 'a non-managed path'}) other than the managed front controller ${MANAGED_GIT_BINARY}.`
|
|
238
|
+
: reason === 'git-remote-update'
|
|
239
|
+
? 'Blocked `git remote update`: it fetches every configured remote, the same network operation as `git fetch`.'
|
|
240
|
+
: reason === 'git-submodule-network'
|
|
241
|
+
? 'Blocked `git submodule update/sync/foreach`: it can fetch a submodule remote, or run an arbitrary command once per submodule.'
|
|
242
|
+
: reason === 'git-credential-helper'
|
|
243
|
+
? 'Blocked `git credential fill/approve/reject`: it reads, stores, or discards a credential directly.'
|
|
244
|
+
: reason === 'credential-helper-binary'
|
|
245
|
+
? `Blocked the credential helper (${finding.detail.helper ?? 'git-credential-*'}) directly: it reads or stores a credential straight from the platform's own store, one layer below the \`git credential\` protocol commands.`
|
|
246
|
+
: reason === 'path-override-git'
|
|
247
|
+
? 'Blocked a `PATH=`/`export PATH=` override alongside a `git` invocation: it can select a different `git` binary than the managed front controller.'
|
|
248
|
+
: reason === 'command-dash-p-git'
|
|
249
|
+
? "Blocked `command -p git …`: `-p` runs with the system default `$PATH`, which can bypass the managed front controller."
|
|
250
|
+
: reason === 'xcrun-git'
|
|
251
|
+
? "Blocked `xcrun git …`: Xcode's own tool locator can resolve to a different `git` binary than the managed front controller."
|
|
252
|
+
: `Blocked \`git ${finding.detail.alias ?? '<alias>'}\`: this repository's own \`.git/config\` resolves it to a network or credential operation the managed front controller would not see through.`
|
|
253
|
+
return {
|
|
254
|
+
user: specific,
|
|
255
|
+
agent:
|
|
256
|
+
`DENIED ${specific} Use \`adl id token <agent>\` or the Azure DevOps MCP server, which brokers credentials as ` +
|
|
257
|
+
'the resolved agent identity — never a raw git binary outside the managed front controller, a PATH/`command -p`/`xcrun` ' +
|
|
258
|
+
`bypass, a repo-configured alias to a network verb, or a submodule/remote/credential-helper shortcut. ${gitAgentTail(ctx.snippet)}`,
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
corpus: {
|
|
262
|
+
deny: [
|
|
263
|
+
'/usr/bin/git push origin main',
|
|
264
|
+
'/opt/homebrew/bin/git status',
|
|
265
|
+
'git remote update',
|
|
266
|
+
'git remote update origin',
|
|
267
|
+
'git submodule update --init',
|
|
268
|
+
'git submodule sync',
|
|
269
|
+
'git submodule foreach "git pull"',
|
|
270
|
+
'git credential fill',
|
|
271
|
+
'git credential approve',
|
|
272
|
+
'git credential reject',
|
|
273
|
+
'git credential-osxkeychain get',
|
|
274
|
+
'git-credential-osxkeychain get',
|
|
275
|
+
'PATH=/tmp/evil:$PATH git push origin main',
|
|
276
|
+
'export PATH=/tmp/evil:$PATH && git push origin main',
|
|
277
|
+
'command -p git push origin main',
|
|
278
|
+
'xcrun git push origin main',
|
|
279
|
+
// The repo-configured-alias case ('repo-alias-network-verb') needs a
|
|
280
|
+
// specific `ctx.index.configuredAlias` fixture the shared corpus
|
|
281
|
+
// cannot supply — see tests/unit/rules-adl-git-credential-bypass.test.ts's
|
|
282
|
+
// dedicated "repo-configured alias" describe block instead.
|
|
283
|
+
],
|
|
284
|
+
allow: [
|
|
285
|
+
'git status',
|
|
286
|
+
'/usr/local/bin/git status',
|
|
287
|
+
'git remote -v',
|
|
288
|
+
'git remote add origin https://github.com/org/repo',
|
|
289
|
+
'git submodule status',
|
|
290
|
+
'git credential-cache exit',
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export const adlSecurityKeychainAdo: RuleSpec = {
|
|
296
|
+
id: SECURITY_RULE_ID,
|
|
297
|
+
category: 'tool',
|
|
298
|
+
severity: 'deny',
|
|
299
|
+
enabledByDefault: true,
|
|
300
|
+
summary: 'Deny `security find-generic-password`/`find-internet-password` naming Azure DevOps — read the credential through adl instead of the macOS keychain directly.',
|
|
301
|
+
params: noParams,
|
|
302
|
+
match(inv: Invocation): Finding | null {
|
|
303
|
+
if (inv.kind !== 'command' || inv.name !== 'security') return null
|
|
304
|
+
if (!securityFindsAdoPassword(inv)) return null
|
|
305
|
+
return { ruleId: SECURITY_RULE_ID, severity: 'deny', detail: { reason: 'security-find-password-ado' } }
|
|
306
|
+
},
|
|
307
|
+
message(_finding: Finding, ctx: MessageContext) {
|
|
308
|
+
const user = 'Blocked `security find-*-password` naming Azure DevOps: it reads a stored credential straight out of the macOS keychain.'
|
|
309
|
+
return {
|
|
310
|
+
user,
|
|
311
|
+
agent:
|
|
312
|
+
`DENIED ${user} Use \`adl id token <agent>\` or the Azure DevOps MCP server, which brokers credentials as the ` +
|
|
313
|
+
`resolved agent identity — never the macOS keychain directly. Blocked command: ${ctx.snippet}`,
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
corpus: {
|
|
317
|
+
deny: ['security find-generic-password -s "Azure DevOps" -w', 'security find-internet-password -s dev.azure.com -w'],
|
|
318
|
+
allow: ['security find-generic-password -s "GitHub" -w', 'security list-keychains'],
|
|
319
|
+
},
|
|
320
|
+
}
|