fix(policy): unify --policy / --policy-source forms across CLI help and docs#1000
Merged
danielmeppiel merged 2 commits intomicrosoft:mainfrom Apr 28, 2026
Merged
Conversation
…nd docs Establish a single Python constant (POLICY_SOURCE_FORMS_HELP) as the source of truth for the user-facing forms accepted by --policy / --policy-source. Both Click decorators and both cli-commands.md bullets align to it; six lockstep tests pin the relationship so future drift fails CI. Also corrects the discover_policy() docstring, which had been omitting the owner/repo case. Closes microsoft#998 and microsoft#994. microsoft#994 (broken cross-reference to a non-existent 'apm install --policy' flag) is subsumed because the offending line is rewritten to the canonical wording rather than redirected.
danielmeppiel
approved these changes
Apr 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
The "policy source" format accepted by
apm audit --policyandapm policy status --policy-sourceis documented inconsistently across four locations — two Click help texts and two docs sections, with the parser supportingowner/reposhorthand that is missing from three of the four. This PR establishes a single Python constant as the source of truth, threads it through both Click decorators, aligns the docs, and adds six lockstep regression tests so future drift fails CI rather than going unnoticed for months.Note
Closes #998 and #994. #994 reported a broken cross-reference (
Same shape as 'apm install --policy'— a flag that does not exist); investigation revealed #998, the underlying drift. Both are fixed in one PR because they touch the same line of code; splitting would force the same line to be rewritten twice with no benefit.Problem (WHY)
policy.py:288lists 4 forms ('org', file path,owner/repo, https URL);audit.py:440lists 3;cli-commands.md:435lists 3;cli-commands.md:523lists 3 and points at a non-existent flag.owner/repo. Users reading the CLI reference cannot discover thatapm policy status --policy-source contoso/.githubis valid input, even though the parser accepts it (proven bytest_override_owner_repo).cli-commands.md:523saysSame shape as \apm install --policy`, butapm installhas no--policyflag (only--no-policy`).discovery.py:543-547itself omits theowner/repocase, so even the in-code spec drifted.Why these matter: the per-flag accepted-forms list is a contract the CLI advertises and the parser enforces; today they describe the same contract differently in four places, which violates the discoverability guarantee the docs imply.
Approach (WHAT)
POLICY_SOURCE_FORMS_HELPin a new lightweight module (apm_cli/policy/_help_text.py) co-located with the parser.apm audit --policyandapm policy status --policy-sourceClick decorators import and embed the constant via f-string.cli-commands.mdbullets are rewritten to the same canonical wording — this also subsumes #994, since the broken cross-reference is rewritten away rather than redirected to another command.discovery.pyis corrected to list all five resolution branches (it was missingowner/repo) and points readers to the constant as the user-facing rendering.tests/unit/policy/test_help_consistency.py) pin the constant, both Click helps, both docs bullets, and the absence ofapm install --policyreferences docs-tree-wide.Implementation (HOW)
src/apm_cli/policy/_help_text.py(new) — holdsPOLICY_SOURCE_FORMS_HELP. Tiny, zero imports, lives next to the parser so a parser-behavior change forces a help-text update in the same diff.src/apm_cli/commands/audit.py— imports the constant, uses f-string interpolation in the--policyClick help so the command-specific suffix (Used with --ci ... [experimental]) is preserved.src/apm_cli/commands/policy.py— imports the constant, replaces the previous (already-most-accurate) help string withf"Override discovery. {POLICY_SOURCE_FORMS_HELP}".src/apm_cli/policy/discovery.py— expands thediscover_policy()docstring from 4 cases to 5 (the previous text omittedowner/repo) and cross-references the constant.docs/src/content/docs/reference/cli-commands.md— the two affected bullets (lines 435 and 523) are rewritten to canonical wording mirroring the constant, using markdown backticks for inline forms.tests/unit/policy/test_help_consistency.py(new) — six lockstep tests; mutation-tested to confirm each catches a distinct drift mode.Trade-offs
host/owner/repoform. The parser supports it via_fetch_from_repobut no user-facing surface advertises it today. Promoting an internal capability to public API is a product decision, not a docs fix. Conservative call: keep the user-facing list at four forms; readers needing explicit-host can use thehttps://URL form.enterprise/policy-reference.md. That page already lists 4 forms correctly (different wording, same information). Pursuing byte-identical SSOT across audience-distinct docs would expand scope and trade reader-friendly prose for build-system parity.discover_policy(). Behavior is unchanged; only the docstring was corrected and a cross-reference to the constant added. The 507 unit tests intests/unit/policy/pass unchanged.Benefits
owner/reposhorthand.--policyand--policy-sourceusers can now find this form from any single doc page or--helpinvocation.Validation
apm audit --help(relevant fragment):apm policy status --help(relevant fragment):Lockstep regression tests:
Aggregate regression on all touched code (563 tests)
The 26 failures observed in
tests/unit/outside this set are pre-existing onmain(marketplace / install / cowork / config — none touched by this PR), confirmed by stashing the changes and rerunning the same selection on the parent commit.Mutation testing performed during review
Each mutation was applied locally, the relevant test was run, then the mutation was reverted.
'owner/repo'fromPOLICY_SOURCE_FORMS_HELPaudit.pyhelp with hand-written string (bypass constant)apm install --policyreference ingovernance-guide.md(a different docs page)owner/repofromcli-commands.md:523bulletHow to test
pytest tests/unit/policy/test_help_consistency.py -v— expect 6 passes.apm audit --help— expect the--policyline to mentionowner/repo,https://, andlocal file path.apm policy status --help— expect the--policy-sourceline to mention all four canonical forms.grep -r "apm install --policy" docs/— expect no matches (closes [cli-consistency] CLI Consistency Report — 2026-04-27 #994).apm policy status --policy-source contoso/.github— expect the parser to attempt fetch (not a parse-level rejection), confirming the newly-documentedowner/repoform actually works.