Skip to content

[policy] Recurse extends: chain at install-time (follow-up to #827) #831

@danielmeppiel

Description

@danielmeppiel

Context

#827 shipped install-time enforcement of apm-policy.yml. The shared discover_policy_with_chain() helper in src/apm_cli/policy/discovery.py resolves the immediate parent via extends: but does not recurse: grandparent / enterprise-hub policies are silently dropped at install time.

apm audit --ci resolves the full multi-level chain via resolve_policy_chain(). Install time should match.

Proposal

In discover_policy_with_chain(), replace the single discover_policy(parent) call with a recursive walk that:

  1. Loads each parent in turn
  2. Detects cycles (use a seen: set[str] keyed on the resolved repo URL or canonical ref)
  3. Caps depth at a sane constant (suggest MAX_CHAIN_DEPTH = 8) and emits a clear error if exceeded
  4. Merges via the existing tighten-only rules (merge_effective_policy())
  5. Stores the full chain refs in the cache meta.json so cache invalidation reflects all hops

Acceptance criteria

  • Recursive walk implemented in discover_policy_with_chain()
  • Cycle detection with explicit error
  • Depth cap with explicit error
  • Cache stores all chain refs (not just immediate parent)
  • Unit tests cover: 3-level chain, cycle, depth cap exceeded, fetch failure mid-chain
  • Integration test on the install path verifies grandparent constraints are enforced
  • Docs updated: drop the install-time chain-depth caution from policy-reference.md and governance.md

Out of scope

  • Diamond inheritance / multiple parents (separate concern; today extends: is single-string)
  • Lazy loading of intermediate policies for very long chains
  • Signing / integrity verification of intermediate hops

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementDeprecated: use type/feature. Kept for issue history; will be removed in milestone 0.10.0.good first issueGood for newcomerspolicyDeprecated: use area/audit-policy. Kept for issue history; will be removed in milestone 0.10.0.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions