@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
|
@@ -84,24 +84,26 @@
|
|
|
84
84
|
* propagates out of `repoDoctorCheck()` uncaught rather than being reported
|
|
85
85
|
* as its own finding. checkBuildServiceCanRelease() answers one narrow
|
|
86
86
|
* question directly, per the real failure above: can the identity that
|
|
87
|
-
* ACTUALLY RUNS THE PIPELINE (repo scope) push a
|
|
88
|
-
* to
|
|
89
|
-
* the
|
|
87
|
+
* ACTUALLY RUNS THE PIPELINE (repo scope) push a `[skip ci]` bump commit
|
|
88
|
+
* to `integration` (GenericContribute), bypass `integration`'s own policies
|
|
89
|
+
* while doing so (PolicyExempt, read at the integration REF token), and
|
|
90
|
+
* create/update the `integration -> main` PR and set auto-complete
|
|
90
91
|
* (PullRequestContribute) — and it FAILS loudly,
|
|
91
92
|
* naming the permission, the identity's display name and the fix path, on
|
|
92
93
|
* any of: the permission not effectively allowed, the identity not
|
|
93
94
|
* resolvable, or the ACL itself not readable by the calling agent.
|
|
94
95
|
*
|
|
95
|
-
*
|
|
96
|
-
* `integration` and
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
96
|
+
* Release flow (Tarun, 2026-09-30, amended 2026-10-01): the CI pipeline runs
|
|
97
|
+
* on PRs into `integration` and bumps nothing; the promote pipeline runs on
|
|
98
|
+
* every push to `integration`, bumps the version with a plain fast-forward
|
|
99
|
+
* push of a `[skip ci]` commit straight to `integration` as the build
|
|
100
|
+
* service, then opens the `integration -> main` PR; a CD pipeline runs on
|
|
101
|
+
* pushes to `main`. So (a) the build service REQUIRES PolicyExempt on
|
|
102
|
+
* `integration` (and Contribute on the repo) — never on `main`, never
|
|
103
|
+
* ForcePush; (b) the release-identity check requires PolicyExempt at the
|
|
104
|
+
* integration ref token; (c) the promotion PR gets NO build validation
|
|
105
|
+
* (Tarun's approval is the only gate; CD runs after the merge), so `main`
|
|
106
|
+
* does not require a build-validation policy and an enabled one is drift.
|
|
105
107
|
*
|
|
106
108
|
* Policy type GUIDs (verified against the azure-devops-cli-extension source,
|
|
107
109
|
* packages/repo-controls already hardcodes the first three the same way):
|
|
@@ -164,7 +166,7 @@ export const GIT_REPOSITORIES_NAMESPACE_ID = "2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd
|
|
|
164
166
|
|
|
165
167
|
type PermissionBitName = keyof typeof GIT_REPO_PERMISSION_BIT;
|
|
166
168
|
|
|
167
|
-
|
|
169
|
+
const REPO_STANDARD = {
|
|
168
170
|
branches: {
|
|
169
171
|
required: ["integration", "main"] as const,
|
|
170
172
|
forbidden: ["develop"] as const,
|
|
@@ -231,13 +233,10 @@ export const REPO_STANDARD = {
|
|
|
231
233
|
* — Tarun, 2026-09-27, cross-checked against
|
|
232
234
|
* /Users/tarunrana/Documents/ADL-ISMS-Policies/.scratchpad/ci_build_service_grant.py,
|
|
233
235
|
* which grants exactly these bits on adl-agent-control). CI needs to push
|
|
234
|
-
* and complete PRs on the repo
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
* PolicyExempt on `integration` is no longer required and, by least
|
|
239
|
-
* privilege, is drift (`permissions.build-service.has-policyExempt-integration`);
|
|
240
|
-
* never on `main` either (existing rule).
|
|
236
|
+
* and complete PRs on the repo, and needs PolicyExempt only on
|
|
237
|
+
* `integration` (Tarun, 2026-10-01: the integration-merge pipeline pushes
|
|
238
|
+
* the `[skip ci]` version bump straight to `integration`, which its own
|
|
239
|
+
* policies would block) — never on `main`.
|
|
241
240
|
*
|
|
242
241
|
* NOT forcePush (Tarun, 2026-09-30): the bump is a plain fast-forward
|
|
243
242
|
* `git push origin HEAD:integration`; agent-identities' build service has
|
|
@@ -248,28 +247,37 @@ export const REPO_STANDARD = {
|
|
|
248
247
|
repo: { allow: ["genericContribute", "pullRequestContribute"] } as {
|
|
249
248
|
allow: readonly PermissionBitName[];
|
|
250
249
|
},
|
|
251
|
-
|
|
250
|
+
// Tarun, 2026-10-01: an explicit gate on the build service's EFFECTIVE permissions on
|
|
251
|
+
// refs/heads/integration -- Contribute and "Bypass policies when pushing" (the
|
|
252
|
+
// `[skip ci]` bump push) required, Force push forbidden. Live reference: effective
|
|
253
|
+
// allow 16550 = read + contribute + createTag + policyExempt + pullRequestContribute.
|
|
254
|
+
integrationRef: { allow: ["genericContribute", "policyExempt"], deny: ["forcePush"] } as {
|
|
255
|
+
allow: readonly PermissionBitName[];
|
|
256
|
+
deny: readonly PermissionBitName[];
|
|
257
|
+
},
|
|
252
258
|
mainRef: { deny: ["policyExempt"] } as { deny: readonly PermissionBitName[] },
|
|
253
259
|
},
|
|
254
260
|
/**
|
|
255
261
|
* checkBuildServiceCanRelease() (file header, "checkBuildServiceCanRelease()"):
|
|
256
|
-
* the permissions the release flow needs from whichever
|
|
257
|
-
* identity actually runs the pipeline — the real failure
|
|
258
|
-
* exists for was a 403 on `pullRequestContribute`.
|
|
262
|
+
* the exact three permissions the release flow needs from whichever
|
|
263
|
+
* build service identity actually runs the pipeline — the real failure
|
|
264
|
+
* this check exists for was a 403 on `pullRequestContribute`.
|
|
259
265
|
*
|
|
260
|
-
* `policyExempt` ("Bypass policies when pushing") is
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
266
|
+
* `policyExempt` ("Bypass policies when pushing") is checked at the
|
|
267
|
+
* `integration` REF token, never the repo-scope token — verified live
|
|
268
|
+
* 2026-09-30 against adl-agent-control: the Infrastructure-AzDo Build
|
|
269
|
+
* Service demonstrably bypassed `integration`'s own policies to push
|
|
270
|
+
* its bump straight to that protected branch, yet its repo-scope
|
|
271
|
+
* effective allow bitmask (16430) does not include PolicyExempt (128) at
|
|
272
|
+
* all — only its `refs/heads/integration`-scope effective allow (16558)
|
|
273
|
+
* does. `genericContribute` and `pullRequestContribute` stay checked at
|
|
274
|
+
* repo scope — both bits ARE present there for real, and PR operations
|
|
275
|
+
* are a repo-level, not branch-level, permission.
|
|
270
276
|
*/
|
|
271
277
|
buildServiceRelease: {
|
|
272
278
|
repoScoped: ["genericContribute", "pullRequestContribute"] as const,
|
|
279
|
+
integrationRefScoped: ["genericContribute", "policyExempt"] as const,
|
|
280
|
+
integrationRefForbidden: ["forcePush"] as const,
|
|
273
281
|
},
|
|
274
282
|
},
|
|
275
283
|
} as const;
|
|
@@ -280,7 +288,7 @@ export const REPO_STANDARD = {
|
|
|
280
288
|
* https://learn.microsoft.com/en-us/azure/devops/repos/git/set-git-repository-permissions),
|
|
281
289
|
* used only to build the fix-path message a human follows in that same UI.
|
|
282
290
|
*/
|
|
283
|
-
|
|
291
|
+
const GIT_REPO_PERMISSION_UI_LABEL: Record<PermissionBitName, string> = {
|
|
284
292
|
genericRead: "Read",
|
|
285
293
|
genericContribute: "Contribute",
|
|
286
294
|
forcePush: "Force push (rewrite history, delete branches and tags)",
|
|
@@ -369,7 +377,7 @@ interface AccessControlListsResponse {
|
|
|
369
377
|
* this; a per-repository override, if one is ever genuinely needed, belongs
|
|
370
378
|
* in that repository's own adl-config.toml / manifest, never an env var.
|
|
371
379
|
*/
|
|
372
|
-
|
|
380
|
+
const STRICT_MAIN_BRANCH_PROJECT = "Enact";
|
|
373
381
|
|
|
374
382
|
function strictMainBranchRulesApply(project: string): boolean {
|
|
375
383
|
return project.toLowerCase() === STRICT_MAIN_BRANCH_PROJECT.toLowerCase();
|
|
@@ -839,11 +847,11 @@ async function resolveBuildServiceDescriptor(namespaceId: string, projectId: str
|
|
|
839
847
|
}
|
|
840
848
|
|
|
841
849
|
/**
|
|
842
|
-
* CI needs to push
|
|
843
|
-
*
|
|
844
|
-
*
|
|
845
|
-
*
|
|
846
|
-
*
|
|
850
|
+
* CI needs to push and complete PRs on the repo itself, and needs to bypass
|
|
851
|
+
* policy only on `integration` (so the `[skip ci]` version-bump commit the
|
|
852
|
+
* integration-merge pipeline pushes there is not blocked by the very
|
|
853
|
+
* policies it satisfies) — never on `main`, where a bypass would defeat the
|
|
854
|
+
* human-reviewer gate entirely.
|
|
847
855
|
*/
|
|
848
856
|
async function checkBuildServicePermissions(
|
|
849
857
|
namespaceId: string,
|
|
@@ -902,14 +910,19 @@ async function checkBuildServicePermissions(
|
|
|
902
910
|
drifts,
|
|
903
911
|
);
|
|
904
912
|
if (integrationEffective) {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
913
|
+
for (const bitName of REPO_STANDARD.permissions.buildService.integrationRef.allow) {
|
|
914
|
+
if ((effectiveAllowBits(integrationEffective) & GIT_REPO_PERMISSION_BIT[bitName]) === 0) {
|
|
915
|
+
drifts.push({
|
|
916
|
+
id: `permissions.build-service.missing-${bitName}-integration`,
|
|
917
|
+
message: `the project build service does not effectively have ${bitName} on refs/heads/integration`,
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
}
|
|
908
921
|
for (const bitName of REPO_STANDARD.permissions.buildService.integrationRef.deny) {
|
|
909
922
|
if ((effectiveAllowBits(integrationEffective) & GIT_REPO_PERMISSION_BIT[bitName]) !== 0) {
|
|
910
923
|
drifts.push({
|
|
911
924
|
id: `permissions.build-service.has-${bitName}-integration`,
|
|
912
|
-
message: `the project build service effectively has ${bitName} on refs/heads/integration, which the standard forbids
|
|
925
|
+
message: `the project build service effectively has ${bitName} (${GIT_REPO_PERMISSION_UI_LABEL[bitName]}) on refs/heads/integration, which the standard forbids: the bump is a plain fast-forward push and force push is required of no identity`,
|
|
913
926
|
});
|
|
914
927
|
}
|
|
915
928
|
}
|
|
@@ -961,6 +974,16 @@ function releaseFixPath(repository: string, identityDisplayName: string, bitName
|
|
|
961
974
|
return `Project settings → Repositories → \`${repository}\` → Security → \`${identityDisplayName}\` → \`${GIT_REPO_PERMISSION_UI_LABEL[bitName]}\` = Allow`;
|
|
962
975
|
}
|
|
963
976
|
|
|
977
|
+
/** Same as releaseFixPath() but for a bit that is granted per-BRANCH (verified live 2026-09-30: PolicyExempt on this org's build service lives on refs/heads/integration's own security page, never the repo-root one). */
|
|
978
|
+
function releaseFixPathForRef(
|
|
979
|
+
repository: string,
|
|
980
|
+
ref: string,
|
|
981
|
+
identityDisplayName: string,
|
|
982
|
+
bitName: PermissionBitName,
|
|
983
|
+
): string {
|
|
984
|
+
return `Repos → \`${repository}\` → Branches → \`${ref}\` → ⋯ → Branch security → \`${identityDisplayName}\` → \`${GIT_REPO_PERMISSION_UI_LABEL[bitName]}\` = Allow`;
|
|
985
|
+
}
|
|
986
|
+
|
|
964
987
|
/**
|
|
965
988
|
* Which build service identity actually runs the pipeline, per Build —
|
|
966
989
|
* General Settings — Get's `enforceJobAuthScope` (file header) — "Limit job
|
|
@@ -983,10 +1006,12 @@ async function fetchEnforceJobAuthScope(c: AdoClient): Promise<boolean | undefin
|
|
|
983
1006
|
/**
|
|
984
1007
|
* One identity's answer to "can it release": resolve its descriptor by exact
|
|
985
1008
|
* display name (Identities — Read Identities, file header), then check
|
|
986
|
-
* `buildServiceRelease.repoScoped` on the repository token
|
|
987
|
-
*
|
|
988
|
-
*
|
|
989
|
-
*
|
|
1009
|
+
* `buildServiceRelease.repoScoped` on the repository token AND
|
|
1010
|
+
* `buildServiceRelease.integrationRefScoped` on the `integration` ref token
|
|
1011
|
+
* — NOT the same token for all three (see REPO_STANDARD.permissions.
|
|
1012
|
+
* buildServiceRelease's own doc comment: PolicyExempt is a per-BRANCH grant
|
|
1013
|
+
* in this org, verified live against real bypass-on-push evidence, and
|
|
1014
|
+
* checking it at repo scope produced a false "missing" finding). Every
|
|
990
1015
|
* failure mode is its own loud, distinct drift — an unresolvable identity,
|
|
991
1016
|
* an ACL the calling agent cannot read, and each missing permission named
|
|
992
1017
|
* with its fix path — never a silent pass.
|
|
@@ -994,6 +1019,7 @@ async function fetchEnforceJobAuthScope(c: AdoClient): Promise<boolean | undefin
|
|
|
994
1019
|
async function checkOneBuildServiceCanRelease(
|
|
995
1020
|
namespaceId: string,
|
|
996
1021
|
repoToken: string,
|
|
1022
|
+
integrationRefToken: string,
|
|
997
1023
|
repository: string,
|
|
998
1024
|
displayName: string,
|
|
999
1025
|
drifts: RepoDoctorDrift[],
|
|
@@ -1020,7 +1046,8 @@ async function checkOneBuildServiceCanRelease(
|
|
|
1020
1046
|
}
|
|
1021
1047
|
|
|
1022
1048
|
// LOW, independent review 2026-09-30: name WHICH token failed — "the ACL"
|
|
1023
|
-
// alone left a human unable to tell
|
|
1049
|
+
// alone left a human unable to tell a repo-scope 403 from a
|
|
1050
|
+
// refs/heads/integration-scope one without re-running this by hand.
|
|
1024
1051
|
async function effectiveAt(token: string, tokenLabel: string): Promise<{ allow: number; deny: number } | undefined> {
|
|
1025
1052
|
let effective: EffectivePermissionsResult;
|
|
1026
1053
|
try {
|
|
@@ -1045,6 +1072,23 @@ async function checkOneBuildServiceCanRelease(
|
|
|
1045
1072
|
message: `'${displayName}' does not effectively have ${GIT_REPO_PERMISSION_UI_LABEL[bitName]} on '${repository}' — the release pipeline will 403 the way agent-identities build 4897 did. Fix: ${releaseFixPath(repository, displayName, bitName)}`,
|
|
1046
1073
|
});
|
|
1047
1074
|
}
|
|
1075
|
+
|
|
1076
|
+
const integrationEffective = await effectiveAt(integrationRefToken, "refs/heads/integration");
|
|
1077
|
+
if (!integrationEffective) return;
|
|
1078
|
+
for (const bitName of REPO_STANDARD.permissions.buildServiceRelease.integrationRefScoped) {
|
|
1079
|
+
if ((effectiveAllowBits(integrationEffective) & GIT_REPO_PERMISSION_BIT[bitName]) !== 0) continue;
|
|
1080
|
+
drifts.push({
|
|
1081
|
+
id: `permissions.release.${slug}.missing-${bitName}`,
|
|
1082
|
+
message: `'${displayName}' does not effectively have ${GIT_REPO_PERMISSION_UI_LABEL[bitName]} on 'refs/heads/integration' of '${repository}' — its own version-bump push to integration would be refused. Fix: ${releaseFixPathForRef(repository, "integration", displayName, bitName)}`,
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
for (const bitName of REPO_STANDARD.permissions.buildServiceRelease.integrationRefForbidden) {
|
|
1086
|
+
if ((effectiveAllowBits(integrationEffective) & GIT_REPO_PERMISSION_BIT[bitName]) === 0) continue;
|
|
1087
|
+
drifts.push({
|
|
1088
|
+
id: `permissions.release.${slug}.has-${bitName}`,
|
|
1089
|
+
message: `'${displayName}' effectively has ${GIT_REPO_PERMISSION_UI_LABEL[bitName]} on 'refs/heads/integration' of '${repository}', which the standard forbids (the version bump is a plain fast-forward push; force push is required of no identity)`,
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1048
1092
|
}
|
|
1049
1093
|
|
|
1050
1094
|
/**
|
|
@@ -1075,8 +1119,9 @@ async function checkBuildServiceCanRelease(
|
|
|
1075
1119
|
: [projectScoped, collectionScoped];
|
|
1076
1120
|
|
|
1077
1121
|
const repoToken = `repoV2/${projectId}/${repositoryId}`;
|
|
1122
|
+
const integrationRefToken = `${repoToken}/refs/heads/${refNameHexUtf16Le("integration")}`;
|
|
1078
1123
|
for (const displayName of displayNames) {
|
|
1079
|
-
await checkOneBuildServiceCanRelease(namespaceId, repoToken, repository, displayName, drifts);
|
|
1124
|
+
await checkOneBuildServiceCanRelease(namespaceId, repoToken, integrationRefToken, repository, displayName, drifts);
|
|
1080
1125
|
}
|
|
1081
1126
|
}
|
|
1082
1127
|
|
|
@@ -1094,6 +1139,10 @@ export async function repoDoctorCheck(options: RepoDoctorOptions = {}): Promise<
|
|
|
1094
1139
|
|
|
1095
1140
|
const repoInfo = await c.get<GitRepositoryResponse>(`/git/repositories/${repository}`, { "api-version": "7.1" });
|
|
1096
1141
|
const repositoryId = repoInfo.id;
|
|
1142
|
+
if (typeof repositoryId !== "string" || repositoryId === "") {
|
|
1143
|
+
// `--repo .` (a path) reaches the list endpoint; never carry on with an `undefined` id.
|
|
1144
|
+
throw new Error(`Azure DevOps returned no repository for '${repository}' — --repo takes a repository name, not a path`);
|
|
1145
|
+
}
|
|
1097
1146
|
const projectId = repoInfo.project?.id;
|
|
1098
1147
|
|
|
1099
1148
|
const refs = await c.get<GitRefsResponse>(`/git/repositories/${repositoryId}/refs`, {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// mcp-server.ts — there is no CLI entry point here (nothing else in the
|
|
3
3
|
// repo invoked this file as a CLI).
|
|
4
4
|
import { AdoClient, adoProjectUrl, resolveProject } from './lib/client.ts'
|
|
5
|
+
import { evaluateWorkflowState, formatWorkflowRefusal, pickWorkflowFlags, type WorkflowFlagRef } from './workflow-rules.ts'
|
|
5
6
|
|
|
6
7
|
// Work-item calls use the SAME org/project resolution as every other tool in
|
|
7
8
|
// this package (`lib/client.ts`). They used to carry their own `config` object
|
|
@@ -28,7 +29,7 @@ export function resetClientForTests(): void {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
/** Canonical work-item contract: only these board levels are user-facing. */
|
|
31
|
-
|
|
32
|
+
const ALLOWED_TYPES = ['Feature', 'Product Backlog Item', 'Bug'] as const;
|
|
32
33
|
type AllowedType = (typeof ALLOWED_TYPES)[number];
|
|
33
34
|
export type WorkItemListOrGetArgs = { id?: number; ids?: number[]; type?: string; state?: string; assignedTo?: string; limit?: number; raw?: boolean };
|
|
34
35
|
export type WorkItemWriteArgs = {
|
|
@@ -107,6 +108,21 @@ function buildWriteOps(args: WorkItemWriteArgs): any[] {
|
|
|
107
108
|
export async function workitemCreateOrUpdate(args: WorkItemWriteArgs): Promise<string> {
|
|
108
109
|
if (args.id === undefined) {
|
|
109
110
|
assertAllowedType(args.type); if (!args.title) throw new Error('title is required for create'); if (args.parentId === undefined) throw new Error(`${args.type} requires parentId`);
|
|
111
|
+
// FENCE 1 (create): System.State via the raw fields escape hatch is
|
|
112
|
+
// fenced for the gated types — the dedicated `state` argument exists so
|
|
113
|
+
// the workflow gate can evaluate the resulting state. Features carry no
|
|
114
|
+
// flags; for them the generic managed-field refusal in buildWriteOps
|
|
115
|
+
// still applies (unchanged behavior).
|
|
116
|
+
if (args.type !== 'Feature' && args.fields !== undefined && 'System.State' in args.fields) {
|
|
117
|
+
throw new Error('System.State via raw fields is fenced — pass the dedicated `state` argument so the workflow gate can evaluate it.');
|
|
118
|
+
}
|
|
119
|
+
// FENCE 2 (create): a new PBI/Bug starts in New with every flag false, so
|
|
120
|
+
// the gate on the resulting pair refuses any non-false flag or advanced
|
|
121
|
+
// state the same way an update would.
|
|
122
|
+
if (args.type !== 'Feature') {
|
|
123
|
+
const violations = evaluateWorkflowState(args.type, args.state ?? 'New', pickWorkflowFlags(args.fields));
|
|
124
|
+
if (violations.length) throw new Error(formatWorkflowRefusal(violations));
|
|
125
|
+
}
|
|
110
126
|
const ops = buildWriteOps(args);
|
|
111
127
|
const c = await getClient();
|
|
112
128
|
const parent = await c.get<any>(`/wit/workitems/${args.parentId}`, { 'api-version': '7.1' });
|
|
@@ -116,10 +132,33 @@ export async function workitemCreateOrUpdate(args: WorkItemWriteArgs): Promise<s
|
|
|
116
132
|
return JSON.stringify(formatItem(created, false), null, 2);
|
|
117
133
|
}
|
|
118
134
|
if (args.type !== undefined) throw new Error('type cannot be changed on an existing work item');
|
|
119
|
-
|
|
135
|
+
// System.State arriving through the raw fields escape hatch is deferred:
|
|
136
|
+
// its refusal is type-dependent (FENCE 1 below) and the type is only known
|
|
137
|
+
// after the read. Every OTHER managed field is still refused inside
|
|
138
|
+
// buildWriteOps, before any network, exactly as before.
|
|
139
|
+
const fields = args.fields ?? {};
|
|
140
|
+
const stateViaRawFields = 'System.State' in fields;
|
|
141
|
+
const fieldsForOps = stateViaRawFields ? Object.fromEntries(Object.entries(fields).filter(([name]) => name !== 'System.State')) : fields;
|
|
142
|
+
let ops = buildWriteOps({ ...args, fields: fieldsForOps }); if (!ops.length && !stateViaRawFields) throw new Error('nothing to write: no fields, state, comment, or relations were supplied');
|
|
120
143
|
const c = await getClient();
|
|
121
144
|
const current = await c.get<any>(`/wit/workitems/${args.id}`, { 'api-version': '7.1', $expand: 'all' });
|
|
122
145
|
assertTracked(current);
|
|
146
|
+
const currentType: AllowedType = current.fields?.['System.WorkItemType'];
|
|
147
|
+
// FENCE 1: System.State via raw fields on a gated type. Features carry no
|
|
148
|
+
// flags and keep the generic managed-field refusal instead.
|
|
149
|
+
if (stateViaRawFields) {
|
|
150
|
+
if (currentType === 'Feature') throw new Error(`fields may only set Custom.* fields; 'System.State' is managed by this tool`);
|
|
151
|
+
throw new Error('System.State via raw fields is fenced — pass the dedicated `state` argument so the workflow gate can evaluate it.');
|
|
152
|
+
}
|
|
153
|
+
// FENCE 2 (workflow matrix): evaluate the RESULTING (state, flags) pair on
|
|
154
|
+
// every write — a state move and a flag-only update are both writes, and a
|
|
155
|
+
// write that leaves the pair violating any yes/no row is refused.
|
|
156
|
+
if (currentType !== 'Feature') {
|
|
157
|
+
const postState = args.state ?? current.fields?.['System.State'];
|
|
158
|
+
const postFlags: Partial<Record<WorkflowFlagRef, boolean>> = { ...pickWorkflowFlags(current.fields), ...pickWorkflowFlags(args.fields) };
|
|
159
|
+
const violations = evaluateWorkflowState(currentType, postState, postFlags);
|
|
160
|
+
if (violations.length) throw new Error(formatWorkflowRefusal(violations));
|
|
161
|
+
}
|
|
123
162
|
if (args.parentId !== undefined) {
|
|
124
163
|
// A parent is singular. Read the existing item so the write can remove all
|
|
125
164
|
// old parent links before adding the one validated replacement.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
// Azure DevOps identity RESOLUTION ONLY (
|
|
2
|
-
//
|
|
3
|
-
// standard"; split from token minting 2026-09-28 -- see
|
|
1
|
+
// Azure DevOps identity RESOLUTION ONLY (Tarun, 2026-09-27; one agent-identity
|
|
2
|
+
// standard for every surface, 2026-09-28; split from token minting -- see
|
|
4
3
|
// ./agent-token.ts's header for why).
|
|
5
4
|
//
|
|
6
5
|
// This module is THE one identity resolver -- every other Azure DevOps
|
|
@@ -35,7 +34,7 @@ export function isValidAgent(name: string): name is ValidAgent {
|
|
|
35
34
|
|
|
36
35
|
/** The one message every surface shows when no agent identity can be resolved at all. */
|
|
37
36
|
export const NO_AGENT_IDENTITY_MESSAGE =
|
|
38
|
-
'no agent identity: prefix the command with ADL_AGENT_ID_AGENT=<agent-tarun|agent-vivek|agent-reviewer
|
|
37
|
+
'no agent identity: prefix the command with ADL_AGENT_ID_AGENT=<agent-tarun|agent-vivek|agent-reviewer>';
|
|
39
38
|
|
|
40
39
|
/** Treat blank and whitespace-only values as unset. */
|
|
41
40
|
function configured(value: string | undefined): string | undefined {
|
|
@@ -129,9 +128,8 @@ export interface AgentIdentityResolution {
|
|
|
129
128
|
}
|
|
130
129
|
|
|
131
130
|
/**
|
|
132
|
-
* The human Azure DevOps pass-through check (
|
|
133
|
-
*
|
|
134
|
-
* `ADL_HUMAN_AZDO=1`). This is the ONE place the rule is expressed in
|
|
131
|
+
* The human Azure DevOps pass-through check (fail closed, the human opts in:
|
|
132
|
+
* a real TTY plus the env marker `ADL_HUMAN_AZDO=1`; Tarun, 2026-09-29). This is the ONE place the rule is expressed in
|
|
135
133
|
* TypeScript -- `adl id whoami` (apps/cli/src/commands/id.ts) calls this
|
|
136
134
|
* rather than re-implementing it. `bin/git-ado`'s own human-pass-through
|
|
137
135
|
* branch implements the IDENTICAL rule in bash (it cannot import this
|
|
@@ -142,9 +140,10 @@ export interface AgentIdentityResolution {
|
|
|
142
140
|
*
|
|
143
141
|
* Both halves are required:
|
|
144
142
|
* - `stdinIsTTY`: the caller's stdin is a real terminal, not a pipe, a
|
|
145
|
-
* closed fd, or a non-interactive automation shell (
|
|
146
|
-
*
|
|
147
|
-
*
|
|
143
|
+
* closed fd, or a non-interactive automation shell (observed 2026-09-29:
|
|
144
|
+
* the desktop agent shell has no TTY and does not inherit `.zshrc`
|
|
145
|
+
* exports either; agents started directly from a terminal DO inherit its
|
|
146
|
+
* env, which is why the TTY half is required alongside the marker).
|
|
148
147
|
* - `env.ADL_HUMAN_AZDO === '1'`: the EXACT string `"1"`, not `"true"`,
|
|
149
148
|
* not `"yes"`, not trimmed whitespace -- Tarun exports it from his own
|
|
150
149
|
* `.zshrc`. An agent must never set it (packages/agent-settings'
|
|
@@ -160,12 +159,11 @@ export function isMarkedHumanAzdoCaller(env: NodeJS.ProcessEnv, stdinIsTTY: bool
|
|
|
160
159
|
|
|
161
160
|
/**
|
|
162
161
|
* The one agent-identity resolver every Azure DevOps surface in this repo
|
|
163
|
-
* shares (
|
|
164
|
-
* function; first match wins; an invalid name is refused, never skipped:
|
|
162
|
+
* shares (Tarun, 2026-09-28). One function; first match wins; an invalid name is refused, never skipped:
|
|
165
163
|
*
|
|
166
164
|
* 1. `ADL_AGENT_ID_AGENT` from the environment (blank/whitespace-only
|
|
167
|
-
* counts as unset) -- set by
|
|
168
|
-
*
|
|
165
|
+
* counts as unset) -- set by a surface's managed default (e.g.
|
|
166
|
+
* Claude's managed-settings env).
|
|
169
167
|
* 2. Else the machine default-agent file, written by fleet reconcile.
|
|
170
168
|
* 3. Else refuse with `NO_AGENT_IDENTITY_MESSAGE` -- there is never a
|
|
171
169
|
* human fallback for an agent.
|
|
@@ -136,8 +136,8 @@ export async function getAccessToken(agent: string): Promise<string> {
|
|
|
136
136
|
* addresses and the same in-memory cache -- for callers whose call sites are
|
|
137
137
|
* all sync (packages/repo-controls' doctor/hook checks), where importing the
|
|
138
138
|
* async mint across the package boundary would mean threading `await`
|
|
139
|
-
* through code that has none today.
|
|
140
|
-
*
|
|
139
|
+
* through code that has none today. This is the ONE mint every surface
|
|
140
|
+
* uses; packages/repo-controls/src/azure-devops-governance.ts
|
|
141
141
|
* no longer keeps its own copy.
|
|
142
142
|
*
|
|
143
143
|
* `env` defaults to `process.env` (matching `getAccessToken`) but is
|
|
@@ -110,11 +110,6 @@ export function currentRemote(cwd?: string): AzureRemote | null {
|
|
|
110
110
|
return remoteCache;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
/** Test seam: forget the cached remote. */
|
|
114
|
-
export function resetRemoteCache(): void {
|
|
115
|
-
remoteCache = undefined;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
113
|
export function resolveOrg(cwd?: string): string {
|
|
119
114
|
return configured(process.env.AZURE_DEVOPS_ORG) ?? currentRemote(cwd)?.org ?? DEFAULT_ORG;
|
|
120
115
|
}
|
|
@@ -79,7 +79,7 @@ function configured(value: string | undefined): string | undefined {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/** The Graph service host — a different host from dev.azure.com entirely. */
|
|
82
|
-
|
|
82
|
+
function vsspsBaseUrl(): string {
|
|
83
83
|
return configured(process.env.AZURE_DEVOPS_VSSPS_BASE_URL) ?? `https://vssps.dev.azure.com/${resolveOrg()}`;
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -92,7 +92,7 @@ export async function fetchJson<T>(url: string, label: string): Promise<T> {
|
|
|
92
92
|
return resp.json() as Promise<T>;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
async function postJson<T>(url: string, body: unknown, label: string): Promise<T> {
|
|
96
96
|
const token = await getAccessToken(resolveAgentIdentity().agent);
|
|
97
97
|
const resp = await fetch(url, {
|
|
98
98
|
method: 'POST',
|
|
@@ -106,7 +106,7 @@ export async function postJson<T>(url: string, body: unknown, label: string): Pr
|
|
|
106
106
|
return resp.json() as Promise<T>;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
interface GraphSubjectQueryResponse {
|
|
110
110
|
value?: Array<{ displayName?: string; descriptor?: string }>;
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -142,7 +142,7 @@ interface GraphStorageKeyResponse {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
/** Resolve a Graph `descriptor` to its legacy GUID storage key, or undefined when Graph has none on file. */
|
|
145
|
-
|
|
145
|
+
async function resolveIdentityStorageKey(descriptor: string): Promise<string | undefined> {
|
|
146
146
|
const result = await fetchJson<GraphStorageKeyResponse>(
|
|
147
147
|
`${vsspsBaseUrl()}/_apis/graph/storagekeys/${encodeURIComponent(descriptor)}?api-version=7.1`,
|
|
148
148
|
'Graph storage key',
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
work_item_type,state,state_category,flag_ref,flag_label,rule,meaning,failure_reason
|
|
2
|
+
Product Backlog Item,New,Proposed,Custom.Planwritten,Plan written,no,must be false,Plan rejected
|
|
3
|
+
Product Backlog Item,New,Proposed,Custom.Implementationcomplete,Implementation complete,no,must be false,
|
|
4
|
+
Product Backlog Item,New,Proposed,Custom.Reviewpassed,Review passed,no,must be false,Reviewer rejected
|
|
5
|
+
Product Backlog Item,New,Proposed,Custom.Testspassing,Tests passing,no,must be false,Tests failed
|
|
6
|
+
Product Backlog Item,New,Proposed,Custom.Docsupdated,Docs updated,no,must be false,
|
|
7
|
+
Product Backlog Item,New,Proposed,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
8
|
+
Product Backlog Item,Approved,Proposed,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
9
|
+
Product Backlog Item,Approved,Proposed,Custom.Implementationcomplete,Implementation complete,no,must be false,
|
|
10
|
+
Product Backlog Item,Approved,Proposed,Custom.Reviewpassed,Review passed,no,must be false,Reviewer rejected
|
|
11
|
+
Product Backlog Item,Approved,Proposed,Custom.Testspassing,Tests passing,no,must be false,Tests failed
|
|
12
|
+
Product Backlog Item,Approved,Proposed,Custom.Docsupdated,Docs updated,no,must be false,
|
|
13
|
+
Product Backlog Item,Approved,Proposed,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
14
|
+
Product Backlog Item,Committed,InProgress,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
15
|
+
Product Backlog Item,Committed,InProgress,Custom.Implementationcomplete,Implementation complete,no,must be false,
|
|
16
|
+
Product Backlog Item,Committed,InProgress,Custom.Reviewpassed,Review passed,no,must be false,Reviewer rejected
|
|
17
|
+
Product Backlog Item,Committed,InProgress,Custom.Testspassing,Tests passing,no,must be false,Tests failed
|
|
18
|
+
Product Backlog Item,Committed,InProgress,Custom.Docsupdated,Docs updated,no,must be false,
|
|
19
|
+
Product Backlog Item,Committed,InProgress,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
20
|
+
Product Backlog Item,In Progress,InProgress,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
21
|
+
Product Backlog Item,In Progress,InProgress,Custom.Implementationcomplete,Implementation complete,free,either — this is where the gate is worked,
|
|
22
|
+
Product Backlog Item,In Progress,InProgress,Custom.Reviewpassed,Review passed,no,must be false,Reviewer rejected
|
|
23
|
+
Product Backlog Item,In Progress,InProgress,Custom.Testspassing,Tests passing,free,either — this is where the gate is worked,Tests failed
|
|
24
|
+
Product Backlog Item,In Progress,InProgress,Custom.Docsupdated,Docs updated,free,either — this is where the gate is worked,
|
|
25
|
+
Product Backlog Item,In Progress,InProgress,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
26
|
+
Product Backlog Item,In Testing,InProgress,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
27
|
+
Product Backlog Item,In Testing,InProgress,Custom.Implementationcomplete,Implementation complete,yes,must be true,
|
|
28
|
+
Product Backlog Item,In Testing,InProgress,Custom.Reviewpassed,Review passed,free,either — this is where the gate is worked,Reviewer rejected
|
|
29
|
+
Product Backlog Item,In Testing,InProgress,Custom.Testspassing,Tests passing,free,either — this is where the gate is worked,Tests failed
|
|
30
|
+
Product Backlog Item,In Testing,InProgress,Custom.Docsupdated,Docs updated,free,either — this is where the gate is worked,
|
|
31
|
+
Product Backlog Item,In Testing,InProgress,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
32
|
+
Product Backlog Item,Done,Completed,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
33
|
+
Product Backlog Item,Done,Completed,Custom.Implementationcomplete,Implementation complete,yes,must be true,
|
|
34
|
+
Product Backlog Item,Done,Completed,Custom.Reviewpassed,Review passed,yes,must be true,Reviewer rejected
|
|
35
|
+
Product Backlog Item,Done,Completed,Custom.Testspassing,Tests passing,yes,must be true,Tests failed
|
|
36
|
+
Product Backlog Item,Done,Completed,Custom.Docsupdated,Docs updated,yes,must be true,
|
|
37
|
+
Product Backlog Item,Done,Completed,Custom.Mergedtointegration,Merged to integration,yes,must be true,Build failed
|
|
38
|
+
Product Backlog Item,Removed,Removed,Custom.Planwritten,Plan written,free,either — this is where the gate is worked,Plan rejected
|
|
39
|
+
Product Backlog Item,Removed,Removed,Custom.Implementationcomplete,Implementation complete,free,either — this is where the gate is worked,
|
|
40
|
+
Product Backlog Item,Removed,Removed,Custom.Reviewpassed,Review passed,free,either — this is where the gate is worked,Reviewer rejected
|
|
41
|
+
Product Backlog Item,Removed,Removed,Custom.Testspassing,Tests passing,free,either — this is where the gate is worked,Tests failed
|
|
42
|
+
Product Backlog Item,Removed,Removed,Custom.Docsupdated,Docs updated,free,either — this is where the gate is worked,
|
|
43
|
+
Product Backlog Item,Removed,Removed,Custom.Mergedtointegration,Merged to integration,free,either — this is where the gate is worked,Build failed
|
|
44
|
+
Bug,New,Proposed,Custom.Planwritten,Plan written,no,must be false,Plan rejected
|
|
45
|
+
Bug,New,Proposed,Custom.Implementationcomplete,Implementation complete,no,must be false,
|
|
46
|
+
Bug,New,Proposed,Custom.Reviewpassed,Review passed,no,must be false,Reviewer rejected
|
|
47
|
+
Bug,New,Proposed,Custom.Testspassing,Tests passing,no,must be false,Tests failed
|
|
48
|
+
Bug,New,Proposed,Custom.Docsupdated,Docs updated,no,must be false,
|
|
49
|
+
Bug,New,Proposed,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
50
|
+
Bug,Approved,Proposed,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
51
|
+
Bug,Approved,Proposed,Custom.Implementationcomplete,Implementation complete,no,must be false,
|
|
52
|
+
Bug,Approved,Proposed,Custom.Reviewpassed,Review passed,no,must be false,Reviewer rejected
|
|
53
|
+
Bug,Approved,Proposed,Custom.Testspassing,Tests passing,no,must be false,Tests failed
|
|
54
|
+
Bug,Approved,Proposed,Custom.Docsupdated,Docs updated,no,must be false,
|
|
55
|
+
Bug,Approved,Proposed,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
56
|
+
Bug,Committed,InProgress,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
57
|
+
Bug,Committed,InProgress,Custom.Implementationcomplete,Implementation complete,no,must be false,
|
|
58
|
+
Bug,Committed,InProgress,Custom.Reviewpassed,Review passed,no,must be false,Reviewer rejected
|
|
59
|
+
Bug,Committed,InProgress,Custom.Testspassing,Tests passing,no,must be false,Tests failed
|
|
60
|
+
Bug,Committed,InProgress,Custom.Docsupdated,Docs updated,no,must be false,
|
|
61
|
+
Bug,Committed,InProgress,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
62
|
+
Bug,In Progress,InProgress,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
63
|
+
Bug,In Progress,InProgress,Custom.Implementationcomplete,Implementation complete,free,either — this is where the gate is worked,
|
|
64
|
+
Bug,In Progress,InProgress,Custom.Reviewpassed,Review passed,no,must be false,Reviewer rejected
|
|
65
|
+
Bug,In Progress,InProgress,Custom.Testspassing,Tests passing,free,either — this is where the gate is worked,Tests failed
|
|
66
|
+
Bug,In Progress,InProgress,Custom.Docsupdated,Docs updated,free,either — this is where the gate is worked,
|
|
67
|
+
Bug,In Progress,InProgress,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
68
|
+
Bug,In Testing,InProgress,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
69
|
+
Bug,In Testing,InProgress,Custom.Implementationcomplete,Implementation complete,yes,must be true,
|
|
70
|
+
Bug,In Testing,InProgress,Custom.Reviewpassed,Review passed,free,either — this is where the gate is worked,Reviewer rejected
|
|
71
|
+
Bug,In Testing,InProgress,Custom.Testspassing,Tests passing,free,either — this is where the gate is worked,Tests failed
|
|
72
|
+
Bug,In Testing,InProgress,Custom.Docsupdated,Docs updated,free,either — this is where the gate is worked,
|
|
73
|
+
Bug,In Testing,InProgress,Custom.Mergedtointegration,Merged to integration,no,must be false,Build failed
|
|
74
|
+
Bug,Done,Completed,Custom.Planwritten,Plan written,yes,must be true,Plan rejected
|
|
75
|
+
Bug,Done,Completed,Custom.Implementationcomplete,Implementation complete,yes,must be true,
|
|
76
|
+
Bug,Done,Completed,Custom.Reviewpassed,Review passed,yes,must be true,Reviewer rejected
|
|
77
|
+
Bug,Done,Completed,Custom.Testspassing,Tests passing,yes,must be true,Tests failed
|
|
78
|
+
Bug,Done,Completed,Custom.Docsupdated,Docs updated,yes,must be true,
|
|
79
|
+
Bug,Done,Completed,Custom.Mergedtointegration,Merged to integration,yes,must be true,Build failed
|
|
80
|
+
Bug,Removed,Removed,Custom.Planwritten,Plan written,free,either — this is where the gate is worked,Plan rejected
|
|
81
|
+
Bug,Removed,Removed,Custom.Implementationcomplete,Implementation complete,free,either — this is where the gate is worked,
|
|
82
|
+
Bug,Removed,Removed,Custom.Reviewpassed,Review passed,free,either — this is where the gate is worked,Reviewer rejected
|
|
83
|
+
Bug,Removed,Removed,Custom.Testspassing,Tests passing,free,either — this is where the gate is worked,Tests failed
|
|
84
|
+
Bug,Removed,Removed,Custom.Docsupdated,Docs updated,free,either — this is where the gate is worked,
|
|
85
|
+
Bug,Removed,Removed,Custom.Mergedtointegration,Merged to integration,free,either — this is where the gate is worked,Build failed
|