@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
|
@@ -17,6 +17,115 @@ export interface ComplianceConfig {
|
|
|
17
17
|
* outright until this key existed.
|
|
18
18
|
*/
|
|
19
19
|
declarations: Record<string, string>
|
|
20
|
+
/**
|
|
21
|
+
* Root-level names this repository adds to the engine's standard root allow-list,
|
|
22
|
+
* from `[controls.compliance.root]`. OMITTED (not `undefined`-valued, not empty)
|
|
23
|
+
* when the repository declares no `root` table, so a repository that declares
|
|
24
|
+
* nothing parses to exactly the shape it always did. `hook.ts` turns each
|
|
25
|
+
* non-empty list into one `--declare root-files=a,b` / `root-dirs=x,y` flag.
|
|
26
|
+
*/
|
|
27
|
+
root?: RootDeclaration
|
|
28
|
+
/**
|
|
29
|
+
* Engine limits this repository sets for itself, from `[controls.compliance.limits]`.
|
|
30
|
+
* OMITTED (not `undefined`-valued) when the repository declares no `limits` table,
|
|
31
|
+
* for the same whole-object-shape reason as `root`. A key absent inside the table
|
|
32
|
+
* keeps the engine's own default. `hook.ts` turns a set `scripts_direct_files`,
|
|
33
|
+
* `open_gaps` and `open_plans` into `--declare scripts-direct-files=<n>`,
|
|
34
|
+
* `--declare open-gaps=<n>` and `--declare open-plans=<n>`.
|
|
35
|
+
*/
|
|
36
|
+
limits?: LimitsDeclaration
|
|
37
|
+
/**
|
|
38
|
+
* Extra Markdown roots this repository declares, from `[controls.compliance.markdown]`.
|
|
39
|
+
* OMITTED (not `undefined`-valued) when the repository declares no `markdown` table,
|
|
40
|
+
* for the same whole-object-shape reason as `root` and `limits`. `hook.ts` turns a
|
|
41
|
+
* non-empty `roots` into one `--declare markdown-roots=a,b` flag.
|
|
42
|
+
*/
|
|
43
|
+
markdown?: MarkdownDeclaration
|
|
44
|
+
/**
|
|
45
|
+
* The manifest and lockfile paths REP-002 scans and grades, from
|
|
46
|
+
* `[controls.compliance.lockfiles]`. OMITTED (not `undefined`-valued) when the
|
|
47
|
+
* repository declares no `lockfiles` table, for the same whole-object-shape reason
|
|
48
|
+
* as `root`, `limits` and `markdown`. `hook.ts` turns each non-empty list into one
|
|
49
|
+
* `--declare bun-manifests=a,b` (and `bun-lockfiles`, `cargo-manifests`,
|
|
50
|
+
* `cargo-lockfiles`) flag.
|
|
51
|
+
*/
|
|
52
|
+
lockfiles?: LockfilesDeclaration
|
|
53
|
+
/**
|
|
54
|
+
* LAY-004's per-tree direct-file ceilings, from `[controls.compliance.directory-ratchet]`.
|
|
55
|
+
* OMITTED (not `undefined`-valued) when the repository declares no
|
|
56
|
+
* `directory-ratchet` table, for the same whole-object-shape reason as `root`,
|
|
57
|
+
* `limits`, `markdown` and `lockfiles`. `hook.ts` turns a non-empty `max_children`
|
|
58
|
+
* into one `--declare directory-ceilings=<path>:<n>,<path>:<n>` flag, entries sorted
|
|
59
|
+
* for deterministic argv.
|
|
60
|
+
*/
|
|
61
|
+
directory_ratchet?: DirectoryRatchetDeclaration
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* `[controls.compliance.directory-ratchet]`: LAY-004's RULE — the per-tree
|
|
66
|
+
* direct-file ceilings, configuration the generic ratchet principle
|
|
67
|
+
* (2026-10-02) moved out of the register, which records state (exemption
|
|
68
|
+
* baselines) only. A ceiling is `max_children.<path> = <n>`: every directory
|
|
69
|
+
* at or below `<path>` (measured per directory) may hold at most `<n>` direct
|
|
70
|
+
* files unless the register records an exemption. Defaults to empty (nothing
|
|
71
|
+
* configured: the gate is inert, the same "no configuration = nothing to
|
|
72
|
+
* enforce" reading DOC-012's cap has).
|
|
73
|
+
*/
|
|
74
|
+
interface DirectoryRatchetDeclaration {
|
|
75
|
+
/** Repo-relative tree path -> its direct-file ceiling (a positive integer). */
|
|
76
|
+
max_children: Record<string, number>
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* `[controls.compliance.lockfiles]`: exactly which paths REP-002 scans and grades. An
|
|
81
|
+
* ecosystem (Bun, Cargo) is declared as a PAIR, a manifests list and a lockfiles list,
|
|
82
|
+
* and a declared pair REPLACES that ecosystem's tree-derived default, in what selects the
|
|
83
|
+
* gate and in what it grades. All four default to empty (nothing declared: the default).
|
|
84
|
+
*/
|
|
85
|
+
interface LockfilesDeclaration {
|
|
86
|
+
/** `package.json` paths or globs, e.g. `package.json`, `apps/*\/package.json`. */
|
|
87
|
+
bun_manifests: string[]
|
|
88
|
+
/** Literal `bun.lock` paths; each must exist and be non-empty. */
|
|
89
|
+
bun_lockfiles: string[]
|
|
90
|
+
/** `Cargo.toml` paths or globs. */
|
|
91
|
+
cargo_manifests: string[]
|
|
92
|
+
/** Literal `Cargo.lock` paths; each one's directory is the cargo workspace graded. */
|
|
93
|
+
cargo_lockfiles: string[]
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** The four keys, in the order `hook.ts` sends them: the Bun pair, then the Cargo pair. */
|
|
97
|
+
export const LOCKFILE_KEYS = ['bun_manifests', 'bun_lockfiles', 'cargo_manifests', 'cargo_lockfiles'] as const
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* `[controls.compliance.markdown]`: directories whose Markdown is site or application
|
|
101
|
+
* content rather than documentation (an Astro site's `src/content/**\/*.md`). LAY-006
|
|
102
|
+
* admits Markdown beneath each in addition to the docs trees, so a declared root only
|
|
103
|
+
* ever widens its allowlist. Defaults to empty.
|
|
104
|
+
*/
|
|
105
|
+
interface MarkdownDeclaration {
|
|
106
|
+
/** Repository-relative directories, trailing `/` normalised away. */
|
|
107
|
+
roots: string[]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** `[controls.compliance.root]`: names directly under the repository root. Both lists default to empty. */
|
|
111
|
+
interface RootDeclaration {
|
|
112
|
+
files: string[]
|
|
113
|
+
dirs: string[]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* `[controls.compliance.limits]`: engine limits a repository overrides. Every key
|
|
118
|
+
* is optional and, absent, leaves the engine default in force.
|
|
119
|
+
*/
|
|
120
|
+
interface LimitsDeclaration {
|
|
121
|
+
/** LAY-014's direct-file limit per scripts directory. The engine default is 15. */
|
|
122
|
+
scripts_direct_files?: number
|
|
123
|
+
/** LAY-016's cap on open gaps in the gap register. The engine default is 10. */
|
|
124
|
+
open_gaps?: number
|
|
125
|
+
/** LAY-016's cap on open plans (Features). Independent of `open_gaps`. The engine default is 10. */
|
|
126
|
+
open_plans?: number
|
|
127
|
+
/** DOC-012's page cap per docs/ directory. The engine default is 15. */
|
|
128
|
+
docs_pages_per_directory?: number
|
|
20
129
|
}
|
|
21
130
|
|
|
22
131
|
/**
|
|
@@ -36,7 +145,7 @@ const ENABLED_SEED_COMMENT = `# Nothing is graded until a gate is named here. A
|
|
|
36
145
|
# the packaged defaults are shaped after the repo these checks were authored
|
|
37
146
|
# against, so an enabled row with unpointed trees grades the wrong files.`
|
|
38
147
|
|
|
39
|
-
|
|
148
|
+
const SEEDED_COMPLIANCE_ATTRIBUTES: SeededAttribute[] = [
|
|
40
149
|
{
|
|
41
150
|
key: 'enabled',
|
|
42
151
|
text: `${ENABLED_SEED_COMMENT}
|
|
@@ -105,7 +214,11 @@ export function parseComplianceConfig(text: string): ComplianceConfig {
|
|
|
105
214
|
const compliance = controls.compliance
|
|
106
215
|
|
|
107
216
|
const problems = new Problems()
|
|
108
|
-
problems.unknownKeys(
|
|
217
|
+
problems.unknownKeys(
|
|
218
|
+
compliance,
|
|
219
|
+
['enabled', 'registry', 'trees', 'inputs', 'license', 'root', 'limits', 'markdown', 'lockfiles', 'directory-ratchet'],
|
|
220
|
+
'',
|
|
221
|
+
)
|
|
109
222
|
|
|
110
223
|
// Absent is the documented default, never an error: install seeds only `version`
|
|
111
224
|
// and `enabled`, and `registry`/`trees` both have working defaults. Present but the
|
|
@@ -127,6 +240,18 @@ export function parseComplianceConfig(text: string): ComplianceConfig {
|
|
|
127
240
|
}
|
|
128
241
|
|
|
129
242
|
const config: ComplianceConfig = { enabled, registry, trees, inputs, declarations }
|
|
243
|
+
// Assigned only when declared: an `undefined`-valued key would still change the
|
|
244
|
+
// shape every whole-object comparison of a root-less repository sees.
|
|
245
|
+
if (compliance.root !== undefined) config.root = parseRoot(compliance.root, problems)
|
|
246
|
+
if (compliance.limits !== undefined) config.limits = parseLimits(compliance.limits, problems)
|
|
247
|
+
if (compliance.markdown !== undefined) config.markdown = parseMarkdown(compliance.markdown, problems)
|
|
248
|
+
if (compliance.lockfiles !== undefined) {
|
|
249
|
+
config.lockfiles = parseLockfiles(compliance.lockfiles, problems)
|
|
250
|
+
rejectSupersededInputs(config.lockfiles, inputs, problems)
|
|
251
|
+
}
|
|
252
|
+
if (compliance['directory-ratchet'] !== undefined) {
|
|
253
|
+
config.directory_ratchet = parseDirectoryRatchet(compliance['directory-ratchet'], problems)
|
|
254
|
+
}
|
|
130
255
|
if (problems.list.length > 0) {
|
|
131
256
|
throw new Error(`${CONFIG_REL} is invalid:\n - ${problems.list.join('\n - ')}`)
|
|
132
257
|
}
|
|
@@ -193,6 +318,289 @@ function parseTrees(
|
|
|
193
318
|
return trees
|
|
194
319
|
}
|
|
195
320
|
|
|
321
|
+
/**
|
|
322
|
+
* A root entry is a NAME directly under the repository root, and the whole list
|
|
323
|
+
* travels to the engine as ONE comma-separated `--declare root-files=a,b` value.
|
|
324
|
+
* So a name may not contain `,` (it would split into two names), `=` (it collides
|
|
325
|
+
* with `--declare name=value`'s own separator) or `/` and `..` (a root name is not
|
|
326
|
+
* a path: either would escape the root or reach below it). Empty and
|
|
327
|
+
* whitespace-only names are refused because the engine rejects an empty item.
|
|
328
|
+
*/
|
|
329
|
+
const ROOT_NAME_FORBIDDEN = /[,/=]|\.\./
|
|
330
|
+
|
|
331
|
+
function parseRoot(value: unknown, problems: Problems): RootDeclaration {
|
|
332
|
+
const root: RootDeclaration = { files: [], dirs: [] }
|
|
333
|
+
if (!isTable(value)) {
|
|
334
|
+
problems.add('root must be a table')
|
|
335
|
+
return root
|
|
336
|
+
}
|
|
337
|
+
problems.unknownKeys(value, ['files', 'dirs'], 'root.')
|
|
338
|
+
for (const key of ['files', 'dirs'] as const) {
|
|
339
|
+
const list = value[key]
|
|
340
|
+
if (list === undefined) continue
|
|
341
|
+
if (!Array.isArray(list)) {
|
|
342
|
+
problems.add(`root.${key} must be an array of strings`)
|
|
343
|
+
continue
|
|
344
|
+
}
|
|
345
|
+
list.forEach((item: unknown, index) => {
|
|
346
|
+
const label = `root.${key}[${index}]`
|
|
347
|
+
if (typeof item !== 'string') problems.add(`${label} must be a string`)
|
|
348
|
+
else if (item.trim() === '') problems.add(`${label} must not be empty`)
|
|
349
|
+
else if (ROOT_NAME_FORBIDDEN.test(item)) problems.add(`${label} must not contain ',', '/', '=' or '..'`)
|
|
350
|
+
else root[key].push(item)
|
|
351
|
+
})
|
|
352
|
+
}
|
|
353
|
+
return root
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const LIMIT_KEYS = ['scripts_direct_files', 'open_gaps', 'open_plans', 'docs_pages_per_directory'] as const
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Each limit travels to the engine as `--declare <name>=N` (`scripts-direct-files`,
|
|
360
|
+
* `open-gaps`, `open-plans`, `docs-pages-per-directory`) and the engine refuses
|
|
361
|
+
* anything but a base-10 positive integer, so the same set is refused here,
|
|
362
|
+
* naming the key. A TOML float with an integral value (`20.0`) reaches this
|
|
363
|
+
* point as the number 20 — the parser does not keep the distinction — and is
|
|
364
|
+
* accepted as 20.
|
|
365
|
+
*/
|
|
366
|
+
function parseLimits(value: unknown, problems: Problems): LimitsDeclaration {
|
|
367
|
+
const limits: LimitsDeclaration = {}
|
|
368
|
+
if (!isTable(value)) {
|
|
369
|
+
problems.add('limits must be a table')
|
|
370
|
+
return limits
|
|
371
|
+
}
|
|
372
|
+
problems.unknownKeys(value, [...LIMIT_KEYS], 'limits.')
|
|
373
|
+
for (const key of LIMIT_KEYS) {
|
|
374
|
+
const limit = value[key]
|
|
375
|
+
if (limit === undefined) continue
|
|
376
|
+
if (typeof limit !== 'number' || !Number.isSafeInteger(limit) || limit < 1) {
|
|
377
|
+
problems.add(`limits.${key} must be a positive integer`)
|
|
378
|
+
} else {
|
|
379
|
+
limits[key] = limit
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return limits
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* A markdown root is a repository-relative DIRECTORY, and the whole list travels to the
|
|
387
|
+
* engine as ONE comma-separated `--declare markdown-roots=a,b` value. So an entry may not
|
|
388
|
+
* contain `,` (it would split into two roots) or `=` (it collides with `--declare
|
|
389
|
+
* name=value`'s own separator), may not be absolute, and may not carry a `.`, `..` or
|
|
390
|
+
* empty path segment -- none of those names a directory this repository owns, and the
|
|
391
|
+
* engine refuses them as could-not-run because a declared root can only WIDEN LAY-006's
|
|
392
|
+
* allowlist. Surrounding whitespace and trailing `/` are normalised away, the same way
|
|
393
|
+
* the engine reads the comma list.
|
|
394
|
+
*/
|
|
395
|
+
const MARKDOWN_ROOT_FORBIDDEN = /[,=]/
|
|
396
|
+
|
|
397
|
+
function parseMarkdown(value: unknown, problems: Problems): MarkdownDeclaration {
|
|
398
|
+
const markdown: MarkdownDeclaration = { roots: [] }
|
|
399
|
+
if (!isTable(value)) {
|
|
400
|
+
problems.add('markdown must be a table')
|
|
401
|
+
return markdown
|
|
402
|
+
}
|
|
403
|
+
problems.unknownKeys(value, ['roots'], 'markdown.')
|
|
404
|
+
const list = value.roots
|
|
405
|
+
if (list === undefined) return markdown
|
|
406
|
+
if (!Array.isArray(list)) {
|
|
407
|
+
problems.add('markdown.roots must be an array of strings')
|
|
408
|
+
return markdown
|
|
409
|
+
}
|
|
410
|
+
list.forEach((item: unknown, index) => {
|
|
411
|
+
const label = `markdown.roots[${index}]`
|
|
412
|
+
if (typeof item !== 'string') {
|
|
413
|
+
problems.add(`${label} must be a string`)
|
|
414
|
+
return
|
|
415
|
+
}
|
|
416
|
+
const trimmed = item.trim()
|
|
417
|
+
if (trimmed === '') {
|
|
418
|
+
problems.add(`${label} must not be empty`)
|
|
419
|
+
return
|
|
420
|
+
}
|
|
421
|
+
const root = trimmed.replace(/\/+$/, '')
|
|
422
|
+
const notADirectory = trimmed.startsWith('/') || root.split('/').some((part) => part === '' || part === '.' || part === '..')
|
|
423
|
+
if (MARKDOWN_ROOT_FORBIDDEN.test(root) || notADirectory) {
|
|
424
|
+
problems.add(
|
|
425
|
+
`${label} must be a repository-relative directory without a leading '/', a '.', '..' or empty segment, ',' or '='`,
|
|
426
|
+
)
|
|
427
|
+
return
|
|
428
|
+
}
|
|
429
|
+
markdown.roots.push(root)
|
|
430
|
+
})
|
|
431
|
+
return markdown
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* The two ecosystems REP-002 grades, with the file name every manifest entry must end in
|
|
436
|
+
* and the per-gate inputs a declared pair supersedes.
|
|
437
|
+
*/
|
|
438
|
+
const LOCKFILE_HALVES = [
|
|
439
|
+
{
|
|
440
|
+
manifests: 'bun_manifests',
|
|
441
|
+
lockfiles: 'bun_lockfiles',
|
|
442
|
+
manifestName: 'package.json',
|
|
443
|
+
inputs: ['REP-002:bun_lock'],
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
manifests: 'cargo_manifests',
|
|
447
|
+
lockfiles: 'cargo_lockfiles',
|
|
448
|
+
manifestName: 'Cargo.toml',
|
|
449
|
+
inputs: ['REP-002:cargo_lock', 'REP-002:cargo_manifest', 'REP-002:workspace'],
|
|
450
|
+
},
|
|
451
|
+
] as const
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Entries travel to the engine as ONE comma-separated `--declare` value, so `,` would split
|
|
455
|
+
* one path in two and `=` collides with `--declare name=value`'s own separator. A backslash,
|
|
456
|
+
* `<`, `>`, `{` and `}` are not path characters here: a `<tree>` placeholder, a brace union
|
|
457
|
+
* and a leading `!` negation are scope SYNTAX, and an entry that carried one would mean more
|
|
458
|
+
* or less than the repository wrote. The engine refuses the same set as could-not-run.
|
|
459
|
+
*/
|
|
460
|
+
const LOCKFILE_ENTRY_FORBIDDEN = /[,=\\<>{}]/
|
|
461
|
+
const LOCKFILE_GLOB_CHARS = /[*?[\]]/
|
|
462
|
+
|
|
463
|
+
/** Is `entry` NOT a path REP-002 can scan? `manifestName` is null for a lockfile entry (a literal path). */
|
|
464
|
+
function lockfileEntryRefused(entry: string, manifestName: string | null): boolean {
|
|
465
|
+
if (LOCKFILE_ENTRY_FORBIDDEN.test(entry) || entry.startsWith('/') || entry.startsWith('!')) return true
|
|
466
|
+
const segments = entry.split('/')
|
|
467
|
+
if (segments.some((part) => part === '' || part === '.' || part === '..')) return true
|
|
468
|
+
if (manifestName !== null) return segments[segments.length - 1] !== manifestName
|
|
469
|
+
return LOCKFILE_GLOB_CHARS.test(entry)
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// A ceiling path is repository-relative and travels to the engine INSIDE one
|
|
473
|
+
// comma-separated `--declare directory-ceilings=<path>:<n>,...` value, so it
|
|
474
|
+
// may not contain `,` (the list separator), `:` or `=` (collisions with the
|
|
475
|
+
// entry and declare separators), a leading `/` or `!`, or a `.`, `..` or empty
|
|
476
|
+
// segment — none of those names a tree this repository owns, and the engine
|
|
477
|
+
// refuses them as could-not-run.
|
|
478
|
+
const CEILING_PATH_FORBIDDEN = /[,:=]/
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* `[controls.compliance.directory-ratchet]`: LAY-004's configured ceilings.
|
|
482
|
+
* The engine reads each `<path>:<n>` entry with the same base-10 positive
|
|
483
|
+
* integer rule as the limits, so the same set is refused here, naming the
|
|
484
|
+
* path.
|
|
485
|
+
*/
|
|
486
|
+
function parseDirectoryRatchet(value: unknown, problems: Problems): DirectoryRatchetDeclaration {
|
|
487
|
+
const ratchet: DirectoryRatchetDeclaration = { max_children: {} }
|
|
488
|
+
if (!isTable(value)) {
|
|
489
|
+
problems.add('directory-ratchet must be a table')
|
|
490
|
+
return ratchet
|
|
491
|
+
}
|
|
492
|
+
problems.unknownKeys(value, ['max_children'], 'directory-ratchet.')
|
|
493
|
+
const ceilings = value.max_children
|
|
494
|
+
if (ceilings === undefined) return ratchet
|
|
495
|
+
if (!isTable(ceilings)) {
|
|
496
|
+
problems.add('directory-ratchet.max_children must be a table')
|
|
497
|
+
return ratchet
|
|
498
|
+
}
|
|
499
|
+
for (const [path, ceiling] of Object.entries(ceilings)) {
|
|
500
|
+
const label = `directory-ratchet.max_children.${path}`
|
|
501
|
+
if (typeof ceiling !== 'number' || !Number.isSafeInteger(ceiling) || ceiling < 1) {
|
|
502
|
+
problems.add(`${label} must be a positive integer`)
|
|
503
|
+
continue
|
|
504
|
+
}
|
|
505
|
+
if (CEILING_PATH_FORBIDDEN.test(path) || path.startsWith('/') || path.startsWith('!')) {
|
|
506
|
+
problems.add(`${label} must be a repository-relative path without a leading '/' or '!', or any of ',', ':', '='`)
|
|
507
|
+
continue
|
|
508
|
+
}
|
|
509
|
+
if (path.split('/').some((part) => part === '' || part === '.' || part === '..')) {
|
|
510
|
+
problems.add(`${label} must be a repository-relative path without a '.', '..' or empty segment`)
|
|
511
|
+
continue
|
|
512
|
+
}
|
|
513
|
+
ratchet.max_children[path] = ceiling
|
|
514
|
+
}
|
|
515
|
+
return ratchet
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
function parseLockfiles(value: unknown, problems: Problems): LockfilesDeclaration {
|
|
519
|
+
const lockfiles: LockfilesDeclaration = { bun_manifests: [], bun_lockfiles: [], cargo_manifests: [], cargo_lockfiles: [] }
|
|
520
|
+
if (!isTable(value)) {
|
|
521
|
+
problems.add('lockfiles must be a table')
|
|
522
|
+
return lockfiles
|
|
523
|
+
}
|
|
524
|
+
problems.unknownKeys(value, [...LOCKFILE_KEYS], 'lockfiles.')
|
|
525
|
+
for (const half of LOCKFILE_HALVES) {
|
|
526
|
+
const broken = new Set<string>()
|
|
527
|
+
for (const [key, manifestName] of [
|
|
528
|
+
[half.manifests, half.manifestName],
|
|
529
|
+
[half.lockfiles, null],
|
|
530
|
+
] as const) {
|
|
531
|
+
const list = value[key]
|
|
532
|
+
if (list === undefined) continue
|
|
533
|
+
if (!Array.isArray(list)) {
|
|
534
|
+
problems.add(`lockfiles.${key} must be an array of strings`)
|
|
535
|
+
broken.add(key)
|
|
536
|
+
continue
|
|
537
|
+
}
|
|
538
|
+
const seen = new Map<string, number>()
|
|
539
|
+
list.forEach((item: unknown, index) => {
|
|
540
|
+
const label = `lockfiles.${key}[${index}]`
|
|
541
|
+
if (typeof item !== 'string') {
|
|
542
|
+
problems.add(`${label} must be a string`)
|
|
543
|
+
broken.add(key)
|
|
544
|
+
return
|
|
545
|
+
}
|
|
546
|
+
const entry = item.trim()
|
|
547
|
+
if (entry === '') {
|
|
548
|
+
problems.add(`${label} must not be empty`)
|
|
549
|
+
broken.add(key)
|
|
550
|
+
return
|
|
551
|
+
}
|
|
552
|
+
if (lockfileEntryRefused(entry, manifestName)) {
|
|
553
|
+
problems.add(
|
|
554
|
+
manifestName === null
|
|
555
|
+
? `${label} must be a literal repository-relative file path without a leading '/' or '!', a '.', '..' or empty segment, a glob character ('*', '?', '[', ']'), or any of ',', '=', '\\', '<', '>', '{', '}'`
|
|
556
|
+
: `${label} must be a repository-relative path or glob ending in ${manifestName}, without a leading '/' or '!', a '.', '..' or empty segment, or any of ',', '=', '\\', '<', '>', '{', '}'`,
|
|
557
|
+
)
|
|
558
|
+
broken.add(key)
|
|
559
|
+
return
|
|
560
|
+
}
|
|
561
|
+
const first = seen.get(entry)
|
|
562
|
+
if (first !== undefined) {
|
|
563
|
+
problems.add(`${label} duplicates lockfiles.${key}[${first}]`)
|
|
564
|
+
broken.add(key)
|
|
565
|
+
return
|
|
566
|
+
}
|
|
567
|
+
seen.set(entry, index)
|
|
568
|
+
lockfiles[key].push(entry)
|
|
569
|
+
})
|
|
570
|
+
}
|
|
571
|
+
// A half is declared as a pair. One list without the other would leave the engine
|
|
572
|
+
// guessing which default the missing list takes, and the engine refuses it too. Skipped
|
|
573
|
+
// when either list already has a problem: that is the one to fix first.
|
|
574
|
+
const hasManifests = lockfiles[half.manifests].length > 0
|
|
575
|
+
const hasLockfiles = lockfiles[half.lockfiles].length > 0
|
|
576
|
+
if (hasManifests !== hasLockfiles && !broken.has(half.manifests) && !broken.has(half.lockfiles)) {
|
|
577
|
+
const [present, missing] = hasManifests ? [half.manifests, half.lockfiles] : [half.lockfiles, half.manifests]
|
|
578
|
+
problems.add(`lockfiles.${present} is declared without lockfiles.${missing}: a half is declared as a pair`)
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
return lockfiles
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* `REP-002:<name>` inputs are the per-gate overrides a declared pair supersedes: the engine
|
|
586
|
+
* grades a declared half from its declaration and never consults them. Left in place they
|
|
587
|
+
* would be silently ignored, so the combination is refused.
|
|
588
|
+
*/
|
|
589
|
+
function rejectSupersededInputs(
|
|
590
|
+
lockfiles: LockfilesDeclaration,
|
|
591
|
+
inputs: Record<string, string>,
|
|
592
|
+
problems: Problems,
|
|
593
|
+
): void {
|
|
594
|
+
for (const half of LOCKFILE_HALVES) {
|
|
595
|
+
if (lockfiles[half.manifests].length === 0 || lockfiles[half.lockfiles].length === 0) continue
|
|
596
|
+
for (const input of half.inputs) {
|
|
597
|
+
if (input in inputs) {
|
|
598
|
+
problems.add(`inputs.${input} is superseded by lockfiles.${half.lockfiles}; remove the input`)
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
196
604
|
export function loadComplianceConfig(repo: string): ComplianceConfig {
|
|
197
605
|
const path = join(repo, CONFIG_REL)
|
|
198
606
|
if (!existsSync(path)) throw new Error(`${CONFIG_REL} is missing — ${INSTALL_HINT}`)
|