Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
434 changes: 434 additions & 0 deletions ARTIFACT_GOVERNANCE_COMPLETE.md

Large diffs are not rendered by default.

395 changes: 395 additions & 0 deletions ARTIFACT_WORKFLOW_DIAGRAM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,395 @@
# Artifact Workflow: Type-Safe Comic Generation

**Updated:** 2026-05-10
**Pattern:** {variant: "Ok"|"Err"} with immutable artifact emission
**Workflow:** MCP subprocess invocation → Rhai processing → Artifact storage → Relation creation

---

## Complete Artifact Flow Diagram

```mermaid
graph TB
subgraph "1. Script Generation Stage"
A["fa:fa-code script_generation(context)"]
B["Validate: script_a, script_b"]
C["BUILD artifact_a: DocumentChunk"]
D["BUILD artifact_b: DocumentChunk"]
E["BUILD provenance"]
F{"variant:<br/>Ok or Err?"}
A --> B --> C --> D --> E --> F
end

subgraph "2. Image Rendering Stage"
G["fa:fa-image image_rendering(context)"]
H["Validate: image_path_a, image_path_b"]
I["BUILD artifact_image_a: EvidenceReference"]
J["BUILD artifact_image_b: EvidenceReference"]
K["BUILD provenance"]
L{"variant:<br/>Ok or Err?"}
G --> H --> I --> J --> K --> L
end

subgraph "3. Forecasting Stage"
M["fa:fa-chart-line forecasting_and_log(context)"]
N["Validate: metrics, scores"]
O["BUILD artifact_forecast: ClassificationOutcome"]
P["BUILD provenance"]
Q{"variant:<br/>Ok or Err?"}
M --> N --> O --> P --> Q
end

subgraph "4. Voting Stage"
R["fa:fa-check-square record_vote(context)"]
S["Validate: voter_hash, choice"]
T["NORMALIZE: null → abstain"]
U["BUILD artifact_vote: AuditEvent"]
V["BUILD provenance"]
W{"variant:<br/>Ok or Err?"}
R --> S --> T --> U --> V --> W
end

subgraph "5. Artifact Storage (MCP Client - TypeScript)"
X["Store artifact in<br/>ontology_artifacts"]
Y["Create Relation:<br/>from → to<br/>type: DerivedFrom|ReviewedByOperator"]
Z["Return artifact_id<br/>+ relation_id"]
X --> Y --> Z
end

subgraph "6. Vote Deduplication (Hybrid)"
AA["INSERT INTO votes<br/>ON CONFLICT UPDATE"]
AB["All vote moments<br/>visible in audit"]
AA --> AB
end

subgraph "7. UX Display"
AC["fa:fa-desktop Comic View"]
AD["Show provenance"]
AE["Show artifact chain"]
AF["Show vote results<br/>with engagement"]
AC --> AD --> AE --> AF
end

F -->|Ok| X
F -->|Err| AC
L -->|Ok| X
L -->|Err| AC
Q -->|Ok| X
Q -->|Err| AC
W -->|Ok| AA
W -->|Err| AC
Z --> AC
AB --> AF
```

---

## State Flow: Success Path

```mermaid
stateDiagram-v2
[*] --> ScriptGen

ScriptGen: script_generation()
ScriptGen: Returns: {variant: Ok, value: {artifact_a, artifact_b, provenance}}

ScriptGen --> StoreScript

StoreScript: Store artifact_a, artifact_b
StoreScript: to ontology_artifacts table

StoreScript --> CreateScriptRelation

CreateScriptRelation: Create Relation(comic → script_a, "DerivedFrom")
CreateScriptRelation: Create Relation(comic → script_b, "DerivedFrom")

CreateScriptRelation --> ImageGen

ImageGen: image_rendering()
ImageGen: Returns: {variant: Ok, value: {artifact_image_a, artifact_image_b, provenance}}

ImageGen --> StoreImage

StoreImage: Store artifact_image_a, artifact_image_b
StoreImage: to ontology_artifacts table

StoreImage --> CreateImageRelation

CreateImageRelation: Create Relation(script_a → image_a, "DerivedFrom")
CreateImageRelation: Create Relation(script_b → image_b, "DerivedFrom")

CreateImageRelation --> Forecast

Forecast: forecasting_and_log()
Forecast: Returns: {variant: Ok, value: {artifact_forecast, provenance}}

Forecast --> StoreForecast

StoreForecast: Store artifact_forecast
StoreForecast: to ontology_artifacts table

StoreForecast --> CreateForecastRelation

CreateForecastRelation: Create Relation(comic → forecast, "ClassifiedAs")

CreateForecastRelation --> WaitForVotes

WaitForVotes: Voting opens (24 hours)

WaitForVotes --> RecordVote

RecordVote: record_vote(choice: a | b | abstain)
RecordVote: Returns: {variant: Ok, value: {artifact_vote, provenance}}

RecordVote --> StoreVote

StoreVote: INSERT INTO votes (mutable)
StoreVote: Store artifact_vote (immutable)

StoreVote --> CreateVoteRelation

CreateVoteRelation: Create Relation(comic → vote, "ReviewedByOperator")
CreateVoteRelation: Timestamp in relation provenance

CreateVoteRelation --> DisplayComic

DisplayComic: [*]
```

---

## Error Paths

