@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.12 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/adl +2 -2
- package/bin/git +16 -17
- package/bin/git-ado +25 -24
- package/bin/git-defaults +173 -0
- package/bin/health-check +8 -1
- package/bin/kimi-hooks +1 -1
- package/bin/lib/adl-package.sh +257 -0
- package/bin/lib/fleet-host.sh +8 -5
- package/bin/reconcile +482 -232
- package/bin/reconcile-host +30 -20
- package/bin/setup +20 -17
- package/bin/shell-path-policy +15 -5
- package/bin/sync-and-reconcile +62 -64
- package/bin/validate-manifest +33 -9
- package/package.json +2 -10
- package/packages/agent-hooks/README.md +14 -9
- package/packages/agent-hooks/assets/hooks.json +0 -20
- package/packages/agent-hooks/src/cli/args.ts +1 -1
- package/packages/agent-hooks/src/cli/doctor.ts +6 -58
- package/packages/agent-hooks/src/deploy/deploy.ts +12 -41
- package/packages/agent-hooks/src/deploy/doctor.ts +8 -11
- package/packages/agent-hooks/src/deploy/index.ts +14 -14
- package/packages/agent-hooks/src/deploy/json-merge.ts +7 -8
- package/packages/agent-hooks/src/deploy/legacy-lock.ts +2 -2
- package/packages/agent-hooks/src/deploy/list.ts +1 -1
- package/packages/agent-hooks/src/deploy/lock.ts +31 -12
- package/packages/agent-hooks/src/deploy/profile.ts +3 -4
- package/packages/agent-hooks/src/deploy/source.ts +1 -1
- package/packages/agent-hooks/src/gating/config.ts +12 -24
- package/packages/agent-hooks/src/gating/root.ts +3 -3
- package/packages/agent-hooks/src/hooks/briefing/handler.ts +2 -2
- package/packages/agent-hooks/src/hooks/briefing/index.ts +27 -287
- package/packages/agent-hooks/src/hooks/contract.ts +17 -17
- package/packages/agent-hooks/src/hooks/crg/background.ts +27 -0
- package/packages/agent-hooks/src/hooks/crg/index.ts +7 -6
- package/packages/agent-hooks/src/hooks/log.ts +8 -10
- package/packages/agent-hooks/src/hooks/user-prompt-submit/match.ts +1 -1
- package/packages/agent-hooks/src/hooks/user-prompt-submit/tokenizer.ts +1 -1
- package/packages/agent-hooks/src/hooks/user-prompt-submit/vector.ts +6 -5
- package/packages/agent-hooks/src/hosts/registry.ts +1 -1
- package/packages/agent-hooks/src/log/adl-dir.ts +44 -0
- package/packages/agent-hooks/src/log/writer.ts +16 -2
- package/packages/agent-hooks/src/main.ts +7 -41
- package/packages/agent-hooks/src/pre-tool-use/handler.ts +71 -82
- package/packages/agent-hooks/src/rules/engine.ts +13 -17
- package/packages/agent-hooks/src/rules/impl/adl-build-run-denied.ts +3 -3
- package/packages/agent-hooks/src/rules/impl/adl-git-credential-bypass.ts +12 -14
- package/packages/agent-hooks/src/rules/impl/adl-git-identity.ts +28 -28
- package/packages/agent-hooks/src/rules/impl/adl-git-push-policy.ts +8 -9
- package/packages/agent-hooks/src/rules/impl/adl-human-azdo-bypass.ts +56 -59
- package/packages/agent-hooks/src/rules/impl/adl-identity.ts +16 -23
- package/packages/agent-hooks/src/rules/impl/adl-mcp-cli.ts +19 -16
- package/packages/agent-hooks/src/rules/impl/adl-pr-complete-pending.ts +2 -2
- package/packages/agent-hooks/src/rules/impl/adl-pr-review-role.ts +9 -12
- package/packages/agent-hooks/src/rules/impl/adl-pr-role.ts +5 -7
- package/packages/agent-hooks/src/rules/impl/adl-run-required.ts +411 -0
- package/packages/agent-hooks/src/rules/impl/adl-token-minting-role.ts +4 -5
- package/packages/agent-hooks/src/rules/impl/adl-workitem-role.ts +6 -7
- package/packages/agent-hooks/src/rules/impl/agent-tamper-protection.ts +77 -70
- package/packages/agent-hooks/src/rules/impl/deny-allowlist.ts +131 -0
- package/packages/agent-hooks/src/rules/impl/git-helpers.ts +21 -23
- package/packages/agent-hooks/src/rules/impl/git-worktree.ts +14 -28
- package/packages/agent-hooks/src/rules/impl/mcp-tool.ts +3 -3
- package/packages/agent-hooks/src/rules/impl/messages.ts +1 -1
- package/packages/agent-hooks/src/rules/impl/pr-completion.ts +1 -1
- package/packages/agent-hooks/src/rules/impl/tool-azure-devops.ts +35 -46
- package/packages/agent-hooks/src/rules/impl/tool-find.ts +34 -7
- package/packages/agent-hooks/src/rules/impl/tool-grep.ts +33 -12
- package/packages/agent-hooks/src/rules/impl/tool-native-search.ts +52 -9
- package/packages/agent-hooks/src/rules/ports.ts +5 -7
- package/packages/agent-hooks/src/rules/registry.ts +4 -6
- package/packages/agent-hooks/src/rules/shell/git-identity.ts +86 -101
- package/packages/agent-hooks/src/rules/shell/git-internals.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/invocation.ts +24 -118
- package/packages/agent-hooks/src/rules/shell/piped-script.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/prefixes.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/protected-carrier-writes.ts +11 -10
- package/packages/agent-hooks/src/rules/shell/protected-carriers.ts +26 -26
- package/packages/agent-hooks/src/rules/shell/substitution.ts +1 -1
- package/packages/agent-hooks/src/rules/shell/xargs.ts +2 -2
- package/packages/agent-hooks/src/rules/spec.ts +2 -2
- package/packages/agent-settings/README.md +287 -0
- package/packages/agent-settings/assets/GLOBAL-AGENTS.md +14 -16
- package/packages/agent-settings/assets/agents/architect.toml +2 -0
- package/packages/agent-settings/assets/agents/code-reviewer.toml +2 -0
- package/packages/agent-settings/assets/agents/executor.toml +2 -0
- package/packages/agent-settings/assets/agents/explore.toml +2 -0
- package/packages/agent-settings/assets/agents/planner.toml +2 -0
- package/packages/agent-settings/assets/mcp.json +0 -4
- package/packages/agent-settings/deploy-profile.json +139 -0
- package/packages/agent-settings/deploy-profile.schema.json +147 -0
- package/packages/agent-settings/managed/README.md +29 -30
- package/packages/agent-settings/managed/codex-requirements.toml +9 -9
- package/packages/agent-settings/package.json +20 -0
- package/packages/agent-settings/src/deploy/agent-render.ts +2 -2
- package/packages/agent-settings/src/deploy/agent-toml.ts +1 -1
- package/packages/agent-settings/src/deploy/agents-deploy.ts +17 -3
- package/packages/agent-settings/src/deploy/doctor.ts +3 -83
- package/packages/agent-settings/src/deploy/index.ts +6 -33
- package/packages/agent-settings/src/deploy/legacy-lock.ts +6 -6
- package/packages/agent-settings/src/deploy/list.ts +5 -19
- package/packages/agent-settings/src/deploy/lock.ts +8 -18
- package/packages/agent-settings/src/deploy/mcp-deploy.ts +10 -5
- package/packages/agent-settings/src/deploy/mcp-merge.ts +22 -3
- package/packages/agent-settings/src/deploy/mcp-source.ts +1 -1
- package/packages/agent-settings/src/deploy/profile.ts +11 -35
- package/packages/agent-settings/src/deploy/retire-lean-ctx.ts +184 -0
- package/packages/agent-settings/src/deploy/settings.ts +17 -22
- package/packages/agent-settings/src/global-surface-sweep.ts +0 -2
- package/packages/agent-settings/src/kimi-hooks.ts +339 -192
- package/packages/agent-settings/src/opencode-hooks.ts +1 -1
- package/packages/agent-settings/tsconfig.json +23 -0
- package/packages/agent-skills/assets/agent-search-tool-audit/SKILL.md +120 -0
- package/packages/agent-skills/assets/agent-search-tool-audit/scripts/audit.sh +276 -0
- package/packages/agent-skills/assets/debug-issue/SKILL.md +8 -7
- package/packages/agent-skills/assets/explore-codebase/SKILL.md +13 -13
- package/packages/agent-skills/assets/refactor-safely/SKILL.md +12 -11
- package/packages/agent-skills/assets/review-changes/SKILL.md +7 -7
- package/packages/agent-skills/assets/testing/references/e2e.md +37 -0
- package/packages/agent-skills/assets/testing/references/integration.md +37 -0
- package/packages/agent-skills/assets/testing/references/unit.md +32 -0
- package/packages/agent-skills/dist/deploy.d.ts +2 -0
- package/packages/agent-skills/dist/deploy.d.ts.map +1 -1
- package/packages/agent-skills/dist/deploy.js +27 -1
- package/packages/agent-skills/dist/deploy.js.map +1 -1
- package/packages/agent-skills/dist/doctor.d.ts +0 -2
- package/packages/agent-skills/dist/doctor.d.ts.map +1 -1
- package/packages/agent-skills/dist/doctor.js +1 -1
- package/packages/agent-skills/dist/doctor.js.map +1 -1
- package/packages/agent-skills/dist/fs-utils.d.ts +0 -1
- package/packages/agent-skills/dist/fs-utils.d.ts.map +1 -1
- package/packages/agent-skills/dist/fs-utils.js +1 -1
- package/packages/agent-skills/dist/fs-utils.js.map +1 -1
- package/packages/agent-skills/src/deploy.ts +29 -1
- package/packages/agent-skills/src/doctor.ts +1 -1
- package/packages/agent-skills/src/fs-utils.ts +1 -1
- package/packages/azdo/README.md +10 -9
- package/packages/azdo/package.json +1 -3
- package/packages/azdo/scripts/probe-ado-rules.ts +311 -0
- package/packages/azdo/src/azdo-pl.ts +2 -54
- package/packages/azdo/src/azdo-pr-review.ts +4 -4
- package/packages/azdo/src/azdo-repo-doctor.ts +101 -52
- package/packages/azdo/src/azdo-wit.ts +44 -2
- package/packages/azdo/src/lib/agent-identity.ts +12 -14
- package/packages/azdo/src/lib/agent-token.ts +2 -2
- package/packages/azdo/src/lib/client.ts +0 -5
- package/packages/azdo/src/lib/graph-identity.ts +4 -4
- package/packages/azdo/src/workflow-ladder.csv +241 -0
- package/packages/azdo/src/workflow-rules-matrix.csv +85 -0
- package/packages/azdo/src/workflow-rules.ts +194 -0
- package/packages/fleet/manifest.json +35 -11
- package/packages/fleet/manifest.schema.json +62 -10
- package/packages/fleet/src/default-agent-file.ts +3 -3
- package/packages/fleet/src/install-adl-package.ts +73 -15
- package/packages/fleet/src/install-embedding-model.ts +13 -13
- package/packages/fleet/src/managed-settings.ts +7 -7
- package/packages/fleet/src/repo-maintain.ts +91 -55
- package/packages/fleet/src/scratch-reap.ts +5 -5
- package/packages/fleet/src/vscode-settings.ts +5 -5
- package/packages/repo-controls/README.md +141 -43
- package/packages/repo-controls/assets/promote.ts +4 -4
- package/packages/repo-controls/assets/reconcile-guard.sh +10 -46
- package/packages/repo-controls/assets/version-bump.sh +31 -84
- package/packages/repo-controls/bunfig.toml +6 -7
- package/packages/repo-controls/package/adl-compliance/AGENTS.md +5 -6
- package/packages/repo-controls/package/adl-compliance/conftest.py +3 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/__init__.py +4 -16
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/adr_lifecycle/test_check.py +9 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/fixtures/docs/notes.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/closed_set/test_check.py +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/check.py +266 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.drafts/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/.hidden.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/data.csv +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/diagram.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/mock.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs/guide/sub/nested.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/docs.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p1.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p2.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p3.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p4.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-assets/plans/deep/p5.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/build.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/architecture/overview.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/install.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/docs/guide/start.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-clean/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-001-tenancy.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-002-carrier.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/adr-003-cli.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-old.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/decisions/archive/adr-000-older.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-decisions/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-01.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-02.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-03.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-04.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-05.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-06.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-07.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-08.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-09.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-10.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-11.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-12.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-13.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-14.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-15.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/docs/guide/page-16.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-default-cap/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-exempt/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-grew/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/docs/guide/e.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-no-section/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/docs/short/only.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-over-cap/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/held/d.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/docs/shrunk/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-stale/grants.yaml +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/a.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/b.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/docs/guide/c.md +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/fixtures/docs-size-unusable/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/directory_size/test_check.py +345 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/check.py +18 -5
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/english_only/test_check.py +35 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/__init__.py +7 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/check.py +91 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/CLAUDE.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/-leading-hyphen.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/AGENTS.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/double--hyphen.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/getting started.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/nested/page-here.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/trailing-hyphen-.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/ui-contract.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/architecture/user_profile.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/UI-CONTRACT.png +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/assets/diagram.png +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/index.md +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/notes.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/reference.html +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/2026-10-experiment.md +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs/research/UI-CONTRACT.md +6 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/fixtures/docs.md +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/filename/test_check.py +194 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/check.py +14 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/docs-knowledge-indexes.yaml +5 -5
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-legacy/docs/compliance/index.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/fixtures/knowledge-indexes-shipped-register-type/docs/compliance/index.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/indexes/test_check.py +58 -6
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/ledger/test_check.py +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/check.py +64 -17
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/docs-okf-profiles.yaml +60 -9
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-clean/docs/notes.md +17 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-ledger-no-lines/docs/notes.md +13 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs/architecture/demo.md +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-clean/docs-okf-profiles.yaml +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/no-type.md +9 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-experiment.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs/research/typed-research.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-untyped/docs-okf-profiles.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs/architecture/bad-status.md +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-profile-violation/docs-okf-profiles.yaml +0 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/experiment-ok.md +15 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-key.md +15 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/extra-keys.md +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-created.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-description.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-last-update.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-sources.md +10 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-status.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/missing-title.md +11 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/optional-keys.md +16 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research/docs/research/research-ok.md +14 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/created-date.md +21 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/architecture/research-shaped.md +19 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/fixtures/okf-research-neighbours/docs/operations/runbook.md +26 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/okf_profile/test_check.py +228 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/register.py +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/docs/semantics/test_check.py +11 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/__init__.py +5 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/check.py +160 -44
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-clean/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/a.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/frontend/packages/desktop/src/b.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-empty-register/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-excluded/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-missing-tree/grants.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/a.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/b.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/frontend/packages/desktop/src/c.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-no-ceilings/grants.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-stale-entry/grants.yaml +5 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unbaselined/grants.yaml +0 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/frontend/packages/desktop/src/renderer/solo/item.ts +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/fixtures/directory-ratchet-unusable-register/grants.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/register.py +127 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/directory_ratchet/test_check.py +265 -29
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/check.py +75 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/markdown_trees/test_check.py +194 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/check.py +56 -10
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/open_work_cap/test_check.py +258 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/check.py +40 -12
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/placement/test_check.py +108 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plan_metadata.py +9 -4
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/check.py +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/fixtures/plans-layout-clean/plans/features/az347-test-coverage/items/az351-restore-entrypoint.md +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/plans_layout/test_check.py +3 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/references/check.py +2 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/check.py +23 -6
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_closed_set/test_check.py +76 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/check.py +58 -17
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/root_markdown_allowlist/test_check.py +161 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/check.py +35 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/layout/scripts_size_depth/test_check.py +108 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/check.py +281 -61
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/absolute-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/backslash-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/baseline-is-a-list.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/boolean-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/dot-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/duplicate-path.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-file.yaml +0 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/empty-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/float-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/negative-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-over-limit-baseline.yaml +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/no-schema-version.yaml +1 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/non-string-path.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/not-yaml.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/null-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/parent-segment.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/string-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/top-level-is-a-list.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/trailing-slash.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/unknown-key.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/wrong-schema-version.yaml +2 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/malformed/zero-size.yaml +3 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/fixtures/valid.yaml +4 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/lfs/integrity/test_check.py +758 -45
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/check.py +4 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/ignored_paths/test_check.py +2 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/cargo_lock.py +490 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/check.py +368 -55
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_check.py +4 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_declared_paths.py +523 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/checks/repository/lockfile_integrity/test_stale_lock.py +1179 -0
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/cli.py +122 -3
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/check.py +33 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/constants.py +0 -11
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/core/context.py +16 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/config.py +1 -2
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/docs_shape.py +12 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.alt.yaml +133 -147
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/gate-registry.yaml +133 -147
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/registry.py +1 -1
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/policy/root_shape.py +52 -10
- package/packages/repo-controls/package/adl-compliance/src/adl_compliance/runner.py +23 -4
- package/packages/repo-controls/package.json +2 -9
- package/packages/repo-controls/scripts/hooks/post-merge +13 -0
- package/packages/repo-controls/scripts/hooks/pre-push +3 -3
- package/packages/repo-controls/src/azdo-push.ts +64 -36
- package/packages/repo-controls/src/azure-devops-governance.ts +7 -9
- package/packages/repo-controls/src/azure-devops-remote.ts +1 -1
- package/packages/repo-controls/src/cli.ts +29 -8
- package/packages/repo-controls/src/compliance-config.ts +410 -2
- package/packages/repo-controls/src/config.ts +133 -60
- package/packages/repo-controls/src/constants.ts +13 -27
- package/packages/repo-controls/src/coverage-ratchet.ts +4 -4
- package/packages/repo-controls/src/doctor.ts +46 -19
- package/packages/repo-controls/src/gitignore-block.ts +5 -29
- package/packages/repo-controls/src/hook-log.ts +1 -2
- package/packages/repo-controls/src/hook.ts +201 -45
- package/packages/repo-controls/src/install.ts +14 -8
- package/packages/repo-controls/src/integrity.ts +3 -3
- package/packages/repo-controls/src/lfs.ts +111 -0
- package/packages/repo-controls/src/promote.ts +8 -8
- package/packages/repo-controls/src/runtime.ts +9 -1
- package/packages/repo-controls/src/workflows-drift.ts +4 -5
- package/packages/repo-controls/src/worktree-guard.ts +3 -3
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""DOC-011 — every Markdown page under docs/ has a lower-kebab stem.
|
|
2
|
+
|
|
3
|
+
The rule being tested, restated from the gate's own docstring:
|
|
4
|
+
|
|
5
|
+
for every `.md` file in scope, the filename stem must full-match
|
|
6
|
+
`^[a-z0-9]+(-[a-z0-9]+)*$`, with exact-name exemptions for the standing
|
|
7
|
+
tree guides `AGENTS.md` and `CLAUDE.md`. Non-`.md` files are not graded
|
|
8
|
+
at all -- docs trees legitimately hold .png/.html/.csv/.yaml assets, and
|
|
9
|
+
the rule is about page names, not asset names.
|
|
10
|
+
|
|
11
|
+
Ported in the same shape `docs/closed_set/test_check.py` uses: ONE corpus,
|
|
12
|
+
and the clean case is the same tree with the violating entries left out of
|
|
13
|
+
the given set -- exactly what a commit touching nothing violating looks like
|
|
14
|
+
in production.
|
|
15
|
+
|
|
16
|
+
Every test calls `DocsFilename` directly rather than through `runner.run`/
|
|
17
|
+
`decide`, bypassing row-scope narrowing and registry lookup; the row is still
|
|
18
|
+
loaded from the real registry because it is the Context's `row`. The row's
|
|
19
|
+
scope excludes (`proposals/`, `compliance/`, guides, `index.md`) are the
|
|
20
|
+
runner's business and are proven by the end-to-end CLI runs recorded in
|
|
21
|
+
`docs/operations/repo-controls-copy-notes.md`, not replayed here -- this
|
|
22
|
+
corpus deliberately carries no fixture for them.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from helpers import corpus, corpus_files
|
|
28
|
+
|
|
29
|
+
from adl_compliance.checks.docs.filename import DocsFilename
|
|
30
|
+
from adl_compliance.core.context import Context, FileSet
|
|
31
|
+
from adl_compliance.core.finding import Finding
|
|
32
|
+
from adl_compliance.policy.registry import load
|
|
33
|
+
|
|
34
|
+
CORPUS = corpus("docs", "filename")
|
|
35
|
+
ROW = load().by_id("DOC-011")
|
|
36
|
+
|
|
37
|
+
# Every violation shape the rule names, kept out of the clean set.
|
|
38
|
+
VIOLATING = (
|
|
39
|
+
"docs/research/UI-CONTRACT.md",
|
|
40
|
+
"docs/architecture/user_profile.md",
|
|
41
|
+
"docs/architecture/getting started.md",
|
|
42
|
+
"docs/architecture/-leading-hyphen.md",
|
|
43
|
+
"docs/architecture/trailing-hyphen-.md",
|
|
44
|
+
"docs/architecture/double--hyphen.md",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# In the corpus, never findings: exempt guide names (root and nested),
|
|
48
|
+
# the standing catalog/ledger names, non-Markdown assets (including one
|
|
49
|
+
# with a deliberately violating stem), and a path that merely lookalikes
|
|
50
|
+
# the docs/ prefix.
|
|
51
|
+
NOT_FINDINGS = (
|
|
52
|
+
"docs.md",
|
|
53
|
+
"docs/AGENTS.md",
|
|
54
|
+
"docs/CLAUDE.md",
|
|
55
|
+
"docs/architecture/AGENTS.md",
|
|
56
|
+
"docs/index.md",
|
|
57
|
+
"docs/notes.md",
|
|
58
|
+
"docs/reference.html",
|
|
59
|
+
"docs/assets/diagram.png",
|
|
60
|
+
"docs/assets/UI-CONTRACT.png",
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
CONFORMING = (
|
|
64
|
+
"docs/architecture/ui-contract.md",
|
|
65
|
+
"docs/architecture/nested/page-here.md",
|
|
66
|
+
"docs/research/2026-10-experiment.md",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def clean_set() -> tuple[str, ...]:
|
|
71
|
+
return tuple(p for p in corpus_files(CORPUS) if p not in VIOLATING)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def findings_for(given: tuple[str, ...]) -> tuple[Finding, ...]:
|
|
75
|
+
ctx = Context(root=CORPUS, row=ROW, inputs={"docs_root": CORPUS / "docs"})
|
|
76
|
+
return tuple(DocsFilename().run(ctx, FileSet(paths=given)))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def messages_for(given: tuple[str, ...]) -> tuple[str, ...]:
|
|
80
|
+
return tuple(f.render() for f in findings_for(given))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_the_premise_holds() -> None:
|
|
84
|
+
"""Asserted, not assumed: a mistyped path would leave the clean set
|
|
85
|
+
identical to the full corpus and every case below would agree for
|
|
86
|
+
nothing."""
|
|
87
|
+
all_files = corpus_files(CORPUS)
|
|
88
|
+
for path in (*VIOLATING, *NOT_FINDINGS, *CONFORMING):
|
|
89
|
+
assert path in all_files, path
|
|
90
|
+
assert len(clean_set()) == len(all_files) - len(VIOLATING)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_conforming_stems_are_silent() -> None:
|
|
94
|
+
findings = findings_for(clean_set())
|
|
95
|
+
assert findings == (), tuple(f.render() for f in findings)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_an_uppercase_stem_is_reported() -> None:
|
|
99
|
+
"""The real consumer case: the Enact tree carries
|
|
100
|
+
docs/architecture/frontend/UI-CONTRACT.md; the gate must name it.
|
|
101
|
+
(The fixture sits under research/ because this checkout's filesystem
|
|
102
|
+
is case-insensitive and cannot hold it beside the lowercase
|
|
103
|
+
ui-contract.md in the same directory.)"""
|
|
104
|
+
messages = messages_for(corpus_files(CORPUS))
|
|
105
|
+
assert any(
|
|
106
|
+
"docs/research/UI-CONTRACT.md" in m and "is not lower-kebab" in m
|
|
107
|
+
for m in messages
|
|
108
|
+
), messages
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_an_underscored_stem_is_reported() -> None:
|
|
112
|
+
messages = messages_for(corpus_files(CORPUS))
|
|
113
|
+
assert any("user_profile.md" in m for m in messages), messages
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def test_a_spaced_stem_is_reported() -> None:
|
|
117
|
+
messages = messages_for(corpus_files(CORPUS))
|
|
118
|
+
assert any("getting started.md" in m for m in messages), messages
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def test_a_leading_hyphen_is_reported() -> None:
|
|
122
|
+
"""A leading hyphen makes the first run empty; full-match fails."""
|
|
123
|
+
messages = messages_for(corpus_files(CORPUS))
|
|
124
|
+
assert any("-leading-hyphen.md" in m for m in messages), messages
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_a_trailing_hyphen_is_reported() -> None:
|
|
128
|
+
"""A trailing hyphen makes the last run empty; full-match fails."""
|
|
129
|
+
messages = messages_for(corpus_files(CORPUS))
|
|
130
|
+
assert any("trailing-hyphen-.md" in m for m in messages), messages
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_a_double_hyphen_is_reported() -> None:
|
|
134
|
+
"""A double hyphen leaves an empty segment between the dashes; the
|
|
135
|
+
`(?:-[a-z0-9]+)*` repeat cannot cross it."""
|
|
136
|
+
messages = messages_for(corpus_files(CORPUS))
|
|
137
|
+
assert any("double--hyphen.md" in m for m in messages), messages
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def test_guide_names_are_exempt_at_any_depth() -> None:
|
|
141
|
+
"""AGENTS.md and CLAUDE.md are the standing tree-guide names the other
|
|
142
|
+
docs gates exclude too; the exemption is by exact name, so it holds in
|
|
143
|
+
nested directories as well as at the docs root."""
|
|
144
|
+
text = "\n".join(messages_for(corpus_files(CORPUS)))
|
|
145
|
+
assert "docs/AGENTS.md" not in text
|
|
146
|
+
assert "docs/CLAUDE.md" not in text
|
|
147
|
+
assert "docs/architecture/AGENTS.md" not in text
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_the_standing_page_names_are_silent() -> None:
|
|
151
|
+
"""`index.md` (the standing catalog name, also scope-excluded) and
|
|
152
|
+
`notes.md` (the task ledger) carry conforming stems; both stay silent."""
|
|
153
|
+
text = "\n".join(messages_for(corpus_files(CORPUS)))
|
|
154
|
+
assert "docs/index.md" not in text
|
|
155
|
+
assert "docs/notes.md" not in text
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def test_non_markdown_files_are_not_graded() -> None:
|
|
159
|
+
"""The rule grades `.md` pages only. `docs/assets/UI-CONTRACT.png` pins
|
|
160
|
+
the sharp edge: a violating STEM in a non-Markdown file is not a
|
|
161
|
+
finding, or every diagram beside a UI contract page would fail."""
|
|
162
|
+
text = "\n".join(messages_for(corpus_files(CORPUS)))
|
|
163
|
+
assert "docs/reference.html" not in text
|
|
164
|
+
assert "docs/assets/diagram.png" not in text
|
|
165
|
+
assert "docs/assets/UI-CONTRACT.png" not in text
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def test_every_finding_is_tagged_doc_011() -> None:
|
|
169
|
+
findings = findings_for(corpus_files(CORPUS))
|
|
170
|
+
assert findings
|
|
171
|
+
assert all(f.rule == "DOC-011" for f in findings), tuple(
|
|
172
|
+
f.render() for f in findings
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def test_a_lookalike_prefix_is_ignored() -> None:
|
|
177
|
+
"""`docs.md` is a root-level file whose name is the tree name plus the
|
|
178
|
+
extension; the gate's prefix carries a trailing slash, so it is outside
|
|
179
|
+
docs/ entirely."""
|
|
180
|
+
assert "docs.md" in corpus_files(CORPUS)
|
|
181
|
+
text = "\n".join(messages_for(corpus_files(CORPUS)))
|
|
182
|
+
assert "docs.md" not in text
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def test_an_empty_set_grades_nothing() -> None:
|
|
186
|
+
"""Every violating stem is still on disk. A check that grades only what
|
|
187
|
+
it is handed must report none of them against an empty given set."""
|
|
188
|
+
findings = findings_for(())
|
|
189
|
+
assert findings == ()
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def test_a_path_outside_docs_is_ignored() -> None:
|
|
193
|
+
findings = findings_for(("documentation/UI-CONTRACT.md",))
|
|
194
|
+
assert findings == ()
|
|
@@ -17,8 +17,20 @@ THIS repository and what each one governs, and this gate means nothing without
|
|
|
17
17
|
it — so it ships as a `resources` entry beside this check (co-located with the
|
|
18
18
|
gate, per `compliance_new/AGENTS.md`'s "a named input lives in the gate's own
|
|
19
19
|
folder"), not fetched from the consumer's tree by path. `docs-knowledge-indexes
|
|
20
|
-
.yaml`
|
|
21
|
-
`compliance_new/checks/docs/indexes/docs-knowledge-indexes.yaml` (2026-08-29)
|
|
20
|
+
.yaml` was transcribed byte-for-byte from
|
|
21
|
+
`compliance_new/checks/docs/indexes/docs-knowledge-indexes.yaml` (2026-08-29),
|
|
22
|
+
with one later amendment recorded here rather than left as drift: on
|
|
23
|
+
2026-10-02 the docs-compliance and docs-product entries' `required_frontmatter`
|
|
24
|
+
flipped `document_type` → `type`. The estate's frontmatter vocabulary is the
|
|
25
|
+
OKF profile's — `docs-okf-profiles.yaml`'s `common_required` is
|
|
26
|
+
`[type, title, description, status]` and no profile knows a `document_type`
|
|
27
|
+
key — and twelve of this register's sixteen catalogues already required
|
|
28
|
+
`type` (the other two require no type-family key); these two were the last
|
|
29
|
+
outliers, and an index satisfying every other
|
|
30
|
+
catalogue's vocabulary failed them for a key nothing else in the estate
|
|
31
|
+
writes. The flip is pinned by the `knowledge-indexes-shipped-register-
|
|
32
|
+
{type,legacy}/` corpora in `test_check.py`, which point the `registry` input
|
|
33
|
+
at this shipped file instead of a cut-down fixture copy.
|
|
22
34
|
|
|
23
35
|
Entirely `graded`: every rule here reads the GIVEN SET, even the ones that look
|
|
24
36
|
at the register alone — an entry the given set never touches is not audited at
|
|
@@ -138,7 +138,7 @@ indexes:
|
|
|
138
138
|
include_extensions: [.md]
|
|
139
139
|
exclude_names: [index.md, AGENTS.md, CLAUDE.md]
|
|
140
140
|
exclude_prefixes: [product/]
|
|
141
|
-
required_frontmatter: [title, description,
|
|
141
|
+
required_frontmatter: [type, title, description, status, last_update, sources, related]
|
|
142
142
|
required_sections: [Reading order]
|
|
143
143
|
display_status: true
|
|
144
144
|
status_map: {draft: draft, stable: stable}
|
|
@@ -150,7 +150,7 @@ indexes:
|
|
|
150
150
|
recursive: true
|
|
151
151
|
include_extensions: [.md]
|
|
152
152
|
exclude_names: [index.md, AGENTS.md, CLAUDE.md]
|
|
153
|
-
required_frontmatter: [title, description,
|
|
153
|
+
required_frontmatter: [title, description, status, last_update, sources, created]
|
|
154
154
|
required_sections: []
|
|
155
155
|
display_status: true
|
|
156
156
|
status_map: {draft: draft, canonical: canonical, stable: stable}
|
|
@@ -162,7 +162,7 @@ indexes:
|
|
|
162
162
|
recursive: true
|
|
163
163
|
include_extensions: [.md, .yaml, .yml]
|
|
164
164
|
exclude_names: [index.md, AGENTS.md, CLAUDE.md]
|
|
165
|
-
required_frontmatter: [title, description,
|
|
165
|
+
required_frontmatter: [title, description, type, status, last_update, reason]
|
|
166
166
|
required_sections: []
|
|
167
167
|
display_status: true
|
|
168
168
|
status_map: {canonical: stable, draft: draft, '-': metadata}
|
|
@@ -174,7 +174,7 @@ indexes:
|
|
|
174
174
|
recursive: false
|
|
175
175
|
include_extensions: [.md]
|
|
176
176
|
exclude_names: [index.md, AGENTS.md, CLAUDE.md]
|
|
177
|
-
required_frontmatter: [title, description,
|
|
177
|
+
required_frontmatter: [type, title, description, status, last_update, sources, related]
|
|
178
178
|
required_sections: []
|
|
179
179
|
display_status: true
|
|
180
180
|
status_map: {draft: draft, stable: stable}
|
|
@@ -186,7 +186,7 @@ indexes:
|
|
|
186
186
|
recursive: true
|
|
187
187
|
include_extensions: [.md]
|
|
188
188
|
exclude_names: [index.md, AGENTS.md, CLAUDE.md]
|
|
189
|
-
required_frontmatter: [title, description,
|
|
189
|
+
required_frontmatter: [title, description, type, status, last_update, reason]
|
|
190
190
|
required_sections: [Normative, "Input, not authority", The schema itself]
|
|
191
191
|
display_status: false
|
|
192
192
|
inventory: exempt
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Compliance
|
|
3
|
+
description: Fixture catalogue for the shipped-register frontmatter tests.
|
|
4
|
+
document_type: compliance
|
|
5
|
+
status: stable
|
|
6
|
+
last_update: 2026-10-02
|
|
7
|
+
reason: fixture for the shipped-register vocabulary tests, not a graded page
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Compliance
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Compliance
|
|
3
|
+
description: Fixture catalogue for the shipped-register frontmatter tests.
|
|
4
|
+
type: compliance
|
|
5
|
+
status: stable
|
|
6
|
+
last_update: 2026-10-02
|
|
7
|
+
reason: fixture for the shipped-register vocabulary tests, not a graded page
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Compliance
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
"""DOC-008 — ported from `compliance_new/checks/docs/indexes/test.sh`.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Five committed corpora. Three share the shell fixtures' scenario names and
|
|
4
|
+
file content under
|
|
5
5
|
`compliance_new/checks/docs/indexes/fixtures/knowledge-indexes-{clean,
|
|
6
6
|
missing-entry,duplicate}/` — only the registry input is flattened to the
|
|
7
7
|
fixture root rather than nested under the shell tree's own `compliance/
|
|
8
8
|
checks/docs/indexes/` path (see `knowledge-indexes-clean/
|
|
9
|
-
docs-knowledge-indexes.yaml`'s own comment).
|
|
9
|
+
docs-knowledge-indexes.yaml`'s own comment). The remaining two
|
|
10
|
+
(`knowledge-indexes-shipped-register-{type,legacy}/`) hold one
|
|
11
|
+
`docs/compliance/index.md` each and point the `registry` input at the GATE'S
|
|
12
|
+
OWN shipped `docs-knowledge-indexes.yaml` rather than a cut-down fixture
|
|
13
|
+
registry: the first three corpora grade the check's mechanics, but only the
|
|
14
|
+
shipped register's own vocabulary can say whether `type` is required — the
|
|
15
|
+
flip of 2026-10-02 (`document_type` → `type` in the docs-compliance and
|
|
16
|
+
docs-product entries, recorded in `check.py`'s module docstring) is pinned
|
|
17
|
+
by these two.
|
|
10
18
|
|
|
11
19
|
This wave's checks are wired into `checks/__init__.py` in a later, single pass
|
|
12
20
|
(see the folder's own docstring / the dispatch instructions), so `Indexes` is
|
|
@@ -44,16 +52,34 @@ FIXTURES = corpus("docs", "indexes")
|
|
|
44
52
|
CLEAN = FIXTURES / "knowledge-indexes-clean"
|
|
45
53
|
MISSING_ENTRY = FIXTURES / "knowledge-indexes-missing-entry"
|
|
46
54
|
DUPLICATE = FIXTURES / "knowledge-indexes-duplicate"
|
|
55
|
+
SHIPPED_TYPE = FIXTURES / "knowledge-indexes-shipped-register-type"
|
|
56
|
+
SHIPPED_LEGACY = FIXTURES / "knowledge-indexes-shipped-register-legacy"
|
|
47
57
|
|
|
48
58
|
ROW = load().by_id("DOC-008")
|
|
49
59
|
|
|
60
|
+
# The register the package ships beside this check — the policy whose
|
|
61
|
+
# vocabulary the two shipped-register corpora grade.
|
|
62
|
+
SHIPPED_REGISTER = FIXTURES.parent / "docs-knowledge-indexes.yaml"
|
|
50
63
|
|
|
51
|
-
|
|
64
|
+
|
|
65
|
+
def _run(
|
|
66
|
+
root: Path,
|
|
67
|
+
*,
|
|
68
|
+
given: Sequence[str] | None = None,
|
|
69
|
+
registry: Path | None = None,
|
|
70
|
+
) -> Verdict:
|
|
52
71
|
"""`runner.run`'s scope-narrow-then-decide, against this check directly —
|
|
53
|
-
the same bypass `CON-003`'s test uses for an unwired check.
|
|
72
|
+
the same bypass `CON-003`'s test uses for an unwired check.
|
|
73
|
+
|
|
74
|
+
`registry` defaults to the corpus's own flattened copy; the
|
|
75
|
+
shipped-register corpora pass the gate folder's own yaml instead."""
|
|
54
76
|
raw = corpus_files(root) if given is None else tuple(given)
|
|
55
77
|
narrowed = FileSet(paths=scope.intersect(ROW.resolved_scope(), raw))
|
|
56
|
-
ctx = Context(
|
|
78
|
+
ctx = Context(
|
|
79
|
+
root=root,
|
|
80
|
+
row=ROW,
|
|
81
|
+
inputs={"registry": registry if registry is not None else root / "docs-knowledge-indexes.yaml"},
|
|
82
|
+
)
|
|
57
83
|
try:
|
|
58
84
|
findings = tuple(Indexes().run(ctx, narrowed))
|
|
59
85
|
except CouldNotRun as exc:
|
|
@@ -100,3 +126,29 @@ def test_the_omitted_page_outside_the_given_set_is_not_reported() -> None:
|
|
|
100
126
|
in the given set this time — so there is nothing to compare it against."""
|
|
101
127
|
verdict = _run(MISSING_ENTRY, given=("docs/index.md", "docs/one.md"))
|
|
102
128
|
assert verdict.outcome is Outcome.CLEAN, verdict.render()
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# ------------------------------------------- the shipped register's vocabulary
|
|
132
|
+
|
|
133
|
+
def test_an_index_satisfying_the_shipped_register_with_type_is_clean() -> None:
|
|
134
|
+
"""The gate's OWN register, not a fixture copy, grades a compliance index
|
|
135
|
+
carrying the OKF `type` key clean. Decision of 2026-10-02: the
|
|
136
|
+
docs-compliance and docs-product entries' `required_frontmatter` flipped
|
|
137
|
+
`document_type` → `type` (see `check.py`'s module docstring) — before the
|
|
138
|
+
flip this corpus was reported as missing `document_type`."""
|
|
139
|
+
verdict = _run(SHIPPED_TYPE, registry=SHIPPED_REGISTER)
|
|
140
|
+
assert verdict.outcome is Outcome.CLEAN, verdict.render()
|
|
141
|
+
assert verdict.findings == ()
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def test_an_index_carrying_only_the_legacy_document_type_key_is_reported() -> None:
|
|
145
|
+
"""The flip's converse: an index that still carries `document_type` and no
|
|
146
|
+
`type` fails the shipped register. Before 2026-10-02 this corpus graded
|
|
147
|
+
CLEAN, which is exactly the drift the flip removes — the OKF profile
|
|
148
|
+
(`docs-okf-profiles.yaml`'s `common_required`) knows `type` only."""
|
|
149
|
+
verdict = _run(SHIPPED_LEGACY, registry=SHIPPED_REGISTER)
|
|
150
|
+
assert verdict.outcome is Outcome.FINDINGS, verdict.render()
|
|
151
|
+
assert verdict.rules == ["KNW-001"]
|
|
152
|
+
finding = verdict.findings[0]
|
|
153
|
+
assert finding.path == "docs/compliance/index.md"
|
|
154
|
+
assert finding.message == "missing required frontmatter field type"
|
|
@@ -2,17 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
Google Cloud's Open Knowledge Format v0.2. The profile register declares the
|
|
4
4
|
common required fields, and then one profile per document kind: which paths it
|
|
5
|
-
covers, the `type`
|
|
6
|
-
fields they must carry, and the
|
|
5
|
+
covers, the `type` those documents must declare (optional: a profile that names
|
|
6
|
+
none leaves the value unconstrained), the extra fields they must carry, and the
|
|
7
|
+
headings they must contain.
|
|
7
8
|
|
|
8
9
|
Six rules, one rule id, because they are one contract:
|
|
9
10
|
|
|
10
11
|
* the file has parseable YAML frontmatter at all;
|
|
11
12
|
* some profile covers its path;
|
|
12
|
-
* `type`
|
|
13
|
+
* `type` matches that profile, where it declares one;
|
|
13
14
|
* every common and profile-specific required field is present;
|
|
14
15
|
* `status` is `draft` or `stable`;
|
|
15
|
-
* each declared heading group has at least one of its headings present
|
|
16
|
+
* each declared heading group has at least one of its headings present;
|
|
17
|
+
* the frontmatter key set is CLOSED (2026-10-02): a document may carry only
|
|
18
|
+
the keys its profile admits — `common_required`, `common_optional`, and
|
|
19
|
+
the profile's own `required` — and every other key is reported by name.
|
|
20
|
+
|
|
21
|
+
The closed set is the same contract `core/models.py`'s `extra="forbid"`
|
|
22
|
+
grades this package's own policy documents with, applied at the frontmatter
|
|
23
|
+
layer. Required-only grading had the hole in reverse: keys nobody admitted
|
|
24
|
+
accumulated in real documents because nothing rejected them, and the register's
|
|
25
|
+
`common_optional` list — until this rule — was read by no check at all. The
|
|
26
|
+
root agent rule names the workflow the finding drives: admit a new key by
|
|
27
|
+
editing `docs-okf-profiles.yaml` (into `common_optional`, or a profile's
|
|
28
|
+
`required` when every document of that kind must carry it), never ad-hoc in a
|
|
29
|
+
document. The set is closed PER PROFILE, not per register: `created` is in the
|
|
30
|
+
vocabulary because the Research profile requires it, but an architecture page
|
|
31
|
+
carrying it is reported — otherwise every profile's `required` list would leak
|
|
32
|
+
into every other profile by construction. `last_update` sits in
|
|
33
|
+
`common_optional` (not any profile's `required`) because every document kind
|
|
34
|
+
carries it while no document kind must.
|
|
16
35
|
|
|
17
36
|
The `plan_state`-agrees-with-its-directory rule is gone. It existed because a
|
|
18
37
|
plan's lifecycle state was mirrored in a directory name (`a_new`,
|
|
@@ -51,12 +70,14 @@ from ....core.scope import matches
|
|
|
51
70
|
|
|
52
71
|
|
|
53
72
|
class Profile(StrictModel):
|
|
54
|
-
type: str
|
|
73
|
+
type: str | None = None
|
|
74
|
+
"""Optional per profile. The Research profile declares none because the
|
|
75
|
+
pages under `docs/research/` legitimately differ in `type` (Research,
|
|
76
|
+
Experiment). A profile that names no `type` asserts nothing about its
|
|
77
|
+
VALUE; the field must still be present, because `common_required` lists
|
|
78
|
+
it."""
|
|
79
|
+
|
|
55
80
|
paths: Annotated[tuple[str, ...], Field(min_length=1, strict=False)]
|
|
56
|
-
document_type: str | None = None
|
|
57
|
-
"""Optional per profile. Two of the shipped profiles — Specification and
|
|
58
|
-
Change Plan — declare none, and a profile that does not name one is not
|
|
59
|
-
asserting anything about the field."""
|
|
60
81
|
|
|
61
82
|
required: Annotated[tuple[str, ...], Field(strict=False)] = ()
|
|
62
83
|
|
|
@@ -159,18 +180,11 @@ class OkfProfile(Check):
|
|
|
159
180
|
return
|
|
160
181
|
|
|
161
182
|
declared_type = frontmatter.get("type")
|
|
162
|
-
if declared_type != profile.type:
|
|
183
|
+
if profile.type is not None and declared_type != profile.type:
|
|
163
184
|
yield self.report(
|
|
164
185
|
relative, f"type must be '{profile.type}' (got {declared_type!r})",
|
|
165
186
|
f"set frontmatter type: {profile.type}",
|
|
166
187
|
)
|
|
167
|
-
declared_document = frontmatter.get("document_type")
|
|
168
|
-
if profile.document_type is not None and declared_document != profile.document_type:
|
|
169
|
-
yield self.report(
|
|
170
|
-
relative,
|
|
171
|
-
f"document_type must be '{profile.document_type}' (got {declared_document!r})",
|
|
172
|
-
f"set frontmatter document_type: {profile.document_type}",
|
|
173
|
-
)
|
|
174
188
|
|
|
175
189
|
for field in register.common_required:
|
|
176
190
|
if not frontmatter.get(field):
|
|
@@ -185,6 +199,8 @@ class OkfProfile(Check):
|
|
|
185
199
|
f"add the {field} field required by this document's OKF profile",
|
|
186
200
|
)
|
|
187
201
|
|
|
202
|
+
yield from self._admitted_keys(relative, frontmatter, register, profile)
|
|
203
|
+
|
|
188
204
|
status = frontmatter.get("status")
|
|
189
205
|
if status not in self.STATUSES:
|
|
190
206
|
yield self.report(
|
|
@@ -194,6 +210,37 @@ class OkfProfile(Check):
|
|
|
194
210
|
|
|
195
211
|
yield from self._headings(relative, body, profile)
|
|
196
212
|
|
|
213
|
+
def _admitted_keys(
|
|
214
|
+
self,
|
|
215
|
+
relative: str,
|
|
216
|
+
frontmatter: Mapping[str, object],
|
|
217
|
+
register: ProfileRegister,
|
|
218
|
+
profile: Profile,
|
|
219
|
+
) -> Iterable[Report]:
|
|
220
|
+
"""The closed key set: common_required, common_optional, and the
|
|
221
|
+
profile's own required. Anything else is reported by name, in key
|
|
222
|
+
order, so a document with three stray keys reports three findings and
|
|
223
|
+
the fix list reads the same way every time.
|
|
224
|
+
|
|
225
|
+
Keys are compared as a SET, not by truthiness: an admitted key with an
|
|
226
|
+
empty value is the required-fields rule's subject, not this one's.
|
|
227
|
+
Non-string YAML keys cannot be in the vocabulary and are reported
|
|
228
|
+
rather than crashing the sort."""
|
|
229
|
+
admitted = (
|
|
230
|
+
set(register.common_required)
|
|
231
|
+
| set(register.common_optional)
|
|
232
|
+
| set(profile.required)
|
|
233
|
+
)
|
|
234
|
+
for key in sorted(frontmatter, key=str):
|
|
235
|
+
if key in admitted:
|
|
236
|
+
continue
|
|
237
|
+
yield self.report(
|
|
238
|
+
relative, f"unknown OKF frontmatter key {key!r}",
|
|
239
|
+
"remove the key, or admit it in docs-okf-profiles.yaml: add it "
|
|
240
|
+
"to common_optional, or to this profile's required if every "
|
|
241
|
+
"document of this kind must carry it",
|
|
242
|
+
)
|
|
243
|
+
|
|
197
244
|
def _headings(self, relative: str, body: str, profile: Profile) -> Iterable[Report]:
|
|
198
245
|
present = [
|
|
199
246
|
line.lstrip("#").strip()
|
|
@@ -5,7 +5,6 @@ version: "0.2"
|
|
|
5
5
|
# |--------------------------|-----------------------------------------------------|
|
|
6
6
|
# | status | unquoted bare scalar: draft | stable (status: draft) |
|
|
7
7
|
# | last_update | quoted ISO-8601 UTC : '2026-08-22T00:00:00Z' |
|
|
8
|
-
# | document_type | unquoted bare scalar (same rule as status) |
|
|
9
8
|
# | created, decision_date, …| unquoted bare YYYY-MM-DD dates where present |
|
|
10
9
|
|
|
11
10
|
# `generated: {by, at}` used to be here. It was machine provenance nobody
|
|
@@ -19,25 +18,55 @@ common_required:
|
|
|
19
18
|
- description
|
|
20
19
|
- status
|
|
21
20
|
|
|
21
|
+
# common_optional is the closed key set's safety valve (DOC-006, 2026-10-02):
|
|
22
|
+
# a key here is admitted on every document kind but required of none. The
|
|
23
|
+
# closed-set rule reads this list; nothing else ever did — it existed in the
|
|
24
|
+
# register for a year with no check enforcing it.
|
|
25
|
+
#
|
|
26
|
+
# last_update is admitted here, not in any profile's required: every document
|
|
27
|
+
# kind carries it (it is a frontmatter convention above, and all 25 documents
|
|
28
|
+
# in the adl-azdo corpus have it) while no document kind must — required
|
|
29
|
+
# belongs to fields a profile's headings cannot be written without.
|
|
30
|
+
#
|
|
31
|
+
# related is admitted the same way and for the measured reason: 24 of those 25
|
|
32
|
+
# documents carry it, across every kind — the Architecture and Operations
|
|
33
|
+
# profiles already REQUIRE it, and research pages carry it without their
|
|
34
|
+
# profile requiring it (see test_check.py: the research fixtures deliberately
|
|
35
|
+
# have none). A key the whole corpus conventionally carries but one kind
|
|
36
|
+
# legitimately omits is the definition of optional.
|
|
22
37
|
common_optional:
|
|
23
38
|
- verified
|
|
24
39
|
- resource
|
|
25
40
|
- tags
|
|
26
41
|
- stale_after
|
|
42
|
+
- last_update
|
|
43
|
+
- related
|
|
27
44
|
|
|
28
|
-
#
|
|
45
|
+
# Five profiles, deliberately (Compliance is disabled, see below).
|
|
29
46
|
#
|
|
30
47
|
# There were eight. Benchmark, Evaluation, Field Note and Specification declared
|
|
31
48
|
# trees that do not exist -- docs/research/benchmarks, docs/research/evaluations,
|
|
32
49
|
# docs/research/field-notes, .specs -- so seven of the eight graded nothing at
|
|
33
50
|
# all while reading as coverage. A register that describes a documentation set
|
|
34
51
|
# nobody has is worse than a smaller one that describes the real thing: it
|
|
35
|
-
# reports clean because it never matched a file.
|
|
52
|
+
# reports clean because it never matched a file. Those four stay removed.
|
|
53
|
+
#
|
|
54
|
+
# Research is added back (2026-10-01), and not as a return of those four:
|
|
55
|
+
# docs/research/ itself exists in the consuming repositories. enact-combined
|
|
56
|
+
# holds docs/research/cloud-local-research-input.md (type Research) and
|
|
57
|
+
# docs/research/codex-app-server-container-experiment.md (type Experiment), and
|
|
58
|
+
# with no profile covering that path DOC-006 reported "no OKF profile matches
|
|
59
|
+
# this path" for both. The profile is minimal on purpose: one entry for
|
|
60
|
+
# docs/research/**, requiring what both pages carry -- title, description and
|
|
61
|
+
# status through common_required, then last_update and sources -- and nothing else. It declares no `type`, because the two pages
|
|
62
|
+
# differ in it, and no headings, because they share no section structure.
|
|
36
63
|
#
|
|
37
64
|
# Architecture what the system is docs/architecture/**
|
|
38
65
|
# ADR why it is that way docs/architecture/decisions/**, docs/decisions/**
|
|
39
|
-
# Compliance what we must show docs/compliance/**
|
|
40
66
|
# Operations how it is operated docs/operations/**
|
|
67
|
+
# Task ledger what each agent task did docs/notes.md
|
|
68
|
+
# Research what is being found out docs/research/**
|
|
69
|
+
# (Compliance what we must show docs/compliance/** -- disabled, see below)
|
|
41
70
|
#
|
|
42
71
|
# plans/ is NOT here. Its frontmatter answers to the Azure DevOps board, not to
|
|
43
72
|
# OKF, and LAY-009 owns it.
|
|
@@ -46,7 +75,6 @@ profiles:
|
|
|
46
75
|
- type: Architecture
|
|
47
76
|
paths:
|
|
48
77
|
- docs/architecture/**
|
|
49
|
-
document_type: architecture
|
|
50
78
|
required:
|
|
51
79
|
- sources
|
|
52
80
|
- related
|
|
@@ -60,7 +88,6 @@ profiles:
|
|
|
60
88
|
paths:
|
|
61
89
|
- docs/architecture/decisions/**
|
|
62
90
|
- docs/decisions/**
|
|
63
|
-
document_type: adr
|
|
64
91
|
required:
|
|
65
92
|
- decision_id
|
|
66
93
|
- decision_date
|
|
@@ -84,8 +111,7 @@ profiles:
|
|
|
84
111
|
# - type: Compliance Assessment
|
|
85
112
|
# paths:
|
|
86
113
|
# - docs/compliance/**
|
|
87
|
-
|
|
88
|
-
# required:
|
|
114
|
+
# required:
|
|
89
115
|
# - control_ids
|
|
90
116
|
# - owner
|
|
91
117
|
# - review_frequency
|
|
@@ -107,7 +133,6 @@ profiles:
|
|
|
107
133
|
- type: Operations
|
|
108
134
|
paths:
|
|
109
135
|
- docs/operations/**
|
|
110
|
-
document_type: operations
|
|
111
136
|
required:
|
|
112
137
|
- sources
|
|
113
138
|
- related
|
|
@@ -117,3 +142,29 @@ profiles:
|
|
|
117
142
|
- ["Credentials", "Access", "Sign"]
|
|
118
143
|
- ["Verification", "Evidence", "Check"]
|
|
119
144
|
|
|
145
|
+
# The task ledger: one append-only list of dated lines, one per task start
|
|
146
|
+
# and finish, that the global agent rule requires in every repository
|
|
147
|
+
# (docs/notes.md, declared in policy/docs_shape.py). It is an operations
|
|
148
|
+
# document, but not a procedure: it has no Purpose/Procedure/Credentials
|
|
149
|
+
# sections and no `related` field, so it gets its own profile rather than
|
|
150
|
+
# the Operations one above. It is graded for what it really has: OKF
|
|
151
|
+
# frontmatter with `sources`, and its `## Lines` section.
|
|
152
|
+
- type: Operations
|
|
153
|
+
paths:
|
|
154
|
+
- docs/notes.md
|
|
155
|
+
required:
|
|
156
|
+
- sources
|
|
157
|
+
headings:
|
|
158
|
+
- ["Lines"]
|
|
159
|
+
|
|
160
|
+
# Research: inputs, findings and experiment plans under docs/research/. No
|
|
161
|
+
# `type` -- the pages there differ (Research, Experiment) -- and no headings;
|
|
162
|
+
# see the header. Title, description and status come from common_required.
|
|
163
|
+
# Research pages are dated: `created` (bare YYYY-MM-DD) records when the work
|
|
164
|
+
# was done -- the date is part of what a research page is.
|
|
165
|
+
- paths:
|
|
166
|
+
- docs/research/**
|
|
167
|
+
required:
|
|
168
|
+
- created
|
|
169
|
+
- last_update
|
|
170
|
+
- sources
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
last_update: 2026-09-28T15:10:00Z
|
|
3
|
+
title: Agent notes ledger
|
|
4
|
+
description: Fixture task ledger, one append-only line per task start and finish.
|
|
5
|
+
type: Operations
|
|
6
|
+
status: stable
|
|
7
|
+
sources: packages/agent-settings/assets/GLOBAL-AGENTS.md
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Agent notes ledger
|
|
11
|
+
|
|
12
|
+
An append-only log; one line when an agent starts a task and one when it finishes.
|
|
13
|
+
|
|
14
|
+
## Lines
|
|
15
|
+
|
|
16
|
+
2026-09-28 05:31 claude start: fixture task
|
|
17
|
+
2026-09-28 05:40 claude finish: fixture task
|