Skip to content

fix(cli): make verdict policy rules fire (license + changed-paths wiring)#195

Merged
theagenticguy merged 2 commits into
mainfrom
roadmap/verdict-policy-wiring
Jun 6, 2026
Merged

fix(cli): make verdict policy rules fire (license + changed-paths wiring)#195
theagenticguy merged 2 commits into
mainfrom
roadmap/verdict-policy-wiring

Conversation

@theagenticguy
Copy link
Copy Markdown
Owner

What

Make the codehub verdict policy engine actually enforce license_allowlist and ownership_required rules. Previously buildPolicyContext hardcoded licenseViolations: [], touchedPaths: [], and ownersByPath: new Map(), so an authored opencodehub.policy.yaml with those rules schema-validated but never blocked a PR — a false green on the exit-code ladder, worse than no feature.

Changes

  • touchedPaths: Added VerdictResponse.changedFiles, populated from the detect_changes file list that computeVerdict already derives (main path + finaliseEmpty). The CLI threads verdict.changedFiles into PolicyContext.touchedPaths, so ownership_required / path-scoped rules evaluate against the real diff. No extra git call.
  • licenseViolations: New collectLicenseViolations runs the existing classifyDependencies over store.graph.listDependencies() and projects flagged deps (copyleft / proprietary / unknown) into LicenseViolationInput[]. Declared license surfaced verbatim; missing/empty normalised to "UNKNOWN" so a strict policy can deny those. Scan only runs when a policy file is loaded; defensive when listDependencies is absent.
  • ownership: require_approval_from now works because touched paths are real; per-path graph-owner mapping (ownersByPath) is left empty pending an email→team reconciliation source (see Follow-up).
  • Exported LicenseViolationInput from @opencodehub/policy.

How verified

  • Scoped build green across all packages.
  • New CLI tests: license_allowlist blocks (exit 3) on a denied GPL-3.0 dep; passes for permissive MIT; can deny UNKNOWN; ownership_required blocks (exit 3) on an unapproved changed path and passes when no path matches.
  • Existing exit-code ladder green: cli 291 / analysis 128 / policy 32, all 0 fail. Biome + banned-strings PASS.

Follow-up

Per-path owner→approval mapping (ownersByPath) needs a contributor-email→team source: OWNED_BY edges resolve to email-hash Contributor nodes, not the team/user handles approvals use.

⚠️ Behavior change to an exit-code-bearing gateverdict can now return exit 3 where it previously passed. Confirm no existing CI running codehub verdict starts failing on a now-enforced rule.

🤖 Surfaced by an automated roadmap-survey workflow; implemented + verified in an isolated worktree.

…policy context

buildPolicyContext previously hardcoded licenseViolations: [], touchedPaths: [],
and ownersByPath: new Map(), so an authored opencodehub.policy.yaml with
license_allowlist or ownership_required rules schema-validated but never blocked
a PR (false green on exit codes).

- touchedPaths: surface the changed-file list computeVerdict already derives from
  detect_changes as VerdictResponse.changedFiles, and thread it into touchedPaths
  so path-scoped rules (ownership_required) evaluate against the real diff.
- licenseViolations: classify the indexed Dependency nodes via classifyDependencies
  and project flagged deps (copyleft/proprietary/unknown) into LicenseViolationInput
  so license_allowlist fires. Declared license surfaced verbatim; missing/UNKNOWN
  normalised to "UNKNOWN" so a strict policy can deny those too. Scan only runs
  when a policy file is actually loaded.
- ownership: require_approval_from now works against real touched paths. Per-path
  graph-owner mapping (ownersByPath) stays empty pending a contributor-email->team
  reconciliation source (separate design item).

Tests prove a license_allowlist rule flips the verdict to block (exit 3) when a
violating dep is present, license_allowlist passes for permissive deps,
UNKNOWN-deny works, ownership_required blocks on an unapproved changed path and
passes when no path matches. Existing exit-code ladder tests stay green.
@theagenticguy theagenticguy merged commit ed70a1b into main Jun 6, 2026
42 checks passed
@theagenticguy theagenticguy deleted the roadmap/verdict-policy-wiring branch June 6, 2026 04:15
@github-actions github-actions Bot mentioned this pull request Jun 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant