@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
|
@@ -35,9 +35,15 @@ export interface StaticCheck {
|
|
|
35
35
|
* repository whose trees are named anything else was graded against
|
|
36
36
|
* enact-m5's, which is why this moved into config.
|
|
37
37
|
*/
|
|
38
|
-
|
|
38
|
+
interface CoverageConfig {
|
|
39
39
|
summary: string
|
|
40
40
|
produce: string
|
|
41
|
+
// The push-phase twin of `produce`: the command pre-push runs when
|
|
42
|
+
// `pre_push.coverage_produce` is armed. Kept separate because a commit-phase
|
|
43
|
+
// producer may mutate the index; the push-phase one must not (a check-mode
|
|
44
|
+
// run is the shape). Empty means "not declared", which is only a problem
|
|
45
|
+
// once the gate itself is armed.
|
|
46
|
+
producePush: string
|
|
41
47
|
sourceRoots: string[]
|
|
42
48
|
srcTestRatioGlobs: string[]
|
|
43
49
|
}
|
|
@@ -77,6 +83,7 @@ export interface RepoControlsConfig {
|
|
|
77
83
|
postCommit: { staticChecks: StaticCheck[] }
|
|
78
84
|
prePush: {
|
|
79
85
|
coverageRatchet: boolean
|
|
86
|
+
coverageProduce: boolean
|
|
80
87
|
findingsRatchet: boolean
|
|
81
88
|
staticChecks: StaticCheck[]
|
|
82
89
|
exportLinks: string[]
|
|
@@ -132,7 +139,7 @@ branches = { protected = ["main", "integration"], prefixes = ["feat", "fix", "do
|
|
|
132
139
|
#
|
|
133
140
|
# Every gate is OFF until its key is added here: installing wires the hooks and arms
|
|
134
141
|
# nothing. Opt in by adding pre_commit (static_checks, staged_coverage, doc_freshness) or the
|
|
135
|
-
# remaining pre_push keys (coverage_ratchet, findings_ratchet, static_checks). README,
|
|
142
|
+
# remaining pre_push keys (coverage_ratchet, coverage_produce, findings_ratchet, static_checks). README,
|
|
136
143
|
# "Configuration", lists each one. Deliberately no example assignments in this comment — commented TOML
|
|
137
144
|
# is indistinguishable from a real setting to find-and-replace, in an editor or a script.
|
|
138
145
|
pre_push = { remote = "origin" }
|
|
@@ -162,19 +169,37 @@ const escapeRegExp = (text: string): string => text.replace(/[.*+?^${}()|[\]\\]/
|
|
|
162
169
|
* the one root key it already owns, which needs no coordination with the other two
|
|
163
170
|
* tools — the same "no tool parses another tool's table" rule the file is built on.
|
|
164
171
|
*/
|
|
165
|
-
|
|
172
|
+
const OWNED_TABLES = ['controls', 'controls.compliance'] as const
|
|
166
173
|
|
|
167
174
|
/**
|
|
168
|
-
* Locates
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
175
|
+
* Locates the byte ranges that make up one table in a shared `adl-config.toml`.
|
|
176
|
+
*
|
|
177
|
+
* A table's ranges are every run of consecutive sections whose header is the table's
|
|
178
|
+
* own `[<tableName>]`, a dotted sub-table `[<tableName>.*]`, or an array table nested
|
|
179
|
+
* under it `[[<tableName>.*]]` (so `[controls.pre_push]` followed by
|
|
180
|
+
* `[[controls.pre_push.static_checks]]` is one range, never split). A range runs to the
|
|
181
|
+
* next line starting with `[` at column 0 that is none of those — except that a
|
|
182
|
+
* sub-table listed in `OWNED_TABLES` terminates it instead, so parent and child stay
|
|
183
|
+
* independently spliceable (`[controls.compliance]` through
|
|
184
|
+
* `[controls.compliance.trees]` is `controls.compliance`'s, not `controls`').
|
|
185
|
+
*
|
|
186
|
+
* More than one range, and no `[<tableName>]` header at all, are both normal: a file
|
|
187
|
+
* written by `adl migrate` carries `[controls.branches]` / `[[controls.pre_push.static_checks]]`
|
|
188
|
+
* and never a bare `[controls]`, and TOML lets a table's descendants be scattered
|
|
189
|
+
* around other tables. Known limitation: a hand-edited block containing a multi-line
|
|
190
|
+
* string whose content starts a line with `[` would confuse this — this tool never
|
|
191
|
+
* writes such content itself.
|
|
176
192
|
*/
|
|
177
|
-
|
|
193
|
+
interface TableRanges {
|
|
194
|
+
text: string
|
|
195
|
+
lines: string[]
|
|
196
|
+
starts: number[]
|
|
197
|
+
ranges: { startLine: number; endLine: number; start: number; end: number }[]
|
|
198
|
+
/** The line index of the exact `[<tableName>]` header, or -1 when the table is only implied by descendants. */
|
|
199
|
+
headerLine: number
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function findTableRanges(text: string, tableName: string): TableRanges {
|
|
178
203
|
const starts: number[] = [0]
|
|
179
204
|
for (let i = 0; i < text.length; i++) if (text[i] === '\n') starts.push(i + 1)
|
|
180
205
|
const lines = text.split('\n').slice(0, starts.length)
|
|
@@ -182,7 +207,7 @@ function findTableSpan(text: string, tableName: string): { start: number; end: n
|
|
|
182
207
|
|
|
183
208
|
const escaped = escapeRegExp(tableName)
|
|
184
209
|
const headerRe = new RegExp(`^\\[${escaped}\\]\\s*$`)
|
|
185
|
-
const subTableRe = new RegExp(`^\\[
|
|
210
|
+
const subTableRe = new RegExp(`^\\[\\[?${escaped}\\.`)
|
|
186
211
|
// A dotted sub-table that this package manages as its own independent span
|
|
187
212
|
// (`[controls.compliance]` living inside `[controls]`) must TERMINATE the parent's
|
|
188
213
|
// span rather than be swallowed by it. Without this, appending compliance to a repo
|
|
@@ -190,49 +215,85 @@ function findTableSpan(text: string, tableName: string): { start: number; end: n
|
|
|
190
215
|
// the next install would read that as drift and refuse — an upgrade path that fails
|
|
191
216
|
// on every already-installed repo.
|
|
192
217
|
const nestedRes = OWNED_TABLES.filter((name) => name !== tableName && name.startsWith(`${tableName}.`)).map(
|
|
193
|
-
(name) => new RegExp(`^\\[
|
|
218
|
+
(name) => new RegExp(`^\\[\\[?${escapeRegExp(name)}(?:\\]|\\.)`),
|
|
194
219
|
)
|
|
195
220
|
const isSeparatelyOwned = (line: string): boolean => nestedRes.some((re) => re.test(line))
|
|
196
221
|
const isSameTableLine = (line: string): boolean => (headerRe.test(line) || subTableRe.test(line)) && !isSeparatelyOwned(line)
|
|
197
222
|
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
223
|
+
const ranges: TableRanges['ranges'] = []
|
|
224
|
+
let headerLine = -1
|
|
225
|
+
const close = (startLine: number, endLine: number): void => {
|
|
226
|
+
// Trim blank lines immediately before the boundary: they separate this table from
|
|
227
|
+
// whatever follows (or end-of-file), not content the table itself owns — so appending
|
|
228
|
+
// another table afterwards never retroactively changes this table's own byte span.
|
|
229
|
+
let contentEnd = endLine
|
|
230
|
+
while (contentEnd > startLine + 1 && (lines[contentEnd - 1] ?? '').trim() === '') contentEnd--
|
|
231
|
+
ranges.push({ startLine, endLine: contentEnd, start: lineStart(startLine), end: contentEnd < starts.length ? lineStart(contentEnd) : text.length })
|
|
232
|
+
}
|
|
233
|
+
let open = -1
|
|
234
|
+
for (let index = 0; index < starts.length; index++) {
|
|
203
235
|
const line = lines[index] ?? ''
|
|
204
|
-
if (
|
|
205
|
-
|
|
206
|
-
|
|
236
|
+
if (!/^\[/.test(line)) continue
|
|
237
|
+
const same = isSameTableLine(line)
|
|
238
|
+
if (same && open === -1) open = index
|
|
239
|
+
if (same && headerLine === -1 && headerRe.test(line)) headerLine = index
|
|
240
|
+
if (!same && open !== -1) {
|
|
241
|
+
close(open, index)
|
|
242
|
+
open = -1
|
|
207
243
|
}
|
|
208
244
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
// another table afterwards never retroactively changes this table's own byte span.
|
|
212
|
-
let contentEnd = endLine
|
|
213
|
-
while (contentEnd > startLine + 1 && (lines[contentEnd - 1] ?? '').trim() === '') contentEnd--
|
|
214
|
-
return { start: lineStart(startLine), end: contentEnd < starts.length ? lineStart(contentEnd) : text.length }
|
|
245
|
+
if (open !== -1) close(open, starts.length)
|
|
246
|
+
return { text, lines, starts, ranges, headerLine }
|
|
215
247
|
}
|
|
216
248
|
|
|
217
|
-
/** The exact bytes of a table's
|
|
249
|
+
/** The exact bytes of a table's ranges (header through its last line, including dotted and array sub-tables), or `null` if absent. */
|
|
218
250
|
export function extractTableSpan(text: string, tableName: string): string | null {
|
|
219
|
-
const
|
|
220
|
-
|
|
251
|
+
const { ranges } = findTableRanges(text, tableName)
|
|
252
|
+
if (ranges.length === 0) return null
|
|
253
|
+
return ranges.map((range) => text.slice(range.start, range.end)).reduce((joined, piece) => (joined === '' || joined.endsWith('\n') ? joined + piece : `${joined}\n${piece}`), '')
|
|
221
254
|
}
|
|
222
255
|
|
|
223
256
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
|
|
257
|
+
* The end of the `[<tableName>]` section's OWN keys: the first sub-table header after
|
|
258
|
+
* it, or the end of its range. A key appended after a sub-table header would belong to
|
|
259
|
+
* that sub-table, so scaffolding must land before it. Comment lines sitting directly on
|
|
260
|
+
* a sub-table header stay with it, and blank separator lines stay in front of it.
|
|
261
|
+
*/
|
|
262
|
+
function ownKeysEnd(found: TableRanges): { offset: number; atRangeEnd: boolean } | null {
|
|
263
|
+
if (found.headerLine === -1) return null
|
|
264
|
+
const range = found.ranges.find((candidate) => candidate.startLine === found.headerLine)
|
|
265
|
+
if (range === undefined) return null
|
|
266
|
+
let sub = range.startLine + 1
|
|
267
|
+
while (sub < range.endLine && !/^\[/.test(found.lines[sub] ?? '')) sub++
|
|
268
|
+
if (sub >= range.endLine) return { offset: range.end, atRangeEnd: true }
|
|
269
|
+
let at = sub
|
|
270
|
+
while (at - 1 > range.startLine && (found.lines[at - 1] ?? '').trim().startsWith('#')) at--
|
|
271
|
+
while (at - 1 > range.startLine && (found.lines[at - 1] ?? '').trim() === '') at--
|
|
272
|
+
return { offset: found.starts[at] ?? found.text.length, atRangeEnd: false }
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* `text` with `addition` inserted at the END of a table's own keys — after its last
|
|
277
|
+
* key line, before its first sub-table header (or whatever follows it). Used to scaffold
|
|
278
|
+
* a single missing attribute into a table this package did not create: every existing
|
|
279
|
+
* byte, including comments, ordering and formatting, is preserved exactly, because
|
|
280
|
+
* nothing is parsed and re-serialized. When the table exists only through its
|
|
281
|
+
* descendants (no `[<tableName>]` header — what `adl migrate` writes), the attribute
|
|
282
|
+
* goes under a new `[<tableName>]` header at the end of the file, which TOML allows
|
|
283
|
+
* after the descendants. Returns `text` unchanged when the table is absent.
|
|
229
284
|
*/
|
|
230
285
|
export function appendToTableSpan(text: string, tableName: string, addition: string): string {
|
|
231
|
-
const
|
|
232
|
-
if (
|
|
233
|
-
const
|
|
286
|
+
const found = findTableRanges(text, tableName)
|
|
287
|
+
if (found.ranges.length === 0) return text
|
|
288
|
+
const lead = addition.startsWith('\n') ? '' : '\n'
|
|
289
|
+
const where = ownKeysEnd(found)
|
|
290
|
+
if (where === null) {
|
|
291
|
+
const base = text.endsWith('\n') ? text : `${text}\n`
|
|
292
|
+
return `${base}\n[${tableName}]${lead}${addition}`
|
|
293
|
+
}
|
|
294
|
+
const before = text.slice(0, where.offset)
|
|
234
295
|
const separator = before.endsWith('\n') ? '' : '\n'
|
|
235
|
-
return `${before}${separator}${addition}${text.slice(
|
|
296
|
+
return `${before}${separator}${addition}${text.slice(where.offset)}`
|
|
236
297
|
}
|
|
237
298
|
|
|
238
299
|
/**
|
|
@@ -244,27 +305,33 @@ export function appendToTableSpan(text: string, tableName: string, addition: str
|
|
|
244
305
|
export const RETIRED_ATTRIBUTES = ['version'] as const
|
|
245
306
|
|
|
246
307
|
/**
|
|
247
|
-
* `text` with `key`'s assignment line removed from
|
|
248
|
-
*
|
|
249
|
-
*
|
|
308
|
+
* `text` with `key`'s assignment line removed from the table's own keys (never from a
|
|
309
|
+
* sub-table or array table under it), along with a blank line left immediately after
|
|
310
|
+
* it. Every other byte is untouched — nothing is parsed and re-serialized. Returns
|
|
311
|
+
* `text` unchanged when the table or key is absent.
|
|
250
312
|
*/
|
|
251
313
|
export function removeFromTableSpan(text: string, tableName: string, key: string): string {
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
const
|
|
314
|
+
const found = findTableRanges(text, tableName)
|
|
315
|
+
const where = ownKeysEnd(found)
|
|
316
|
+
const range = found.ranges.find((candidate) => candidate.startLine === found.headerLine)
|
|
317
|
+
if (where === null || range === undefined) return text
|
|
318
|
+
const body = text.slice(range.start, where.offset)
|
|
255
319
|
const assignment = new RegExp(`^${escapeRegExp(key)}\\s*=.*\\n(\\n)?`, 'm')
|
|
256
320
|
if (!assignment.test(body)) return text
|
|
257
|
-
return text.slice(0,
|
|
321
|
+
return text.slice(0, range.start) + body.replace(assignment, '') + text.slice(where.offset)
|
|
258
322
|
}
|
|
259
323
|
|
|
260
|
-
/** `text` with a table
|
|
324
|
+
/** `text` with every range of a table removed (a no-op if there are none); other tables are untouched. */
|
|
261
325
|
export function removeTableSpan(text: string, tableName: string): string {
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
326
|
+
const { ranges } = findTableRanges(text, tableName)
|
|
327
|
+
let result = text
|
|
328
|
+
for (const range of [...ranges].reverse()) {
|
|
329
|
+
let before = result.slice(0, range.start)
|
|
330
|
+
const after = result.slice(range.end)
|
|
331
|
+
if (before.endsWith('\n\n')) before = before.slice(0, -1)
|
|
332
|
+
result = before + after
|
|
333
|
+
}
|
|
334
|
+
return result
|
|
268
335
|
}
|
|
269
336
|
|
|
270
337
|
/** The exact bytes of the `[controls]` table, or `null` if absent. */
|
|
@@ -417,7 +484,7 @@ export function parseConfig(text: string): RepoControlsConfig {
|
|
|
417
484
|
// so "no branch policy" cannot be spelled as an empty list. Everything else is
|
|
418
485
|
// optional and defaults to off.
|
|
419
486
|
const preCommit = problems.optionalTable(controls, 'pre_commit', ['static_checks', 'staged_coverage', 'doc_freshness', 'compliance'])
|
|
420
|
-
const prePush = problems.table(controls, 'pre_push', ['coverage_ratchet', 'findings_ratchet', 'static_checks', 'export_links', 'remote'])
|
|
487
|
+
const prePush = problems.table(controls, 'pre_push', ['coverage_ratchet', 'coverage_produce', 'findings_ratchet', 'static_checks', 'export_links', 'remote'])
|
|
421
488
|
// Optional, and every field defaults, so a repository that never writes this
|
|
422
489
|
// table behaves exactly as before. `pre_push.coverage_ratchet` stays where it
|
|
423
490
|
// is: that key says WHETHER the gate is armed, this table says WHAT it grades.
|
|
@@ -435,6 +502,7 @@ export function parseConfig(text: string): RepoControlsConfig {
|
|
|
435
502
|
const coverage = problems.optionalTable(controls, 'coverage', [
|
|
436
503
|
'summary',
|
|
437
504
|
'produce',
|
|
505
|
+
'produce_push',
|
|
438
506
|
'source_roots',
|
|
439
507
|
'src_test_ratio_globs',
|
|
440
508
|
])
|
|
@@ -468,13 +536,17 @@ export function parseConfig(text: string): RepoControlsConfig {
|
|
|
468
536
|
// Same shape as `pre_push.static_checks`; this package never interprets
|
|
469
537
|
// the command and names no tool.
|
|
470
538
|
staticChecks: preCommit.static_checks === undefined ? [] : parseStaticChecks(preCommit.static_checks, problems, 'pre_commit.static_checks'),
|
|
471
|
-
stagedCoverage: problems.optionalBool(preCommit, 'staged_coverage', 'pre_commit.staged_coverage',
|
|
472
|
-
docFreshness: problems.optionalBool(preCommit, 'doc_freshness', 'pre_commit.doc_freshness',
|
|
473
|
-
compliance: problems.optionalBool(preCommit, 'compliance', 'pre_commit.compliance',
|
|
539
|
+
stagedCoverage: problems.optionalBool(preCommit, 'staged_coverage', 'pre_commit.staged_coverage', true),
|
|
540
|
+
docFreshness: problems.optionalBool(preCommit, 'doc_freshness', 'pre_commit.doc_freshness', true),
|
|
541
|
+
compliance: problems.optionalBool(preCommit, 'compliance', 'pre_commit.compliance', true),
|
|
474
542
|
},
|
|
475
543
|
prePush: {
|
|
476
|
-
coverageRatchet: problems.optionalBool(prePush, 'coverage_ratchet', 'pre_push.coverage_ratchet',
|
|
477
|
-
|
|
544
|
+
coverageRatchet: problems.optionalBool(prePush, 'coverage_ratchet', 'pre_push.coverage_ratchet', true),
|
|
545
|
+
// New gates opt in: the coverage measurement moved to pre-push, so a
|
|
546
|
+
// repository that never writes this key keeps measuring (or not) exactly
|
|
547
|
+
// where it did before.
|
|
548
|
+
coverageProduce: problems.optionalBool(prePush, 'coverage_produce', 'pre_push.coverage_produce', false),
|
|
549
|
+
findingsRatchet: problems.optionalBool(prePush, 'findings_ratchet', 'pre_push.findings_ratchet', true),
|
|
478
550
|
staticChecks: prePush.static_checks === undefined ? [] : parseStaticChecks(prePush.static_checks, problems, 'pre_push.static_checks'),
|
|
479
551
|
// Untracked paths the HEAD export needs, e.g. a dependency directory.
|
|
480
552
|
// The hook used to hardcode `node_modules`, which assumed JavaScript in a
|
|
@@ -486,6 +558,7 @@ export function parseConfig(text: string): RepoControlsConfig {
|
|
|
486
558
|
coverage: {
|
|
487
559
|
summary: problems.optionalString(coverage, 'summary', 'coverage.summary', DEFAULT_COVERAGE_SUMMARY),
|
|
488
560
|
produce: problems.optionalString(coverage, 'produce', 'coverage.produce', ''),
|
|
561
|
+
producePush: problems.optionalString(coverage, 'produce_push', 'coverage.produce_push', ''),
|
|
489
562
|
sourceRoots: problems.optionalNames(coverage, 'source_roots', 'coverage.source_roots', []),
|
|
490
563
|
srcTestRatioGlobs: problems.optionalNames(
|
|
491
564
|
coverage,
|
|
@@ -3,19 +3,19 @@ import { join, resolve } from 'node:path'
|
|
|
3
3
|
|
|
4
4
|
export const TOOL = 'adl-repo-controls'
|
|
5
5
|
/**
|
|
6
|
-
* Never published (
|
|
6
|
+
* Never published (2026-09-27): kept only as this
|
|
7
7
|
* package's own internal identity (USAGE text, error messages, the lock
|
|
8
8
|
* file's `tool` field) — none of that is a claim that `adl-repo-controls`
|
|
9
9
|
* is installable. NPM_INSTALL/PACKAGE_NAME describe a registry package that
|
|
10
10
|
* does not exist; do not point a user-facing "how do I get this on PATH"
|
|
11
11
|
* message at them (see ADL_NPM_INSTALL below for the one that is real).
|
|
12
12
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const PACKAGE_NAME = '@amsterdamdatalabs/adl-repo-controls'
|
|
14
|
+
const NPM_INSTALL = `npm i -g ${PACKAGE_NAME}`
|
|
15
15
|
/**
|
|
16
16
|
* How a repository's committed git-hook stubs actually get `adl` onto
|
|
17
17
|
* PATH: this package is folded into the `adl` binary's `repo controls`
|
|
18
|
-
* namespace (docs/architecture/cli-design.md §6
|
|
18
|
+
* namespace (docs/architecture/cli-design.md §6) and is never itself
|
|
19
19
|
* a standalone global command. `adl` is either fleet-installed
|
|
20
20
|
* (bin/reconcile's `bun-compile` manager) or, for a machine not yet pinned
|
|
21
21
|
* to the fleet, this published wrapper — see
|
|
@@ -23,7 +23,7 @@ export const NPM_INSTALL = `npm i -g ${PACKAGE_NAME}`
|
|
|
23
23
|
* packaging/npm/wrapper-bin.js.
|
|
24
24
|
*/
|
|
25
25
|
export const ADL_NPM_INSTALL = 'npm install -g @amsterdamdatalabs/adl-agent-control'
|
|
26
|
-
|
|
26
|
+
const PACKAGE_ROOT = resolve(import.meta.dir, '..')
|
|
27
27
|
export const VERSION: string = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8')).version
|
|
28
28
|
|
|
29
29
|
/** Package-owned hook implementations, flattened in commit 20ec790. */
|
|
@@ -37,16 +37,21 @@ export const BUNDLE_ROOT = join(PACKAGE_ROOT, 'scripts')
|
|
|
37
37
|
/** Bundled Python compliance engine (a `uv`-managed project), installed alongside this package. */
|
|
38
38
|
export const COMPLIANCE_ROOT = join(PACKAGE_ROOT, 'package', 'adl-compliance')
|
|
39
39
|
|
|
40
|
-
// `post-checkout` added 2026-09-27
|
|
40
|
+
// `post-checkout` added 2026-09-27: the only backstop
|
|
41
41
|
// for the repo's worktree-count limit (see `MAX_WORKTREES` below and
|
|
42
42
|
// `worktree-guard.ts`) that runs regardless of which agent host or shell path
|
|
43
43
|
// created the worktree — see that file's header for why git has no
|
|
44
44
|
// pre-worktree hook and `post-checkout` is the earliest hook a `git worktree
|
|
45
45
|
// add` actually triggers.
|
|
46
|
-
|
|
46
|
+
//
|
|
47
|
+
// `post-merge` added 2026-10-01 with Git LFS chaining: git-lfs installs
|
|
48
|
+
// pre-push, post-checkout, post-commit and post-merge, and none of them runs under
|
|
49
|
+
// `core.hooksPath=.workflows/hooks` unless the projected hook calls it
|
|
50
|
+
// (scripts/hooks/lib/lfs.sh). post-merge has no other job.
|
|
51
|
+
export const HOOK_NAMES = ['pre-commit', 'commit-msg', 'pre-push', 'post-commit', 'post-checkout', 'post-merge'] as const
|
|
47
52
|
export type HookName = (typeof HOOK_NAMES)[number]
|
|
48
53
|
|
|
49
|
-
|
|
54
|
+
|
|
50
55
|
|
|
51
56
|
// Repository-relative paths written into target repositories.
|
|
52
57
|
export const HOOKS_PATH = '.workflows/hooks'
|
|
@@ -59,8 +64,6 @@ export const WORKFLOWS_ROOT = '.workflows'
|
|
|
59
64
|
|
|
60
65
|
/** The standalone promoter, deployed so CI needs nothing on PATH. */
|
|
61
66
|
export const PROMOTE_REL = '.workflows/promote.ts'
|
|
62
|
-
/** The standalone integration PR auto-complete helper. */
|
|
63
|
-
export const AUTO_COMPLETE_REL = '.workflows/scripts/enable-integration-auto-complete.mjs'
|
|
64
67
|
/** The standalone immutable package-version allocator for integration CI. */
|
|
65
68
|
export const VERSION_BUMP_REL = '.workflows/version-bump.sh'
|
|
66
69
|
/** The standalone CI stage-2 guard: a PR branch must contain integration's tip and be at its version + 1 patch. */
|
|
@@ -68,12 +71,6 @@ export const RECONCILE_GUARD_REL = '.workflows/reconcile-guard.sh'
|
|
|
68
71
|
|
|
69
72
|
export const MANAGED_ASSETS = [
|
|
70
73
|
{ rel: PROMOTE_REL, source: join(PACKAGE_ROOT, 'assets', 'promote.ts'), mode: 0o755, doctorId: 'promote' },
|
|
71
|
-
{
|
|
72
|
-
rel: AUTO_COMPLETE_REL,
|
|
73
|
-
source: join(PACKAGE_ROOT, 'assets', 'enable-integration-auto-complete.mjs'),
|
|
74
|
-
mode: 0o755,
|
|
75
|
-
doctorId: 'integration-auto-complete',
|
|
76
|
-
},
|
|
77
74
|
{
|
|
78
75
|
rel: VERSION_BUMP_REL,
|
|
79
76
|
source: join(PACKAGE_ROOT, 'assets', 'version-bump.sh'),
|
|
@@ -91,15 +88,4 @@ export const MANAGED_ASSETS = [
|
|
|
91
88
|
export const CONFIG_REL = 'adl-config.toml'
|
|
92
89
|
export const LOCK_REL = '.workflows/repo-controls.lock.json'
|
|
93
90
|
export const GITIGNORE_REL = '.gitignore'
|
|
94
|
-
/**
|
|
95
|
-
* Legacy, pre-hard-cut repository-local log root (owner-qualified filenames
|
|
96
|
-
* prevented collisions there). Nothing writes here any more: git-hook logs
|
|
97
|
-
* moved to the shared `.adl/logs/` JSON-Lines format (Tarun, 2026-09-27,
|
|
98
|
-
* docs/architecture/cli-design.md §5a — see `hook-log.ts`). Kept only so existing evidence
|
|
99
|
-
* in an already-installed repository can still be named and quarantined in
|
|
100
|
-
* place (`install.ts`'s `LEGACY_LOG_QUARANTINES`, `gitignore-block.ts`);
|
|
101
|
-
* never read or written by this package.
|
|
102
|
-
*/
|
|
103
|
-
export const LOGS_ROOT_REL = '.enact/logs'
|
|
104
|
-
|
|
105
91
|
export const INSTALL_HINT = `run: ${TOOL} install --repo .`
|
|
@@ -24,17 +24,17 @@
|
|
|
24
24
|
* was the package claiming a surface that is not its own.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
interface MetricSummary {
|
|
28
28
|
total: number
|
|
29
29
|
covered: number
|
|
30
30
|
skipped?: number
|
|
31
31
|
pct: number
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
type CoverageMetric = 'lines' | 'statements' | 'functions' | 'branches'
|
|
35
|
+
const COVERAGE_METRICS: readonly CoverageMetric[] = ['lines', 'statements', 'functions', 'branches']
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
type FileSummary = Record<CoverageMetric, MetricSummary>
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* A summary is a map of repo-relative path -> per-file metrics, plus two
|
|
@@ -112,8 +112,8 @@ export function doctor(repoArg: string, env: Env, options: string | DoctorOption
|
|
|
112
112
|
const bun = which('bun', env)
|
|
113
113
|
add('bun', bun ? null : 'bun not found on PATH (the bundled enact-m5 scripts run with bun)', `bun at ${bun}`)
|
|
114
114
|
// Checks for `adl`, not TOOL ("adl-repo-controls"): the installed git-hook
|
|
115
|
-
// stubs exec `adl repo controls hook <name>` (
|
|
116
|
-
//
|
|
115
|
+
// stubs exec `adl repo controls hook <name>` (2026-09-27 —
|
|
116
|
+
// see install.ts's `stubText`), never a standalone
|
|
117
117
|
// `adl-repo-controls` binary, which is not published and never on PATH by
|
|
118
118
|
// design. TOOL stays this package's own internal identity (USAGE text,
|
|
119
119
|
// the lock file's `tool` field) — a different thing from what a repo's
|
|
@@ -154,37 +154,64 @@ export function doctor(repoArg: string, env: Env, options: string | DoctorOption
|
|
|
154
154
|
)
|
|
155
155
|
// The path the pre-push ratchet grades, not a default: a repository that
|
|
156
156
|
// declares `[controls.coverage].summary` elsewhere was probed at the wrong
|
|
157
|
-
// file and passed with its real summary missing.
|
|
157
|
+
// file and passed with its real summary missing. The gate has a safety
|
|
158
|
+
// gate: with no summary on either side of the index, the step is a no-op
|
|
159
|
+
// (see hook.ts), so this is informational rather than blocking.
|
|
158
160
|
const coverageSummaryExists = existsSync(join(repo, config.coverage.summary))
|
|
159
161
|
add(
|
|
160
162
|
'coverage-summary',
|
|
161
163
|
config.prePush.coverageRatchet && !coverageSummaryExists
|
|
162
|
-
? `pre_push.coverage_ratchet is enabled but ${config.coverage.summary} does not exist — the
|
|
164
|
+
? `pre_push.coverage_ratchet is enabled but ${config.coverage.summary} does not exist — the gate is a no-op until a baseline lands; commit one or set pre_push.coverage_ratchet = false`
|
|
163
165
|
: null,
|
|
164
166
|
`${config.coverage.summary} is present or the ratchet is disabled`,
|
|
167
|
+
'warn',
|
|
168
|
+
)
|
|
169
|
+
// Same shape: `coverage_produce` defaults OFF, but armed with no declared
|
|
170
|
+
// `[controls.coverage].produce_push` it is NOT a no-op — the push gate
|
|
171
|
+
// fails loud (a step that measures nothing is not a pass), so doctor names
|
|
172
|
+
// the misconfiguration before the first push does.
|
|
173
|
+
add(
|
|
174
|
+
'coverage-produce',
|
|
175
|
+
config.prePush.coverageProduce && config.coverage.producePush.trim() === ''
|
|
176
|
+
? 'pre_push.coverage_produce is enabled but [controls.coverage].produce_push declares no command — the push gate fails every push until one is declared; add produce_push or set pre_push.coverage_produce = false'
|
|
177
|
+
: null,
|
|
178
|
+
'pre_push.coverage_produce is disabled or [controls.coverage].produce_push is declared',
|
|
179
|
+
'warn',
|
|
165
180
|
)
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
// use for.
|
|
181
|
+
// Same shape: `findings_ratchet` defaults ON but is a no-op when the floor
|
|
182
|
+
// file is absent. A repo with no lint tooling at all is never asked for a
|
|
183
|
+
// floor it has no use for.
|
|
170
184
|
const findingsFloorExists = existsSync(join(repo, config.findings.floor))
|
|
171
185
|
add(
|
|
172
186
|
'findings-floor',
|
|
173
187
|
config.prePush.findingsRatchet && !findingsFloorExists
|
|
174
|
-
? `pre_push.findings_ratchet is enabled but ${config.findings.floor} does not exist — the
|
|
188
|
+
? `pre_push.findings_ratchet is enabled but ${config.findings.floor} does not exist — the gate is a no-op until a floor lands; commit one or set pre_push.findings_ratchet = false`
|
|
175
189
|
: null,
|
|
176
190
|
`${config.findings.floor} is present or the ratchet is disabled`,
|
|
191
|
+
'warn',
|
|
177
192
|
)
|
|
178
|
-
// A floor on its own measures nothing.
|
|
179
|
-
// empty
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
193
|
+
// A floor on its own measures nothing. With the safety gate in hook.ts
|
|
194
|
+
// (counters empty + no floor → no-op), this is informational when the
|
|
195
|
+
// floor is missing; it stays a hard error only when a floor IS committed
|
|
196
|
+
// but no counter is declared to drive it (the runtime hard-fails too:
|
|
197
|
+
// `findingsRatchetReport` returns 1 when counters is empty).
|
|
198
|
+
if (config.prePush.findingsRatchet && findingsFloorExists && Object.keys(config.findings.counters).length === 0) {
|
|
199
|
+
add(
|
|
200
|
+
'findings-counters',
|
|
201
|
+
'pre_push.findings_ratchet is enabled and a floor is committed but [controls.findings.counters] declares none — a ratchet with nothing to measure grades nothing, so the push is rejected; declare at least one counter or set pre_push.findings_ratchet = false',
|
|
202
|
+
'',
|
|
203
|
+
'fail',
|
|
204
|
+
)
|
|
205
|
+
} else if (config.prePush.findingsRatchet && Object.keys(config.findings.counters).length === 0) {
|
|
206
|
+
add(
|
|
207
|
+
'findings-counters',
|
|
208
|
+
'pre_push.findings_ratchet is enabled but [controls.findings.counters] declares none — the gate is a no-op until a counter is declared',
|
|
209
|
+
'at least one findings counter is declared, or the ratchet is disabled',
|
|
210
|
+
'warn',
|
|
211
|
+
)
|
|
212
|
+
} else {
|
|
213
|
+
add('findings-counters', null, 'at least one findings counter is declared, or the ratchet is disabled')
|
|
214
|
+
}
|
|
188
215
|
// A release declaration is a claim that this repository promotes through a
|
|
189
216
|
// PR. That claim is only armed when the remote branch policies are proved
|
|
190
217
|
// here. Repositories with no release declaration remain outside this
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
// One marker-bounded block, written into a target repository's root
|
|
2
2
|
// `.gitignore` by `install()`, listing every repository-local directory the
|
|
3
|
-
// adl process (repo-controls itself,
|
|
4
|
-
//
|
|
5
|
-
// logger, and the `.scratchpad/` convention every agent surface follows) is
|
|
3
|
+
// adl process (repo-controls itself, the `adl` CLI's own logger, and the
|
|
4
|
+
// `.scratchpad/` convention every agent surface follows) is
|
|
6
5
|
// known to create there. Before this module the only programmatic coverage
|
|
7
6
|
// was two individually-appended lines (`GITIGNORE_LINES`, retired) plus a
|
|
8
7
|
// data-dependent legacy-quarantine reconciliation; everything else
|
|
9
|
-
// (`.scratchpad/`, `.
|
|
8
|
+
// (`.scratchpad/`, `.adl/`) accumulated by hand into
|
|
10
9
|
// this monorepo's own root `.gitignore` over time and was never shipped to a
|
|
11
10
|
// repository that only runs `install`. This is the single source of truth
|
|
12
11
|
// for that list, and the one mechanism that writes or checks it — see
|
|
@@ -15,8 +14,7 @@
|
|
|
15
14
|
//
|
|
16
15
|
// Evidence for each entry, gathered 2026-09-27 by reading this monorepo's
|
|
17
16
|
// own source (not guessed):
|
|
18
|
-
// - `/.enact/logs/` — pre-hard-cut evidence only
|
|
19
|
-
// `LOGS_ROOT_REL`). Neither repo-controls' git
|
|
17
|
+
// - `/.enact/logs/` — pre-hard-cut evidence only. Neither repo-controls' git
|
|
20
18
|
// hooks (`src/hook-log.ts`, 2026-09-27) nor
|
|
21
19
|
// agent-hooks' own hook log write here any more —
|
|
22
20
|
// both moved to `.adl/logs/` JSON-Lines files
|
|
@@ -40,23 +38,6 @@
|
|
|
40
38
|
// root's session/tool-call log; docs/architecture/cli-design.md
|
|
41
39
|
// §5a). Whole `.adl/` dir ignored, matching this
|
|
42
40
|
// monorepo's own hand-authored line.
|
|
43
|
-
// - `/.agents/lean-ctx/{data,state,cache}/`
|
|
44
|
-
// — packages/agent-hooks/src/lean-ctx/env.ts:
|
|
45
|
-
// `leanCtxEnv` points the `lean-ctx` binary's
|
|
46
|
-
// data/state/cache dirs under
|
|
47
|
-
// `<repo>/<DEFAULT_LEAN_CTX_DIR>/{data,state,cache}`.
|
|
48
|
-
// `config/` is deliberately NOT listed: this
|
|
49
|
-
// monorepo's own `.agents/lean-ctx/config/lean-ctx/
|
|
50
|
-
// *.toml` is git-tracked (confirmed via
|
|
51
|
-
// `git ls-files .agents`), so it is committed
|
|
52
|
-
// configuration, not generated state. A repository
|
|
53
|
-
// whose `adl-config.toml` overrides
|
|
54
|
-
// `[hooks] lean_ctx_dir` away from the default is
|
|
55
|
-
// a known gap this static list does not cover —
|
|
56
|
-
// repo-controls does not depend on agent-hooks, so
|
|
57
|
-
// it cannot resolve that override at install time
|
|
58
|
-
// without introducing a new cross-package
|
|
59
|
-
// dependency nobody asked for.
|
|
60
41
|
// - `/.scratchpad/`, `packages/*/.scratchpad/`
|
|
61
42
|
// — not created by any single tool's code, but
|
|
62
43
|
// mandated by the global agent convention (every
|
|
@@ -112,11 +93,6 @@ export const GITIGNORE_BLOCK_LINES: readonly string[] = [
|
|
|
112
93
|
"# adl CLI: repo-root session/tool-call logs (docs/architecture/cli-design.md §5a)",
|
|
113
94
|
'/.adl/',
|
|
114
95
|
'',
|
|
115
|
-
'# agent-hooks: lean-ctx per-repo runtime state (config/ subtree is committed)',
|
|
116
|
-
'/.agents/lean-ctx/data/',
|
|
117
|
-
'/.agents/lean-ctx/state/',
|
|
118
|
-
'/.agents/lean-ctx/cache/',
|
|
119
|
-
'',
|
|
120
96
|
'# adl process convention: scratch and throwaway work, never committed',
|
|
121
97
|
'/.scratchpad/',
|
|
122
98
|
'packages/*/.scratchpad/',
|
|
@@ -224,7 +200,7 @@ export function removeGitignoreBlock(text: string): string {
|
|
|
224
200
|
return joinText(next, nl)
|
|
225
201
|
}
|
|
226
202
|
|
|
227
|
-
|
|
203
|
+
interface GitignoreBlockFinding {
|
|
228
204
|
/** Same id `doctor()` uses for this surface (`gitignore`). */
|
|
229
205
|
readonly id: string
|
|
230
206
|
readonly message: string
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
* `.adl/logs/hooks-deny.log` (FAIL rows only — shared with agent-hooks' own
|
|
20
20
|
* PreToolUse denies, so a human `git commit` denial and an agent's blocked
|
|
21
21
|
* shell command land in one timeline). `.enact/logs/` is a hard cut: this
|
|
22
|
-
* module never reads or writes it; whatever evidence is already there
|
|
23
|
-
* `constants.ts`'s `LOGS_ROOT_REL`) is left exactly where it is.
|
|
22
|
+
* module never reads or writes it; whatever evidence is already there is left exactly where it is.
|
|
24
23
|
*
|
|
25
24
|
* Field mapping onto `LogEntryInput` (`../../agent-hooks/src/log/writer.ts`)
|
|
26
25
|
* — the old CSV's single `git:<hook>` label now lands in the schema's real
|