@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.12 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/adl +2 -2
- package/bin/git +16 -17
- package/bin/git-ado +25 -24
- package/bin/git-defaults +173 -0
- package/bin/health-check +8 -1
- package/bin/kimi-hooks +1 -1
- package/bin/lib/adl-package.sh +257 -0
- package/bin/lib/fleet-host.sh +8 -5
- package/bin/reconcile +482 -232
- package/bin/reconcile-host +30 -20
- package/bin/setup +20 -17
- package/bin/shell-path-policy +15 -5
- package/bin/sync-and-reconcile +62 -64
- package/bin/validate-manifest +33 -9
- package/package.json +2 -10
- package/packages/agent-hooks/README.md +14 -9
- package/packages/agent-hooks/assets/hooks.json +0 -20
- package/packages/agent-hooks/src/cli/args.ts +1 -1
- package/packages/agent-hooks/src/cli/doctor.ts +6 -58
- package/packages/agent-hooks/src/deploy/deploy.ts +12 -41
- package/packages/agent-hooks/src/deploy/doctor.ts +8 -11
- package/packages/agent-hooks/src/deploy/index.ts +14 -14
- package/packages/agent-hooks/src/deploy/json-merge.ts +7 -8
- package/packages/agent-hooks/src/deploy/legacy-lock.ts +2 -2
- package/packages/agent-hooks/src/deploy/list.ts +1 -1
- package/packages/agent-hooks/src/deploy/lock.ts +31 -12
- package/packages/agent-hooks/src/deploy/profile.ts +3 -4
- package/packages/agent-hooks/src/deploy/source.ts +1 -1
- package/packages/agent-hooks/src/gating/config.ts +10 -24
- package/packages/agent-hooks/src/gating/root.ts +3 -3
- package/packages/agent-hooks/src/hooks/briefing/handler.ts +2 -2
- package/packages/agent-hooks/src/hooks/briefing/index.ts +27 -287
- package/packages/agent-hooks/src/hooks/contract.ts +17 -17
- package/packages/agent-hooks/src/hooks/crg/background.ts +27 -0
- package/packages/agent-hooks/src/hooks/crg/index.ts +7 -6
- package/packages/agent-hooks/src/hooks/log.ts +8 -10
- package/packages/agent-hooks/src/hooks/user-prompt-submit/match.ts +1 -1
- package/packages/agent-hooks/src/hooks/user-prompt-submit/tokenizer.ts +1 -1
- package/packages/agent-hooks/src/hooks/user-prompt-submit/vector.ts +6 -5
- package/packages/agent-hooks/src/hosts/registry.ts +1 -1
- package/packages/agent-hooks/src/log/adl-dir.ts +44 -0
- package/packages/agent-hooks/src/log/writer.ts +16 -2
- package/packages/agent-hooks/src/main.ts +7 -41
- package/packages/agent-hooks/src/pre-tool-use/handler.ts +71 -82
- package/packages/agent-hooks/src/rules/engine.ts +13 -17
- package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +3 -3
- package/packages/agent-hooks/src/rules/impl/adl-git-credential-bypass.ts +12 -14
- package/packages/agent-hooks/src/rules/impl/adl-git-identity.ts +28 -28
- package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +8 -9
- package/packages/agent-hooks/src/rules/impl/adl-human-azdo-bypass.ts +56 -59
- package/packages/agent-hooks/src/rules/impl/adl-identity.ts +16 -23
- package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +19 -16
- package/packages/agent-hooks/src/rules/impl/adl-pr-complete-pending.ts +2 -2
- package/packages/agent-hooks/src/rules/impl/adl-pr-review-role.ts +9 -12
- package/packages/agent-hooks/src/rules/impl/adl-pr-role.ts +5 -7
- package/packages/agent-hooks/src/rules/impl/adl-run-required.ts +411 -0
- package/packages/agent-hooks/src/rules/impl/adl-token-minting-role.ts +4 -5
- package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +6 -7
- package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +77 -70
- package/packages/agent-hooks/src/rules/impl/deny-allowlist.ts +159 -0
- package/packages/agent-hooks/src/rules/impl/git-helpers.ts +21 -23
- package/packages/agent-hooks/src/rules/impl/git-worktree.ts +14 -28
- package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +3 -3
- package/packages/agent-hooks/src/rules/impl/messages.ts +1 -1
- package/packages/agent-hooks/src/rules/impl/pr-completion.ts +1 -1
- package/packages/agent-hooks/src/rules/impl/tool-azure-devops.ts +35 -46
- package/packages/agent-hooks/src/rules/impl/tool-find.ts +34 -7
- package/packages/agent-hooks/src/rules/impl/tool-grep.ts +34 -12
- package/packages/agent-hooks/src/rules/impl/tool-native-search.ts +52 -9
- package/packages/agent-hooks/src/rules/ports.ts +5 -7
- package/packages/agent-hooks/src/rules/registry.ts +4 -6
- package/packages/agent-hooks/src/rules/shell/git-identity.ts +86 -101
- package/packages/agent-hooks/src/rules/shell/git-internals.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/invocation.ts +24 -118
- package/packages/agent-hooks/src/rules/shell/piped-script.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/prefixes.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/protected-carrier-writes.ts +11 -10
- package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +26 -26
- package/packages/agent-hooks/src/rules/shell/substitution.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/xargs.ts +2 -2
- package/packages/agent-hooks/src/rules/spec.ts +2 -2
- package/packages/agent-settings/README.md +287 -0
- package/packages/agent-settings/assets/GLOBAL-AGENTS.md +14 -16
- package/packages/agent-settings/assets/agents/architect.toml +2 -0
- package/packages/agent-settings/assets/agents/code-reviewer.toml +2 -0
- package/packages/agent-settings/assets/agents/executor.toml +2 -0
- package/packages/agent-settings/assets/agents/explore.toml +2 -0
- package/packages/agent-settings/assets/agents/planner.toml +2 -0
- package/packages/agent-settings/assets/mcp.json +0 -4
- package/packages/agent-settings/deploy-profile.json +139 -0
- package/packages/agent-settings/deploy-profile.schema.json +147 -0
- package/packages/agent-settings/managed/README.md +29 -30
- package/packages/agent-settings/managed/codex-requirements.toml +9 -9
- package/packages/agent-settings/package.json +20 -0
- package/packages/agent-settings/src/deploy/agent-render.ts +2 -2
- package/packages/agent-settings/src/deploy/agent-toml.ts +1 -1
- package/packages/agent-settings/src/deploy/agents-deploy.ts +17 -3
- package/packages/agent-settings/src/deploy/doctor.ts +3 -83
- package/packages/agent-settings/src/deploy/index.ts +6 -33
- package/packages/agent-settings/src/deploy/legacy-lock.ts +6 -6
- package/packages/agent-settings/src/deploy/list.ts +5 -19
- package/packages/agent-settings/src/deploy/lock.ts +8 -18
- package/packages/agent-settings/src/deploy/mcp-deploy.ts +10 -5
- package/packages/agent-settings/src/deploy/mcp-merge.ts +22 -3
- package/packages/agent-settings/src/deploy/mcp-source.ts +1 -1
- package/packages/agent-settings/src/deploy/profile.ts +11 -35
- package/packages/agent-settings/src/deploy/retire-lean-ctx.ts +184 -0
- package/packages/agent-settings/src/deploy/settings.ts +17 -22
- package/packages/agent-settings/src/global-surface-sweep.ts +0 -2
- package/packages/agent-settings/src/kimi-hooks.ts +339 -192
- package/packages/agent-settings/src/opencode-hooks.ts +1 -1
- package/packages/agent-settings/tsconfig.json +23 -0
- package/packages/agent-skills/assets/agent-search-tool-audit/SKILL.md +120 -0
- package/packages/agent-skills/assets/agent-search-tool-audit/scripts/audit.sh +276 -0
- package/packages/agent-skills/assets/debug-issue/SKILL.md +8 -7
- package/packages/agent-skills/assets/explore-codebase/SKILL.md +13 -13
- package/packages/agent-skills/assets/refactor-safely/SKILL.md +12 -11
- package/packages/agent-skills/assets/review-changes/SKILL.md +7 -7
- package/packages/agent-skills/assets/testing/references/e2e.md +37 -0
- package/packages/agent-skills/assets/testing/references/integration.md +37 -0
- package/packages/agent-skills/assets/testing/references/unit.md +32 -0
- package/packages/agent-skills/dist/deploy.d.ts +2 -0
- package/packages/agent-skills/dist/deploy.d.ts.map +1 -1
- package/packages/agent-skills/dist/deploy.js +27 -1
- package/packages/agent-skills/dist/deploy.js.map +1 -1
- package/packages/agent-skills/dist/doctor.d.ts +0 -2
- package/packages/agent-skills/dist/doctor.d.ts.map +1 -1
- package/packages/agent-skills/dist/doctor.js +1 -1
- package/packages/agent-skills/dist/doctor.js.map +1 -1
- package/packages/agent-skills/dist/fs-utils.d.ts +0 -1
- package/packages/agent-skills/dist/fs-utils.d.ts.map +1 -1
- package/packages/agent-skills/dist/fs-utils.js +1 -1
- package/packages/agent-skills/dist/fs-utils.js.map +1 -1
- package/packages/agent-skills/src/deploy.ts +29 -1
- package/packages/agent-skills/src/doctor.ts +1 -1
- package/packages/agent-skills/src/fs-utils.ts +1 -1
- package/packages/azdo/README.md +10 -9
- package/packages/azdo/package.json +1 -3
- package/packages/azdo/src/azdo-pl.ts +2 -54
- package/packages/azdo/src/azdo-pr-review.ts +4 -4
- package/packages/azdo/src/azdo-repo-doctor.ts +101 -52
- package/packages/azdo/src/azdo-wit.ts +41 -2
- package/packages/azdo/src/lib/agent-identity.ts +12 -14
- package/packages/azdo/src/lib/agent-token.ts +2 -2
- package/packages/azdo/src/lib/client.ts +0 -5
- package/packages/azdo/src/lib/graph-identity.ts +4 -4
- package/packages/azdo/src/workflow-rules-matrix.csv +85 -0
- package/packages/azdo/src/workflow-rules.ts +128 -0
- package/packages/fleet/manifest.json +35 -11
- package/packages/fleet/manifest.schema.json +62 -10
- package/packages/fleet/src/default-agent-file.ts +3 -3
- package/packages/fleet/src/install-adl-package.ts +73 -15
- package/packages/fleet/src/install-embedding-model.ts +13 -13
- package/packages/fleet/src/managed-settings.ts +7 -7
- package/packages/fleet/src/repo-maintain.ts +91 -55
- package/packages/fleet/src/scratch-reap.ts +5 -5
- package/packages/fleet/src/vscode-settings.ts +5 -5
- package/packages/repo-controls/README.md +141 -43
- package/packages/repo-controls/assets/promote.ts +4 -4
- package/packages/repo-controls/assets/reconcile-guard.sh +10 -46
- package/packages/repo-controls/assets/version-bump.sh +31 -84
- package/packages/repo-controls/bunfig.toml +6 -7
- package/packages/repo-controls/package/adl-compliance/AGENTS.md +5 -6
- package/packages/repo-controls/package/adl-compliance/conftest.py +3 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +4 -16
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +9 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/notes.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/check.py +266 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.hidden.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/data.csv +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/diagram.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/mock.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/sub/nested.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p1.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p2.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p3.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p4.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p5.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/build.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/overview.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/install.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/start.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-001-tenancy.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-002-carrier.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-003-cli.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-old.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-older.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-01.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-02.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-03.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-04.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-05.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-06.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-07.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-08.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-09.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-10.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-11.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-12.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-13.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-14.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-15.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-16.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/e.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/short/only.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/grants.yaml +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/test_check.py +345 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +18 -5
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +35 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/check.py +91 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/CLAUDE.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/-leading-hyphen.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/double--hyphen.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/getting started.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/nested/page-here.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/trailing-hyphen-.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/ui-contract.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/user_profile.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/UI-CONTRACT.png +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/diagram.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/index.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/notes.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/reference.html +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/2026-10-experiment.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/UI-CONTRACT.md +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/test_check.py +194 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +14 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +5 -5
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-legacy/docs/compliance/index.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-type/docs/compliance/index.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +58 -6
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +64 -17
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +60 -9
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-clean/docs/notes.md +17 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-no-lines/docs/notes.md +13 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/no-type.md +9 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-experiment.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-research.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs-okf-profiles.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs/architecture/bad-status.md +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/experiment-ok.md +15 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-key.md +15 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-keys.md +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-created.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-description.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-last-update.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-sources.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-status.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-title.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/optional-keys.md +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/research-ok.md +14 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/created-date.md +21 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/research-shaped.md +19 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/operations/runbook.md +26 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +228 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +11 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +5 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +160 -44
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/a.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/b.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/grants.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/a.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/b.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/c.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/grants.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/register.py +127 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +265 -29
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +75 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +194 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +56 -10
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +256 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +40 -12
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +108 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +2 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +23 -6
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +76 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +58 -17
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +161 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +35 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +108 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +281 -61
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/absolute-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/backslash-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/baseline-is-a-list.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/boolean-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/dot-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/duplicate-path.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-file.yaml +0 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/float-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/negative-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-over-limit-baseline.yaml +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-schema-version.yaml +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/non-string-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/not-yaml.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/null-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/parent-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/string-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/top-level-is-a-list.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/trailing-slash.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/unknown-key.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/wrong-schema-version.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/zero-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/valid.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +758 -45
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +4 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +2 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/cargo_lock.py +490 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +368 -55
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +4 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_declared_paths.py +523 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_stale_lock.py +1179 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +122 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +33 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +0 -11
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +16 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +1 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +12 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +133 -147
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +133 -147
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +52 -10
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +23 -4
- package/packages/repo-controls/package.json +2 -9
- package/packages/repo-controls/scripts/hooks/post-merge +13 -0
- package/packages/repo-controls/scripts/hooks/pre-push +3 -3
- package/packages/repo-controls/src/azdo-push.ts +64 -36
- package/packages/repo-controls/src/azure-devops-governance.ts +7 -9
- package/packages/repo-controls/src/azure-devops-remote.ts +1 -1
- package/packages/repo-controls/src/cli.ts +29 -8
- package/packages/repo-controls/src/compliance-config.ts +410 -2
- package/packages/repo-controls/src/config.ts +133 -60
- package/packages/repo-controls/src/constants.ts +13 -27
- package/packages/repo-controls/src/coverage-ratchet.ts +4 -4
- package/packages/repo-controls/src/doctor.ts +46 -19
- package/packages/repo-controls/src/gitignore-block.ts +5 -29
- package/packages/repo-controls/src/hook-log.ts +1 -2
- package/packages/repo-controls/src/hook.ts +201 -45
- package/packages/repo-controls/src/install.ts +14 -8
- package/packages/repo-controls/src/integrity.ts +3 -3
- package/packages/repo-controls/src/lfs.ts +111 -0
- package/packages/repo-controls/src/promote.ts +8 -8
- package/packages/repo-controls/src/runtime.ts +9 -1
- package/packages/repo-controls/src/workflows-drift.ts +4 -5
- package/packages/repo-controls/src/worktree-guard.ts +3 -3
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place that makes a repository's `.adl/` folder self-ignoring.
|
|
3
|
+
*
|
|
4
|
+
* Every adl component that creates `<repo>/.adl/` (the `.adl/logs/` writer,
|
|
5
|
+
* `adl run`'s transcript, the crg background update, the git-hook log seam)
|
|
6
|
+
* calls `ensureAdlGitignore` right after it creates the directory. The file it
|
|
7
|
+
* writes, `.adl/.gitignore` containing exactly `*\n`, ignores the folder's whole
|
|
8
|
+
* content INCLUDING itself, so `.adl/` never shows in `git status` -- in any git
|
|
9
|
+
* repository, adl-controlled or not, without ever editing the repo's own
|
|
10
|
+
* `.gitignore` (the `/.adl/` block `adl repo controls install` writes covers
|
|
11
|
+
* controlled repos only). Logs carry commands and output, so they must not be
|
|
12
|
+
* committable by accident.
|
|
13
|
+
*
|
|
14
|
+
* `apps/cli` and `packages/repo-controls` import this module by relative path
|
|
15
|
+
* (as they already do `./writer.ts`), so there is exactly one copy.
|
|
16
|
+
*/
|
|
17
|
+
import { writeFileSync } from "node:fs";
|
|
18
|
+
import { basename, dirname, join } from "node:path";
|
|
19
|
+
|
|
20
|
+
const ADL_DIR_NAME = ".adl";
|
|
21
|
+
|
|
22
|
+
/** Exactly this content, nothing else: ignore every entry, this file included. */
|
|
23
|
+
const ADL_GITIGNORE_CONTENT = "*\n";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Finds the nearest `.adl` directory at or above `path` and, if it has no
|
|
27
|
+
* `.gitignore` yet, writes one containing `*\n`. An existing `.gitignore` is
|
|
28
|
+
* never overwritten or read. A `path` with no `.adl` segment (the
|
|
29
|
+
* `~/.local/state/adl/logs` fallback, a test tmp dir) is a no-op. The `.adl`
|
|
30
|
+
* directory must already exist; a missing one throws, like any other write.
|
|
31
|
+
*/
|
|
32
|
+
export function ensureAdlGitignore(path: string): void {
|
|
33
|
+
if (basename(path) !== ADL_DIR_NAME) {
|
|
34
|
+
const parent = dirname(path);
|
|
35
|
+
if (parent !== path) ensureAdlGitignore(parent);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
// "wx": create only if absent -- an existing file is left untouched.
|
|
40
|
+
writeFileSync(join(path, ".gitignore"), ADL_GITIGNORE_CONTENT, { flag: "wx" });
|
|
41
|
+
} catch (error) {
|
|
42
|
+
if ((error as NodeJS.ErrnoException).code !== "EEXIST") throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* The `.adl/logs/` logger (docs/architecture/cli-design.md §5a, item 9). `agent-hooks`
|
|
3
3
|
* "holds logs" (§12): this module lives here and writes `hooks.log` /
|
|
4
4
|
* `hooks-deny.log` (`../hooks/log.ts`); `apps/cli/src/log.ts` re-exports it
|
|
5
|
-
* unchanged so `adl run`'s `tool-calls.log` writer keeps working. The module
|
|
5
|
+
* unchanged so `adl run`'s `agents/tool-calls.log` writer keeps working. The module
|
|
6
6
|
* is generic across all five documented files so a caller never has to
|
|
7
7
|
* reinvent the format.
|
|
8
8
|
*
|
|
@@ -28,7 +28,8 @@ import {
|
|
|
28
28
|
writeFileSync,
|
|
29
29
|
} from "node:fs";
|
|
30
30
|
import { homedir } from "node:os";
|
|
31
|
-
import { dirname, join } from "node:path";
|
|
31
|
+
import { basename, dirname, join } from "node:path";
|
|
32
|
+
import { ensureAdlGitignore } from "./adl-dir.ts";
|
|
32
33
|
|
|
33
34
|
export type LogFileName = "hooks" | "hooks-deny" | "tool-rewrites" | "tool-calls" | "repo-controls";
|
|
34
35
|
|
|
@@ -128,9 +129,22 @@ function tightenMode(path: string, target: number): void {
|
|
|
128
129
|
function ensureDirSecure(dir: string): void {
|
|
129
130
|
const parent = dirname(dir);
|
|
130
131
|
mkdirSync(parent, { recursive: true });
|
|
132
|
+
// A nested log stream such as `.adl/logs/agents/` must not leave the
|
|
133
|
+
// repository's `.adl/` ancestor at the default mkdir mode (0755).
|
|
134
|
+
// Root-level streams already tightened it as `parent`; locate it rather
|
|
135
|
+
// than changing unrelated ancestors of the state-directory fallback.
|
|
136
|
+
let ancestor = parent;
|
|
137
|
+
while (ancestor !== dirname(ancestor)) {
|
|
138
|
+
if (basename(ancestor) === ".adl") {
|
|
139
|
+
tightenMode(ancestor, 0o700);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
ancestor = dirname(ancestor);
|
|
143
|
+
}
|
|
131
144
|
tightenMode(parent, 0o700);
|
|
132
145
|
mkdirSync(dir, { recursive: true });
|
|
133
146
|
tightenMode(dir, 0o700);
|
|
147
|
+
ensureAdlGitignore(dir);
|
|
134
148
|
}
|
|
135
149
|
|
|
136
150
|
function ensureFileSecure(filePath: string): void {
|
|
@@ -7,11 +7,9 @@
|
|
|
7
7
|
*
|
|
8
8
|
* adl hook <kind> [subcommand] --host=<claude|codex|cursor|kimi|opencode>
|
|
9
9
|
*
|
|
10
|
-
* kinds: pre-tool-use, user-prompt-submit, briefing, crg <subcommand
|
|
11
|
-
* lean-ctx <subcommand>
|
|
10
|
+
* kinds: pre-tool-use, user-prompt-submit, briefing, crg <subcommand>
|
|
12
11
|
* crg subcommands: after-file-edit, pre-commit, session-stop
|
|
13
|
-
*
|
|
14
|
-
* payload: JSON on stdin (NOT for `lean-ctx mcp` — see below)
|
|
12
|
+
* payload: JSON on stdin
|
|
15
13
|
* --version prints the package version and exits 0
|
|
16
14
|
*
|
|
17
15
|
* Operator commands (src/cli/; no --host, no stdin):
|
|
@@ -30,14 +28,6 @@
|
|
|
30
28
|
* loud (non-zero exit, reason on stderr) — never silently ignored.
|
|
31
29
|
* - `[hooks] enabled = false`: silent no-op, same as unmanaged.
|
|
32
30
|
*
|
|
33
|
-
* `lean-ctx mcp` is the one exception to this whole flow (work item A.1): it
|
|
34
|
-
* takes no JSON payload, needs no `--host`, and never no-ops for an
|
|
35
|
-
* unmanaged repo (an MCP client that just spawned it expects a running
|
|
36
|
-
* server, not a silent exit) — see `src/lean-ctx/mcp.ts`'s header. It is
|
|
37
|
-
* dispatched before `--host` resolution, before stdin is read at all, and
|
|
38
|
-
* bypasses `HookHandler`/`HookResult` entirely (real stdio passthrough
|
|
39
|
-
* cannot be buffered into a string).
|
|
40
|
-
*
|
|
41
31
|
* Every other hook kind is dispatched through the shared `HookHandler` shape
|
|
42
32
|
* in `src/hooks/contract.ts` so a handler never touches `process`, argv, or
|
|
43
33
|
* stdin directly.
|
|
@@ -49,7 +39,7 @@
|
|
|
49
39
|
* the shared fail-closed signal `pre-tool-use`'s own decisions already use
|
|
50
40
|
* (`FAIL_CLOSED_EXIT_CODE`, `src/rules/engine.ts`) for Kimi/OpenCode denials.
|
|
51
41
|
* Every other kind is advisory or best-effort (`user-prompt-submit`,
|
|
52
|
-
* `briefing`, `crg
|
|
42
|
+
* `briefing`, `crg`) and none of them has a "block"
|
|
53
43
|
* concept at all — worse, on Claude Code and Codex, exit code 2 from
|
|
54
44
|
* `UserPromptSubmit` specifically blocks the prompt AND ERASES IT (documented
|
|
55
45
|
* Claude Code hook behaviour: a `UserPromptSubmit` hook exiting 2 shows
|
|
@@ -88,13 +78,11 @@ import { handlePreToolUse } from './pre-tool-use/handler.ts'
|
|
|
88
78
|
import { handleUserPromptSubmit } from './hooks/user-prompt-submit/handler.ts'
|
|
89
79
|
import { handleBriefing } from './hooks/briefing/handler.ts'
|
|
90
80
|
import { handleCrg } from './hooks/crg/handler.ts'
|
|
91
|
-
import { handleLeanCtx } from './hooks/lean-ctx/handler.ts'
|
|
92
|
-
import { runLeanCtxMcp } from './lean-ctx/mcp.ts'
|
|
93
81
|
import { runRules } from './cli/rules.ts'
|
|
94
82
|
import { runDoctor } from './cli/doctor.ts'
|
|
95
83
|
import { runLogged } from './hooks/log.ts'
|
|
96
84
|
|
|
97
|
-
const HOOK_KINDS = ['pre-tool-use', 'user-prompt-submit', 'briefing', 'crg'
|
|
85
|
+
const HOOK_KINDS = ['pre-tool-use', 'user-prompt-submit', 'briefing', 'crg'] as const
|
|
98
86
|
type HookKind = (typeof HOOK_KINDS)[number]
|
|
99
87
|
|
|
100
88
|
function isHookKind(value: string | undefined): value is HookKind {
|
|
@@ -102,14 +90,12 @@ function isHookKind(value: string | undefined): value is HookKind {
|
|
|
102
90
|
}
|
|
103
91
|
|
|
104
92
|
const CRG_SUBCOMMANDS = ['after-file-edit', 'pre-commit', 'session-stop'] as const
|
|
105
|
-
const LEAN_CTX_SUBCOMMANDS = ['mcp', 'pre-tool-use', 'post-tool-use'] as const
|
|
106
93
|
|
|
107
94
|
const HANDLERS: Readonly<Record<HookKind, HookHandler>> = {
|
|
108
95
|
'pre-tool-use': handlePreToolUse,
|
|
109
96
|
'user-prompt-submit': handleUserPromptSubmit,
|
|
110
97
|
briefing: handleBriefing,
|
|
111
98
|
crg: handleCrg,
|
|
112
|
-
'lean-ctx': handleLeanCtx,
|
|
113
99
|
}
|
|
114
100
|
|
|
115
101
|
/** Exit code `pre-tool-use` alone uses to fail closed on an undecidable payload — see this file's header (work item D). */
|
|
@@ -167,24 +153,6 @@ export async function run(argv: readonly string[]): Promise<number> {
|
|
|
167
153
|
}
|
|
168
154
|
subcommand = candidate
|
|
169
155
|
}
|
|
170
|
-
if (kind === 'lean-ctx') {
|
|
171
|
-
const candidate = argv[1]
|
|
172
|
-
if (candidate === undefined || !(LEAN_CTX_SUBCOMMANDS as readonly string[]).includes(candidate)) {
|
|
173
|
-
process.stderr.write(
|
|
174
|
-
`adl hook: lean-ctx requires a subcommand (one of ${LEAN_CTX_SUBCOMMANDS.join(', ')})\n`,
|
|
175
|
-
)
|
|
176
|
-
return 1
|
|
177
|
-
}
|
|
178
|
-
subcommand = candidate
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// `lean-ctx mcp` bypasses everything below: no --host, no stdin-as-JSON,
|
|
182
|
-
// no HookHandler dispatch, and unmanaged is NOT a no-op — see
|
|
183
|
-
// `./lean-ctx/mcp.ts`'s header and this file's own header (work item A.1).
|
|
184
|
-
if (kind === 'lean-ctx' && subcommand === 'mcp') {
|
|
185
|
-
return runLeanCtxMcp(process.cwd(), process.env)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
156
|
// az385: host resolution failure fails CLOSED (FAIL_CLOSED_EXIT_CODE, 2)
|
|
189
157
|
// only for pre-tool-use — the one kind whose job is "block a dangerous
|
|
190
158
|
// action," matching the invalid-JSON-on-stdin split a few lines below and
|
|
@@ -217,11 +185,9 @@ export async function run(argv: readonly string[]): Promise<number> {
|
|
|
217
185
|
// `adl-config.toml` where `adl hooks deploy` has run — nowhere else. No
|
|
218
186
|
// git root, or no `adl-config.toml` above `cwd`: a strict no-op (this
|
|
219
187
|
// file's own header) — no rule evaluation, no identity check, no
|
|
220
|
-
// `hooks.log` write.
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
// repo; Tarun decided the repos where `adl-config.toml` does not exist
|
|
224
|
-
// have no business running hooks at all.
|
|
188
|
+
// `hooks.log` write. There is no global identity baseline: a repo where
|
|
189
|
+
// `adl-config.toml` does not exist has no business running hooks at all.
|
|
190
|
+
// The same no-op applies when `[hooks] enabled = false` (below).
|
|
225
191
|
const managed = resolveManagedRepo(realRootIO, cwd)
|
|
226
192
|
if (!managed.managed || managed.root === null || managed.configPath === null) {
|
|
227
193
|
return writeResult(silentNoop())
|
|
@@ -35,7 +35,7 @@ import { gitIdentityNeedsIdentityMessage, hostCannotRewriteMessage, RULE_ID as G
|
|
|
35
35
|
import { RULE_ID as GIT_CREDENTIAL_BYPASS_RULE_ID, SECURITY_RULE_ID as SECURITY_KEYCHAIN_ADO_RULE_ID } from '../rules/impl/adl-git-credential-bypass.ts'
|
|
36
36
|
import { RULE_ID as HUMAN_AZDO_BYPASS_RULE_ID } from '../rules/impl/adl-human-azdo-bypass.ts'
|
|
37
37
|
import { resolveFromEnvOrFile } from '../rules/impl/adl-identity.ts'
|
|
38
|
-
import { identityBearingReason } from '../rules/impl/adl-
|
|
38
|
+
import { identityBearingReason } from '../rules/impl/adl-run-required.ts'
|
|
39
39
|
import { commandHasValidInlineIdentity, effectiveIdentityForCommand } from '../rules/shell/git-identity.ts'
|
|
40
40
|
import { invocations } from '../rules/shell/invocation.ts'
|
|
41
41
|
import { KNOWN_MCP_TOOL_NAMES, mcpToolName, toolNameEndingWithKnownSuffix } from '../rules/impl/mcp-tool.ts'
|
|
@@ -82,7 +82,7 @@ const RULES = requireRegistered(BUILTIN_RULES)
|
|
|
82
82
|
export function toDecideInput(payload: Record<string, unknown>): DecideInput | null {
|
|
83
83
|
const toolInput = (payload.tool_input ?? {}) as Record<string, unknown>
|
|
84
84
|
|
|
85
|
-
//
|
|
85
|
+
// Codex's `apply_patch` names its
|
|
86
86
|
// patch body `tool_input.command` — the same key name a real shell tool
|
|
87
87
|
// call uses. Checked BEFORE the generic loop below, which would otherwise
|
|
88
88
|
// read that patch TEXT as if it were a shell command and walk it through
|
|
@@ -167,13 +167,11 @@ function classifyCommandTool(payload: Record<string, unknown>): CommandToolClass
|
|
|
167
167
|
if (typeof tool !== 'string' || tool.length === 0) return 'native-shell'
|
|
168
168
|
if (tool.startsWith('mcp__') || tool.startsWith('MCP:')) return 'mcp'
|
|
169
169
|
if (NATIVE_SHELL_TOOL_NAMES.has(tool)) return 'native-shell'
|
|
170
|
-
// ASSUMPTION (unverified
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
// `<server>.ctx_shell` / `<server>:ctx_shell` (or the ctx_execute
|
|
176
|
-
// sibling). Treated as MCP-class defensively: an unrewritten push through
|
|
170
|
+
// ASSUMPTION (unverified): OpenCode's and Kimi's own MCP tool-call naming
|
|
171
|
+
// has not been confirmed against a live capture (the tests use synthetic names) — they may
|
|
172
|
+
// carry no mcp__/MCP: prefix at all, spelling the lean-ctx shell tool
|
|
173
|
+
// `<server>_ctx_shell` / `<server>.ctx_shell` / `<server>:ctx_shell` (or
|
|
174
|
+
// the ctx_execute sibling). Treated as MCP-class defensively: an unrewritten push through
|
|
177
175
|
// such a call would otherwise silently fall through to 'other' and reach
|
|
178
176
|
// git-ado's human pass-through unrewritten — the exact incident this
|
|
179
177
|
// module exists to close (see this file's own header).
|
|
@@ -229,7 +227,7 @@ export async function handlePreToolUse(inv: HookInvocation): Promise<HookResult>
|
|
|
229
227
|
|
|
230
228
|
// The invocation's own environment, not the handler process's ambient one:
|
|
231
229
|
// `main.ts` passes `process.env` here in production, and the identity rules
|
|
232
|
-
// (`adl.
|
|
230
|
+
// (`adl.run-required-for-writes`, `adl.git-push-branch-policy`,
|
|
233
231
|
// `adl.git-identity`'s rewrite) must read the environment the caller handed
|
|
234
232
|
// the invocation — tests inject it explicitly, and a host that scrubs its
|
|
235
233
|
// hook child's environment must not inherit the hook wrapper's own identity.
|
|
@@ -257,24 +255,21 @@ export async function handlePreToolUse(inv: HookInvocation): Promise<HookResult>
|
|
|
257
255
|
}
|
|
258
256
|
|
|
259
257
|
/**
|
|
260
|
-
* The identity rule ids — used below
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
258
|
+
* The identity rule ids — used below purely to tell `denyIdentity`/
|
|
259
|
+
* `passIdentity` which decisions in a MANAGED repo's own normal rule pass
|
|
260
|
+
* are identity decisions worth logging `identity_source`/`identityAgent`
|
|
261
|
+
* for, as opposed to an unrelated deny (`fs.rm`, `git.no-verify`, …) that
|
|
262
|
+
* made no identity decision at all.
|
|
265
263
|
*
|
|
266
|
-
*
|
|
267
|
-
* config.toml`
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
* calls anything for either of those cases but a strict, silent no-op — see
|
|
273
|
-
* its own header and `silentNoop`. The rule ids themselves stay meaningful
|
|
274
|
-
* only for the logging purpose above, in the repos where hooks already run.
|
|
264
|
+
* This is NOT a baseline that runs anywhere else: hooks run only in a repo
|
|
265
|
+
* with its own `adl-config.toml` where `adl hooks deploy` has run
|
|
266
|
+
* (Tarun, 2026-09-29: "the repos where `adl-config.toml` does not exist have
|
|
267
|
+
* no business running hooks"). `main.ts` calls nothing but a strict, silent
|
|
268
|
+
* no-op for an unmanaged repo or one with `[hooks] enabled = false` — see its
|
|
269
|
+
* own header and `silentNoop`.
|
|
275
270
|
*/
|
|
276
271
|
const IDENTITY_RULE_IDS: ReadonlySet<RuleId> = new Set([
|
|
277
|
-
'adl.
|
|
272
|
+
'adl.run-required-for-writes',
|
|
278
273
|
'adl.git-identity',
|
|
279
274
|
'adl.token-minting-role',
|
|
280
275
|
'tool.azure-devops',
|
|
@@ -285,18 +280,17 @@ const IDENTITY_RULE_IDS: ReadonlySet<RuleId> = new Set([
|
|
|
285
280
|
])
|
|
286
281
|
|
|
287
282
|
/**
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
* `adl.
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
* would have been without the role mismatch.
|
|
283
|
+
* The four role-gate rules that deny a SPECIFIC Azure DevOps MCP tool call by
|
|
284
|
+
* the caller's identity (`adl.workitem-requires-tarun-or-vivek`,
|
|
285
|
+
* `adl.pr-create-update-role`, `adl.pr-review-role`,
|
|
286
|
+
* `adl.build-run-denied`). None of these are in `IDENTITY_RULE_IDS` above —
|
|
287
|
+
* that set covers the rules that fire when no identity is resolved or
|
|
288
|
+
* carried, never a rule that denies WITH an identity already resolved, on the
|
|
289
|
+
* strength of who that identity is. Each of them can only fire on the same
|
|
290
|
+
* Azure DevOps MCP tool-call shape the PASS-side logging covers
|
|
291
|
+
* (`isAdoMcpToolCall`, below), so a role-gate deny is just as much an
|
|
292
|
+
* identity decision as the PASS it would have been without the role
|
|
293
|
+
* mismatch, and its deny log line carries `identity_source` too.
|
|
300
294
|
*/
|
|
301
295
|
const ROLE_GATE_RULE_IDS: ReadonlySet<RuleId> = new Set([
|
|
302
296
|
'adl.workitem-requires-tarun-or-vivek',
|
|
@@ -314,23 +308,23 @@ interface EffectiveIdentity {
|
|
|
314
308
|
}
|
|
315
309
|
|
|
316
310
|
/**
|
|
317
|
-
* Where the effective agent identity for THIS decision came from
|
|
318
|
-
*
|
|
319
|
-
* actually names (M8, STATUS.md 12p) — a valid
|
|
311
|
+
* Where the effective agent identity for THIS decision came from
|
|
312
|
+
* (`identity_source` in the log), AND the agent it actually names: a valid
|
|
320
313
|
* inline `ADL_AGENT_ID_AGENT=` on the command itself (step 1 of the
|
|
321
|
-
*
|
|
322
|
-
* 2-3, `resolveFromEnvOrFile`'s own `source`/`agent`), else
|
|
323
|
-
* A tool-call input carries no command text at all, so it
|
|
324
|
-
*
|
|
325
|
-
*
|
|
314
|
+
* resolution order), else the session env or the machine default-agent file
|
|
315
|
+
* (steps 2-3, `resolveFromEnvOrFile`'s own `source`/`agent`), else
|
|
316
|
+
* `none`/no agent. A tool-call input carries no command text at all, so it
|
|
317
|
+
* can never be `inline`: its identity is the session env or the machine
|
|
318
|
+
* default-agent file. MCP is the primary route to Azure DevOps operations;
|
|
319
|
+
* `ADL_AGENT_ID_AGENT=<agent> adl mcp cli <command>` (which does carry an
|
|
320
|
+
* inline prefix) is the fallback when MCP is not working.
|
|
326
321
|
*
|
|
327
322
|
* The AGENT half matters because it can differ from the session's own
|
|
328
323
|
* `ADL_AGENT_ID_AGENT`: `ADL_AGENT_ID_AGENT=agent-vivek git push …` run in
|
|
329
324
|
* an agent-tarun session is agent-vivek's push, not agent-tarun's — the
|
|
330
|
-
* override, not the session env, is what actually acted, and
|
|
331
|
-
* reads THIS agent for the log's `agent` column
|
|
332
|
-
*
|
|
333
|
-
* column shows the session agent" even on an overridden command).
|
|
325
|
+
* override, not the session env, is what actually acted, and
|
|
326
|
+
* `../hooks/log.ts` reads THIS agent for the log's `agent` column rather
|
|
327
|
+
* than the session env var.
|
|
334
328
|
*/
|
|
335
329
|
function effectiveIdentityFor(input: DecideInput, engineCtx: EngineContext): EffectiveIdentity {
|
|
336
330
|
const resolution = resolveFromEnvOrFile(engineCtx.env)
|
|
@@ -344,10 +338,10 @@ function effectiveIdentityFor(input: DecideInput, engineCtx: EngineContext): Eff
|
|
|
344
338
|
}
|
|
345
339
|
|
|
346
340
|
/**
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
341
|
+
* The resolved FALLBACK identity alone (steps 2-3 of the resolution order:
|
|
342
|
+
* env, else the machine default-agent file) — never the coarse,
|
|
343
|
+
* whole-command "any inline override anywhere on the line"
|
|
344
|
+
* `effectiveIdentityFor` also reports.
|
|
351
345
|
*
|
|
352
346
|
* `adl.git-identity`'s REWRITE stage (`decision.rewrite`) and its own
|
|
353
347
|
* fallback-based DENY reasons (`identity-mismatch`'s hint, `unrewritable-
|
|
@@ -393,11 +387,10 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
|
|
|
393
387
|
//
|
|
394
388
|
// Every branch below decided an identity (the rewrite ALWAYS comes from
|
|
395
389
|
// adl.git-identity), so every inv.record?.() call here carries
|
|
396
|
-
// identitySource/identityAgent
|
|
397
|
-
//
|
|
398
|
-
//
|
|
399
|
-
//
|
|
400
|
-
// elsewhere on a chained command.
|
|
390
|
+
// identitySource/identityAgent — the FALLBACK identity specifically, not
|
|
391
|
+
// `effectiveIdentityFor`'s coarse whole-command value (see
|
|
392
|
+
// `fallbackIdentity`'s own doc for why a rewrite is always about the
|
|
393
|
+
// fallback, never an inline override elsewhere on a chained command).
|
|
401
394
|
if (!decision.blocked && decision.rewrite) {
|
|
402
395
|
const identity = fallbackIdentity(engineCtx)
|
|
403
396
|
const identitySource = identity.source
|
|
@@ -413,7 +406,7 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
|
|
|
413
406
|
inv.record?.({ reason: `REWRITE ${decision.rewrite.ruleId}`, ...identityFields(identity) })
|
|
414
407
|
return { stdout: `${JSON.stringify(rendered)}\n`, stderr: '', exitCode: 0 }
|
|
415
408
|
}
|
|
416
|
-
//
|
|
409
|
+
// `native-shell` here is only reached when the host could not
|
|
417
410
|
// render a rewrite for this payload shape (Kimi has none at all;
|
|
418
411
|
// Cursor's beforeShellExecution has no tool_input to replace) — SKIP
|
|
419
412
|
// (allow unchanged) is only safe when `ADL_AGENT_ID_AGENT` is actually
|
|
@@ -434,7 +427,7 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
|
|
|
434
427
|
return denyHostCannotRewrite(spec, inv.host, message)
|
|
435
428
|
}
|
|
436
429
|
|
|
437
|
-
//
|
|
430
|
+
// Walker-found identity-bearing shapes the rewrite scanner missed: the
|
|
438
431
|
// branch above only runs when `adl.git-identity`'s own narrow, offset-
|
|
439
432
|
// based scanner recognized the command as identity-bearing at all
|
|
440
433
|
// (`decision.rewrite` set) — it does not walk into `if`/`!`/`for..do`/
|
|
@@ -444,11 +437,11 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
|
|
|
444
437
|
// backstop for a shape THIS scanner misses on a REWRITING host's native
|
|
445
438
|
// shell). But `../rules/shell/invocation.ts`'s walker (reused here via
|
|
446
439
|
// `identityBearingReason`, already proven against every one of those
|
|
447
|
-
// shapes for `adl.
|
|
440
|
+
// shapes for `adl.run-required-for-writes`'s own deny) DOES find them
|
|
448
441
|
// — and once found, there is no rewritten command to offer at all (this
|
|
449
442
|
// scanner never computed one), so the only safe outcomes are: a
|
|
450
443
|
// native-shell tool with an ENV-sourced identity (its child inherits it
|
|
451
|
-
// regardless of any rewrite, exactly like the
|
|
444
|
+
// regardless of any rewrite, exactly like the native-shell SKIP in the rewrite branch above), or an
|
|
452
445
|
// inline override already on the command text (travels with the text
|
|
453
446
|
// itself, no env inheritance needed) — anything else must be denied
|
|
454
447
|
// rather than run with no identity anyone can prove reached the child.
|
|
@@ -476,13 +469,11 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
|
|
|
476
469
|
// unrelated deny (fs.rm, git.no-verify, …) made no identity decision at
|
|
477
470
|
// all. A PASS made one too when the command is identity-bearing but
|
|
478
471
|
// needed no rewrite because it ALREADY carried a valid inline override
|
|
479
|
-
// (
|
|
480
|
-
//
|
|
481
|
-
//
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
// R7 (STATUS.md 12p, re-review 2026-09-28 night): a
|
|
485
|
-
// `adl.git-identity` deny (identity-mismatch/unrewritable-wrapper/
|
|
472
|
+
// (the override's PASS line): `rewriteGitNetworkCommands`'s `unchanged`
|
|
473
|
+
// outcome covers BOTH "not identity-bearing at all" and "fully covered by
|
|
474
|
+
// an inline override already", and only `commandHasValidInlineIdentity`
|
|
475
|
+
// tells those two apart from here.
|
|
476
|
+
// An `adl.git-identity` deny (identity-mismatch/unrewritable-wrapper/
|
|
486
477
|
// network-alias-redefinition/dynamic-agent/unsafe-identity) is ALWAYS
|
|
487
478
|
// about the piece LACKING a valid override — the same fallback-only
|
|
488
479
|
// reasoning `fallbackIdentity`'s doc gives the rewrite branch, and
|
|
@@ -490,15 +481,13 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
|
|
|
490
481
|
// hint ("your session's own resolved identity is X"). The coarse
|
|
491
482
|
// `effectiveIdentityFor` could otherwise report an unrelated, valid
|
|
492
483
|
// override sitting on a DIFFERENT piece of the same chained command. The
|
|
493
|
-
// other
|
|
494
|
-
//
|
|
495
|
-
//
|
|
496
|
-
// token-minting-role`/`tool.azure-devops` are not piece-correlated
|
|
497
|
-
//
|
|
498
|
-
//
|
|
499
|
-
//
|
|
500
|
-
// can also test it — a role-gate deny of an Azure DevOps MCP call is the
|
|
501
|
-
// same shape as its PASS, just with the wrong identity.
|
|
484
|
+
// other identity rules keep the coarse helper: `adl.run-required-for-writes`
|
|
485
|
+
// only ever denies when `commandHasValidInlineIdentity` is ALSO false (so
|
|
486
|
+
// the two never actually disagree for it), and
|
|
487
|
+
// `adl.token-minting-role`/`tool.azure-devops` are not piece-correlated.
|
|
488
|
+
// `isAdoMcpToolCall` is computed ahead of `denyIdentity` because the
|
|
489
|
+
// DENY-side computation tests it too: a role-gate deny of an Azure DevOps
|
|
490
|
+
// MCP call is the same shape as its PASS, just with the wrong identity.
|
|
502
491
|
const isAdoMcpToolCall = input.kind === 'tool-call' && KNOWN_MCP_TOOL_NAMES.has(mcpToolName(input.tool) ?? '')
|
|
503
492
|
const denyIdentity =
|
|
504
493
|
decision.blocked && (IDENTITY_RULE_IDS.has(decision.ruleId) || (isAdoMcpToolCall && ROLE_GATE_RULE_IDS.has(decision.ruleId)))
|
|
@@ -506,7 +495,7 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
|
|
|
506
495
|
? fallbackIdentity(engineCtx)
|
|
507
496
|
: effectiveIdentityFor(input, engineCtx)
|
|
508
497
|
: undefined
|
|
509
|
-
//
|
|
498
|
+
// An ALLOWED Azure DevOps MCP
|
|
510
499
|
// tool call — reads included (workitem_list_or_get/pr_list_or_get/
|
|
511
500
|
// build_list_or_get, not only the four writes) — logs `identitySource`/
|
|
512
501
|
// `identityAgent` too, the SAME field names the shell path already uses
|
|
@@ -515,11 +504,11 @@ function decideAndRespond(inv: HookInvocation, engineCtx: EngineContext): HookRe
|
|
|
515
504
|
// tool-call branch already reflects that, unchanged), so this is exactly
|
|
516
505
|
// the session's resolved identity (env, else the machine default-agent
|
|
517
506
|
// file). Every one of these calls ALREADY required a resolvable identity
|
|
518
|
-
// to reach this PASS line at all (`adl.
|
|
507
|
+
// to reach this PASS line at all (`adl.run-required-for-writes` denies
|
|
519
508
|
// otherwise) — this only makes that already-decided identity visible in
|
|
520
509
|
// the log, the same way the shell path's own inline-override PASS line
|
|
521
|
-
// does
|
|
522
|
-
//
|
|
510
|
+
// does. Tarun, 2026-09-29: every Azure DevOps MCP call logs
|
|
511
|
+
// `identity_source`, reads included.
|
|
523
512
|
const passIdentity = !decision.blocked && ((input.kind === 'command' && commandHasValidInlineIdentity(input.command)) || isAdoMcpToolCall) ? effectiveIdentityFor(input, engineCtx) : undefined
|
|
524
513
|
inv.record?.(
|
|
525
514
|
decision.blocked
|
|
@@ -87,14 +87,14 @@ export type DecideInput =
|
|
|
87
87
|
| { readonly kind: 'command'; readonly command: string }
|
|
88
88
|
| { readonly kind: 'tool-call'; readonly tool: string; readonly input: Readonly<Record<string, unknown>> }
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
interface DenyDecision {
|
|
91
91
|
readonly blocked: true
|
|
92
92
|
readonly ruleId: RuleId
|
|
93
93
|
readonly userMessage: string
|
|
94
94
|
readonly agentMessage: string
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
interface AdviceDecision {
|
|
98
98
|
readonly blocked: false
|
|
99
99
|
readonly advice?: { readonly ruleId: RuleId; readonly userMessage: string; readonly agentMessage: string }
|
|
100
100
|
/**
|
|
@@ -205,9 +205,8 @@ function decideCommand(command: string, ctx: EngineContext): Decision {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
// adl.git-identity's REWRITE stage (docs/architecture/cli-design.md §1a;
|
|
208
|
-
//
|
|
209
|
-
// every
|
|
210
|
-
// passed — carry the resolved identity (steps 2-3: session env, else the
|
|
208
|
+
// it covers every identity-bearing command class, not only network git):
|
|
209
|
+
// every rule passed — carry the resolved identity (steps 2-3: session env, else the
|
|
211
210
|
// machine default-agent file) into every identity-bearing invocation in
|
|
212
211
|
// the command. A VALID inline override (step 1) is honoured as-is
|
|
213
212
|
// (`kind: 'unchanged'`, handled inside `rewriteGitNetworkCommands` itself,
|
|
@@ -216,19 +215,16 @@ function decideCommand(command: string, ctx: EngineContext): Decision {
|
|
|
216
215
|
// rule can be disabled per-repo; an unsafe identity is never the rule's to
|
|
217
216
|
// see).
|
|
218
217
|
//
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
// command earlier in the rule pass — a separate classification (the
|
|
218
|
+
// `needs-identity` (an identity-bearing command with no inline override
|
|
219
|
+
// and no resolvable fallback) is denied HERE, directly, rather than left
|
|
220
|
+
// to `adl.run-required-for-writes` having already denied the SAME command
|
|
221
|
+
// earlier in the rule pass: that rule is a separate classification (the
|
|
224
222
|
// shared shell/invocation.ts walker) that can be disabled per repo
|
|
225
|
-
// (`[rules."adl.
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
// L4 (STATUS.md 12p): resolve the fallback
|
|
231
|
-
// identity — which can read the REAL machine default-agent file
|
|
223
|
+
// (`[rules."adl.run-required-for-writes"] enabled = false`) or simply not
|
|
224
|
+
// recognize a shape this scanner does, and nothing else here would stand
|
|
225
|
+
// between an unidentified network git command and a plain allow.
|
|
226
|
+
//
|
|
227
|
+
// The fallback identity — which can read the REAL machine default-agent file
|
|
232
228
|
// (`resolveFromEnvOrFile`) — ONLY when the command actually has an
|
|
233
229
|
// identity-bearing piece that would use it. A probe scan with
|
|
234
230
|
// `fallback: null` is fallback-INDEPENDENT for every outcome except
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* branch on `ADL_AGENT_ID_AGENT` at all: the matrix's own hook-action column
|
|
6
6
|
* shows ❌ for both `agent-tarun`/`agent-vivek` and `agent-reviewer`, so there
|
|
7
7
|
* is no identity this tool is allowed for. With no identity at all,
|
|
8
|
-
* `adl.
|
|
8
|
+
* `adl.run-required-for-writes` (registered ahead of this rule) reports
|
|
9
9
|
* first with its own, more specific "no session" message; this rule is what
|
|
10
10
|
* fires once an identity IS present, which is the case that rule leaves
|
|
11
11
|
* alone.
|
|
@@ -25,10 +25,10 @@ export const adlBuildRunDenied: RuleSpec = {
|
|
|
25
25
|
category: 'tool-call',
|
|
26
26
|
severity: 'deny',
|
|
27
27
|
enabledByDefault: true,
|
|
28
|
-
summary: 'Deny build_run for every identity (docs/operations/agent-permissions.md row 12) — the MCP tool AND its adl mcp cli equivalent
|
|
28
|
+
summary: 'Deny build_run for every identity (docs/operations/agent-permissions.md row 12) — the MCP tool AND its adl mcp cli equivalent.',
|
|
29
29
|
params: noParams,
|
|
30
30
|
match(inv: Invocation): Finding | null {
|
|
31
|
-
//
|
|
31
|
+
// Also catch `adl mcp cli build-run` — same tool, same deny.
|
|
32
32
|
const call = toolCallFor(inv)
|
|
33
33
|
if (call === null) return null
|
|
34
34
|
if (mcpToolName(call.tool) !== 'build_run') return null
|