feat(convergence/p2): PatternGate + CommandVerify unified traits
Layer C + D. 6 gate modules + 3 verify modules → 1 generic struct per
family + const declarations. Data-driven, not module-per-capability.
New:
- src/gates/pattern_gate.rs (192 LOC) — PatternGate struct with
GateMode::{DenyIfMatch, AllowIfMatch}, static regex compilation via
once_cell, bypass env support, Capability trait impl
- src/verifies/command_verify.rs (142 LOC) — CommandVerify struct with
WorkDir::{WorkspaceRoot, CrateDir, MainRepoSub}, subprocess exec +
exit-code check, extra_env support, Capability trait impl
Converted (const declarations, ~15-27 LOC each):
- gates/policy_no_git_ops.rs (49→22)
- gates/safety_no_dep_bump.rs (35→19)
- gates/scope_files_whitelist.rs (37→16)
- gates/scope_files_denylist.rs (35→16)
- gates/tools_bash_allowlist.rs (58→27)
- verifies/quality_cargo_check_green.rs (41→18)
- verifies/quality_tests_green.rs (75→80, folded common shape)
- verifies/safety_no_dep_bump.rs (39→47)
Kept separate (different shape, not PatternGate/CommandVerify):
- gates/tools_deny_tools.rs (tool-name match, not pattern)
- verifies/quality_constructor_pattern.rs (LOC walker)
- verifies/output/report_format.rs + severity_grade.rs (text parsers)
- verifies/scope_files_{whitelist,denylist}.rs (diff-walkers)
Registry.rs preserves alias table + deprecation warnings + all_names().
Tests: 57/57 green (was 41, +16: 10 pattern_gate_smoke + 6 command_verify_smoke).
LOC net: 5 gates 214→100 (-53%), shared PatternGate+CommandVerify 334
LOC absorb duplication. Amortization breaks even around 3-4 new gates
added later.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>