Files
correx/docs/modules/core/core-validation.adoc
T
kami 9734eec63c docs: add module documentation in AsciiDoc with PlantUML diagrams
Generated by per-group subagents covering all 52 modules across:
core (18), infrastructure (10), apps (5), interfaces (3),
plugins (7), testing (9)

Documentation format:
- AsciiDoc (.adoc) files in docs/modules/<group>/
- PlantUML (.puml) files in docs/diagrams/
- .adoc files reference diagrams via include:: directives

Each doc covers: purpose, responsibilities, non-responsibilities,
key types, event flow, integration points, invariants, PlantUML
diagram, known issues, and open questions.
2026-05-26 16:59:21 +04:00

157 lines
6.4 KiB
Plaintext

= core-validation
== purpose
Runs a pipeline of validators against a `ValidationContext` (containing the workflow graph, detected cycles, cycle policies, and session state) to produce a `ValidationReport`. If structural errors are found, the pipeline rejects immediately as non-retryable. If issues warrant human review, it signals `NeedsApproval`.
== responsibilities
* Validating workflow graph structure (start node exists, no dangling transitions)
* Validating transition integrity (endpoint references, deterministic ordering)
* Validating session temporal and status consistency
* Running semantic rules (e.g. cycle policy binding checks)
* Validating artifact payloads against their declared schemas
* Producing a `ValidationOutcome` (Passed, Rejected, or NeedsApproval)
* Determining whether validation failures are retryable
* Triggering approval requests when validation risk exceeds thresholds
== non-responsibilities
* Does not enforce approvals or block execution — only signals the need for approval
* Does not modify state or emit events — it is a pure validation function
* Does not manage the lifecycle of validation reports
* Does not validate LLM outputs directly — validates artifacts and graph structures
== key types
=== Validator
* **kind**: fun interface
* **purpose**: Performs a single validation pass and returns a `ValidationSection`.
=== ValidationPipeline
* **kind**: class
* **purpose**: Runs a list of validators in sequence. Short-circuits on structural errors (non-retryable rejection). Optionally evaluates an `ApprovalTrigger` after all validators pass.
* **fields**: `validators` (list), `approvalTrigger` (nullable)
=== ValidationOutcome
* **kind**: sealed interface
* **purpose**: Result of a validation run.
* **variants**:
* `Passed(report)` — validation succeeded
* `Rejected(report, retryable)` — validation failed; `retryable` is set by the validator and must not be overridden
* `NeedsApproval(request)` — validation passed but human approval is required
=== ValidationReport
* **kind**: data class
* **purpose**: Collection of `ValidationSection`s produced by a pipeline run.
=== ValidationSection
* **kind**: data class
* **purpose**: Named group of issues from a single validator.
* **fields**: `name`, `issues`, `metadata`
=== ValidationIssue
* **kind**: data class
* **purpose**: A single finding with machine-readable code, human message, severity, and optional location.
=== ValidationSeverity
* **kind**: enum
* **variants**: `INFO`, `WARNING`, `ERROR`
=== ValidationLocation
* **kind**: sealed interface
* **purpose**: Points to where an issue was found.
* **variants**:
* `Graph(stageId, transitionId)` — issue in workflow graph
* `Session(sessionId)` — issue in session state
=== ValidationContext
* **kind**: data class
* **purpose**: Input to validators, containing the workflow graph, cycles, policies, and session state.
* **fields**: `graph` (WorkflowGraph), `detectedCycles`, `cyclePolicies`, `sessionState`
=== GraphValidator
* **kind**: class
* **purpose**: Checks start node existence, dangling transitions, and records detected cycles as INFO issues.
=== TransitionValidator
* **kind**: class
* **purpose**: Checks transition endpoint integrity and deterministic ordering per source node.
=== SessionValidator
* **kind**: class
* **purpose**: Checks temporal consistency, negative invalid transition count, and suspicious failure states.
=== SemanticValidator
* **kind**: class
* **purpose**: Runs a list of `SemanticRule` instances.
=== SemanticRule
* **kind**: interface
* **purpose**: Validates a single semantic property.
=== CyclePolicyBindingRule
* **kind**: class
* **purpose**: Warns when detected cycles lack a policy binding. Only active when `requirePolicyForCycles` is true.
=== ArtifactPayloadValidator
* **kind**: class
* **purpose**: Validates artifact payloads (`FileWrittenArtifact`, `ProcessResultArtifact`) against their schemas by reading from `ArtifactStore`.
=== ApprovalTrigger
* **kind**: class
* **purpose**: Evaluates a `ValidationReport` and returns an `ApprovalRequest` if error count > 0 or cycle policies are missing.
=== ApprovalRequest (validation)
* **kind**: data class
* **purpose**: Signals that an operation requires human approval.
* **fields**: `sessionId` (SessionId?, nullable — may be absent at early validation stage), `riskSummary` (ValidationRiskStats), `validationReport`
=== ValidationRiskStats
* **kind**: data class
* **purpose**: Summary of error and warning counts plus cycle policy status.
== event flow
*inbound:*
* None. Validation is invoked by the orchestrator before executing operations. It does not subscribe to events.
*outbound:*
* None. Validation is a pure function — it returns a sealed outcome, it does not emit events.
== integration points
* `:core:events` — shared identity types (SessionId, StageId, etc.)
* `:core:sessions` — `SessionState`, `SessionStatus`
* `:core:transitions` — `WorkflowGraph`, `DetectedCycle`, `CyclePolicyBinding`, `TransitionEdge`, `TransitionOrdering`, `CycleSignatureFactory`
* `:core:artifacts` — `FileWrittenArtifact`, `ProcessResultArtifact`, `TypedArtifactSlot`
* `:core:artifacts-store` — `ArtifactStore`
== invariants
* `ValidationOutcome.Rejected.retryable` is set by the validator and must not be overridden by the orchestrator
* Structural validation errors (ERROR severity in the graph) produce `retryable = false`
* Pipeline short-circuits on the first ERROR severity issue — remaining validators are skipped
* `ApprovalRequest` produced by `ApprovalTrigger` is implicitly `Tier.T2 (REVERSIBLE)` — validation affects workflow progression, not external state
* The `RiskSummary` and `ValidationRiskStats` types are duplicate definitions of the same data
== PlantUML diagram
[plantuml, core-validation, "png"]
----
include::../../diagrams/core-validation.puml[]
----
== known issues
* `RiskSummary` and `ValidationRiskStats` are separate data classes with identical fields — likely a leftover from refactoring.
* `ApprovalRequest` lives in the validation module but is consumed by the approvals module, which has its own `DomainApprovalRequest` type. These are two different representations of the same concept with no shared type.
== open questions
* Should the `ApprovalRequest` produced by validation share a common type with the approvals module instead of being a validation-local class?
* Should validation produce structured IDs for reports and risk summaries that are meaningful to the approvals module?