# Data Model: Clean Release Compliance Subsystem Redesign **Feature**: [`025-clean-release-compliance`](specs/025-clean-release-compliance) **Spec**: [`spec.md`](specs/025-clean-release-compliance/spec.md) **Research**: [`research.md`](specs/025-clean-release-compliance/research.md) ## 1. Entity: ReleaseCandidate Represents the release unit that is being prepared, checked, approved and published. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Stable candidate identifier. | | version | string | Yes | Release version label. | | source_snapshot_ref | string | Yes | Reference to code/source snapshot used to create candidate. | | build_id | string | No | Upstream build or pipeline identifier. | | created_at | datetime | Yes | Candidate creation timestamp. | | created_by | string | Yes | Actor that created the candidate. | | provenance_ref | string | No | Optional provenance or attestation reference. | | status | enum | Yes | Current lifecycle state. | ### Validation Rules - `id`, `version`, `source_snapshot_ref`, `created_at`, `created_by`, `status` must be present. - `status` must be one of: `DRAFT`, `PREPARED`, `MANIFEST_BUILT`, `CHECK_PENDING`, `CHECK_RUNNING`, `CHECK_PASSED`, `CHECK_BLOCKED`, `CHECK_ERROR`, `APPROVED`, `PUBLISHED`, `REVOKED`. - Terminal publication evidence cannot exist without a valid candidate. ### Lifecycle / State Transitions - `DRAFT -> PREPARED` - `PREPARED -> MANIFEST_BUILT` - `MANIFEST_BUILT -> CHECK_PENDING` - `CHECK_PENDING -> CHECK_RUNNING` - `CHECK_RUNNING -> CHECK_PASSED` - `CHECK_RUNNING -> CHECK_BLOCKED` - `CHECK_RUNNING -> CHECK_ERROR` - `CHECK_PASSED -> APPROVED` - `APPROVED -> PUBLISHED` - `PUBLISHED -> REVOKED` --- ## 2. Entity: CandidateArtifact Represents one artifact associated with a release candidate. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Stable artifact identifier. | | candidate_id | string | Yes | Owning release candidate. | | path | string | Yes | Artifact path or logical location. | | sha256 | string | Yes | Artifact checksum. | | size | integer | Yes | Artifact size in bytes. | | detected_category | string | No | Category determined by system or pipeline. | | declared_category | string | No | Category declared by external input. | | source_uri | string | No | Artifact source URI if known. | | source_host | string | No | Parsed source host if known. | | metadata | object | Yes | Additional attributes. | ### Validation Rules - `sha256` must be present and stable for the artifact content. - `size >= 0`. - `declared_category` and `detected_category` may differ, but the difference must remain observable. --- ## 3. Entity: DistributionManifest Immutable snapshot describing the candidate payload selected for distribution. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Stable manifest identifier. | | candidate_id | string | Yes | Owning release candidate. | | manifest_version | integer | Yes | Monotonic manifest version per candidate. | | manifest_digest | string | Yes | Overall digest of manifest content. | | artifacts_digest | string | Yes | Digest over artifact selection. | | created_at | datetime | Yes | Manifest creation time. | | created_by | string | Yes | Actor that built the manifest. | | source_snapshot_ref | string | Yes | Source snapshot bound to the manifest. | | content_json | object | Yes | Serialized immutable manifest content. | | immutable | boolean | Yes | Must be `true` after creation. | ### Validation Rules - `manifest_version >= 1` and strictly increases for a candidate. - Existing manifest content cannot be overwritten. - `manifest_digest` must uniquely reflect `content_json`. --- ## 4. Entity: CleanPolicySnapshot Immutable policy snapshot used to evaluate a run. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Snapshot identifier. | | policy_id | string | Yes | Logical policy identifier in trusted store. | | policy_version | string | Yes | Trusted policy version. | | created_at | datetime | Yes | Snapshot creation time. | | content_json | object | Yes | Frozen policy content. | | registry_snapshot_id | string | Yes | Bound source registry snapshot. | | immutable | boolean | Yes | Must be `true`. | ### Validation Rules - Snapshot must reference a valid registry snapshot. - UI/env input cannot mutate `content_json` after creation. --- ## 5. Entity: SourceRegistrySnapshot Immutable registry snapshot for allowed sources and schemes. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Snapshot identifier. | | registry_id | string | Yes | Logical trusted registry identifier. | | registry_version | string | Yes | Trusted registry version. | | created_at | datetime | Yes | Snapshot creation time. | | allowed_hosts | array[string] | Yes | Allowed hosts or host patterns. | | allowed_schemes | array[string] | Yes | Allowed URL schemes. | | allowed_source_types | array[string] | Yes | Allowed source type labels. | | immutable | boolean | Yes | Must be `true`. | --- ## 6. Entity: ComplianceRun Operational record for one compliance execution request. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Run identifier. | | candidate_id | string | Yes | Candidate being checked. | | manifest_id | string | Yes | Manifest used for the run. | | manifest_digest | string | Yes | Manifest digest copied at request time. | | policy_snapshot_id | string | Yes | Policy snapshot used. | | registry_snapshot_id | string | Yes | Registry snapshot used. | | requested_by | string | Yes | Actor that requested the run. | | requested_at | datetime | Yes | Request time. | | started_at | datetime | No | Execution start time. | | finished_at | datetime | No | Execution finish time. | | status | enum | Yes | Execution status. | | final_status | enum | No | Final compliance result. | | failure_reason | string | No | System or validation failure summary. | | task_id | string | No | Linked async task identifier. | ### Validation Rules - `status` must be one of `PENDING`, `RUNNING`, `SUCCEEDED`, `FAILED`, `CANCELLED`. - `final_status`, when present, must be one of `PASSED`, `BLOCKED`, `ERROR`. - `task_id` is mutable only until execution binding is established. --- ## 7. Entity: ComplianceStageRun Stage-level execution record inside one run. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Stage run identifier. | | run_id | string | Yes | Owning compliance run. | | stage_name | string | Yes | Canonical stage name. | | status | string | Yes | Stage execution status. | | started_at | datetime | No | Stage start time. | | finished_at | datetime | No | Stage finish time. | | decision | string | No | `PASSED`, `BLOCKED`, or `ERROR`. | | details_json | object | Yes | Structured stage details. | --- ## 8. Entity: ComplianceViolation Violation produced by one stage within one run. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Violation identifier. | | run_id | string | Yes | Owning compliance run. | | stage_name | string | Yes | Stage that detected the issue. | | code | string | Yes | Canonical violation code. | | severity | string | Yes | Severity label. | | artifact_path | string | No | Related artifact path. | | artifact_sha256 | string | No | Related artifact checksum. | | message | string | Yes | Human-readable explanation. | | evidence_json | object | Yes | Structured evidence. | ### Validation Rules - Violations cannot be deleted in real mode. - `code`, `severity`, `message` must be present. --- ## 9. Entity: ComplianceReport Immutable result derived from a completed run. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Report identifier. | | run_id | string | Yes | Source compliance run. | | candidate_id | string | Yes | Candidate checked by this run. | | final_status | string | Yes | Final outcome. | | summary_json | object | Yes | Structured summary of stages and violations. | | generated_at | datetime | Yes | Report generation time. | | immutable | boolean | Yes | Must be `true`. | --- ## 10. Entity: ApprovalDecision Approval or rejection bound to a candidate and report. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Decision identifier. | | candidate_id | string | Yes | Candidate being decided. | | report_id | string | Yes | Report used as approval basis. | | decision | string | Yes | `APPROVED` or `REJECTED`. | | decided_by | string | Yes | Actor making the decision. | | decided_at | datetime | Yes | Decision timestamp. | | comment | string | No | Optional operator note. | --- ## 11. Entity: PublicationRecord Publication or revocation record bound to a candidate. ### Fields | Field | Type | Required | Description | |---|---|---|---| | id | string | Yes | Publication identifier. | | candidate_id | string | Yes | Published candidate. | | report_id | string | Yes | Approved report used as basis. | | published_by | string | Yes | Publishing actor. | | published_at | datetime | Yes | Publish time. | | target_channel | string | Yes | Target release channel. | | publication_ref | string | No | External publish reference. | | status | string | Yes | Publication status label. | --- ## 12. Entity: CandidateOverviewDTO Read model used by CLI, TUI and API to show current candidate state. ### Fields | Field | Type | Required | Description | |---|---|---|---| | candidate_id | string | Yes | Candidate identifier. | | version | string | Yes | Candidate version. | | source_snapshot_ref | string | Yes | Source snapshot ref. | | status | string | Yes | Current lifecycle status. | | latest_manifest_id | string | No | Latest manifest identifier. | | latest_manifest_digest | string | No | Latest manifest digest. | | latest_run_id | string | No | Latest run identifier. | | latest_run_status | string | No | Latest run execution status. | | latest_report_id | string | No | Latest report identifier. | | latest_report_final_status | string | No | Latest report final status. | | latest_policy_snapshot_id | string | No | Latest policy snapshot identifier. | | latest_policy_version | string | No | Latest policy version used for latest run. | | latest_registry_snapshot_id | string | No | Latest registry snapshot identifier. | | latest_registry_version | string | No | Latest registry version used for latest run. | | latest_approval_decision | string | No | Latest approval decision affecting publication gate. | | latest_publication_id | string | No | Latest publication identifier. | | latest_publication_status | string | No | Latest publication status. | --- ## 13. Entity: ComplianceRunDTO Read model for run status tracking. ### Fields | Field | Type | Required | Description | |---|---|---|---| | run_id | string | Yes | Run identifier. | | candidate_id | string | Yes | Candidate identifier. | | status | string | Yes | Run execution status. | | final_status | string | No | Final compliance result. | | report_id | string | No | Final report identifier. | | task_id | string | Yes | Linked task identifier. | --- ## 14. Entity: ReportDTO Compact report view used by interfaces. ### Fields | Field | Type | Required | Description | |---|---|---|---| | report_id | string | Yes | Report identifier. | | candidate_id | string | Yes | Candidate identifier. | | final_status | string | Yes | Final report result. | | policy_version | string | Yes | Policy version used for the report. | | manifest_digest | string | Yes | Manifest digest used for the run. | | violation_count | integer | Yes | Number of violations. | | generated_at | datetime | Yes | Report generation time. | --- ## 15. Relationships - `ReleaseCandidate 1 -> N CandidateArtifact` - `ReleaseCandidate 1 -> N DistributionManifest` - `ReleaseCandidate 1 -> N ComplianceRun` - `ComplianceRun 1 -> N ComplianceStageRun` - `ComplianceRun 1 -> N ComplianceViolation` - `ComplianceRun 1 -> 1 ComplianceReport` (for terminal runs that produce a report) - `ComplianceReport 1 -> N ApprovalDecision` (history allowed, latest valid decision governs) - `ReleaseCandidate 1 -> N PublicationRecord` - `CleanPolicySnapshot 1 -> 1 SourceRegistrySnapshot` ## 16. Invariants - Policy, registry, manifest, report, approval and publication snapshots are immutable after creation. - Real mode compliance evidence is append-only and not user-deletable. - `APPROVED` requires a valid `PASSED` report. - `PUBLISHED` requires a valid approval. - `REJECTED` is modeled as an immutable latest approval decision, not as a separate candidate lifecycle state. - Demo namespace never shares identifiers or historical storage with real mode. ## 17. Scale Assumptions - Candidate histories may accumulate multiple manifests and multiple compliance runs per release. - A single run may produce many violations and stage details, so read models should not require loading all artifacts for each overview request. - Most interface reads use latest-only summary views, while audit and compliance screens require full history retrieval.