Skip to content

feat(policy): add custom_checks for arbitrary subprocess validation in apm-policy.yml #519

@danielmeppiel

Description

@danielmeppiel

Why

APM's policy system (apm-policy.yml) enforces governance over dependencies, MCP servers, compilation targets, and manifest fields. But enterprise teams need to enforce rules beyond what APM natively checks — readiness thresholds, quality evaluation, license compliance, custom org validators.

Today there is no extension point. The check list is hardcoded in run_policy_checks(). Adding a custom_checks section lets governance teams plug in any tool via subprocess commands, keeping APM tool-agnostic (like npm never hardcodes ESLint).

What

A new custom_checks field in apm-policy.yml that defines arbitrary subprocess commands. Each runs during apm audit --ci --policy, returns pass/fail via exit code, and integrates into the existing JSON/SARIF audit output.

Policy YAML format

name: contoso-org-policy
version: "1.0.0"
enforcement: block

custom_checks:
  - name: agentrc-readiness
    description: "Repo must meet AI readiness level 3"
    command: "agentrc readiness --json --fail-level 3"
    timeout: 60
    on_failure: warn

  - name: license-check
    description: "All dependencies must have OSS licenses"
    command: "./scripts/check-licenses.sh"
    timeout: 30
    on_failure: block

Execution model

During apm audit --ci --policy org:

  1. Baseline checks run (lockfile, integrity, Unicode) — unchanged
  2. Policy checks run (allowlist, denylist, required) — unchanged
  3. Custom checks run — NEW: for each entry, run command as subprocess with timeout. Exit 0 = pass, non-zero = fail. Results appear alongside built-in checks in JSON/SARIF.

Result format

Uses existing CheckResult model — no new output format:

{
  "name": "custom:agentrc-readiness",
  "passed": false,
  "message": "Repo must meet AI readiness level 3",
  "details": ["exit code 1: achieved level 2, required 3"]
}

How

~150 lines across 4 files:

  • schema.pyCustomCheck dataclass + field on ApmPolicy
  • parser.py — parse custom_checks from YAML
  • policy_checks.py_run_custom_checks() with subprocess + CheckResult
  • Tests

Design principles

  • APM stays tool-agnostic — any command works (agentrc, scripts, scanners)
  • No library coupling — subprocess execution across language boundaries
  • Inherits enforcementon_failure defaults to top-level enforcement
  • Safe — timeout prevents hangs; missing commands handled gracefully

Use cases

Check Command Value
AI readiness agentrc readiness --json --fail-level 3 Gate on maturity
License compliance ./scripts/check-licenses.sh Legal requirements
Secret scanning gitleaks detect --no-banner -q Security hygiene
Doc coverage test -f README.md Documentation standards

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions