Skip to content
Like what we’re building? Star on GitHub

Data model — runs and their satellites ​

A run is one execution; this page draws its per-run streams, its tree, the collections its launch and its outcome bind it to, and its assistant supervision.

Drawn from the code at commit 61a305262 — main at v3.266.1, after #2391, which carries the launch rung; how this page is kept true: README.

Block 1 — the run and its per-run streams ​

  • Every stream names its run with a top-level run_id. run_seq is the one exception — its run id lives inside the compound _id. The counter is one row per (tenant value, run), not one per run.
  • A gap in seq is normal.
  • interactions is the durable question/answer record and runs.checkpoint.interaction_id is only a pointer to the pending one.
  • dev is a tenant value, not a team. A server started with DisableAuth stamps the store ctx under the id dev for both tenant and owner, so every row written in that ctx — for example events — carries tenant_id: dev.

Block 2 — the run tree and the run's identity edges ​

  • The four self-edges look alike and mean different things. parent_run_id is the tree. subbot_children is the parent's subbot re-attach map. forked_from records the run a fork was taken from. A delegated run is not in its source's tree.
  • source.schedule_id may be a cloud scheduled_bots._id, a host-cron entry name or a trigger subscription id — polymorphic, hence the dotted edge here, where the automation page draws one solid edge per resolvable value — scheduled_bots for a cloud schedule id.
  • Every satellite here is optional.
  • run_secrets._id never appears on the run document: the publisher writes it into the queue message.

Block 3 — assistant supervision and outcomes ​

  • One idempotence motif, three keys: (run_id, outcome_seq) settles a routing decision, (watch_id, outcome_event_id) settles a watch delivery, (tenant_id, operator_id, invocation_key) settles a mission. Each is a unique index.
  • The run locks in NATS KV are the runner's execution lease. They are not the leases collection, which is charted on the automation page.

Where a run's bytes live ​

Outside Mongo, a cloud run writes into six S3 key spaces of one bucket — beside a seventh, uploads/, where the server stages what a launch form uploads before any run exists — and one NATS KV bucket, and its launch travels on a JetStream subject; a second KV bucket holds the fleet's rollout epoch. The marked participants of Block 3 are the two stores a run itself writes; the streams are transport rather than state, so no entity draws them. The six run key spaces are keyed by the run id alone, with no tenant in the key: they are deleted by store.DeleteRun — DELETE /api/runs/{id}, and the org purge, which deletes each run of a purged org through it before any Mongo row goes (flow-org-team-lifecycle.md).

storekey or namewhat it holds
S3, bucket iterion-artifacts (the default name)artifacts/<run>/<node>/<version>.jsonone object per artifact revision of a node
S3attachments/<run>/<name>/<file>the attachment bodies runs.attachments indexes — plus the reserved name __gitdiff, where a per-file diff too large to inline is offloaded and deliberately left OUT of that index
S3tools/<run>/<toolUseID>/input · /outputone object per tool call and direction
S3ir/<run>.json · ir/<run>-bundle-<digest>.jsonthe compiled IR when it rides out of band, and the immutable bundle snapshot when it exceeds the queue payload — both deleted by DeleteRunIR
S3sessions/<run>/<ref>the backend conversation a resume reattaches to
S3runfiles/<run>/<rel path>tool-produced files
S3uploads/<upload>/<file>an upload a launch form staged and no run claimed yet — reached only through its staged_uploads record, read under the tenant filter, never presigned, swept after an hour (bytes, then record)
NATS KV iterion-run-locksthe run idthe runner's execution lease (LeaseInfo: runner id, started_at, run_status, tenant, pool); bucket TTL LockTTL, 60s by default
NATS KV iterion-runner-rolloutepoch.high-waterthe monotonic runner rollout epoch, no TTL
JetStream ITERION_RUNS, ITERION_RUNS_DLQiterion.queue.runs, iterion.queue.runs.dlqthe run work queue and its park; a sovereign pool gets its own ITERION_RUNS_POOL_<pool> pair on an exact, never wildcard, subject

Run status vocabulary ​

  • IsTerminal is finished, failed, failed_resumable, cancelled. failed_resumable and cancelled are terminal and resumable.
  • A local resume has no queue and CASes from one of the four resumable statuses to running — on an answered human gate, replayAnsweredGate can first write paused_waiting_human, the status a replay that dies before its claim leaves.
  • continuation_state says who owns a terminal run's future: redelivery_pending (the queue still holds the message), retry_armed (a scheduled retry will resume it), final (acting on it is the consumer's decision).
  • deleted is written only by DeleteRun. A reader querying runs by status therefore meets a ninth value the enum does not declare.

Collections ​

collectionpackagedocument structtenant field (values)unique / TTL indexestwin
runspkg/store/mongostore.Runtenant_id — team id, or dev under DisableAuth; empty on local runsnone unique beyond _id; no TTLfile run.json
eventspkg/store/mongostore.Eventtenant_id — team idunique (run_id, seq); TTL ts after eventsTTLDaysfile events.jsonl
run_logspkg/store/mongorunLogDoctenant_id — team idunique (run_id, offset); TTL ts after eventsTTLDaysfile run.log
run_seqpkg/store/mongobson.M literal, no Go structinside _id — {tenant_id, run_id}, team id_id only; no TTLnone (cloud-only)
interactionspkg/store/mongointeractionDoc wrapping store.Interactiontenant_id — team id_id {run_id, interaction_id}; no TTLfile interactions/<id>.json
user_messagespkg/store/mongouserMessageDoc wrapping store.QueuedUserMessagetenant_id — team id_id {run_id, message_id}; no TTLfile user_messages.jsonl
run_planspkg/store/mongorunPlanDoctenant_id — team idunique (run_id, seq); TTL ts after eventsTTLDaysfile plans/<NNNN>.json
run_notespkg/store/mongorunNoteDoctenant_id — team idunique (run_id, seq); no TTLfile notes/<NNNN>.json
run_turnspkg/store/mongorunTurnDoc for store.TurnCheckpointtenant_id — team idunique (run_id, node_id, loop_iter, turn_index); TTL tsfile turns/<node>/<iter>/<turn>.json
run_tagspkg/store/mongorunTagsDoctenant_id — team idunique run_id; no TTLfile tags.json
staged_uploadspkg/store/mongostore.StagedUploadtenant_id — team id_id is the upload id; index created_at; no TTL index — the staging sweep reaps after an hour, bytes then recordfile uploads/<id>/meta.json
run_gitmetapkg/store/mongorunGitMetaDoctenant_id — team idunique run_id; no TTLfile gitmeta.json
run_route_decisionspkg/store/mongostore.RouteDecisiontenant_id — team id; the watermark sentinel is untenantedunique (run_id, outcome_seq); no TTLfile route_decisions.json
retry_circuitspkg/store/mongostore.RetryCircuitStatetenant_id — team idunique (tenant_id, key); TTL updated_at after 30 daysnone (cloud-only)
run_secretspkg/secretssecrets.RunSecretsRecordtenant_id — team idnone unique beyond _id; TTL expires_at, expireAfterSeconds 0none (cloud-only)
teamspkg/identityidentity.Team_id is the tenantunique slug, unique partial runner_pool; no TTLnone (cloud-only)
userspkg/identityidentity.Usernone — globalunique email; no TTLnone (cloud-only)
bot_sourcespkg/botsourcebotsource.BotSourcetenant_id — team id, or platform:unique (tenant_id, slug); no TTLmemory-only (local mode and tests)
board_issuespkg/dispatcher/boardmongoissueDoc wrapping native.Issuetenant_id — team id_id is native:<uuid>; no TTLfile issues/<id>.json
scheduled_botspkg/cloudschedcloudsched.ScheduledBottenant_id — team idnone unique beyond _id; no TTLnone (cloud-only) — the in-process store is test-only; ~/.iterion/schedules.yaml is the host counterpart
assistant_run_watchespkg/runwatchrunwatch.Watchtenant_id — team id, a plain tenant parameter on the per-operator readsunique partial (tenant_id, owner_id, target_run_id) on state: active; no TTLfile assistant-run-watches.json
assistant_run_watch_episodespkg/runwatchrunwatch.Episodetenant_id — team id, ignored by the claim queriesunique (watch_id, outcome_event_id); no TTLfile assistant-run-watches.json
assistant_missionspkg/assistantmissionassistantmission.Missiontenant_id — team id, a plain tenant parameter on the per-operator reads, ignored by the reconcile and claim queriesunique (tenant_id, operator_id, invocation_key), unique partial active_target_key; no TTLfile assistant-missions.json
"S3: artifacts and backend sessions"pkg/store/blobkey spaces, not documentsthe run id is the key's second path segment — the upload id under uploads/, scoped by its staged_uploads recordnoneS3
"NATS KV: run locks"pkg/queue/natsnats.LeaseInfotenant_id inside the lease payloadbucket TTL LockTTL, default 60sNATS KV