Creative operations — diagrams
Three diagrams of the same system. Edge names match creative-ops EDGES exactly.
1. Creative lifecycle
Nine states, eight forward edges (T1–T8) plus one reject edge (T3'). Terminal
states (rejected, superseded, retired) sink to nothing. T8 re-opens the
brief on a new draft.
digraph creative_lifecycle {
bgcolor="white";
rankdir=TB;
node [shape=box, style="rounded,filled", fontname=Helvetica, fontsize=10];
edge [fontname=Helvetica, fontsize=9];
// Entry / terminal — grey
start [label="brief opens", shape=circle, fillcolor="#f5f5f5", color="#525252", width=0.5, height=0.5];
done_reject [label="✕", shape=doublecircle, fillcolor="#fee2e2", color="#b91c1c", width=0.35, height=0.35];
done_super [label="✕", shape=doublecircle, fillcolor="#fee2e2", color="#b91c1c", width=0.35, height=0.35];
done_retire [label="✕", shape=doublecircle, fillcolor="#fee2e2", color="#b91c1c", width=0.35, height=0.35];
// Pre-live states — blue
draft [fillcolor="#dbeafe", color="#1d4ed8"];
generated [fillcolor="#dbeafe", color="#1d4ed8"];
in_review [fillcolor="#ede9fe", color="#6b21a8"];
approved [fillcolor="#ede9fe", color="#6b21a8"];
rejected [fillcolor="#fee2e2", color="#b91c1c"];
// Live states — green
live [fillcolor="#dcfce7", color="#15803d"];
fatigued [fillcolor="#fef3c7", color="#b45309"];
superseded [fillcolor="#fee2e2", color="#b91c1c"];
retired [fillcolor="#fee2e2", color="#b91c1c"];
// Forward edges
start -> draft [style=dashed, color="#525252"];
draft -> generated [label="T1\njob done + sha\n+ changeReason if derived"];
generated -> in_review [label="T2\ncheck-plates = 0"];
in_review -> approved [label="T3\nreview + I11"];
in_review -> rejected [label="T3'\nreason required", color="#b91c1c"];
approved -> live [label="T4\ncheck-contract + unit binding\n+ I12 human if new brief"];
live -> fatigued [label="T5\n≥5000 imp OR ≥45 days"];
live -> superseded [label="T6\nsibling live"];
live -> retired [label="T7\noperator reason"];
fatigued -> draft [label="T8\nsuccessor,\nderivedFrom set", style=dashed, color="#15803d"];
// Terminal sinks
rejected -> done_reject [style=dotted, color="#b91c1c"];
superseded -> done_super [style=dotted, color="#b91c1c"];
retired -> done_retire [style=dotted, color="#b91c1c"];
// Legend as a cluster
subgraph cluster_note {
label="notes";
style="rounded,filled";
fillcolor="#fefce8";
color="#a16207";
fontname=Helvetica;
fontsize=10;
note_t4 [shape=note, fillcolor="#fef9c3", color="#a16207",
label="T4 is the edge that bites.\nContract-valid in isolation is\nnot enough — an unbound\ncreative never serves."];
note_i12 [shape=note, fillcolor="#fef9c3", color="#a16207",
label="I12: new brief needs human:\nEstablished brief may proceed\non model: review alone."];
}
}
2. Unit construction — three boundaries
B1 admits documents to inventory. B2 is the SOLE constructor of a Unit
(Contract.unit). B3 is the last chance to refuse — non-displacement checked at
render time. Every crossing has a reject path.
digraph unit_construction {
bgcolor="white";
rankdir=LR;
compound=true;
node [shape=box, style="rounded,filled", fontname=Helvetica, fontsize=10];
edge [fontname=Helvetica, fontsize=9];
// Data sources / sinks — grey
index [label="search-index.json\n(docs[])", fillcolor="#f5f5f5", color="#525252", shape=cylinder];
query [label="query", fillcolor="#f5f5f5", color="#525252", shape=parallelogram];
dom [label="DOM", fillcolor="#f5f5f5", color="#525252", shape=box3d];
// B1 — corpus admission
subgraph cluster_b1 {
label="B1 corpus admission (build time)";
style="rounded,filled";
fillcolor="#eff6ff";
color="#1d4ed8";
fontname=Helvetica;
fontsize=11;
eligible [label="eligible?\n_id, title,\ndescription,\n≥1 keyword",
fillcolor="#dbeafe", color="#1d4ed8"];
b1_reject [label="reject\n(missing field)", shape=octagon,
fillcolor="#fee2e2", color="#b91c1c"];
eligible -> b1_reject [label="fail", color="#b91c1c", style=dashed];
}
// B2 — sole constructor
subgraph cluster_b2 {
label="B2 Contract.unit (only constructor)";
style="rounded,filled";
fillcolor="#f5f3ff";
color="#6b21a8";
fontname=Helvetica;
fontsize=11;
matched [label="matchedTerms\nkeywords ∩ query",
fillcolor="#ede9fe", color="#6b21a8"];
ctor [label="unit(...)\nfreeze + brand",
fillcolor="#ede9fe", color="#6b21a8"];
validate [label="validate\nI1 referent · I2 address\nI3 fidelity · I4 closure\nI5 alignment · I6 relevance\nI7 attribution",
fillcolor="#ede9fe", color="#6b21a8", shape=note];
b2_err [label="err(violations)\nno partial fill (I9)", shape=octagon,
fillcolor="#fee2e2", color="#b91c1c"];
matched -> ctor;
ctor -> validate;
validate -> b2_err [label="fail", color="#b91c1c", style=dashed];
}
// B3 — last refusal at render
subgraph cluster_b3 {
label="B3 render (last refusal)";
style="rounded,filled";
fillcolor="#fffbeb";
color="#b45309";
fontname=Helvetica;
fontsize=11;
snap1 [label="snapshot organic\nchildren", fillcolor="#fef3c7", color="#b45309"];
mount [label="append placement", fillcolor="#fef3c7", color="#b45309"];
snap2 [label="snapshot again\ncompare I8", fillcolor="#fef3c7", color="#b45309"];
b3_err [label="throw\nnon-displacement violated", shape=octagon,
fillcolor="#fee2e2", color="#b91c1c"];
snap1 -> mount -> snap2;
snap2 -> b3_err [label="fail", color="#b91c1c", style=dashed];
}
// Cross-cluster flow
index -> eligible [lhead=cluster_b1];
eligible -> matched [ltail=cluster_b1, lhead=cluster_b2, label="ok"];
query -> matched [lhead=cluster_b2];
validate -> snap1 [ltail=cluster_b2, lhead=cluster_b3, label="ok(Unit)"];
snap2 -> dom [ltail=cluster_b3, label="I8 holds"];
}
3. Brief cycle — one research-engraving run
Elapsed time from draft to successor. Bar widths are proportional to duration.
Generation is a hairline; review latency dominates; serving dwarfs everything.
digraph brief_cycle {
bgcolor="white";
rankdir=LR;
ranksep=0.15;
nodesep=0.05;
node [shape=box, style="rounded,filled", fontname=Helvetica, fontsize=9,
height=0.6];
edge [style=invis, minlen=0];
// Phase bars — width in inches roughly proportional to duration
// 7 min gen, 4 days review, 32 min binding, 45 days serving
// Log-ish: use fixedsize to keep width visible for tiny bars
{ rank=same;
// Generation — 7 minutes — tiny bar
gen1 [label="plan\n1m", fillcolor="#dbeafe", color="#1d4ed8",
fixedsize=true, width=0.15];
gen2 [label="flux2-klein\n3m", fillcolor="#dbeafe", color="#1d4ed8",
fixedsize=true, width=0.20];
gen3 [label="crop\n1m", fillcolor="#dbeafe", color="#1d4ed8",
fixedsize=true, width=0.15];
gen4 [label="check-plates\n2m", fillcolor="#dbeafe", color="#1d4ed8",
fixedsize=true, width=0.18];
// Review — 4 days — medium bar (I12 waiting for human)
rev1 [label="wait for human reviewer (I12)\n4 days",
fillcolor="#ede9fe", color="#6b21a8",
fixedsize=true, width=3.5];
rev2 [label="T3\napprove\n15m", fillcolor="#ede9fe", color="#6b21a8",
fixedsize=true, width=0.25];
// Binding — 32 minutes — small bar
bind1 [label="bind creative\nto units\n30m",
fillcolor="#fef3c7", color="#b45309",
fixedsize=true, width=0.4];
bind2 [label="check-\ncontract\n2m", fillcolor="#fef3c7", color="#b45309",
fixedsize=true, width=0.2];
// Serving — 45 days — huge bar (accrues to fatigue)
serve [label="live · accruing impressions\n45 days (POLICY.fatigueDays)",
fillcolor="#dcfce7", color="#15803d",
fixedsize=true, width=4.0];
// Successor
succ [label="T8\nsuccessor\nopen\n1m",
fillcolor="#dbeafe", color="#1d4ed8",
fixedsize=true, width=0.28];
}
gen1 -> gen2 -> gen3 -> gen4 -> rev1 -> rev2 -> bind1 -> bind2 -> serve -> succ;
// Milestone markers below the timeline
m_t2 [label="T2", shape=circle, fillcolor="white", color="#525252",
fontsize=8, width=0.3, height=0.3];
m_t4 [label="T4", shape=circle, fillcolor="white", color="#525252",
fontsize=8, width=0.3, height=0.3];
m_t5 [label="T5", shape=circle, fillcolor="white", color="#525252",
fontsize=8, width=0.3, height=0.3];
{ rank=sink; m_t2; m_t4; m_t5; }
gen4 -> m_t2 [style=dotted, minlen=1];
bind2 -> m_t4 [style=dotted, minlen=1];
serve -> m_t5 [style=dotted, minlen=1];
// Legend cluster
subgraph cluster_share {
label="phase share (excl. serving is 92%)";
style="rounded,filled";
fillcolor="#fefce8";
color="#a16207";
fontname=Helvetica; fontsize=10;
share [shape=plaintext, label=<
<table border="0" cellborder="1" cellspacing="0" cellpadding="4">
<tr><td align="left"><b>Phase</b></td><td><b>Elapsed</b></td><td><b>Share</b></td></tr>
<tr><td align="left" bgcolor="#dbeafe">Generation</td><td>~7 min</td><td>0.01%</td></tr>
<tr><td align="left" bgcolor="#ede9fe">Review wait</td><td>4 days</td><td>8%</td></tr>
<tr><td align="left" bgcolor="#fef3c7">Binding</td><td>~32 min</td><td>0.05%</td></tr>
<tr><td align="left" bgcolor="#dcfce7">Serving</td><td>45 days</td><td>92%</td></tr>
<tr><td align="left" colspan="3"><i>generation : review ≈ 1 : 800</i></td></tr>
</table>
>];
}
}
4. Reading the timeline
Two caveats the diagram cannot show. The 4-day review wait is a placeholder
until I12 has actually blocked something — an unqueued reviewer has no measured
latency. And the 45-day POLICY.fatigueDays will bind before
POLICY.fatigueImpressions at wal.sh traffic, so every creative fatigues on
age; the impression threshold is effectively dead code and worth dropping.
5. Rendering
Diagrams regenerate via gmake diagrams (calls elisp/regen-diagrams.el which
org-babel-execute-src-block on every dot block in this file). The generated
PNGs land alongside as creative-lifecycle.png etc. per Graphviz convention.
:exports both shows both dot source and image in the HTML render.