Summary
The validate-policy and test-policy workflows orchestrate multiple domain calls directly in both the CLI and MCP transport layers. Per AGENTS.md, transport layers should be thin wiring over domain functions, not orchestration points.
Problem
Both the CLI commands and their MCP counterparts contain the same multi-step orchestration logic:
validate-policy pipeline (Validate → LoadSchema → CheckContract → Lint):
- CLI:
cmd/complypack/cli/validate_policy.go:104-212 (runValidatePolicy())
- MCP:
internal/mcp/tools.go:235-282 (handleValidatePolicy())
test-policy pipeline (LoadSchema → ValidateTestData → Test):
- CLI:
cmd/complypack/cli/test_policy.go:116-215 (runTestPolicy())
- MCP:
internal/mcp/tools.go:284-326 (handleTestPolicy())
Other CLI commands (triage, delta, applicability) follow the correct pattern: each calls a single domain function (e.g., requirement.TriageAssessmentPlans(), requirement.AnalyzeDelta()).
Proposed Solution
Extract two domain orchestration functions into internal/evaluator/ (or a new domain package):
// ValidatePolicy runs the full validation pipeline: syntax, contract, lint.
func ValidatePolicy(ctx context.Context, params ValidatePolicyParams) (*ValidatePolicyResult, error)
// TestPolicy runs optional test-data validation and executes the test suite.
func TestPolicy(ctx context.Context, params TestPolicyParams) (*TestPolicyResult, error)
Then refactor both CLI and MCP transport layers to call these functions, reducing each to: parse input → call domain function → serialize output.
Acceptance Criteria
- runValidatePolicy() in CLI calls a single domain function
- handleValidatePolicy() in MCP calls the same domain function
- runTestPolicy() in CLI calls a single domain function
- handleTestPolicy() in MCP calls the same domain function
- No behavior change in CLI or MCP output
- Existing tests continue to pass
## Constitution & Architecture References
- AGENTS.md: "MCP handlers and CLI commands are thin wiring: parse input, call a domain function, serialize output. No business logic in these layers."
- Principle II (Simplicity & Isolation): Functions MUST follow the Single
Responsibility Principle.
- Principle III (Incremental Improvement): This is a standalone refactor scoped to moving existing logic, not adding new features.
Context
Identified during review of #227. The MCP handlers had this pattern before #227;
the CLI commands replicated it for parity. This issue addresses both layers together.
Summary
The
validate-policyandtest-policyworkflows orchestrate multiple domain calls directly in both the CLI and MCP transport layers. Per AGENTS.md, transport layers should be thin wiring over domain functions, not orchestration points.Problem
Both the CLI commands and their MCP counterparts contain the same multi-step orchestration logic:
validate-policy pipeline (Validate → LoadSchema → CheckContract → Lint):
cmd/complypack/cli/validate_policy.go:104-212(runValidatePolicy())internal/mcp/tools.go:235-282(handleValidatePolicy())test-policy pipeline (LoadSchema → ValidateTestData → Test):
cmd/complypack/cli/test_policy.go:116-215(runTestPolicy())internal/mcp/tools.go:284-326(handleTestPolicy())Other CLI commands (
triage,delta,applicability) follow the correct pattern: each calls a single domain function (e.g.,requirement.TriageAssessmentPlans(),requirement.AnalyzeDelta()).Proposed Solution
Extract two domain orchestration functions into
internal/evaluator/(or a new domain package):Then refactor both CLI and MCP transport layers to call these functions, reducing each to: parse input → call domain function → serialize output.
Acceptance Criteria
## Constitution & Architecture References
Responsibility Principle.
Context
Identified during review of #227. The MCP handlers had this pattern before #227;
the CLI commands replicated it for parity. This issue addresses both layers together.