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.
152 lines
7.1 KiB
Plaintext
152 lines
7.1 KiB
Plaintext
= core-artifacts
|
|
|
|
== purpose
|
|
|
|
Defines the artifact model — a structured output produced during a workflow stage. Manages artifact lifecycle phases (created → validating → validated/rejected → superseded/archived) as event-sourced state, provides a kind system for typed artifact payloads (file_written, process_result), and supports materialization of file artifacts to disk.
|
|
|
|
== responsibilities
|
|
|
|
* Defining the `Artifact` sealed interface and its common fields (id, session, stage, lifecycle phase, lineage, metadata)
|
|
* Managing artifact lifecycle phase transitions with state machine validation
|
|
* Tracking artifact lineage (parent IDs, relationships, validation report IDs)
|
|
* Defining and registering `ArtifactKind` implementations for typed payloads
|
|
* Providing JSON schema derivation for each artifact kind
|
|
* Materializing file artifacts to disk via `MaterializingArtifactWriter`
|
|
* Providing a repository interface for querying artifact state by session, stage, or ID
|
|
|
|
== non-responsibilities
|
|
|
|
* Does not manage binary blob storage — that is delegated to `:core:artifacts-store` via `ArtifactStore`
|
|
* Does not validate artifact payloads — validation is handled by `:core:validation` via `ArtifactPayloadValidator`
|
|
* Does not produce artifacts — they are created by the orchestrator or infrastructure adapters
|
|
* Does not manage the full artifact content — only metadata and lifecycle state are projected
|
|
|
|
== key types
|
|
|
|
=== Artifact
|
|
* **kind**: sealed interface
|
|
* **purpose**: Base type for all artifacts. Declares common fields.
|
|
* **fields**: `id`, `sessionId`, `stageId`, `schemaVersion`, `createdAt`, `lifecyclePhase`, `lineage`, `metadata`
|
|
|
|
=== ArtifactState
|
|
* **kind**: data class
|
|
* **purpose**: Event-sourced projection of a single artifact's lifecycle state.
|
|
* **fields**: `phase` (ArtifactLifecyclePhase), `lineage` (ArtifactLineage)
|
|
|
|
=== ArtifactReducer / DefaultArtifactReducer
|
|
* **kind**: interface / class
|
|
* **purpose**: Transforms `ArtifactState` given a stored event. Validates lifecycle phase transitions and returns `Result.Failure` for illegal transitions. Handles `ArtifactCreatedEvent`, `ArtifactValidatingEvent`, `ArtifactValidatedEvent`, `ArtifactRejectedEvent`, `ArtifactSupersededEvent`, `ArtifactArchivedEvent`, `ArtifactRelationshipAddedEvent`.
|
|
|
|
=== ArtifactProjector
|
|
* **kind**: class
|
|
* **purpose**: Wraps `ArtifactReducer` as a `Projection<ArtifactState>`. Invalid lifecycle transitions are logged as warnings and do not crash replay.
|
|
|
|
=== ArtifactLineage
|
|
* **kind**: data class
|
|
* **purpose**: Tracks an artifact's provenance.
|
|
* **fields**: `parentIds`, `relationships` (list of ArtifactRelationship), `validationReportIds`
|
|
|
|
=== ArtifactRelationship
|
|
* **kind**: data class
|
|
* **purpose**: A directed, typed relationship between two artifacts.
|
|
* **fields**: `sourceId`, `targetId`, `type` (ArtifactRelationshipType)
|
|
|
|
=== ArtifactKind
|
|
* **kind**: interface
|
|
* **purpose**: Declares a type of artifact with a payload serializer and JSON schema.
|
|
* **fields**: `id`, `payloadSerializer`, `llmEmitted`
|
|
|
|
=== ArtifactKindRegistry / DefaultArtifactKindRegistry
|
|
* **kind**: interface / class
|
|
* **purpose**: Maps artifact kind IDs to `ArtifactKind` instances. Pre-registers `FileWrittenKind` and `ProcessResultKind`.
|
|
|
|
=== FileWrittenKind
|
|
* **kind**: object
|
|
* **purpose**: Artifact kind for files written to disk. Declares a JSON schema with `path`, `content`, `mode`.
|
|
|
|
=== FileWrittenPayload
|
|
* **kind**: data class
|
|
* **purpose**: Input payload for a file write operation (before materialization).
|
|
* **fields**: `path`, `content`, `mode`
|
|
|
|
=== FileWrittenArtifact
|
|
* **kind**: data class
|
|
* **purpose**: Canonical form of a written file after materialization (content-addressed by hash).
|
|
* **fields**: `path`, `contentHash`, `size`, `mode`
|
|
|
|
=== ProcessResultKind
|
|
* **kind**: object
|
|
* **purpose**: Artifact kind for process execution results. Declares a JSON schema with `command`, `exitCode`, `stdout`, `stderr`, `durationMs`.
|
|
|
|
=== ProcessResultArtifact
|
|
* **kind**: data class
|
|
* **purpose**: Record of a process execution.
|
|
* **fields**: `command`, `exitCode`, `stdout`, `stderr`, `durationMs`
|
|
|
|
=== TypedArtifactSlot
|
|
* **kind**: data class
|
|
* **purpose**: Associates a named artifact slot with its expected kind.
|
|
* **fields**: `name` (ArtifactId), `kind` (ArtifactKind)
|
|
|
|
=== MaterializingArtifactWriter
|
|
* **kind**: interface
|
|
* **purpose**: Writes a `FileWrittenPayload` to disk within a sandbox root and returns a `FileWrittenArtifact`. Supports content-addressed storage by returning a hash.
|
|
|
|
=== MaterializationResult
|
|
* **kind**: sealed interface
|
|
* **purpose**: Outcome of a materialization attempt.
|
|
* **variants**: `Success(artifact, resolvedPath)`, `Failure(reason)`
|
|
|
|
=== ArtifactRepository
|
|
* **kind**: interface
|
|
* **purpose**: Queries artifact state by session, stage, or ID.
|
|
|
|
=== JsonSchema / JsonSchemaProperty
|
|
* **kind**: data classes
|
|
* **purpose**: JSON Schema representation for artifact kind derived schemas.
|
|
|
|
== event flow
|
|
|
|
*inbound:*
|
|
* `ArtifactCreatedEvent` → sets phase to `CREATED`
|
|
* `ArtifactValidatingEvent` → transitions from `CREATED` to `VALIDATING` (fails if phase is not `CREATED`)
|
|
* `ArtifactValidatedEvent` → transitions from `VALIDATING` to `VALIDATED`
|
|
* `ArtifactRejectedEvent` → transitions from `VALIDATING` to `REJECTED`
|
|
* `ArtifactSupersededEvent` → transitions from `VALIDATED` to `SUPERSEDED`
|
|
* `ArtifactArchivedEvent` → transitions from `VALIDATED` or `REJECTED` to `ARCHIVED`
|
|
* `ArtifactRelationshipAddedEvent` → adds a relationship to the lineage
|
|
|
|
*outbound:*
|
|
* None. This module is purely a projection.
|
|
|
|
== integration points
|
|
|
|
* `:core:events` — `StoredEvent`, artifact lifecycle event types, `ArtifactId`, `ArtifactLifecyclePhase`, `ArtifactRelationshipType`
|
|
|
|
== invariants
|
|
|
|
* Lifecycle phase transitions follow a strict state machine: `CREATED → VALIDATING → {VALIDATED, REJECTED}`, then `VALIDATED → {SUPERSEDED, ARCHIVED}`, `REJECTED → ARCHIVED`
|
|
* Invalid transitions return `Result.Failure` from the reducer — they do not crash the projector
|
|
* `ArtifactProjector` catches `IllegalStateException` from invalid transitions, logs a warning, and leaves state unchanged during replay
|
|
* `ArtifactKind` registrations are idempotent — the registry is a map, so re-registering overwrites the previous entry
|
|
|
|
== PlantUML diagram
|
|
|
|
[plantuml, core-artifacts, "png"]
|
|
----
|
|
include::../../diagrams/core-artifacts.puml[]
|
|
----
|
|
|
|
|
|
|
|
|
|
== known issues
|
|
|
|
* `Artifact` sealed interface has no concrete subclasses in the current codebase. The `artifactModule` serializers module has a polymorphic block for `Artifact::class` with no subclass registrations. Concrete artifact types are needed before polymorphic serialization works.
|
|
* `ArtifactState` is a single-artifact projection — each `ArtifactState` tracks one artifact's lifecycle. The `ArtifactRepository` interface returns maps keyed by `ArtifactId`, which suggests the caller is responsible for aggregating multiple states.
|
|
|
|
== open questions
|
|
|
|
* How are multiple artifact states (one per artifact) stored and queried? The repository returns maps, but the event replayer typically rebuilds a single state per session. The bridge between them is not visible in this module.
|
|
* What concrete `Artifact` subclasses are planned? (The sealed interface exists but has no implementations.)
|