```mermaid
stateDiagram-v2
[*] --> ScriptGen

ScriptGen: script_generation(context)

ScriptGen --> ValidateScripts

ValidateScripts: if script_a == "" or script_b == ""

ValidateScripts --> ErrorScript: validation fails
ValidateScripts --> Proceed1: validation passes

ErrorScript: Return {variant: Err, error_code: "script_validation_failed", reason: "...", input_received: {...}}
ErrorScript --> AuditError

Proceed1 --> ImageGen
ImageGen: image_rendering(context)
ImageGen --> ValidateImages

ValidateImages: if image_path_a == "" or image_path_b == ""
ValidateImages --> ErrorImage: validation fails
ValidateImages --> Proceed2: validation passes

ErrorImage: Return {variant: Err, error_code: "image_validation_failed", ...}
ErrorImage --> AuditError

Proceed2 --> Forecast
Forecast: forecasting_and_log(context)
Forecast --> ValidateMetrics

ValidateMetrics: if metrics == null or metrics == ""
ValidateMetrics --> ErrorForecast: validation fails
ValidateMetrics --> DisplaySuccess: validation passes

ErrorForecast: Return {variant: Err, error_code: "forecast_validation_failed", ...}
ErrorForecast --> AuditError

AuditError: Log error to audit trail
AuditError: Notify operator for review
AuditError --> [*]

DisplaySuccess: [*]
```

---

## Artifact ID Determinism

```mermaid
graph LR
A["Input: variant_a, day, model_a, script_a"]
B["blake3 hash function"]
C["content-hash digest"]
D["Artifact ID: blake3_variant_a2026-05-10Gemma4..."]

A --> B --> C --> D

E["Same inputs"]
E --> F["Same artifact_id"]

G["Different day"]
H["Different script_a"]
I["Different model_a"]

G --> J["Different artifact_id"]
H --> J
I --> J

F -.-> K["Idempotent within-day"]
J -.-> L["Unique across days<br/>or models"]
```

---

## Ontology Mapping

```mermaid
graph TB
subgraph "Artifact Types (ArtifactKind enum)"
Comic["Comic<br/>(ModelProposal)"]
Script["Script Variant A<br/>(DocumentChunk)"]
Image["Image Variant A<br/>(EvidenceReference)"]
Vote["Vote Record<br/>(AuditEvent)"]
Forecast["Forecast<br/>(ClassificationOutcome)"]
end

subgraph "Relations (RelationKind enum)"
R1["DerivedFrom"]
R2["ReviewedByOperator"]
R3["ClassifiedAs"]
end

Comic -->|DerivedFrom| Script
Script -->|DerivedFrom| Image
Comic -->|ReviewedByOperator| Vote
Comic -->|ClassifiedAs| Forecast

Comic -.-> R1
Script -.-> R1
Vote -.-> R2
Forecast -.-> R3
```

---

## Provenance Chain

```mermaid
graph TB
subgraph "script_generation() Provenance"
P1["generated_at: timestamp"]
P2["generator: rhai"]
P3["day: 2026-05-10"]
P4["seed: 12345"]
P5["model_a: Gemma4"]
P6["model_b: Qwen3"]
end

subgraph "image_rendering() Provenance"
Q1["rendered_at: timestamp"]
Q2["generator: rhai"]
Q3["day: 2026-05-10"]
Q4["model_a: FLUX"]
Q5["model_b: FLUX"]
Q6["images_validated: 2"]
end

subgraph "record_vote() Provenance"
R1["recorded_at: timestamp"]
R2["generator: rhai"]
R3["day: 2026-05-10"]
R4["voter: voter_hash"]
R5["choice: a|b|abstain"]
end

subgraph "Immutable in Artifact.attrs"
S["All provenance stored"]
S["in artifact attrs"]
S["BTreeMap<String, String>"]
end

P1 --> S
P2 --> S
P3 --> S
P4 --> S
P5 --> S
P6 --> S
Q1 --> S
Q2 --> S
Q3 --> S
Q4 --> S
Q5 --> S
Q6 --> S
R1 --> S
R2 --> S
R3 --> S
R4 --> S
R5 --> S
```

---

## Vote Counting: Hybrid Mutable/Immutable

```mermaid
graph TB
subgraph "Mutable Layer (votes table)"
A["INSERT INTO votes (day, voter_hash, choice)"]
B["ON CONFLICT(day, voter_hash) DO UPDATE"]
C["Always ONE row per voter"]
D["Used for vote counts"]
A --> B --> C --> D
end

subgraph "Immutable Layer (ontology_artifacts)"
E["Each vote moment →"]
E --> F["NEW AuditEvent artifact"]
F --> G["Different timestamp"]
G --> H["Different artifact_id"]
H --> I["Full audit trail visible"]
end

subgraph "Fitness Calculation"
J["SELECT choice, COUNT FROM votes"]
K["voteA, voteB, abstain"]
L["engagement = voteA + voteB"]
M["variant_a_score = voteA / engaged"]
N["fitness_a = score * engagement"]
J --> K --> L --> M --> N
end

D --> J
I --> J
```

---

## Type-Safe Return Pattern

```mermaid
graph TB
subgraph "Success Case"
A["return {"]
B[" variant: Ok,"]
C[" value: {"]
D[" artifact_a: Artifact,"]
E[" artifact_b: Artifact,"]
F[" provenance: map,"]
G[" audit_entry: map"]
H[" }"]
I["}"]
A --> B --> C --> D --> E --> F --> G --> H --> I
end

subgraph "Error Case"
J["return {"]
K[" variant: Err,"]
L[" error_code: string,"]
M[" reason: string,"]
N[" input_received: map"]
O["}"]
J --> K --> L --> M --> N --> O
end

subgraph "Abstain Case (null → abstain)"
P["Input: choice = null"]
Q["Normalize: null → abstain"]
R["Output: attrs.choice = abstain"]
P --> Q --> R
end
```

Loading
Loading