9734eec63c
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.
157 lines
6.4 KiB
Plaintext
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?
|