@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.12 → 0.1.26
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 +2 -2
- package/bin/git +16 -17
- package/bin/git-ado +25 -24
- package/bin/git-defaults +173 -0
- package/bin/health-check +8 -1
- package/bin/kimi-hooks +1 -1
- package/bin/lib/adl-package.sh +257 -0
- package/bin/lib/fleet-host.sh +8 -5
- package/bin/reconcile +482 -232
- package/bin/reconcile-host +30 -20
- package/bin/setup +20 -17
- package/bin/shell-path-policy +15 -5
- package/bin/sync-and-reconcile +62 -64
- package/bin/validate-manifest +33 -9
- package/package.json +2 -10
- package/packages/agent-hooks/README.md +14 -9
- package/packages/agent-hooks/assets/hooks.json +0 -20
- package/packages/agent-hooks/src/cli/args.ts +1 -1
- package/packages/agent-hooks/src/cli/doctor.ts +6 -58
- package/packages/agent-hooks/src/deploy/deploy.ts +12 -41
- package/packages/agent-hooks/src/deploy/doctor.ts +8 -11
- package/packages/agent-hooks/src/deploy/index.ts +14 -14
- package/packages/agent-hooks/src/deploy/json-merge.ts +7 -8
- package/packages/agent-hooks/src/deploy/legacy-lock.ts +2 -2
- package/packages/agent-hooks/src/deploy/list.ts +1 -1
- package/packages/agent-hooks/src/deploy/lock.ts +31 -12
- package/packages/agent-hooks/src/deploy/profile.ts +3 -4
- package/packages/agent-hooks/src/deploy/source.ts +1 -1
- package/packages/agent-hooks/src/gating/config.ts +10 -24
- package/packages/agent-hooks/src/gating/root.ts +3 -3
- package/packages/agent-hooks/src/hooks/briefing/handler.ts +2 -2
- package/packages/agent-hooks/src/hooks/briefing/index.ts +27 -287
- package/packages/agent-hooks/src/hooks/contract.ts +17 -17
- package/packages/agent-hooks/src/hooks/crg/background.ts +27 -0
- package/packages/agent-hooks/src/hooks/crg/index.ts +7 -6
- package/packages/agent-hooks/src/hooks/log.ts +8 -10
- package/packages/agent-hooks/src/hooks/user-prompt-submit/match.ts +1 -1
- package/packages/agent-hooks/src/hooks/user-prompt-submit/tokenizer.ts +1 -1
- package/packages/agent-hooks/src/hooks/user-prompt-submit/vector.ts +6 -5
- package/packages/agent-hooks/src/hosts/registry.ts +1 -1
- package/packages/agent-hooks/src/log/adl-dir.ts +44 -0
- package/packages/agent-hooks/src/log/writer.ts +16 -2
- package/packages/agent-hooks/src/main.ts +7 -41
- package/packages/agent-hooks/src/pre-tool-use/handler.ts +71 -82
- package/packages/agent-hooks/src/rules/engine.ts +13 -17
- package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +3 -3
- package/packages/agent-hooks/src/rules/impl/adl-git-credential-bypass.ts +12 -14
- package/packages/agent-hooks/src/rules/impl/adl-git-identity.ts +28 -28
- package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +8 -9
- package/packages/agent-hooks/src/rules/impl/adl-human-azdo-bypass.ts +56 -59
- package/packages/agent-hooks/src/rules/impl/adl-identity.ts +16 -23
- package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +19 -16
- package/packages/agent-hooks/src/rules/impl/adl-pr-complete-pending.ts +2 -2
- package/packages/agent-hooks/src/rules/impl/adl-pr-review-role.ts +9 -12
- package/packages/agent-hooks/src/rules/impl/adl-pr-role.ts +5 -7
- package/packages/agent-hooks/src/rules/impl/adl-run-required.ts +411 -0
- package/packages/agent-hooks/src/rules/impl/adl-token-minting-role.ts +4 -5
- package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +6 -7
- package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +77 -70
- package/packages/agent-hooks/src/rules/impl/deny-allowlist.ts +159 -0
- package/packages/agent-hooks/src/rules/impl/git-helpers.ts +21 -23
- package/packages/agent-hooks/src/rules/impl/git-worktree.ts +14 -28
- package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +3 -3
- package/packages/agent-hooks/src/rules/impl/messages.ts +1 -1
- package/packages/agent-hooks/src/rules/impl/pr-completion.ts +1 -1
- package/packages/agent-hooks/src/rules/impl/tool-azure-devops.ts +35 -46
- package/packages/agent-hooks/src/rules/impl/tool-find.ts +34 -7
- package/packages/agent-hooks/src/rules/impl/tool-grep.ts +34 -12
- package/packages/agent-hooks/src/rules/impl/tool-native-search.ts +52 -9
- package/packages/agent-hooks/src/rules/ports.ts +5 -7
- package/packages/agent-hooks/src/rules/registry.ts +4 -6
- package/packages/agent-hooks/src/rules/shell/git-identity.ts +86 -101
- package/packages/agent-hooks/src/rules/shell/git-internals.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/invocation.ts +24 -118
- package/packages/agent-hooks/src/rules/shell/piped-script.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/prefixes.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/protected-carrier-writes.ts +11 -10
- package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +26 -26
- package/packages/agent-hooks/src/rules/shell/substitution.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/xargs.ts +2 -2
- package/packages/agent-hooks/src/rules/spec.ts +2 -2
- package/packages/agent-settings/README.md +287 -0
- package/packages/agent-settings/assets/GLOBAL-AGENTS.md +14 -16
- package/packages/agent-settings/assets/agents/architect.toml +2 -0
- package/packages/agent-settings/assets/agents/code-reviewer.toml +2 -0
- package/packages/agent-settings/assets/agents/executor.toml +2 -0
- package/packages/agent-settings/assets/agents/explore.toml +2 -0
- package/packages/agent-settings/assets/agents/planner.toml +2 -0
- package/packages/agent-settings/assets/mcp.json +0 -4
- package/packages/agent-settings/deploy-profile.json +139 -0
- package/packages/agent-settings/deploy-profile.schema.json +147 -0
- package/packages/agent-settings/managed/README.md +29 -30
- package/packages/agent-settings/managed/codex-requirements.toml +9 -9
- package/packages/agent-settings/package.json +20 -0
- package/packages/agent-settings/src/deploy/agent-render.ts +2 -2
- package/packages/agent-settings/src/deploy/agent-toml.ts +1 -1
- package/packages/agent-settings/src/deploy/agents-deploy.ts +17 -3
- package/packages/agent-settings/src/deploy/doctor.ts +3 -83
- package/packages/agent-settings/src/deploy/index.ts +6 -33
- package/packages/agent-settings/src/deploy/legacy-lock.ts +6 -6
- package/packages/agent-settings/src/deploy/list.ts +5 -19
- package/packages/agent-settings/src/deploy/lock.ts +8 -18
- package/packages/agent-settings/src/deploy/mcp-deploy.ts +10 -5
- package/packages/agent-settings/src/deploy/mcp-merge.ts +22 -3
- package/packages/agent-settings/src/deploy/mcp-source.ts +1 -1
- package/packages/agent-settings/src/deploy/profile.ts +11 -35
- package/packages/agent-settings/src/deploy/retire-lean-ctx.ts +184 -0
- package/packages/agent-settings/src/deploy/settings.ts +17 -22
- package/packages/agent-settings/src/global-surface-sweep.ts +0 -2
- package/packages/agent-settings/src/kimi-hooks.ts +339 -192
- package/packages/agent-settings/src/opencode-hooks.ts +1 -1
- package/packages/agent-settings/tsconfig.json +23 -0
- package/packages/agent-skills/assets/agent-search-tool-audit/SKILL.md +120 -0
- package/packages/agent-skills/assets/agent-search-tool-audit/scripts/audit.sh +276 -0
- package/packages/agent-skills/assets/debug-issue/SKILL.md +8 -7
- package/packages/agent-skills/assets/explore-codebase/SKILL.md +13 -13
- package/packages/agent-skills/assets/refactor-safely/SKILL.md +12 -11
- package/packages/agent-skills/assets/review-changes/SKILL.md +7 -7
- package/packages/agent-skills/assets/testing/references/e2e.md +37 -0
- package/packages/agent-skills/assets/testing/references/integration.md +37 -0
- package/packages/agent-skills/assets/testing/references/unit.md +32 -0
- package/packages/agent-skills/dist/deploy.d.ts +2 -0
- package/packages/agent-skills/dist/deploy.d.ts.map +1 -1
- package/packages/agent-skills/dist/deploy.js +27 -1
- package/packages/agent-skills/dist/deploy.js.map +1 -1
- package/packages/agent-skills/dist/doctor.d.ts +0 -2
- package/packages/agent-skills/dist/doctor.d.ts.map +1 -1
- package/packages/agent-skills/dist/doctor.js +1 -1
- package/packages/agent-skills/dist/doctor.js.map +1 -1
- package/packages/agent-skills/dist/fs-utils.d.ts +0 -1
- package/packages/agent-skills/dist/fs-utils.d.ts.map +1 -1
- package/packages/agent-skills/dist/fs-utils.js +1 -1
- package/packages/agent-skills/dist/fs-utils.js.map +1 -1
- package/packages/agent-skills/src/deploy.ts +29 -1
- package/packages/agent-skills/src/doctor.ts +1 -1
- package/packages/agent-skills/src/fs-utils.ts +1 -1
- package/packages/azdo/README.md +10 -9
- package/packages/azdo/package.json +1 -3
- package/packages/azdo/src/azdo-pl.ts +2 -54
- package/packages/azdo/src/azdo-pr-review.ts +4 -4
- package/packages/azdo/src/azdo-repo-doctor.ts +101 -52
- package/packages/azdo/src/azdo-wit.ts +41 -2
- package/packages/azdo/src/lib/agent-identity.ts +12 -14
- package/packages/azdo/src/lib/agent-token.ts +2 -2
- package/packages/azdo/src/lib/client.ts +0 -5
- package/packages/azdo/src/lib/graph-identity.ts +4 -4
- package/packages/azdo/src/workflow-rules-matrix.csv +85 -0
- package/packages/azdo/src/workflow-rules.ts +128 -0
- package/packages/fleet/manifest.json +35 -11
- package/packages/fleet/manifest.schema.json +62 -10
- package/packages/fleet/src/default-agent-file.ts +3 -3
- package/packages/fleet/src/install-adl-package.ts +73 -15
- package/packages/fleet/src/install-embedding-model.ts +13 -13
- package/packages/fleet/src/managed-settings.ts +7 -7
- package/packages/fleet/src/repo-maintain.ts +91 -55
- package/packages/fleet/src/scratch-reap.ts +5 -5
- package/packages/fleet/src/vscode-settings.ts +5 -5
- package/packages/repo-controls/README.md +141 -43
- package/packages/repo-controls/assets/promote.ts +4 -4
- package/packages/repo-controls/assets/reconcile-guard.sh +10 -46
- package/packages/repo-controls/assets/version-bump.sh +31 -84
- package/packages/repo-controls/bunfig.toml +6 -7
- package/packages/repo-controls/package/adl-compliance/AGENTS.md +5 -6
- package/packages/repo-controls/package/adl-compliance/conftest.py +3 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +4 -16
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +9 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/notes.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/check.py +266 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.hidden.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/data.csv +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/diagram.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/mock.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/sub/nested.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p1.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p2.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p3.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p4.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p5.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/build.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/overview.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/install.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/start.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-001-tenancy.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-002-carrier.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-003-cli.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-old.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-older.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-01.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-02.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-03.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-04.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-05.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-06.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-07.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-08.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-09.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-10.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-11.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-12.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-13.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-14.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-15.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-16.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/e.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/short/only.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/grants.yaml +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/test_check.py +345 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +18 -5
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +35 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/check.py +91 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/CLAUDE.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/-leading-hyphen.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/double--hyphen.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/getting started.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/nested/page-here.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/trailing-hyphen-.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/ui-contract.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/user_profile.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/UI-CONTRACT.png +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/diagram.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/index.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/notes.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/reference.html +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/2026-10-experiment.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/UI-CONTRACT.md +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/test_check.py +194 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +14 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +5 -5
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-legacy/docs/compliance/index.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-type/docs/compliance/index.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +58 -6
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +64 -17
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +60 -9
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-clean/docs/notes.md +17 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-no-lines/docs/notes.md +13 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/no-type.md +9 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-experiment.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-research.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs-okf-profiles.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs/architecture/bad-status.md +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/experiment-ok.md +15 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-key.md +15 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-keys.md +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-created.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-description.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-last-update.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-sources.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-status.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-title.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/optional-keys.md +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/research-ok.md +14 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/created-date.md +21 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/research-shaped.md +19 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/operations/runbook.md +26 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +228 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +11 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +5 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +160 -44
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/a.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/b.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/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-missing-tree/grants.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/a.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/b.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/c.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/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-stale-entry/grants.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/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-unusable-register/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/register.py +127 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +265 -29
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +75 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +194 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +56 -10
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +256 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +40 -12
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +108 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +2 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +23 -6
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +76 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +58 -17
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +161 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +35 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +108 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +281 -61
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/absolute-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/backslash-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/baseline-is-a-list.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/boolean-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/dot-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/duplicate-path.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-file.yaml +0 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/float-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/negative-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-over-limit-baseline.yaml +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-schema-version.yaml +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/non-string-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/not-yaml.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/null-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/parent-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/string-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/top-level-is-a-list.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/trailing-slash.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/unknown-key.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/wrong-schema-version.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/zero-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/valid.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +758 -45
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +4 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +2 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/cargo_lock.py +490 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +368 -55
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +4 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_declared_paths.py +523 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_stale_lock.py +1179 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +122 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +33 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +0 -11
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +16 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +1 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +12 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +133 -147
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +133 -147
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +52 -10
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +23 -4
- package/packages/repo-controls/package.json +2 -9
- package/packages/repo-controls/scripts/hooks/post-merge +13 -0
- package/packages/repo-controls/scripts/hooks/pre-push +3 -3
- package/packages/repo-controls/src/azdo-push.ts +64 -36
- package/packages/repo-controls/src/azure-devops-governance.ts +7 -9
- package/packages/repo-controls/src/azure-devops-remote.ts +1 -1
- package/packages/repo-controls/src/cli.ts +29 -8
- package/packages/repo-controls/src/compliance-config.ts +410 -2
- package/packages/repo-controls/src/config.ts +133 -60
- package/packages/repo-controls/src/constants.ts +13 -27
- package/packages/repo-controls/src/coverage-ratchet.ts +4 -4
- package/packages/repo-controls/src/doctor.ts +46 -19
- package/packages/repo-controls/src/gitignore-block.ts +5 -29
- package/packages/repo-controls/src/hook-log.ts +1 -2
- package/packages/repo-controls/src/hook.ts +201 -45
- package/packages/repo-controls/src/install.ts +14 -8
- package/packages/repo-controls/src/integrity.ts +3 -3
- package/packages/repo-controls/src/lfs.ts +111 -0
- package/packages/repo-controls/src/promote.ts +8 -8
- package/packages/repo-controls/src/runtime.ts +9 -1
- package/packages/repo-controls/src/workflows-drift.ts +4 -5
- package/packages/repo-controls/src/worktree-guard.ts +3 -3
|
@@ -242,6 +242,27 @@ def test_a_tree_that_does_not_exist_is_not_asked_for_a_guide() -> None:
|
|
|
242
242
|
assert ".specs/AGENTS.md" not in reported
|
|
243
243
|
|
|
244
244
|
|
|
245
|
+
def test_a_workflows_tree_without_a_guide_is_not_a_finding(tmp_path: pathlib.Path) -> None:
|
|
246
|
+
"""`.workflows/` is machine-managed: `adl-repo-controls install` writes it
|
|
247
|
+
wholesale, so nobody hand-authors a guide there and the tree does not need
|
|
248
|
+
one. Owner decision 2026-10-01 (reversing the earlier requirement).
|
|
249
|
+
|
|
250
|
+
`plans/` and `docs/` are hand-authored trees and still need their guide, so
|
|
251
|
+
this also fails against a check that stopped asking any tree for one."""
|
|
252
|
+
(tmp_path / ".workflows").mkdir()
|
|
253
|
+
(tmp_path / ".workflows" / "promote.ts").write_text("// managed\n")
|
|
254
|
+
assert structural(tmp_path).findings == ()
|
|
255
|
+
|
|
256
|
+
(tmp_path / "plans").mkdir()
|
|
257
|
+
(tmp_path / "docs").mkdir()
|
|
258
|
+
verdict = structural(tmp_path)
|
|
259
|
+
assert sorted(f.path for f in verdict.findings) == [
|
|
260
|
+
"docs/AGENTS.md",
|
|
261
|
+
"plans/AGENTS.md",
|
|
262
|
+
], verdict.render()
|
|
263
|
+
assert all(f.message == "tree has no AGENTS.md guide" for f in verdict.findings)
|
|
264
|
+
|
|
265
|
+
|
|
245
266
|
def test_the_missing_guide_corpus_reports_only_the_structural_finding() -> None:
|
|
246
267
|
"""The whole corpus, both hooks combined: none of its files violate the
|
|
247
268
|
graded rules (README.md at root, AGENTS.md by basename), so the only
|
|
@@ -327,3 +348,143 @@ def test_a_redeclared_estate_still_allows_the_resolved_tree_exceptions(
|
|
|
327
348
|
f"real files under redeclared roots were wrongly reported outside "
|
|
328
349
|
f"the allowlist: {verdict.render()}"
|
|
329
350
|
)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
# ---------------------------------------------- per-repository root declarations
|
|
354
|
+
def graded_declaring(root: pathlib.Path, declarations: dict[str, str], given: tuple[str, ...]):
|
|
355
|
+
"""`graded`, plus what the repository declared about its own root
|
|
356
|
+
(`[controls.compliance.root]` arrives as the `root-files` / `root-dirs`
|
|
357
|
+
declarations). The graded rule only reads files that exist on disk, so the
|
|
358
|
+
caller creates them."""
|
|
359
|
+
ctx = Context(
|
|
360
|
+
root=root, row=ROW, declarations=declarations,
|
|
361
|
+
inputs={
|
|
362
|
+
"workflows_root": root / ".workflows",
|
|
363
|
+
"plans_root": root / "plans",
|
|
364
|
+
"specs_root": root / ".specs",
|
|
365
|
+
"docs_root": root / "docs",
|
|
366
|
+
"rust_root": root / "backend",
|
|
367
|
+
"frontend_root": root / "frontend",
|
|
368
|
+
},
|
|
369
|
+
)
|
|
370
|
+
findings = tuple(RootMarkdownAllowlist().graded(ctx, FileSet(paths=given)))
|
|
371
|
+
return decide(ROW, findings, 0, ())
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
def _touch(root: pathlib.Path, *names: str) -> None:
|
|
375
|
+
for name in names:
|
|
376
|
+
target = root / name
|
|
377
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
378
|
+
target.write_text("# x\n")
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def test_a_non_standard_root_register_is_reported_without_a_declaration(
|
|
382
|
+
tmp_path: pathlib.Path,
|
|
383
|
+
) -> None:
|
|
384
|
+
"""STATUS.md and DRIFT.md are not on the central list any more."""
|
|
385
|
+
_touch(tmp_path, "STATUS.md", "DRIFT.md")
|
|
386
|
+
verdict = graded_declaring(tmp_path, {}, ("STATUS.md", "DRIFT.md"))
|
|
387
|
+
assert sorted(f.path for f in verdict.findings) == ["DRIFT.md", "STATUS.md"], verdict.render()
|
|
388
|
+
assert all(
|
|
389
|
+
f.message == "tracked Markdown is outside the root allowlist" for f in verdict.findings
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def test_a_declared_root_markdown_name_is_allowed(tmp_path: pathlib.Path) -> None:
|
|
394
|
+
_touch(tmp_path, "STATUS.md", "DRIFT.md")
|
|
395
|
+
verdict = graded_declaring(
|
|
396
|
+
tmp_path, {"root-files": "STATUS.md, DRIFT.md"}, ("STATUS.md", "DRIFT.md"),
|
|
397
|
+
)
|
|
398
|
+
assert verdict.outcome is Outcome.CLEAN, verdict.render()
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
def test_a_declaration_admits_only_the_names_it_lists(tmp_path: pathlib.Path) -> None:
|
|
402
|
+
"""Without this, the case above also passes against a gate that stops
|
|
403
|
+
grading root Markdown as soon as any declaration is present."""
|
|
404
|
+
_touch(tmp_path, "STATUS.md", "STRAY.md")
|
|
405
|
+
verdict = graded_declaring(tmp_path, {"root-files": "STATUS.md"}, ("STATUS.md", "STRAY.md"))
|
|
406
|
+
assert [f.path for f in verdict.findings] == ["STRAY.md"], verdict.render()
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
def test_a_declared_root_name_does_not_admit_the_same_name_nested(
|
|
410
|
+
tmp_path: pathlib.Path,
|
|
411
|
+
) -> None:
|
|
412
|
+
"""The declaration is about the repository ROOT: `STATUS.md` declared does
|
|
413
|
+
not make `notes/STATUS.md` (a path with a `/`) allowed."""
|
|
414
|
+
_touch(tmp_path, "notes/STATUS.md")
|
|
415
|
+
verdict = graded_declaring(tmp_path, {"root-files": "STATUS.md"}, ("notes/STATUS.md",))
|
|
416
|
+
assert [f.path for f in verdict.findings] == ["notes/STATUS.md"], verdict.render()
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def test_a_root_dirs_declaration_does_not_admit_a_root_markdown_file(
|
|
420
|
+
tmp_path: pathlib.Path,
|
|
421
|
+
) -> None:
|
|
422
|
+
_touch(tmp_path, "STATUS.md")
|
|
423
|
+
verdict = graded_declaring(tmp_path, {"root-dirs": "STATUS.md"}, ("STATUS.md",))
|
|
424
|
+
assert [f.path for f in verdict.findings] == ["STATUS.md"], verdict.render()
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def test_a_stray_root_markdown_fix_names_the_declaration_route(tmp_path: pathlib.Path) -> None:
|
|
428
|
+
"""The fix for a root-level stray `.md` must say how a repository carries
|
|
429
|
+
such a file legitimately -- declare it under `[controls.compliance.root]`
|
|
430
|
+
in its own `adl-config.toml` -- and must not send the user to edit this
|
|
431
|
+
gate's source (`check.py`) to add an exception."""
|
|
432
|
+
_touch(tmp_path, "STATUS.md")
|
|
433
|
+
verdict = graded_declaring(tmp_path, {}, ("STATUS.md",))
|
|
434
|
+
assert len(verdict.findings) == 1, verdict.render()
|
|
435
|
+
fix = verdict.findings[0].fix
|
|
436
|
+
assert "[controls.compliance.root]" in fix, fix
|
|
437
|
+
assert "adl-config.toml" in fix, fix
|
|
438
|
+
assert "check.py" not in fix, fix
|
|
439
|
+
# The other half of the advice -- moving the file under an allowed tree --
|
|
440
|
+
# is kept, so the declaration route is an addition and not a replacement.
|
|
441
|
+
assert "docs/" in fix, fix
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
def test_the_central_names_are_allowed_without_reading_the_context() -> None:
|
|
445
|
+
"""`tests/core/test_root_shape.py` asks about the central names with no
|
|
446
|
+
Context at all, so the declaration lookup must come after that answer."""
|
|
447
|
+
assert RootMarkdownAllowlist()._allowed_markdown(None, "AGENTS.md") # type: ignore[arg-type]
|
|
448
|
+
assert RootMarkdownAllowlist()._allowed_markdown(None, "GAPS-AND-FINDINGS.md") # type: ignore[arg-type]
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
# ------------------------------------------------- a tree declared absent
|
|
452
|
+
def test_rust_and_frontend_declared_absent_contribute_nothing_to_the_allowlist(
|
|
453
|
+
tmp_path: pathlib.Path,
|
|
454
|
+
) -> None:
|
|
455
|
+
"""`rust = ""` and `frontend = ""` drop `rust_root` and `frontend_root` from
|
|
456
|
+
the resolved inputs. Here they only ever ADD allowlist entries (the governance
|
|
457
|
+
suffixes and code-asset roots beneath them), so absent they contribute
|
|
458
|
+
nothing and the file is reported -- strictly stricter, never a silent pass.
|
|
459
|
+
A stray root-level Markdown file reached `ctx.inputs["rust_root"]` unguarded
|
|
460
|
+
and raised `KeyError`, a traceback with exit 1, measured against enact-combined
|
|
461
|
+
with `--tree rust= --tree frontend=`."""
|
|
462
|
+
_touch(tmp_path, "NOTES.md", "backend/crates/enact-app/assets/builtin-skills/s.md")
|
|
463
|
+
ctx = Context(
|
|
464
|
+
root=tmp_path, row=ROW,
|
|
465
|
+
inputs={
|
|
466
|
+
"workflows_root": tmp_path / "workflows",
|
|
467
|
+
"plans_root": tmp_path / "plans",
|
|
468
|
+
"docs_root": tmp_path / "docs",
|
|
469
|
+
},
|
|
470
|
+
)
|
|
471
|
+
given = ("NOTES.md", "backend/crates/enact-app/assets/builtin-skills/s.md")
|
|
472
|
+
findings = tuple(RootMarkdownAllowlist().graded(ctx, FileSet(paths=given)))
|
|
473
|
+
assert sorted(f.path for f in findings) == sorted(given), findings
|
|
474
|
+
assert all(f.message == "tracked Markdown is outside the root allowlist" for f in findings)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def test_a_declared_rust_tree_still_admits_its_governance_files(tmp_path: pathlib.Path) -> None:
|
|
478
|
+
"""The other half: with the tree declared, the same entries still admit."""
|
|
479
|
+
_touch(tmp_path, "rust/CHANGELOG.md")
|
|
480
|
+
ctx = Context(
|
|
481
|
+
root=tmp_path, row=ROW,
|
|
482
|
+
inputs={
|
|
483
|
+
"workflows_root": tmp_path / "workflows",
|
|
484
|
+
"plans_root": tmp_path / "plans",
|
|
485
|
+
"docs_root": tmp_path / "docs",
|
|
486
|
+
"rust_root": tmp_path / "rust",
|
|
487
|
+
"frontend_root": tmp_path / "web",
|
|
488
|
+
},
|
|
489
|
+
)
|
|
490
|
+
assert tuple(RootMarkdownAllowlist().graded(ctx, FileSet(paths=("rust/CHANGELOG.md",)))) == ()
|
|
@@ -11,7 +11,13 @@ row's `engine.scope` (`<workflows>/scripts/**`, excluding its own
|
|
|
11
11
|
Two measurements, both taken over the given set alone — never a walk:
|
|
12
12
|
|
|
13
13
|
LAY-014 a directory directly under the CI scripts root holding more than
|
|
14
|
-
`MAX_DIRECT_FILES`
|
|
14
|
+
the direct-file limit: `MAX_DIRECT_FILES` (15) unless the
|
|
15
|
+
repository declares its own, as `--declare scripts-direct-files=N`
|
|
16
|
+
(`[controls.compliance.limits].scripts_direct_files` in its
|
|
17
|
+
adl-config.toml). `direct_file_limit` resolves it: absent is the
|
|
18
|
+
default, and a value that is not a base-10 positive integer is
|
|
19
|
+
could-not-run, never a quiet fall back to the default. The depth
|
|
20
|
+
limit is not configurable.
|
|
15
21
|
LAY-014 a directory nested more than `MAX_SUBFOLDER_DEPTH` levels below
|
|
16
22
|
that same root.
|
|
17
23
|
|
|
@@ -37,11 +43,13 @@ source being ported, not reinvented.
|
|
|
37
43
|
|
|
38
44
|
from __future__ import annotations
|
|
39
45
|
|
|
46
|
+
import re
|
|
40
47
|
from collections.abc import Iterable
|
|
41
48
|
from typing import ClassVar
|
|
42
49
|
|
|
43
50
|
from ....core.check import Check
|
|
44
51
|
from ....core.context import Context, FileSet
|
|
52
|
+
from ....core.errors import CouldNotRun
|
|
45
53
|
from ....core.finding import Finding, Report
|
|
46
54
|
|
|
47
55
|
|
|
@@ -49,9 +57,13 @@ class ScriptsSizeDepth(Check):
|
|
|
49
57
|
id: ClassVar[str] = "LAY-014"
|
|
50
58
|
rule: ClassVar[str] = "LAY-014"
|
|
51
59
|
|
|
60
|
+
# The engine default. A repository states its own with the
|
|
61
|
+
# `scripts-direct-files` declaration; see `direct_file_limit`.
|
|
52
62
|
MAX_DIRECT_FILES: ClassVar[int] = 15
|
|
53
63
|
MAX_SUBFOLDER_DEPTH: ClassVar[int] = 4
|
|
54
64
|
|
|
65
|
+
DIRECT_FILES_DECLARATION: ClassVar[str] = "scripts-direct-files"
|
|
66
|
+
|
|
55
67
|
# `<workflows>` indirection, not the literal `.workflows/scripts` this held
|
|
56
68
|
# until 2026-09-15. That literal is a consumer path inside the package
|
|
57
69
|
# (K-42), and it was not a near-miss: enact-m5 keeps CI in `workflows/`
|
|
@@ -68,6 +80,25 @@ class ScriptsSizeDepth(Check):
|
|
|
68
80
|
"""Repository-relative, for both probing and display."""
|
|
69
81
|
return ctx.relative(ctx.inputs["scripts_root"])
|
|
70
82
|
|
|
83
|
+
def direct_file_limit(self, ctx: Context) -> int:
|
|
84
|
+
"""The direct-file limit in force: the declared one, else `MAX_DIRECT_FILES`.
|
|
85
|
+
|
|
86
|
+
ASCII digits only, so `+20`, `1_0`, ` 20` and full-width digits are
|
|
87
|
+
refused, which `int()` alone would accept. A declaration that cannot be
|
|
88
|
+
read as a positive integer is could-not-run: falling back to the default
|
|
89
|
+
would grade the repository against a limit it explicitly replaced.
|
|
90
|
+
"""
|
|
91
|
+
declared = ctx.declarations.get(self.DIRECT_FILES_DECLARATION)
|
|
92
|
+
if declared is None:
|
|
93
|
+
return self.MAX_DIRECT_FILES
|
|
94
|
+
if re.fullmatch(r"[0-9]+", declared) is None or int(declared) < 1:
|
|
95
|
+
raise CouldNotRun(
|
|
96
|
+
f"declaration {self.DIRECT_FILES_DECLARATION}={declared!r} is not a "
|
|
97
|
+
"base-10 positive integer; set [controls.compliance.limits]."
|
|
98
|
+
"scripts_direct_files to a whole number of at least 1"
|
|
99
|
+
)
|
|
100
|
+
return int(declared)
|
|
101
|
+
|
|
71
102
|
def structural(self, ctx: Context) -> Iterable[Report]:
|
|
72
103
|
root = self._root(ctx)
|
|
73
104
|
if not ctx.inputs["scripts_root"].is_dir():
|
|
@@ -81,6 +112,7 @@ class ScriptsSizeDepth(Check):
|
|
|
81
112
|
def graded(self, ctx: Context, files: FileSet) -> Iterable[Report]:
|
|
82
113
|
root = self._root(ctx)
|
|
83
114
|
prefix = f"{root}/"
|
|
115
|
+
direct_limit = self.direct_file_limit(ctx)
|
|
84
116
|
|
|
85
117
|
direct_files: dict[str, int] = {}
|
|
86
118
|
deep_directories: dict[str, int] = {}
|
|
@@ -107,10 +139,10 @@ class ScriptsSizeDepth(Check):
|
|
|
107
139
|
deep_directories[directory] = depth
|
|
108
140
|
|
|
109
141
|
for directory, count in direct_files.items():
|
|
110
|
-
if count >
|
|
142
|
+
if count > direct_limit:
|
|
111
143
|
findings.append(self.report(
|
|
112
144
|
directory,
|
|
113
|
-
f"has {count} direct files; limit is {
|
|
145
|
+
f"has {count} direct files; limit is {direct_limit}",
|
|
114
146
|
f"split the files in {directory} into subdirectories by "
|
|
115
147
|
"responsibility",
|
|
116
148
|
))
|
|
@@ -34,13 +34,15 @@ import pathlib
|
|
|
34
34
|
|
|
35
35
|
from pathlib import Path
|
|
36
36
|
|
|
37
|
+
import pytest
|
|
37
38
|
from helpers import corpus_files
|
|
38
39
|
|
|
39
40
|
from adl_compliance.checks.layout.scripts_size_depth import ScriptsSizeDepth
|
|
40
41
|
from adl_compliance.core import scope
|
|
41
42
|
from adl_compliance.core.context import Context, FileSet
|
|
43
|
+
from adl_compliance.core.errors import CouldNotRun
|
|
42
44
|
from adl_compliance.core.finding import Finding
|
|
43
|
-
from adl_compliance.core.verdict import Outcome, decide
|
|
45
|
+
from adl_compliance.core.verdict import Outcome, could_not_run, decide
|
|
44
46
|
from adl_compliance.policy.registry import load
|
|
45
47
|
|
|
46
48
|
FIXTURES = pathlib.Path(__file__).parent / "fixtures"
|
|
@@ -161,3 +163,108 @@ def test_a_missing_scripts_root_names_the_declared_path_not_a_constant(tmp_path:
|
|
|
161
163
|
text = result.render()
|
|
162
164
|
assert "missing ci/scripts" in text, text
|
|
163
165
|
assert ".workflows" not in text, text
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# ----------------------------------------- the direct-file limit is declarable
|
|
169
|
+
# `[controls.compliance.limits].scripts_direct_files` reaches the engine as
|
|
170
|
+
# `--declare scripts-direct-files=N`. The engine default stays 15; a repository
|
|
171
|
+
# that needs more says so in its own adl-config.toml, and a value the engine
|
|
172
|
+
# cannot read is a could-not-run, never a quiet fall back to 15.
|
|
173
|
+
DECLARATION = "scripts-direct-files"
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def declared_verdict(
|
|
177
|
+
given: tuple[str, ...],
|
|
178
|
+
declarations: dict[str, str],
|
|
179
|
+
root: Path = CORPUS,
|
|
180
|
+
scripts_root: str = ".workflows/scripts",
|
|
181
|
+
):
|
|
182
|
+
ctx = Context(
|
|
183
|
+
root=root, row=ROW, declarations=declarations,
|
|
184
|
+
inputs={"scripts_root": root / scripts_root},
|
|
185
|
+
)
|
|
186
|
+
findings = tuple(
|
|
187
|
+
r for r in ScriptsSizeDepth().run(ctx, FileSet(paths=given))
|
|
188
|
+
if isinstance(r, Finding)
|
|
189
|
+
)
|
|
190
|
+
return decide(ROW, findings, 0, ())
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def flat_scripts_repo(tmp_path: Path, count: int) -> tuple[Path, tuple[str, ...]]:
|
|
194
|
+
"""A repository whose `.workflows/scripts` holds `count` direct files and nothing else."""
|
|
195
|
+
root = tmp_path / "repo"
|
|
196
|
+
scripts = root / ".workflows/scripts"
|
|
197
|
+
scripts.mkdir(parents=True)
|
|
198
|
+
given = []
|
|
199
|
+
for index in range(count):
|
|
200
|
+
(scripts / f"s{index}.sh").write_text("#!/bin/sh\n")
|
|
201
|
+
given.append(f".workflows/scripts/s{index}.sh")
|
|
202
|
+
return root, tuple(given)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def test_no_declaration_keeps_the_engine_default_of_fifteen() -> None:
|
|
206
|
+
ctx = Context(root=CORPUS, row=ROW)
|
|
207
|
+
assert ScriptsSizeDepth().direct_file_limit(ctx) == 15
|
|
208
|
+
assert ScriptsSizeDepth.MAX_DIRECT_FILES == 15
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def test_a_declared_limit_is_the_effective_limit() -> None:
|
|
212
|
+
ctx = Context(root=CORPUS, row=ROW, declarations={DECLARATION: "20"})
|
|
213
|
+
assert ScriptsSizeDepth().direct_file_limit(ctx) == 20
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def test_declared_twenty_accepts_the_sixteen_file_fixture() -> None:
|
|
217
|
+
"""NARROWED holds 16 direct files, one over the default and well under 20."""
|
|
218
|
+
result = declared_verdict(NARROWED, {DECLARATION: "20"})
|
|
219
|
+
assert result.outcome is Outcome.CLEAN, result.render()
|
|
220
|
+
assert result.findings == ()
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def test_declared_twenty_leaves_only_the_depth_finding_on_the_full_fixture() -> None:
|
|
224
|
+
"""The depth limit is not configurable: the direct-file finding goes, the depth one stays."""
|
|
225
|
+
result = declared_verdict(GIVEN, {DECLARATION: "20"})
|
|
226
|
+
assert result.outcome is Outcome.FINDINGS, result.render()
|
|
227
|
+
text = result.render()
|
|
228
|
+
assert "direct files" not in text, text
|
|
229
|
+
assert "a/b/c/d/e: is 5 levels below .workflows/scripts; limit is 4" in text
|
|
230
|
+
assert len(result.findings) == 1
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def test_declared_twenty_with_twenty_one_files_reports_the_declared_limit(tmp_path: Path) -> None:
|
|
234
|
+
root, given = flat_scripts_repo(tmp_path, 21)
|
|
235
|
+
result = declared_verdict(given, {DECLARATION: "20"}, root=root)
|
|
236
|
+
assert result.outcome is Outcome.FINDINGS, result.render()
|
|
237
|
+
assert len(result.findings) == 1
|
|
238
|
+
text = result.render()
|
|
239
|
+
assert ".workflows/scripts: has 21 direct files; limit is 20" in text, text
|
|
240
|
+
assert "limit is 15" not in text, text
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def test_declared_twenty_with_exactly_twenty_files_is_clean(tmp_path: Path) -> None:
|
|
244
|
+
root, given = flat_scripts_repo(tmp_path, 20)
|
|
245
|
+
result = declared_verdict(given, {DECLARATION: "20"}, root=root)
|
|
246
|
+
assert result.outcome is Outcome.CLEAN, result.render()
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def test_declared_fifteen_grades_exactly_like_no_declaration() -> None:
|
|
250
|
+
declared = declared_verdict(GIVEN, {DECLARATION: "15"})
|
|
251
|
+
default = verdict(GIVEN)
|
|
252
|
+
assert declared.outcome is default.outcome
|
|
253
|
+
assert [f.render() for f in declared.findings] == [f.render() for f in default.findings]
|
|
254
|
+
assert ".workflows/scripts: has 16 direct files; limit is 15" in declared.render()
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def test_an_unrelated_declaration_does_not_change_the_limit() -> None:
|
|
258
|
+
result = declared_verdict(GIVEN, {"license": "Proprietary", "root-dirs": "apps"})
|
|
259
|
+
assert ".workflows/scripts: has 16 direct files; limit is 15" in result.render()
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
@pytest.mark.parametrize("value", ["abc", "0", "-3", "2.5", "", "+20", "1_0", "20"])
|
|
263
|
+
def test_an_unreadable_declared_limit_could_not_run(value: str) -> None:
|
|
264
|
+
"""Never a silent fall back to 15: a value that is not a base-10 positive integer is loud."""
|
|
265
|
+
with pytest.raises(CouldNotRun) as raised:
|
|
266
|
+
declared_verdict(GIVEN, {DECLARATION: value})
|
|
267
|
+
message = str(raised.value)
|
|
268
|
+
assert DECLARATION in message, message
|
|
269
|
+
assert repr(value) in message, message
|
|
270
|
+
assert could_not_run(ROW, message).outcome is Outcome.COULD_NOT_RUN
|