@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.10 → 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 +17 -18
- package/bin/git-ado +27 -26
- 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/bun-compile-build.sh +1 -1
- package/bin/lib/fleet-host.sh +62 -0
- package/bin/lib/lean-ctx-observe-hooks.sh +9 -9
- package/bin/reconcile +693 -470
- package/bin/reconcile-host +121 -0
- package/bin/setup +219 -0
- package/bin/shell-path-policy +15 -5
- package/bin/sync-and-reconcile +79 -68
- package/bin/validate-manifest +46 -51
- package/package.json +2 -12
- package/packages/agent-hooks/README.md +14 -9
- package/packages/agent-hooks/assets/hooks.json +0 -20
- package/packages/agent-hooks/package.json +1 -2
- 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/fs-trash.ts +2 -2
- 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 +18 -18
- 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 +5 -17
- 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/package.json +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 +2 -5
- 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 +38 -33
- package/packages/fleet/manifest.schema.json +67 -65
- 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 +14 -14
- package/packages/fleet/src/managed-settings.ts +7 -7
- package/packages/fleet/src/repo-maintain.ts +439 -0
- package/packages/fleet/src/scratch-reap.ts +6 -6
- 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 -10
- 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
- package/packages/fleet/jobs/git-maintain/src/main.ts +0 -848
- package/packages/fleet/systemd/adl-azure-agent-update.service +0 -13
- package/packages/fleet/systemd/adl-azure-agent-update.timer +0 -10
package/bin/validate-manifest
CHANGED
|
@@ -11,11 +11,17 @@ manifest="${1:-}"
|
|
|
11
11
|
|
|
12
12
|
if ! jq -e '
|
|
13
13
|
def relpath: type == "string" and length > 0 and (startswith("/") | not) and (split("/") | index("..") | not);
|
|
14
|
+
# git_global_config (bin/git-defaults): key -> string, or key -> non-empty ordered array of strings.
|
|
15
|
+
# {git-credential-manager} is the only placeholder a value may carry (gh/GitHub is not managed by adl).
|
|
16
|
+
def gitcfg_value: type == "string" and ([match("\\{[^}]*\\}"; "g").string] | all(. == "{git-credential-manager}"));
|
|
17
|
+
def gitcfg: type == "object" and
|
|
18
|
+
(to_entries | all((.key | test("^[A-Za-z][A-Za-z0-9-]*\\..+")) and
|
|
19
|
+
(.value | gitcfg_value or (type == "array" and length > 0 and all(gitcfg_value)))));
|
|
14
20
|
keys == ["config", "linux", "mac"] and
|
|
15
21
|
.config.schema == 1 and
|
|
16
22
|
(.config.repository | type == "string" and test("^https://dev\\.azure\\.com/[A-Za-z0-9._-]+/[A-Za-z0-9._-]+/_git/[A-Za-z0-9._-]+$")) and
|
|
17
23
|
.config.branch == "main" and
|
|
18
|
-
.config.interval_seconds ==
|
|
24
|
+
.config.interval_seconds == 43200 and
|
|
19
25
|
.config.update_policy == "latest-stable" and
|
|
20
26
|
.config.allow_major_updates == true and
|
|
21
27
|
.config.remove_deleted_entries == true and
|
|
@@ -26,15 +32,21 @@ if ! jq -e '
|
|
|
26
32
|
.config.surface_policy == {"enabled": true} and
|
|
27
33
|
.config.global_agents == {"enabled": true} and
|
|
28
34
|
.config.vscode_settings == {"enabled": true} and
|
|
35
|
+
(.config.repo_maintain | type == "object") and
|
|
36
|
+
(.config.repo_maintain | keys == ["branch_max_age_days"]) and
|
|
37
|
+
(.config.repo_maintain.branch_max_age_days | type == "number" and . >= 1 and floor == .) and
|
|
29
38
|
(.config.scratch_reap | type == "object") and
|
|
30
39
|
(.config.scratch_reap | keys == ["enabled", "idle_days", "reap_days", "remove_worktrees"]) and
|
|
31
40
|
.config.scratch_reap.enabled == true and
|
|
32
41
|
(.config.scratch_reap.idle_days | type == "number" and . >= 0 and floor == .) and
|
|
33
42
|
(.config.scratch_reap.reap_days | type == "number" and . >= 1 and floor == .) and
|
|
34
43
|
(.config.scratch_reap.remove_worktrees | type == "boolean") and
|
|
44
|
+
(.config.brew_upgrade_exclude | type == "array" and
|
|
45
|
+
(. | unique | length) == length and
|
|
46
|
+
all(type == "string" and test("^[A-Za-z0-9][A-Za-z0-9@._+/-]*$"))) and
|
|
35
47
|
(.config.protected_tools | type == "array") and
|
|
36
|
-
(.config.git_global_config |
|
|
37
|
-
|
|
48
|
+
(.config.git_global_config | gitcfg) and
|
|
49
|
+
([.mac.common, .linux.common] | all((.git_global_config // {}) | gitcfg)) and
|
|
38
50
|
(.mac.common.tools | type == "object") and
|
|
39
51
|
(.mac.devices | type == "object") and
|
|
40
52
|
(.linux.common.tools | type == "object") and
|
|
@@ -43,28 +55,23 @@ if ! jq -e '
|
|
|
43
55
|
all(.minimum_free_gib >= 1) and
|
|
44
56
|
all((.home | type) == "string" and (.home | startswith("/"))) and
|
|
45
57
|
all((.default_agent | type) == "string" and (.default_agent | test("^agent-[a-z0-9-]+$"))) and
|
|
46
|
-
all((
|
|
58
|
+
all((.git_user | type == "object" and (keys | sort) == ["email", "name"] and
|
|
59
|
+
all(.[]; type == "string" and length > 0))) and
|
|
60
|
+
all((keys - ["administrator", "default_agent", "git_user", "home", "minimum_free_gib", "schedule_minute", "scratch_repos", "brew_upgrade_all", "surface_clis", "repo_location", "tools"] | length) == 0) and
|
|
47
61
|
all((.scratch_repos // []) | type == "array" and (. | unique | length) == length and
|
|
48
62
|
all(type == "string" and startswith("/") and . != "/" and
|
|
49
63
|
(endswith("/") | not) and (contains("..") | not) and (test("\\s") | not))) and
|
|
50
|
-
#
|
|
51
|
-
# repositories
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
# point of actual use (jobs/git-maintain/src/main.ts,
|
|
62
|
-
# isForbiddenAzurePipelinesPath) -- this schema check alone only ever
|
|
63
|
-
# sees the manifest literal string, never what a symlink resolves to.
|
|
64
|
-
all((.git_maintain_repos // []) | type == "array" and (. | unique | length) == length and
|
|
65
|
-
all(type == "string" and startswith("/") and . != "/" and
|
|
66
|
-
(endswith("/") | not) and (contains("..") | not) and (test("\\s") | not) and
|
|
67
|
-
(ascii_downcase | contains("azagent") | not) and (ascii_downcase | contains("vsts.agent") | not))) and
|
|
64
|
+
# repo_location (2026-09-30): the ONE directory `adl reconcile` maintains
|
|
65
|
+
# repositories under (immediate children carrying adl-config.toml only). It
|
|
66
|
+
# is the whole scope of that step, so it must be an exact absolute directory
|
|
67
|
+
# path: never "/", no trailing slash, no "..", no whitespace. The
|
|
68
|
+
# azagent/vsts.agent substring bans keep it off Azure Pipelines agent
|
|
69
|
+
# installs (case-insensitively -- a value could be typed AzAgent2 as easily
|
|
70
|
+
# as azagent2); the maintenance step refuses the same names again, by
|
|
71
|
+
# realpath too, at the point of use.
|
|
72
|
+
all((.repo_location // "/ok") | type == "string" and startswith("/") and . != "/" and
|
|
73
|
+
(endswith("/") | not) and (contains("..") | not) and (test("\\s") | not) and
|
|
74
|
+
(ascii_downcase | contains("azagent") | not) and (ascii_downcase | contains("vsts.agent") | not)) and
|
|
68
75
|
all((.brew_upgrade_all // false) | type == "boolean") and
|
|
69
76
|
all(
|
|
70
77
|
(.surface_clis // []) as $surfaces |
|
|
@@ -72,13 +79,23 @@ if ! jq -e '
|
|
|
72
79
|
($surfaces | map(.name) | length == (unique | length)) and
|
|
73
80
|
($surfaces | all(
|
|
74
81
|
(.name | type == "string" and length > 0) and
|
|
75
|
-
(.manager | type == "string" and (. == "native" or . == "npm" or . == "brew" or . == "unknown")) and
|
|
82
|
+
(.manager | type == "string" and (. == "native" or . == "npm" or . == "brew" or . == "bun" or . == "unknown")) and
|
|
76
83
|
((.report_only // false) | type == "boolean") and
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
# manager bun (2026-10-01): installed and updated as `bun add -g <package>@latest`, so it
|
|
85
|
+
# names a bare registry package (no version spec: versions are never pinned) and a command,
|
|
86
|
+
# and carries no update_args (the manager fixes the argv) and no report_only.
|
|
87
|
+
(if .manager == "bun" then
|
|
88
|
+
((.package | type == "string") and (.package | test("^(@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$"))) and
|
|
89
|
+
((.command | type == "string") and (.command | length > 0) and (.command | contains("/") | not)) and
|
|
90
|
+
(has("update_args") | not) and (has("version") | not) and ((.report_only // false) == false)
|
|
79
91
|
else
|
|
80
|
-
(
|
|
81
|
-
(.
|
|
92
|
+
(has("package") | not) and
|
|
93
|
+
(if (.report_only // false) == true then
|
|
94
|
+
(.executable | type == "string" and startswith("/"))
|
|
95
|
+
else
|
|
96
|
+
(.command | type == "string" and length > 0 and (contains("/") | not)) and
|
|
97
|
+
(.update_args | type == "array" and length > 0 and all(type == "string" and length > 0))
|
|
98
|
+
end)
|
|
82
99
|
end) and
|
|
83
100
|
(.manager != "brew" or
|
|
84
101
|
((.report_only // false) == false and .command == "brew" and
|
|
@@ -159,30 +176,8 @@ if ! jq -e '
|
|
|
159
176
|
((.allow_scripts // []) | type == "array" and
|
|
160
177
|
all(type == "string" and test("^(@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$")))
|
|
161
178
|
else true end)) and
|
|
162
|
-
|
|
163
|
-
([.linux.
|
|
164
|
-
(.mac.common.launch_agents["git-maintain"] as $job |
|
|
165
|
-
($job | type == "object") and
|
|
166
|
-
($job.repo_scope | type == "object" and keys == ["glob", "recursive", "root"] and
|
|
167
|
-
(.root | relpath) and .glob == "*" and .recursive == true) and
|
|
168
|
-
($job.environment | has("GIT_MAINTAIN_ROOT") | not) and
|
|
169
|
-
($job.environment | has("GIT_MAINTAIN_GLOB") | not)) and
|
|
170
|
-
([.mac.common.launch_agents, .mac.devices[].launch_agents] | map(. // {}) |
|
|
171
|
-
all(type == "object") and
|
|
172
|
-
([.[] | to_entries[] | .value] |
|
|
173
|
-
all(
|
|
174
|
-
type == "object" and
|
|
175
|
-
(keys - ["label", "source", "entry", "start_interval_seconds", "run_at_load", "environment", "log", "replaces", "repo_scope"] | length == 0) and
|
|
176
|
-
((.label | type) == "string" and (.label | test("^[A-Za-z0-9][A-Za-z0-9._-]*$"))) and
|
|
177
|
-
(.source | relpath) and
|
|
178
|
-
(.entry | relpath) and
|
|
179
|
-
((.start_interval_seconds | type) == "number" and .start_interval_seconds >= 60 and (.start_interval_seconds | floor) == .start_interval_seconds) and
|
|
180
|
-
((.run_at_load | type) == "boolean") and
|
|
181
|
-
((.environment | type) == "object" and (.environment | to_entries | all((.key | test("^[A-Z_][A-Z0-9_]*$")) and (.value | type) == "string"))) and
|
|
182
|
-
(.log | relpath) and
|
|
183
|
-
((.replaces // []) | type == "array" and all(relpath))
|
|
184
|
-
) and
|
|
185
|
-
(map(.label) | length == (unique | length))))
|
|
179
|
+
# launch_agents are gone (2026-09-30): a stale declaration must fail loud.
|
|
180
|
+
([.mac.common, .linux.common] | all(keys - ["os_upgrade", "git_global_config", "tools"] | length == 0))
|
|
186
181
|
' "$manifest" >/dev/null; then
|
|
187
182
|
echo "global-tools manifest: INVALID ($manifest does not satisfy bin/validate-manifest's schema)" >&2
|
|
188
183
|
exit 1
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amsterdamdatalabs/adl-agent-control-linux-x64",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.26",
|
|
4
4
|
"description": "adl CLI binary for linux/x64 (agent identity + Azure DevOps front door — see docs/architecture/cli-design.md)",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"os": [
|
|
@@ -14,13 +14,7 @@
|
|
|
14
14
|
"packages/fleet/manifest.json",
|
|
15
15
|
"packages/fleet/manifest.schema.json",
|
|
16
16
|
"packages/fleet/src",
|
|
17
|
-
"packages/
|
|
18
|
-
"packages/fleet/systemd",
|
|
19
|
-
"packages/agent-settings/surface-policy.json",
|
|
20
|
-
"packages/agent-settings/protected.json",
|
|
21
|
-
"packages/agent-settings/src",
|
|
22
|
-
"packages/agent-settings/assets",
|
|
23
|
-
"packages/agent-settings/managed",
|
|
17
|
+
"packages/agent-settings",
|
|
24
18
|
"packages/agent-skills",
|
|
25
19
|
"packages/repo-controls",
|
|
26
20
|
"packages/agent-hooks",
|
|
@@ -31,13 +25,9 @@
|
|
|
31
25
|
},
|
|
32
26
|
"dependencies": {
|
|
33
27
|
"@iarna/toml": "^2.2.5",
|
|
34
|
-
"@tailwindcss/node": "4.2.1",
|
|
35
28
|
"ajv": "^8.17.1",
|
|
36
29
|
"ajv-formats": "^3.0.1",
|
|
37
|
-
"istanbul-lib-coverage": "3.2.2",
|
|
38
30
|
"minisearch": "7.2.0",
|
|
39
|
-
"svelte": "5.38.10",
|
|
40
|
-
"tailwindcss": "4.1.11",
|
|
41
31
|
"typescript": "5.9.3",
|
|
42
32
|
"yaml": "^2.9.0"
|
|
43
33
|
}
|
|
@@ -213,14 +213,16 @@ directory containing a `.git` entry) and checking for
|
|
|
213
213
|
|
|
214
214
|
### File format
|
|
215
215
|
|
|
216
|
-
|
|
217
|
-
`[controls]`,
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
216
|
+
The recognized root keys include `version`, `[hooks]`, `[rules]`, `[repo]`,
|
|
217
|
+
`[agent]`, `[controls]`, `[skills]`, `[extensions]`, and `[azdo]`. `[controls]`
|
|
218
|
+
and `[skills]` belong to other tools sharing this file; `[azdo]` is reserved
|
|
219
|
+
for shared Azure DevOps configuration. `adl hook` accepts these tables without
|
|
220
|
+
reading their contents, so optional tables such as `[azdo.scope]` can be present
|
|
221
|
+
while its hook configuration remains independent. `[extensions]` is also a
|
|
222
|
+
shared table, but `adl hook` reads its sub-table names to locate extension
|
|
223
|
+
skills. Every other top-level key — and every unrecognized key inside `[hooks]`
|
|
224
|
+
or `[repo]` — is a decode error (fails loud, non-zero exit, reason on stderr),
|
|
225
|
+
never silently ignored; see "Unknown keys fail loud" below.
|
|
224
226
|
|
|
225
227
|
```toml
|
|
226
228
|
version = 1 # optional; accepted for the marker file's
|
|
@@ -353,7 +355,10 @@ fixed in the process (see `src/lib/spawn-with-timeout.ts`,
|
|
|
353
355
|
`XDG_CONFIG_HOME` / `XDG_DATA_HOME` / `XDG_STATE_HOME` / `XDG_CACHE_HOME`
|
|
354
356
|
environment (rooted at `<repo root>/.agents/lean-ctx/`) that wrapper used
|
|
355
357
|
to set, so `lean-ctx`'s state stays per-repository even though the
|
|
356
|
-
binary itself is shared.
|
|
358
|
+
binary itself is shared. In a linked git worktree the four stores root at
|
|
359
|
+
the main checkout (resolved from the worktree's own `.git` file), so
|
|
360
|
+
worktree sessions share the accumulated knowledge instead of starting
|
|
361
|
+
cold.
|
|
357
362
|
|
|
358
363
|
## Integration pass (three independently-migrated slices + foundation)
|
|
359
364
|
|
|
@@ -21,16 +21,6 @@
|
|
|
21
21
|
"timeout": 10
|
|
22
22
|
}
|
|
23
23
|
]
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"hooks": [
|
|
27
|
-
{
|
|
28
|
-
"type": "command",
|
|
29
|
-
"command": "adl hook lean-ctx pre-tool-use",
|
|
30
|
-
"statusMessage": "adl-repo: lean-ctx pre-tool-use",
|
|
31
|
-
"timeout": 10
|
|
32
|
-
}
|
|
33
|
-
]
|
|
34
24
|
}
|
|
35
25
|
],
|
|
36
26
|
"UserPromptSubmit": [
|
|
@@ -69,16 +59,6 @@
|
|
|
69
59
|
"timeout": 5
|
|
70
60
|
}
|
|
71
61
|
]
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
"hooks": [
|
|
75
|
-
{
|
|
76
|
-
"type": "command",
|
|
77
|
-
"command": "adl hook lean-ctx post-tool-use",
|
|
78
|
-
"statusMessage": "adl-repo: lean-ctx post-tool-use",
|
|
79
|
-
"timeout": 10
|
|
80
|
-
}
|
|
81
|
-
]
|
|
82
62
|
}
|
|
83
63
|
],
|
|
84
64
|
"SessionEnd": [
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
"start": "bun src/main.ts",
|
|
9
9
|
"build": "bun ../../workflows/scripts/build/agent-hooks/build.ts",
|
|
10
10
|
"typecheck": "tsc --noEmit",
|
|
11
|
-
"test": "bun test --timeout 30000",
|
|
12
|
-
"test:coverage": "bun test --coverage --timeout 30000",
|
|
11
|
+
"test": "bun test --coverage --timeout 30000",
|
|
13
12
|
"check": "bun run typecheck && bun test --coverage"
|
|
14
13
|
},
|
|
15
14
|
"dependencies": {
|
|
@@ -70,7 +70,7 @@ function isDirectory(path: string): boolean {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/** The built-in config an unmanaged repo is described with — the decode of an empty file, i.e. the schema defaults. */
|
|
73
|
-
|
|
73
|
+
function defaultConfig(): AdlRepoConfig {
|
|
74
74
|
return (decodeConfig('') as { readonly value: AdlRepoConfig }).value
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -13,13 +13,10 @@
|
|
|
13
13
|
* signal for that lives now, since UserPromptSubmit only WARNS -- an
|
|
14
14
|
* empty corpus has an innocent explanation once it is per-host and
|
|
15
15
|
* per-extension, and a dead prompt is worse than a missing hint);
|
|
16
|
-
* `
|
|
17
|
-
* lean-ctx hooks shell out to it); `code-review-graph` not on PATH
|
|
18
|
-
* (the crg hooks shell out to it).
|
|
16
|
+
* `code-review-graph` not on PATH (the crg hooks shell out to it).
|
|
19
17
|
* warn — unmanaged repo (hooks no-op by design); `[hooks] enabled = false`;
|
|
20
18
|
* embedding model missing/corrupt (user-prompt-submit falls back to
|
|
21
|
-
* BM25-only, never fatal); vector half disabled
|
|
22
|
-
* count not readable.
|
|
19
|
+
* BM25-only, never fatal); vector half disabled.
|
|
23
20
|
*
|
|
24
21
|
* The vector half is "effectively disabled by cosineFloor" when the floor
|
|
25
22
|
* exceeds 1: a vector hit must reach `cosine >= cosineFloor` to enter fusion
|
|
@@ -36,8 +33,6 @@ import { scanSkills } from '../hooks/user-prompt-submit/skills.ts'
|
|
|
36
33
|
import { loadTokenizer } from '../hooks/user-prompt-submit/tokenizer.ts'
|
|
37
34
|
import { loadVectorHalf, resolveGlobalArtifactDir } from '../hooks/user-prompt-submit/vector.ts'
|
|
38
35
|
import { HOOKS_DENY_LOG_REL, HOOKS_LOG_REL } from '../hooks/log.ts'
|
|
39
|
-
import { DEFAULT_LEAN_CTX_DIR, leanCtxEnv } from '../lean-ctx/env.ts'
|
|
40
|
-
import { spawnWithTimeout } from '../lib/spawn-with-timeout.ts'
|
|
41
36
|
import { buildEngineContext } from '../rules/engine.ts'
|
|
42
37
|
import { liveEnv, liveRepoIndex } from '../rules/ports.ts'
|
|
43
38
|
import { BUILTIN_RULES, requireRegistered } from '../rules/registry.ts'
|
|
@@ -46,6 +41,9 @@ import { type CliResult, type LoadedRepo, cliError, loadRepo, parseArgs, unmanag
|
|
|
46
41
|
type Status = 'ok' | 'warn' | 'FAIL' | 'skip' | 'info'
|
|
47
42
|
type Env = Readonly<Record<string, string | undefined>>
|
|
48
43
|
|
|
44
|
+
/** Reserved for callers that previously supplied process-check timeouts. */
|
|
45
|
+
export interface DoctorOptions { readonly timeoutMs?: number }
|
|
46
|
+
|
|
49
47
|
interface Check {
|
|
50
48
|
readonly status: Status
|
|
51
49
|
readonly text: string
|
|
@@ -53,13 +51,6 @@ interface Check {
|
|
|
53
51
|
|
|
54
52
|
const check = (status: Status, name: string, detail: string): Check => ({ status, text: `${name}: ${detail}` })
|
|
55
53
|
|
|
56
|
-
export interface DoctorOptions {
|
|
57
|
-
/** Per-subprocess timeout for `lean-ctx --version` / `lean-ctx doctor --json`. */
|
|
58
|
-
readonly timeoutMs?: number
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const DEFAULT_TIMEOUT_MS = 10_000
|
|
62
|
-
|
|
63
54
|
/** Config + rule resolution, and the config the downstream checks use (null when unusable). */
|
|
64
55
|
function repoChecks(loaded: LoadedRepo): { readonly checks: Check[]; readonly config: AdlRepoConfig | null } {
|
|
65
56
|
const { state } = loaded
|
|
@@ -148,48 +139,6 @@ function modelAndVector(env: Env): Check[] {
|
|
|
148
139
|
return [model, vector]
|
|
149
140
|
}
|
|
150
141
|
|
|
151
|
-
async function leanCtxChecks(
|
|
152
|
-
loaded: LoadedRepo,
|
|
153
|
-
config: AdlRepoConfig | null,
|
|
154
|
-
env: Env,
|
|
155
|
-
timeoutMs: number,
|
|
156
|
-
): Promise<Check[]> {
|
|
157
|
-
const path = Bun.which('lean-ctx', { PATH: env.PATH ?? '' })
|
|
158
|
-
const skipAllowlist = check('skip', 'lean-ctx allowlist', 'lean-ctx not usable')
|
|
159
|
-
if (path === null) return [check('FAIL', 'lean-ctx', `not found on PATH (${env.PATH ?? ''})`), skipAllowlist]
|
|
160
|
-
const version = await spawnWithTimeout(path, ['--version'], { env, timeoutMs })
|
|
161
|
-
if (version.exitCode !== 0) {
|
|
162
|
-
const reason = version.timedOut ? `timed out after ${timeoutMs}ms` : `exited ${version.exitCode}: ${version.stderr.trim()}`
|
|
163
|
-
return [check('FAIL', 'lean-ctx', `${path} --version ${reason}`), skipAllowlist]
|
|
164
|
-
}
|
|
165
|
-
const binary = check('ok', 'lean-ctx', `${path} (${version.stdout.trim().split('\n')[0]})`)
|
|
166
|
-
|
|
167
|
-
// Same env the hooks give lean-ctx: repo-rooted LEAN_CTX_* in a managed repo, lean-ctx's own defaults otherwise (mcp.ts).
|
|
168
|
-
// `config` is the value `repoChecks` already decoded — reusing it keeps an invalid
|
|
169
|
-
// `adl-config.toml` reported by the `config` check above rather than thrown from here.
|
|
170
|
-
const root = loaded.state.managed && config !== null ? (loaded.state.root as string) : null
|
|
171
|
-
const childEnv = root === null ? { ...env } : leanCtxEnv(root, env, config?.hooks.leanCtxDir ?? DEFAULT_LEAN_CTX_DIR)
|
|
172
|
-
const scope = root === null ? 'lean-ctx defaults; LEAN_CTX_CONFIG_DIR unset' : `LEAN_CTX_CONFIG_DIR=${childEnv.LEAN_CTX_CONFIG_DIR}`
|
|
173
|
-
const unavailable = (reason: string): Check[] => [binary, check('warn', 'lean-ctx allowlist', `unavailable (${reason})`)]
|
|
174
|
-
const doctor = await spawnWithTimeout(path, ['doctor', '--json'], { env: childEnv, timeoutMs, ...(root === null ? {} : { cwd: root }) })
|
|
175
|
-
if (doctor.timedOut) return unavailable(`lean-ctx doctor --json timed out after ${timeoutMs}ms`)
|
|
176
|
-
// A non-zero exit alone is not a failure: lean-ctx 3.10.1 exits 1 whenever any of its OWN checks fail
|
|
177
|
-
// (e.g. no shell aliases) while still printing the full report. Only a report we cannot read is.
|
|
178
|
-
let parsed: { readonly checks?: readonly { readonly name?: string }[] }
|
|
179
|
-
try {
|
|
180
|
-
parsed = JSON.parse(doctor.stdout) as typeof parsed
|
|
181
|
-
} catch {
|
|
182
|
-
return unavailable(
|
|
183
|
-
doctor.exitCode === 0
|
|
184
|
-
? 'lean-ctx doctor --json printed invalid JSON'
|
|
185
|
-
: `lean-ctx doctor --json exited ${doctor.exitCode}: ${doctor.stderr.trim()}`,
|
|
186
|
-
)
|
|
187
|
-
}
|
|
188
|
-
const count = (parsed.checks ?? []).map((entry) => /Shell allowlist\s+(\d+) command/.exec(entry.name ?? '')?.[1]).find((n) => n !== undefined)
|
|
189
|
-
if (count === undefined) return unavailable('no "Shell allowlist" check in lean-ctx doctor --json')
|
|
190
|
-
return [binary, check('ok', 'lean-ctx allowlist', `${count} command(s) enforced (${scope})`)]
|
|
191
|
-
}
|
|
192
|
-
|
|
193
142
|
/** Both hook logs: path, row count, and for the deny log its last 5 rows. JSON Lines (docs/architecture/cli-design.md §5a): every line is a record, there is no header row to skip. */
|
|
194
143
|
function logChecks(loaded: LoadedRepo): Check[] {
|
|
195
144
|
if (!loaded.state.managed) return [check('skip', 'logs', 'not a managed repo (hooks log nothing here)')]
|
|
@@ -216,7 +165,7 @@ function crgCheck(env: Env): Check {
|
|
|
216
165
|
}
|
|
217
166
|
|
|
218
167
|
/** `argv` is everything after `doctor`. */
|
|
219
|
-
export async function runDoctor(argv: readonly string[], cwd: string, env: Env,
|
|
168
|
+
export async function runDoctor(argv: readonly string[], cwd: string, env: Env, _options: DoctorOptions = {}): Promise<CliResult> {
|
|
220
169
|
const parsed = parseArgs(argv, false)
|
|
221
170
|
if ('error' in parsed) return cliError(parsed.error)
|
|
222
171
|
if (parsed.positionals.length > 0) return cliError(`unexpected argument '${parsed.positionals[0]}'`)
|
|
@@ -228,7 +177,6 @@ export async function runDoctor(argv: readonly string[], cwd: string, env: Env,
|
|
|
228
177
|
...repo.checks,
|
|
229
178
|
...hooksAndSkills(loaded, repo.config),
|
|
230
179
|
...modelAndVector(env),
|
|
231
|
-
...(await leanCtxChecks(loaded, repo.config, env, options.timeoutMs ?? DEFAULT_TIMEOUT_MS)),
|
|
232
180
|
crgCheck(env),
|
|
233
181
|
...logChecks(loaded),
|
|
234
182
|
]
|
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
readLegacyLock,
|
|
24
24
|
sha256Hex,
|
|
25
25
|
stripLegacyOwnership,
|
|
26
|
-
unionOwnedCommands,
|
|
27
26
|
} from './legacy-lock.ts'
|
|
28
27
|
import { type HookLockEntry, lockPathFor, readLock, writeLock } from './lock.ts'
|
|
29
28
|
import { type HookDeployProfile, type HookSurface, loadProfile } from './profile.ts'
|
|
@@ -51,13 +50,13 @@ export interface DeployHooksOptions {
|
|
|
51
50
|
readonly dryRun?: boolean
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
|
|
53
|
+
interface HookConflict {
|
|
55
54
|
readonly file: string
|
|
56
55
|
readonly reason: string
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
/** One hook healed via the PAIR fallback (not hash, not the legacy channel) this run — see json-merge.ts's `RestoredHook` for the full rationale (2026-09-30, round 5, finding 2). */
|
|
60
|
-
|
|
59
|
+
interface RestoredHookReport {
|
|
61
60
|
readonly file: string
|
|
62
61
|
readonly event: string
|
|
63
62
|
readonly command: string
|
|
@@ -78,17 +77,6 @@ export interface DeployHooksResult {
|
|
|
78
77
|
readonly unchanged: readonly string[]
|
|
79
78
|
readonly conflicts: readonly HookConflict[]
|
|
80
79
|
readonly lockPath: string
|
|
81
|
-
/**
|
|
82
|
-
* Surface files whose lock entry moved from the legacy
|
|
83
|
-
* (`ownedCommands`-only) shape to the content-addressed one
|
|
84
|
-
* (`ownedEntries`) on THIS run (independent review, 2026-09-30, finding
|
|
85
|
-
* 7). This can be non-empty even when the surface's own `written`/
|
|
86
|
-
* `unchanged` outcome looks like nothing happened — the deployed JSON
|
|
87
|
-
* file can stay byte-identical while the LOCK itself is rewritten, and
|
|
88
|
-
* that rewrite deserves its own truthful line in the CLI's output
|
|
89
|
-
* rather than being folded silently into "unchanged".
|
|
90
|
-
*/
|
|
91
|
-
readonly lockMigrated: readonly string[]
|
|
92
80
|
/** Hooks healed via the pair fallback this run, named explicitly (round 5, finding 2) so deploy's own output, doctor's preview, and `adl install` can all say "restored adl hook <event>/<matcher>/<command> — local changes to it were replaced". */
|
|
93
81
|
readonly restored: readonly RestoredHookReport[]
|
|
94
82
|
}
|
|
@@ -134,12 +122,11 @@ export function deployHooks(options: DeployHooksOptions): DeployHooksResult {
|
|
|
134
122
|
const written: string[] = []
|
|
135
123
|
const unchanged: string[] = []
|
|
136
124
|
const conflicts: HookConflict[] = []
|
|
137
|
-
const lockMigrated: string[] = []
|
|
138
125
|
const restored: RestoredHookReport[] = []
|
|
139
126
|
const takeover = { any: false }
|
|
140
127
|
|
|
141
128
|
for (const surface of profile.surfaces) {
|
|
142
|
-
deploySurface(surface, { assetsDir, targetRepo, hooksDoc, lock, legacyDoc, takeover, newEntries, written, unchanged, conflicts,
|
|
129
|
+
deploySurface(surface, { assetsDir, targetRepo, hooksDoc, lock, legacyDoc, takeover, newEntries, written, unchanged, conflicts, restored, dryRun })
|
|
143
130
|
}
|
|
144
131
|
|
|
145
132
|
if (!dryRun) writeLock(targetRepo, { version: 1, entries: newEntries })
|
|
@@ -158,7 +145,6 @@ export function deployHooks(options: DeployHooksOptions): DeployHooksResult {
|
|
|
158
145
|
unchanged: unchanged.sort(),
|
|
159
146
|
conflicts: conflicts.sort((a, b) => a.file.localeCompare(b.file)),
|
|
160
147
|
lockPath: lockPathFor(targetRepo),
|
|
161
|
-
lockMigrated: lockMigrated.sort(),
|
|
162
148
|
restored,
|
|
163
149
|
}
|
|
164
150
|
}
|
|
@@ -176,7 +162,6 @@ interface DeploySurfaceContext {
|
|
|
176
162
|
readonly written: string[]
|
|
177
163
|
readonly unchanged: string[]
|
|
178
164
|
readonly conflicts: HookConflict[]
|
|
179
|
-
readonly lockMigrated: string[]
|
|
180
165
|
readonly restored: RestoredHookReport[]
|
|
181
166
|
readonly dryRun: boolean
|
|
182
167
|
}
|
|
@@ -212,38 +197,24 @@ function deploySurface(surface: HookSurface, ctx: DeploySurfaceContext): void {
|
|
|
212
197
|
// Ownership is content-addressed (json-merge.ts's own header, second
|
|
213
198
|
// independent review 2026-09-29): `recordedEntries` is THIS package's own
|
|
214
199
|
// prior write, read straight from the lock as hash+command pairs, never
|
|
215
|
-
// derived from command text alone.
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
// "command text is the only proof we have" shape).
|
|
200
|
+
// derived from command text alone. `readLock` (lock.ts) has already
|
|
201
|
+
// refused any entry without `ownedEntries` (Tarun, 2026-10-01: the legacy
|
|
202
|
+
// `ownedCommands`-only shape is no longer migrated). The command-anywhere
|
|
203
|
+
// channel below is fed ONLY by `legacyTakeover.ownedByEvent` — the
|
|
204
|
+
// pre-agent-hooks engine's own hash-verified takeover signal, a different
|
|
205
|
+
// legacy source that is deliberately kept.
|
|
222
206
|
const sameFormatPrev = prevEntry !== undefined && prevEntry.format === surface.format ? prevEntry : undefined
|
|
223
|
-
const isLegacyShapedLock = sameFormatPrev !== undefined && sameFormatPrev.ownedEntries === undefined
|
|
224
|
-
// Independent review, 2026-09-30, finding 7: this transitional deploy
|
|
225
|
-
// rewrites the LOCK from the legacy (`ownedCommands`-only) shape to the
|
|
226
|
-
// content-addressed one — report it, since the deployed JSON file can
|
|
227
|
-
// stay byte-identical while that rewrite happens underneath it.
|
|
228
|
-
if (isLegacyShapedLock) ctx.lockMigrated.push(surface.file)
|
|
229
207
|
const recordedEntries = sameFormatPrev?.ownedEntries ?? {}
|
|
230
|
-
const ownCommandsLegacyFallback = isLegacyShapedLock ? sameFormatPrev.ownedCommands : {}
|
|
231
208
|
const existingRaw = readExistingJson(targetAbs)
|
|
232
209
|
const legacyTakeover = legacyTakeoverForJsonHooksSurface(existingRaw, ctx.legacyDoc, surface.file)
|
|
233
210
|
if (legacyTakeover.matched) ctx.takeover.any = true
|
|
234
|
-
const legacyCommandsAnywhere =
|
|
211
|
+
const legacyCommandsAnywhere = legacyTakeover.ownedByEvent
|
|
235
212
|
|
|
236
213
|
if (surface.format === 'cursor-hooks-v1') {
|
|
237
214
|
const desired = renderCursorEntries(ctx.hooksDoc, surface)
|
|
238
215
|
const { fileContent, ownedCommands, ownedEntries, changed, restored, ambiguousConflicts } = mergeCursorHooksFile(existingRaw, desired, recordedEntries, legacyCommandsAnywhere)
|
|
239
216
|
writeJsonIfChanged(targetAbs, fileContent, changed, ctx.dryRun)
|
|
240
|
-
|
|
241
|
-
// migration rewrites the LOCK for real even when this surface's own
|
|
242
|
-
// deployed content stays byte-identical — count that as "written",
|
|
243
|
-
// not "unchanged", so a caller reading these two arrays (which is
|
|
244
|
-
// exactly what "up to date (no changes)" and "written: N" do) never
|
|
245
|
-
// reports a pure no-op when something real did change on disk.
|
|
246
|
-
;(changed || isLegacyShapedLock ? ctx.written : ctx.unchanged).push(surface.file)
|
|
217
|
+
;(changed ? ctx.written : ctx.unchanged).push(surface.file)
|
|
247
218
|
ctx.newEntries[surface.file] = { format: 'cursor-hooks-v1', ownedCommands, ownedEntries }
|
|
248
219
|
for (const hook of restored) ctx.restored.push(makeRestoredReport(surface.file, hook))
|
|
249
220
|
for (const conflict of ambiguousConflicts) ctx.conflicts.push({ file: surface.file, reason: ambiguousConflictReason(conflict) })
|
|
@@ -254,7 +225,7 @@ function deploySurface(surface: HookSurface, ctx: DeploySurfaceContext): void {
|
|
|
254
225
|
const desired = renderJsonHooksGroups(ctx.hooksDoc, surface)
|
|
255
226
|
const { fileContent, ownedCommands, ownedEntries, changed, restored, ambiguousConflicts } = mergeJsonHooksFile(existingRaw, desired, recordedEntries, legacyCommandsAnywhere)
|
|
256
227
|
writeJsonIfChanged(targetAbs, fileContent, changed, ctx.dryRun)
|
|
257
|
-
;(changed
|
|
228
|
+
;(changed ? ctx.written : ctx.unchanged).push(surface.file)
|
|
258
229
|
ctx.newEntries[surface.file] = { format: surface.format, ownedCommands, ownedEntries }
|
|
259
230
|
for (const hook of restored) ctx.restored.push(makeRestoredReport(surface.file, hook))
|
|
260
231
|
for (const conflict of ambiguousConflicts) ctx.conflicts.push({ file: surface.file, reason: ambiguousConflictReason(conflict) })
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import { renderCursorEntries, renderJsonHooksGroups } from './render.ts'
|
|
30
30
|
import { type CanonicalHooksDoc, loadHooksSource } from './source.ts'
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
interface DoctorIssue {
|
|
33
33
|
readonly severity: 'error' | 'info'
|
|
34
34
|
readonly path: string
|
|
35
35
|
readonly reason: string
|
|
@@ -44,7 +44,7 @@ function toResult(issues: readonly DoctorIssue[]): DoctorResult {
|
|
|
44
44
|
return { ok: issues.every((issue) => issue.severity !== 'error'), issues }
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
|
|
49
49
|
export interface DoctorDeploymentOptions {
|
|
50
50
|
readonly assetsDir: string
|
|
@@ -71,13 +71,10 @@ function doctorJsonSurface(surface: HookSurface, targetRepo: string, hooksDoc: C
|
|
|
71
71
|
const targetAbs = join(targetRepo, surface.file)
|
|
72
72
|
const exists = existsSync(targetAbs)
|
|
73
73
|
const lockEntry = lock.entries[surface.file]?.format === surface.format ? (lock.entries[surface.file] as JsonHooksLockEntry) : undefined
|
|
74
|
-
//
|
|
75
|
-
// (
|
|
76
|
-
//
|
|
77
|
-
// instead -- otherwise doctor would report drift for every currently-
|
|
78
|
-
// enrolled repo's untouched content that deploy itself recognizes fine.
|
|
74
|
+
// `readLock` has already refused any entry without `ownedEntries`
|
|
75
|
+
// (Tarun, 2026-10-01: the legacy `ownedCommands`-only shape is no longer
|
|
76
|
+
// migrated), so ownership here is always the content-addressed record.
|
|
79
77
|
const recordedEntries = lockEntry?.ownedEntries ?? {}
|
|
80
|
-
const legacyCommandsAnywhere = lockEntry !== undefined && lockEntry.ownedEntries === undefined ? lockEntry.ownedCommands : {}
|
|
81
78
|
|
|
82
79
|
let parseFailed = false
|
|
83
80
|
if (exists) {
|
|
@@ -92,8 +89,8 @@ function doctorJsonSurface(surface: HookSurface, targetRepo: string, hooksDoc: C
|
|
|
92
89
|
const existingRaw = readExistingJson(targetAbs)
|
|
93
90
|
const merged =
|
|
94
91
|
surface.format === 'cursor-hooks-v1'
|
|
95
|
-
? mergeCursorHooksFile(existingRaw, renderCursorEntries(hooksDoc, surface), recordedEntries
|
|
96
|
-
: mergeJsonHooksFile(existingRaw, renderJsonHooksGroups(hooksDoc, surface), recordedEntries
|
|
92
|
+
? mergeCursorHooksFile(existingRaw, renderCursorEntries(hooksDoc, surface), recordedEntries)
|
|
93
|
+
: mergeJsonHooksFile(existingRaw, renderJsonHooksGroups(hooksDoc, surface), recordedEntries)
|
|
97
94
|
|
|
98
95
|
if (!exists) {
|
|
99
96
|
return [{ severity: 'error', path: surface.file, reason: 'expected hook wiring has not been deployed' }]
|
|
@@ -144,7 +141,7 @@ function doctorJsonSurface(surface: HookSurface, targetRepo: string, hooksDoc: C
|
|
|
144
141
|
severity: 'error' as const,
|
|
145
142
|
path: `${surface.file}#${event}`,
|
|
146
143
|
reason:
|
|
147
|
-
recordedEntries[event] !== undefined
|
|
144
|
+
recordedEntries[event] !== undefined
|
|
148
145
|
? 'deploy-written hook entries were modified since deploy, or assets/hooks.json changed since; run deploy to update'
|
|
149
146
|
: 'expected hook wiring for this event has not been deployed',
|
|
150
147
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
export { deployHooks,
|
|
2
|
-
export { doctorDeployment,
|
|
3
|
-
export { formatHookLine, listHooks,
|
|
4
|
-
|
|
1
|
+
export { deployHooks, type DeployHooksResult, } from './deploy.ts'
|
|
2
|
+
export { doctorDeployment, type DoctorResult } from './doctor.ts'
|
|
3
|
+
export { formatHookLine, listHooks, } from './list.ts'
|
|
4
|
+
|
|
5
5
|
export {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
12
|
loadProfile,
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
|
|
14
|
+
|
|
15
15
|
} from './profile.ts'
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
|
|
17
|
+
|