@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.12 → 0.1.28
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 +12 -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 +131 -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 +33 -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/scripts/probe-ado-rules.ts +311 -0
- 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 +44 -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-ladder.csv +241 -0
- package/packages/azdo/src/workflow-rules-matrix.csv +85 -0
- package/packages/azdo/src/workflow-rules.ts +194 -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 +258 -2
- 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/plan_metadata.py +9 -4
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/check.py +1 -1
- 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 +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +3 -3
- 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
|
@@ -26,11 +26,26 @@ declared. `<rust>` resolves to `backend` and `<typescript>` resolves to
|
|
|
26
26
|
defaults, just reached through `ctx.inputs` now, the same as every other
|
|
27
27
|
check that names a consumer path.
|
|
28
28
|
|
|
29
|
+
A tree declared absent (`rust = ""` or `typescript = ""` in
|
|
30
|
+
`[controls.compliance.trees]`) drops the inputs naming it, and each half of this
|
|
31
|
+
row is then graded on its own: a repository declaring no Rust tree is graded on
|
|
32
|
+
its TypeScript lockfile alone and is never asked for a `Cargo.lock`. With
|
|
33
|
+
neither tree left the row is could-not-run (see `structural`) -- it used to raise
|
|
34
|
+
`KeyError`.
|
|
35
|
+
|
|
36
|
+
Retired 2026-10-01: `coverage.backend-ratchet` and `coverage.backend-crate`,
|
|
37
|
+
named here as precedents, were deleted with the `coverage` domain
|
|
38
|
+
(COV-001..005); the references record the pattern this check followed.
|
|
39
|
+
|
|
29
40
|
LCK-001 a required lockfile is missing or empty (`[ -s FILE ]` in check.sh
|
|
30
41
|
— MISSING and EMPTY are the same finding, worded the same way).
|
|
31
42
|
LCK-002 `cargo metadata --locked` rejects `backend/Cargo.lock` against
|
|
32
43
|
`backend/Cargo.toml` — the lock exists but does not satisfy the
|
|
33
|
-
manifest
|
|
44
|
+
manifest — or the lock's CONTENT fails the validation in
|
|
45
|
+
`cargo_lock.py` (see "`--no-deps` never reads the lockfile" below):
|
|
46
|
+
not TOML, an unsupported `version`, no packages, a package listed
|
|
47
|
+
as a dependency but absent, a workspace member or a direct
|
|
48
|
+
dependency of one missing from it.
|
|
34
49
|
|
|
35
50
|
**check.sh stops at the first problem.** Each of the three failure branches
|
|
36
51
|
ends in `report_summary; exit` — a missing frontend lockfile is never reported
|
|
@@ -56,29 +71,112 @@ finding (`LCK-002`) here exactly as it is in check.sh — this check trusts
|
|
|
56
71
|
`cargo --version` having already ruled out "cargo cannot run at all" for the
|
|
57
72
|
same reason check.sh does.
|
|
58
73
|
|
|
74
|
+
**`--no-deps` never reads the lockfile (measured 2026-10-01).** check.sh's command,
|
|
75
|
+
kept unchanged, passes `--no-deps`, so cargo never resolves and never opens
|
|
76
|
+
`Cargo.lock`: a lock that was `version = 4` alone, one that was not TOML, and one
|
|
77
|
+
with `version = 99` all came out CLEAN through this check, and only a missing or
|
|
78
|
+
empty lock was ever reported. Dropping `--no-deps` is not the fix: cargo then loads
|
|
79
|
+
every dependency's manifest, which fails offline whenever the crate sources are not
|
|
80
|
+
in the registry cache, so the gate would pass on one machine and fail or be
|
|
81
|
+
could-not-run on another. The lock's CONTENT is therefore judged in Python, in
|
|
82
|
+
addition to the cargo call and after it (`cargo_lock.CargoLock`, `tomllib`, no cargo,
|
|
83
|
+
no registry, no network; what it checks, and what it cannot judge and so refuses with
|
|
84
|
+
could-not-run, is that module's docstring). Per lock the order is: `cargo --version`;
|
|
85
|
+
`cargo metadata`, whose rejection is the one finding for that lock (cargo is the
|
|
86
|
+
authority on a manifest it refuses, and a lock cannot be compared with one); only when
|
|
87
|
+
cargo accepts, the content validation, one `LCK-002` per problem with the same remedy.
|
|
88
|
+
The limit, stated plainly: version-REQUIREMENT drift (a manifest raising a requirement
|
|
89
|
+
past the locked version) is not detected offline; `cargo metadata` without `--no-deps`
|
|
90
|
+
is the authority for that and needs the registry.
|
|
91
|
+
|
|
59
92
|
cargo resolves its toolchain from the WORKING DIRECTORY — rustup applies
|
|
60
93
|
`backend/rust-toolchain.toml` as a directory override, and `--manifest-path`
|
|
61
94
|
does not change that: toolchain selection precedes reading the manifest. So
|
|
62
95
|
both cargo calls run with `cwd` set to the workspace directory, not the
|
|
63
96
|
manifest's own directory, matching check.sh's identical comment.
|
|
97
|
+
|
|
98
|
+
**A repository can declare exactly which paths this gate scans and grades**
|
|
99
|
+
(Tarun, 2026-10-01: "it should be configurable and declarative on what paths
|
|
100
|
+
should be scanned"). `[controls.compliance.lockfiles]` in `adl-config.toml`
|
|
101
|
+
reaches the engine as four comma-list declarations, a HALF (Bun, Cargo) being
|
|
102
|
+
declared by its manifests list and its lockfiles list together:
|
|
103
|
+
|
|
104
|
+
bun-manifests / bun-lockfiles `package.json` paths or globs / `bun.lock` paths
|
|
105
|
+
cargo-manifests / cargo-lockfiles `Cargo.toml` paths or globs / `Cargo.lock` paths
|
|
106
|
+
|
|
107
|
+
Why: the registry scope is `<typescript>/package.json` and `<typescript>/bun.lock`
|
|
108
|
+
(and the `<rust>` pair), a tree placeholder joined to a ONE-level file name.
|
|
109
|
+
enact-combined's `typescript` tree is a brace union of directories and its
|
|
110
|
+
manifests sit at the repository ROOT and under `apps/*/` and `packages/*/`, so on
|
|
111
|
+
a whole-tree run `engine.scope` matched no file and the row was could-not-run
|
|
112
|
+
(measured live: a narrowed run passed, the exhaustive run could not). The
|
|
113
|
+
per-gate `bun_lock` input moved the grade and never the scope.
|
|
114
|
+
|
|
115
|
+
A declared half REPLACES that half's tree defaults, in both places the paths are
|
|
116
|
+
used:
|
|
117
|
+
|
|
118
|
+
* scope (`declared_scope`): which changed files select the gate, and, because a
|
|
119
|
+
restated scope is graded whole, which files `graded` is handed;
|
|
120
|
+
* grade (`structural`): each declared lockfile must exist and be non-empty
|
|
121
|
+
(LCK-001, same wording and remedy as before); each declared Cargo lockfile's
|
|
122
|
+
directory is the cargo workspace and `<that directory>/Cargo.toml` its
|
|
123
|
+
manifest (LCK-002 as before).
|
|
124
|
+
|
|
125
|
+
`graded` makes the declaration honest: every declared manifest entry must match
|
|
126
|
+
at least one file of the complete in-scope set, or the row is could-not-run
|
|
127
|
+
naming the declaration and the entry. A declared glob that matches nothing would
|
|
128
|
+
otherwise shrink what the gate scans to nothing and say OK.
|
|
129
|
+
|
|
130
|
+
An undeclared half is exactly what it was: tree defaults, the `inputs`, the same
|
|
131
|
+
early-return shape. A malformed declaration (empty, absolute, backslash, `.`/`..`
|
|
132
|
+
segments, placeholder or brace or negation syntax, duplicate, the wrong file
|
|
133
|
+
name, a glob in a lockfile entry, or a half with only one of its two lists) is
|
|
134
|
+
could-not-run naming the declaration; the engine never grades against a guess at
|
|
135
|
+
what was meant. `adl` refuses the same values when it reads `adl-config.toml`.
|
|
64
136
|
"""
|
|
65
137
|
|
|
66
138
|
from __future__ import annotations
|
|
67
139
|
|
|
68
140
|
import shutil
|
|
69
141
|
import subprocess
|
|
70
|
-
from collections.abc import Iterable
|
|
71
|
-
from
|
|
142
|
+
from collections.abc import Iterable, Mapping
|
|
143
|
+
from pathlib import Path
|
|
144
|
+
from typing import ClassVar, NamedTuple
|
|
72
145
|
|
|
73
146
|
from ....core.check import Check, FileState
|
|
74
|
-
from ....core.context import Context
|
|
147
|
+
from ....core.context import Context, FileSet
|
|
75
148
|
from ....core.errors import CouldNotRun
|
|
76
149
|
from ....core.finding import Report
|
|
150
|
+
from ....core.scope import matches
|
|
151
|
+
from .cargo_lock import CargoLock, Undecidable
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class Half(NamedTuple):
|
|
155
|
+
"""One of the two ecosystems this row grades, and the names that declare it."""
|
|
156
|
+
|
|
157
|
+
manifests: str
|
|
158
|
+
"""The `--declare` name carrying the manifest paths or globs."""
|
|
159
|
+
lockfiles: str
|
|
160
|
+
"""The `--declare` name carrying the literal lockfile paths."""
|
|
161
|
+
manifest_name: str
|
|
162
|
+
"""The file name every manifest entry must end in."""
|
|
163
|
+
tree: str
|
|
164
|
+
"""Prefix of the registry scope entries a declaration of this half replaces."""
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class Declared(NamedTuple):
|
|
168
|
+
manifests: tuple[str, ...]
|
|
169
|
+
lockfiles: tuple[str, ...]
|
|
77
170
|
|
|
78
171
|
|
|
79
172
|
class LockfileIntegrity(Check):
|
|
80
173
|
id: ClassVar[str] = "REP-002"
|
|
81
174
|
|
|
175
|
+
CARGO: ClassVar[Half] = Half("cargo-manifests", "cargo-lockfiles", "Cargo.toml", "<rust>/")
|
|
176
|
+
BUN: ClassVar[Half] = Half("bun-manifests", "bun-lockfiles", "package.json", "<typescript>/")
|
|
177
|
+
# Cargo first, as the registry lists it and as `structural` grades it.
|
|
178
|
+
HALVES: ClassVar[tuple[Half, ...]] = (CARGO, BUN)
|
|
179
|
+
|
|
82
180
|
inputs: ClassVar[dict[str, str]] = {
|
|
83
181
|
"workspace": "<rust>",
|
|
84
182
|
"cargo_lock": "<rust>/Cargo.lock",
|
|
@@ -94,33 +192,208 @@ class LockfileIntegrity(Check):
|
|
|
94
192
|
MISSING: ClassVar[str] = "LCK-001"
|
|
95
193
|
STALE: ClassVar[str] = "LCK-002"
|
|
96
194
|
|
|
195
|
+
|
|
196
|
+
# ------------------------------------------------------------ declarations
|
|
197
|
+
|
|
198
|
+
@classmethod
|
|
199
|
+
def _entries(
|
|
200
|
+
cls, declarations: Mapping[str, str], name: str, manifest_name: str | None
|
|
201
|
+
) -> tuple[str, ...] | None:
|
|
202
|
+
"""The validated entries of one comma-list declaration, `None` when absent.
|
|
203
|
+
|
|
204
|
+
`manifest_name` is the file name a manifest entry must end in; `None`
|
|
205
|
+
marks a lockfile list, whose entries are literal paths. Present but blank
|
|
206
|
+
is not absent: an empty entry is refused, never read as "declared nothing".
|
|
207
|
+
"""
|
|
208
|
+
raw = declarations.get(name)
|
|
209
|
+
if raw is None:
|
|
210
|
+
return None
|
|
211
|
+
entries = tuple(part.strip() for part in raw.split(","))
|
|
212
|
+
for entry in entries:
|
|
213
|
+
why = cls._refusal(entry, manifest_name)
|
|
214
|
+
if why is not None:
|
|
215
|
+
raise CouldNotRun(
|
|
216
|
+
f"{cls.id}: declaration `{name}` entry {entry!r} {why}; fix "
|
|
217
|
+
f"[controls.compliance.lockfiles].{name.replace('-', '_')} in "
|
|
218
|
+
"adl-config.toml -- the gate does not guess which path was meant"
|
|
219
|
+
)
|
|
220
|
+
for index, entry in enumerate(entries):
|
|
221
|
+
if entry in entries[:index]:
|
|
222
|
+
raise CouldNotRun(
|
|
223
|
+
f"{cls.id}: declaration `{name}` lists {entry!r} twice; fix "
|
|
224
|
+
f"[controls.compliance.lockfiles].{name.replace('-', '_')} in adl-config.toml"
|
|
225
|
+
)
|
|
226
|
+
return entries
|
|
227
|
+
|
|
228
|
+
@staticmethod
|
|
229
|
+
def _refusal(entry: str, manifest_name: str | None) -> str | None:
|
|
230
|
+
"""Why `entry` is not a repository-relative path this row can scan, or None.
|
|
231
|
+
|
|
232
|
+
The same set `adl` refuses when it reads `adl-config.toml`. Placeholder,
|
|
233
|
+
brace and negation syntax are scope SYNTAX, and a declared entry is a
|
|
234
|
+
path: letting one through would be a pattern that means more or less than
|
|
235
|
+
the repository wrote.
|
|
236
|
+
"""
|
|
237
|
+
if entry == "":
|
|
238
|
+
return "is empty"
|
|
239
|
+
if entry.startswith("/"):
|
|
240
|
+
return "is absolute"
|
|
241
|
+
if "\\" in entry:
|
|
242
|
+
return "contains a backslash"
|
|
243
|
+
if entry.startswith("!") or any(char in entry for char in "<>{}"):
|
|
244
|
+
return "contains scope syntax (a leading '!', a <placeholder>, or braces)"
|
|
245
|
+
if any(segment in ("", ".", "..") for segment in entry.split("/")):
|
|
246
|
+
return "has a `.`, `..` or empty path segment"
|
|
247
|
+
if manifest_name is not None:
|
|
248
|
+
if entry.rsplit("/", 1)[-1] != manifest_name:
|
|
249
|
+
return f"does not end in {manifest_name}"
|
|
250
|
+
elif any(char in entry for char in "*?[]"):
|
|
251
|
+
return (
|
|
252
|
+
"is a glob, but a lockfile is a literal path: a missing one is "
|
|
253
|
+
"reported by name"
|
|
254
|
+
)
|
|
255
|
+
return None
|
|
256
|
+
|
|
257
|
+
@classmethod
|
|
258
|
+
def declared(cls, half: Half, declarations: Mapping[str, str]) -> Declared | None:
|
|
259
|
+
"""What the repository declares for one half, or `None` when it declares nothing.
|
|
260
|
+
|
|
261
|
+
A half is declared by BOTH lists. One without the other is refused: the
|
|
262
|
+
missing list would have to fall back to a tree default, and which default
|
|
263
|
+
is exactly the guess this declaration exists to remove.
|
|
264
|
+
"""
|
|
265
|
+
manifests = cls._entries(declarations, half.manifests, half.manifest_name)
|
|
266
|
+
lockfiles = cls._entries(declarations, half.lockfiles, None)
|
|
267
|
+
if manifests is None and lockfiles is None:
|
|
268
|
+
return None
|
|
269
|
+
if manifests is None or lockfiles is None:
|
|
270
|
+
present, missing = (
|
|
271
|
+
(half.lockfiles, half.manifests) if manifests is None else (half.manifests, half.lockfiles)
|
|
272
|
+
)
|
|
273
|
+
raise CouldNotRun(
|
|
274
|
+
f"{cls.id}: declaration `{present}` is set without `{missing}`; a half is "
|
|
275
|
+
"declared as a pair -- set both under [controls.compliance.lockfiles] in "
|
|
276
|
+
"adl-config.toml"
|
|
277
|
+
)
|
|
278
|
+
return Declared(manifests, lockfiles)
|
|
279
|
+
|
|
280
|
+
@classmethod
|
|
281
|
+
def declared_scope(
|
|
282
|
+
cls, scope: tuple[str, ...], declarations: Mapping[str, str]
|
|
283
|
+
) -> tuple[str, ...] | None:
|
|
284
|
+
"""The registry scope with each declared half's tree defaults replaced.
|
|
285
|
+
|
|
286
|
+
A half's defaults are the registry entries under its tree prefix
|
|
287
|
+
(`<rust>/...`, `<typescript>/...`); `test_the_registry_scope_the_hook_
|
|
288
|
+
replaces_is_two_entries_per_tree` pins that shape. The other half, and
|
|
289
|
+
anything else the row lists, is kept as it was.
|
|
290
|
+
"""
|
|
291
|
+
restated = scope
|
|
292
|
+
any_declared = False
|
|
293
|
+
for half in cls.HALVES:
|
|
294
|
+
declared = cls.declared(half, declarations)
|
|
295
|
+
if declared is None:
|
|
296
|
+
continue
|
|
297
|
+
any_declared = True
|
|
298
|
+
restated = (
|
|
299
|
+
*(pattern for pattern in restated if not pattern.startswith(half.tree)),
|
|
300
|
+
*declared.manifests,
|
|
301
|
+
*declared.lockfiles,
|
|
302
|
+
)
|
|
303
|
+
return restated if any_declared else None
|
|
304
|
+
|
|
97
305
|
# ------------------------------------------------------------- structural
|
|
98
306
|
|
|
307
|
+
# The three inputs that all name the `<rust>` tree. They are resolved or
|
|
308
|
+
# dropped together, so seeing only some of them means a per-gate
|
|
309
|
+
# `--input REP-002:<name>=...` replaced part of the triple.
|
|
310
|
+
CARGO_INPUTS: ClassVar[tuple[str, ...]] = ("workspace", "cargo_lock", "cargo_manifest")
|
|
311
|
+
|
|
99
312
|
def structural(self, ctx: Context) -> Iterable[Report]:
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
313
|
+
# Decision for a tree declared absent (`rust = ""` / `typescript = ""`,
|
|
314
|
+
# which drops every input naming the tree). Unlike an exclusion path, a
|
|
315
|
+
# lockfile IS what this row grades, so each half is judged on its own:
|
|
316
|
+
#
|
|
317
|
+
# * a half whose tree is declared absent is not graded -- the owner
|
|
318
|
+
# stated there is no such lockfile to require, which is the narrower,
|
|
319
|
+
# honest verdict `resolve_inputs` documents ("grades a smaller scope");
|
|
320
|
+
# * with NEITHER half left there is nothing to grade, and an empty set of
|
|
321
|
+
# findings would read as a pass -- `CouldNotRun`, naming both inputs and
|
|
322
|
+
# trees;
|
|
323
|
+
# * a half-resolved Cargo triple is `CouldNotRun`, naming what is missing.
|
|
324
|
+
#
|
|
325
|
+
# This read `ctx.inputs["cargo_lock"]` and `["bun_lock"]` unguarded: a
|
|
326
|
+
# `KeyError` traceback (exit 1), not a verdict, whenever either tree was
|
|
327
|
+
# declared absent.
|
|
328
|
+
#
|
|
329
|
+
# A half the repository DECLARES (see the module docstring) is graded from
|
|
330
|
+
# its declaration and never from the tree or the inputs; the rules above
|
|
331
|
+
# apply to the halves it did not declare.
|
|
332
|
+
cargo_declared = self.declared(self.CARGO, ctx.declarations)
|
|
333
|
+
bun_declared = self.declared(self.BUN, ctx.declarations)
|
|
334
|
+
|
|
335
|
+
present_cargo = [name for name in self.CARGO_INPUTS if name in ctx.inputs]
|
|
336
|
+
if cargo_declared is None and present_cargo and len(present_cargo) != len(self.CARGO_INPUTS):
|
|
337
|
+
missing = [name for name in self.CARGO_INPUTS if name not in ctx.inputs]
|
|
338
|
+
raise CouldNotRun(
|
|
339
|
+
f"{self.id}: the Cargo inputs resolve together from <rust>, but only "
|
|
340
|
+
f"{present_cargo} are set; missing {missing} -- declare "
|
|
341
|
+
"[controls.compliance.trees].rust, or override all three"
|
|
111
342
|
)
|
|
112
|
-
return
|
|
113
343
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
344
|
+
# (lockfile, cargo workspace, manifest) per Cargo lockfile to grade.
|
|
345
|
+
cargo: list[tuple[Path, Path, Path]] = []
|
|
346
|
+
if cargo_declared is not None:
|
|
347
|
+
for relative in cargo_declared.lockfiles:
|
|
348
|
+
lock = ctx.path(relative)
|
|
349
|
+
cargo.append((lock, lock.parent, lock.parent / "Cargo.toml"))
|
|
350
|
+
elif "cargo_lock" in ctx.inputs:
|
|
351
|
+
cargo.append(
|
|
352
|
+
(ctx.inputs["cargo_lock"], ctx.inputs["workspace"], ctx.inputs["cargo_manifest"])
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
bun: list[Path] = []
|
|
356
|
+
if bun_declared is not None:
|
|
357
|
+
bun = [ctx.path(relative) for relative in bun_declared.lockfiles]
|
|
358
|
+
elif "bun_lock" in ctx.inputs:
|
|
359
|
+
bun = [ctx.inputs["bun_lock"]]
|
|
360
|
+
|
|
361
|
+
if not cargo and not bun:
|
|
362
|
+
raise CouldNotRun(
|
|
363
|
+
f"{self.id}: no lockfile to grade -- `cargo_lock` (<rust>/Cargo.lock) and "
|
|
364
|
+
"`bun_lock` (<typescript>/bun.lock) are both absent because the trees "
|
|
365
|
+
"<rust> and <typescript> are both declared absent in "
|
|
366
|
+
"[controls.compliance.trees]; a row that grades nothing is could-not-run, "
|
|
367
|
+
"never a clean pass"
|
|
123
368
|
)
|
|
369
|
+
|
|
370
|
+
for lock, workspace, _manifest in cargo:
|
|
371
|
+
if self.state(ctx, lock) is not FileState.PRESENT:
|
|
372
|
+
shown = ctx.relative(lock)
|
|
373
|
+
yield self.report(
|
|
374
|
+
shown,
|
|
375
|
+
f"missing {shown}",
|
|
376
|
+
f"run: (cd {ctx.relative(workspace)} && "
|
|
377
|
+
"cargo generate-lockfile) and commit the result",
|
|
378
|
+
rule=self.MISSING,
|
|
379
|
+
)
|
|
380
|
+
return
|
|
381
|
+
|
|
382
|
+
for lock in bun:
|
|
383
|
+
if self.state(ctx, lock) is not FileState.PRESENT:
|
|
384
|
+
shown = ctx.relative(lock)
|
|
385
|
+
typescript_dir = shown.rsplit("/", 1)[0] if "/" in shown else "."
|
|
386
|
+
yield self.report(
|
|
387
|
+
shown,
|
|
388
|
+
f"missing {shown}",
|
|
389
|
+
f"run: (cd {typescript_dir} && bun install) to generate the "
|
|
390
|
+
"lockfile and commit the result",
|
|
391
|
+
rule=self.MISSING,
|
|
392
|
+
)
|
|
393
|
+
return
|
|
394
|
+
|
|
395
|
+
if not cargo:
|
|
396
|
+
# Rust declared absent: the TypeScript lockfile above was the whole row.
|
|
124
397
|
return
|
|
125
398
|
|
|
126
399
|
if shutil.which("cargo") is None:
|
|
@@ -129,39 +402,79 @@ class LockfileIntegrity(Check):
|
|
|
129
402
|
"not a finding"
|
|
130
403
|
)
|
|
131
404
|
|
|
132
|
-
workspace
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
)
|
|
140
|
-
if version_check.returncode != 0:
|
|
141
|
-
raise CouldNotRun(
|
|
142
|
-
f"repository.lockfile-integrity: cargo could not run in "
|
|
143
|
-
f"{ctx.relative(workspace)}; tool failure, not a finding"
|
|
405
|
+
for lock, workspace, manifest in cargo:
|
|
406
|
+
version_check = subprocess.run(
|
|
407
|
+
["cargo", "--version"],
|
|
408
|
+
cwd=workspace,
|
|
409
|
+
capture_output=True,
|
|
410
|
+
text=True,
|
|
411
|
+
check=False,
|
|
144
412
|
)
|
|
413
|
+
if version_check.returncode != 0:
|
|
414
|
+
raise CouldNotRun(
|
|
415
|
+
f"repository.lockfile-integrity: cargo could not run in "
|
|
416
|
+
f"{ctx.relative(workspace)}; tool failure, not a finding"
|
|
417
|
+
)
|
|
145
418
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if metadata_run.returncode != 0:
|
|
158
|
-
lock_shown = ctx.relative(cargo_lock)
|
|
419
|
+
metadata_run = subprocess.run(
|
|
420
|
+
[
|
|
421
|
+
"cargo", "metadata", "--locked", "--offline", "--no-deps",
|
|
422
|
+
"--format-version", "1", "--manifest-path", str(manifest),
|
|
423
|
+
],
|
|
424
|
+
cwd=workspace,
|
|
425
|
+
capture_output=True,
|
|
426
|
+
text=True,
|
|
427
|
+
check=False,
|
|
428
|
+
)
|
|
429
|
+
lock_shown = ctx.relative(lock)
|
|
159
430
|
manifest_shown = ctx.relative(manifest)
|
|
160
|
-
|
|
161
|
-
lock_shown,
|
|
162
|
-
f"{lock_shown} does not satisfy {manifest_shown}",
|
|
431
|
+
remedy = (
|
|
163
432
|
f"run: (cd {ctx.relative(workspace)} && cargo update) to "
|
|
164
433
|
f"resync {lock_shown} with {manifest_shown}, then commit "
|
|
165
|
-
"the result"
|
|
166
|
-
rule=self.STALE,
|
|
434
|
+
"the result"
|
|
167
435
|
)
|
|
436
|
+
if metadata_run.returncode != 0:
|
|
437
|
+
yield self.report(
|
|
438
|
+
lock_shown,
|
|
439
|
+
f"{lock_shown} does not satisfy {manifest_shown}",
|
|
440
|
+
remedy,
|
|
441
|
+
rule=self.STALE,
|
|
442
|
+
)
|
|
443
|
+
continue
|
|
444
|
+
|
|
445
|
+
# `--no-deps` never reads the lockfile (see the module docstring), so cargo
|
|
446
|
+
# accepting the manifest says nothing about the lock. The content is judged
|
|
447
|
+
# here, deterministically and without cargo; a lock this cannot judge is
|
|
448
|
+
# could-not-run, never a pass.
|
|
449
|
+
try:
|
|
450
|
+
problems = CargoLock(lock, manifest, ctx.relative).problems()
|
|
451
|
+
except Undecidable as exc:
|
|
452
|
+
raise CouldNotRun(f"{self.id}: cannot judge {lock_shown}: {exc}") from exc
|
|
453
|
+
for problem in problems:
|
|
454
|
+
yield self.report(lock_shown, problem, remedy, rule=self.STALE)
|
|
455
|
+
|
|
456
|
+
# ----------------------------------------------------------------- graded
|
|
457
|
+
|
|
458
|
+
def graded(self, ctx: Context, files: FileSet) -> Iterable[Report]:
|
|
459
|
+
"""A declared manifest entry that matches no file is could-not-run.
|
|
460
|
+
|
|
461
|
+
`files` is the COMPLETE in-scope set here: a declared half restates the
|
|
462
|
+
row's scope, and a restated scope is graded whole (`Check.declared_scope`),
|
|
463
|
+
so "matches nothing" is a statement about the repository and not about
|
|
464
|
+
which files happened to change. Matched with the scope's own matcher.
|
|
465
|
+
"""
|
|
466
|
+
paths = tuple(files)
|
|
467
|
+
for half in self.HALVES:
|
|
468
|
+
declared = self.declared(half, ctx.declarations)
|
|
469
|
+
if declared is None:
|
|
470
|
+
continue
|
|
471
|
+
for pattern in declared.manifests:
|
|
472
|
+
if not any(matches(pattern, path) for path in paths):
|
|
473
|
+
raise CouldNotRun(
|
|
474
|
+
f"{self.id}: declaration `{half.manifests}` names {pattern!r}, which "
|
|
475
|
+
"matches no file in the repository; fix "
|
|
476
|
+
f"[controls.compliance.lockfiles].{half.manifests.replace('-', '_')} "
|
|
477
|
+
"in adl-config.toml -- a declared manifest that is not there would "
|
|
478
|
+
"shrink what this gate scans to nothing and still read OK"
|
|
479
|
+
)
|
|
480
|
+
return ()
|
|
@@ -14,7 +14,7 @@ Ported here as two COMMITTED fixture directories built the identical way (see
|
|
|
14
14
|
file for the exact commands that produced them), rather than reconstructed at
|
|
15
15
|
test time — the same shift every other ported check.sh/test.sh pair in this
|
|
16
16
|
package already made, and the one this task calls out `coverage.backend-ratchet`
|
|
17
|
-
(`COV-002
|
|
17
|
+
(`COV-002`, retired 2026-10-01) as its concrete precedent for.
|
|
18
18
|
|
|
19
19
|
A real Rust toolchain and a real `cargo` invocation are both required to prove
|
|
20
20
|
the `LCK-002` branch (`cargo metadata --locked` rejecting a stale lock), but
|
|
@@ -100,7 +100,9 @@ def test_a_redeclared_rust_tree_is_honoured(tmp_path: Path) -> None:
|
|
|
100
100
|
graded against `rust-workspace/Cargo.lock`, never the packaged default.
|
|
101
101
|
"""
|
|
102
102
|
trees = effective_trees({"rust": "rust-workspace", "typescript": "ts-workspace"})
|
|
103
|
-
|
|
103
|
+
# The subject here is an EMPTY tree: the lockfile is reported missing because
|
|
104
|
+
# nothing exists, so the empty corpus is opted into explicitly.
|
|
105
|
+
verdict = runner.run(ROW, tmp_path, corpus_files(tmp_path, allow_empty=True), trees=trees)
|
|
104
106
|
assert verdict.outcome is Outcome.FINDINGS, verdict.render()
|
|
105
107
|
assert len(verdict.findings) == 1
|
|
106
108
|
finding = verdict.findings[0]
|