Docs / Specification
A-surface — Operator surfaces decisions
Status: accepted
control-document-cas — The control document is CAS-versioned, validated per entry, and fails static
Cited bysurface.arm.unreadable-schedulesurface.arm.unreadable-scheduleA schedule string the grammar cannot read, including L, W, ?, # and @ macros, raises ScheduleUnreadable for that entry alone, naming the diagnostic; every other entry of the document arms.surface.reconcile.fail-staticsurface.reconcile.fail-staticAn unreadable pointer, an unparseable snapshot or a control plane answering 5xx raises ControlSnapshotUnreadable, logs a diagnostic, and leaves the armed set in place running.surface.reconcile.pulled-control-untrustedsurface.reconcile.pulled-control-untrustedA pulled control head with an invalid signature, project, digest, predecessor chain or local validation raises ControlSnapshotUntrusted, names the reason and arms none of that version.surface.reconcile.learns-by-readingsurface.reconcile.learns-by-readingA daemon learns of a new snapshot only by reading its control source, on each poll and on each wake; nothing pushes a snapshot to it.surface.edit.store-draftsurface.edit.store-draftAn Admin edit validates a complete control document and saves one store-scoped draft bound to its applied version, verified operator and random nonce, leaving the applied pointer unchanged.surface.apply.version-racesurface.apply.version-raceAn apply whose compare-and-swap loses raises ManifestVersionConflict, reloads the winning version and reapplies its pending edits onto it, overwriting no applied version.
One hand-edited control document arms every scheduled entry unattended, so one bad entry or failed poll stops no unrelated schedule.
| Option | Lost on | Cost |
|---|
| CAS on an engine version, per-entry validation, fail-static poll (chosen) | — | A loser’s edits land on a document they never read; a silent control plane leaves an old cadence running. |
| Last-write-wins on the pointer | Immutability | An applied version is superseded unobserved. |
| A lock or lease in front of the document | Writer count under failure | An expiring lease admits an unordered second writer. |
| Arm empty, or fall back to local schedules, on a failed poll | Visibility of the failure | A transient error stops ingestion or runs an unapplied cadence while reporting healthy. |
configuration-reaches-engine — Configuration reaches only engine-named code and secrets
Cited byconnector.import.forwarded-configconnector.import.forwarded-configThe pipeline's guest configuration table is the one part of the source configuration crossing inward, as one JSON object delivered once per session ahead of discovery.surface.reconcile.loopback-onlysurface.reconcile.loopback-onlyA control URL whose host is not a loopback address raises ControlSourceNotLoopback and arms nothing; a poll follows no redirect and routes through no proxy.surface.fire.job-kind-unknownsurface.fire.job-kind-unknownA block naming a kind outside the union, an argument vector or a host command raises JobKindUnknown at validation.surface.fire.store-driven-concurrencysurface.fire.store-driven-concurrencyA store-driven block declaring no positive integer max_in_flight raises JobConcurrencyUnset at validation; no default applies.surface.fire.store-driven-bodysurface.fire.store-driven-bodyA store-driven block whose body names no body the embedding binary registers and no delegate under binding raises JobBodyUnregistered at validation.surface.fire.scheduled-bodysurface.fire.scheduled-bodyA scheduled store-driven job runs through the cadence lease and dispatch pool under job:<name>, using the embedding executable's registered body or its bound delegate, and the applied snapshot's job declaration.surface.fire.scheduled-historysurface.fire.scheduled-historyA scheduled store-driven job computes its next fire from its host execution's recorded start, including failed attempts; a restarted daemon resumes pending execution through input-pin.surface.fire.job-snapshotsurface.fire.job-snapshotImport and full apply retain validated job declarations in the immutable snapshot; a pipeline-only apply preserves the snapshot's jobs, and a pipeline-only editor refuses to discard them under validation.surface.fire.model-snapshotsurface.fire.model-snapshotImport and full apply retain validated model declarations with file SQL resolved inline; pipeline-only apply preserves applied models, and applied build dispatch reads that version's model, contract and tests without consulting draft definitions.surface.fire.standalone-snapshotsurface.fire.standalone-snapshotImport and full apply retain standalone table contracts in immutable snapshot metadata; pipeline-only apply preserves that metadata, including absent metadata.surface.fire.applied-data-contractsurface.fire.applied-data-contractApplied store-driven and build jobs resolve standalone and pipeline table declarations and models from their snapshot; unapplied edits to them change neither input selection nor output landing contracts.surface.fire.applied-contract-missingsurface.fire.applied-contract-missingApplied jobs lacking standalone contract metadata refuse under validation until full apply captures those contracts; no live declaration substitutes for missing snapshot metadata.surface.fire.executable-pinsurface.fire.executable-pinStore-driven and build executions pin table declarations, model definitions, output membership, and memory shapes and relations; changed structure meets pinned-plan-changed before replay or publication.surface.fire.scheduled-buildsurface.fire.scheduled-buildA scheduled build job dispatches the native model publisher through the cadence lease and pool under job:<name>; its execution records starts and outcomes for restart cadence, including failed attempts.surface.fire.build-dependencysurface.fire.build-dependencyA build job's after names a pipeline and inherits its dependent-run head schedule; builds follow all pipeline steps and run only after a successful unit. Jobs without after read already committed inputs.surface.fire.plan-jobsurface.fire.plan-jobA plan block names a compiled plan file beside its manifest; job fire lowers that plan onto one execution under host scope job:<name>, pinned to the plan's version.surface.apply.weak-conditional-backendsurface.apply.weak-conditional-backendA configuration owner or catalog backend whose conditional replacement is not linearizable raises ConditionalWriteUnsupported at startup or open.surface.register-store.malformed-entrysurface.register-store.malformed-entryOne entry that does not decode raises StoreEntryMalformed naming it, and is dropped while its siblings are served.surface.register-store.authored-namesurface.register-store.authored-nameAn entry carrying its own credential or binding name raises StoreNameAuthored.
Configuration selects among things the engine names, never code, a host command, a secret or a remote control source.
| Option | Lost on | Cost |
|---|
| Closed job union, derived names, loopback control source (chosen) | — | A new job kind needs a release; renaming a store rotates its secret name. |
| A job carrying an argument vector, or a plugin registry of kinds | Trust boundary | A manifest writer gains arbitrary execution with the store’s credentials and egress. |
| Authored credential and binding names per entry | Reachable secrets | A runtime edit sends any worker secret to a chosen host. |
| A remote control URL over TLS with a bearer | Content authenticity | The server, or anyone who compels or replays it, pins or rolls back the schedule set. |
Revisit: a remote control source with a bearer-authenticated read, TLS, and producer-side signing over (version, content-hash) verified before arming.
answer-surfaces-read — Answer surfaces read through server-chosen, grounded calls
Cited byauthority.resist.read-only-faceauthority.resist.read-only-faceAn organization-wide face serves the read subset of the tool surface; conversational writes are server-authored.authority.resist.write-toolauthority.resist.write-toolRegistering a write tool on an organization-wide face raises EnforceWriteOnReadOnlyFace.surface.speak.unanswerable-suggestionsurface.speak.unanswerable-suggestionA suggested prompt whose answer under these rules is a decline raises ConsoleSuggestionUnanswerable when the suggestion set is built.surface.speak.stream-redactionsurface.speak.stream-redactionThe server redacts each streamed model chunk before Query emits prose to the operator.surface.ground.unadmitted-toolsurface.ground.unadmitted-toolA call naming a tool the turn's packs do not admit raises ConsoleToolNotAdmitted and dispatches nothing.surface.ground.mutating-toolsurface.ground.mutating-toolThe console's query endpoint admits a read subset: a client-reachable path naming a write raises ConsoleMutatingToolRequested. The one write a turn performs is authored on the server.surface.ground.org-face-read-onlysurface.ground.org-face-read-onlyA pack registering a write tool on an organization-wide face raises ConsoleWriteToolOnOrgFace at startup, naming the pack and the tool, and the face serves nothing.surface.ground.sources-blocksurface.ground.sources-blockEvery grounded answer includes a sources block citing only the governed results its admitted read tools returned.surface.plan-turn.planner-reached-memorysurface.plan-turn.planner-reached-memoryScaffolding and every deterministic fallback cover data tables; scaffolding naming a memory relation raises ConsolePlannerReachedMemory.surface.plan-turn.turn-flowsurface.plan-turn.turn-flowA Query turn plans over admitted read tools, replans once after an unanswered first round, and synthesizes from the resulting governed rows.surface.browse.discovered-chipssurface.browse.discovered-chipsQuery builds pre-question chips from described tables admitted to the reader's zone and humanizes their table labels.surface.learn.unscopedsurface.learn.unscopedA distilled conclusion landing without the reading-session scope raises ConsoleLearningUnscoped.surface.learn.subject-resolutionsurface.learn.subject-resolutionDistillation preserves the subject it observes; recall resolves that subject through entity matching.surface.render.client-authored-viewsurface.render.client-authored-viewA view specification arriving from a client, or composed by the model, raises ConsoleViewNotServerBuilt.surface.render.older-transcriptsurface.render.older-transcriptA client reading a transcript with an unknown component-union member renders its view as a table.surface.brief.absence-is-earnedsurface.brief.absence-is-earnedThe card needs a session with no turns, at present time, a live conclusion, an arrived row matching an interest, and a derivation inside its budget. An error or timeout raises ConsoleBriefUnavailable, and no card renders.surface.brief.greetingsurface.brief.greetingQuery derives a greeting card from arrived rows matching live conclusions in a turnless present-time session.surface.publish-answer.share-affordancesurface.publish-answer.share-affordanceA surface offering a share control on access-explanation output raises VisibilityShareAffordance.surface.publish-answer.askerless-audiencesurface.publish-answer.askerless-audienceA scheduled job posting to an audience under a service identity raises VisibilityAskerlessAudience, naming the destination; a scheduled post's corpus is narrowed in the reviewed manifest to what the destination reaches.surface.publish-answer.one-operator-principalsurface.publish-answer.one-operator-principalAn answer uses one operator's credential; the console offers no room-intersection principal.
The server decides every capability a turn exercises, so an injected instruction finds no write tool to reach for.
| Option | Lost on | Cost |
|---|
| Server-chosen calls, recall as the one door, server-built views (chosen) | — | A caller-initiated write needs another surface; no third-party component ships. |
| Client-named tools against an allowlist | The adversarial body | Arguments arrive unvalidated, so the weakest tool sets the boundary. |
| Writes behind a reader confirmation | Who confirms | The steered reader confirms inside the steered answer. |
| One generic query tool the model fills in | Enumerability | No audit can say what a turn can do. |
| Memory exposed to the planner with a documented predicate | The checks | A predicate the model writes is one it can omit. |
query-admin-use — Query and Admin use separate verified page grants
Cited bysurface.open-console.identity-gatesurface.open-console.identity-gateCloudflare Access gates the hosted Query and Admin pages by default; a deployment without Access uses Cognito managed password login and first-party sessions.surface.open-console.page-grantssurface.open-console.page-grantsThe server maps each verified Access application audience or Cognito group to Query and Admin grants and verifies the matching grant on every page and API request.surface.open-console.engine-facessurface.open-console.engine-facesQuery reaches the governed read face; Admin reaches workflow state and sends edit or apply through a server-held control capability.surface.open-console.wrong-pagesurface.open-console.wrong-pageA Query or Admin page or API request without a verified Access assertion or Cognito session granting that page raises ConsolePageForbidden and dispatches nothing.surface.open-console.admin-grantsurface.open-console.admin-grantAn Admin edit or apply without a server-held admin capability raises ConsoleAdminGrantMissing and reaches no control call.
Page admission and engine capability checks both stay necessary.
| Option | Lost on | Cost |
|---|
| Cloudflare Access or Cognito managed login (chosen) | — | Cognito needs a user pool, group mapping and first-party sessions. |
| One shared password for each page | Individual accountability | Two people become one subject in grants and audit records. |
| Self-managed operator passwords | Credential lifecycle | The console owns hashing, resets, lockout and recovery. |
| Cloudflare Access only | Deployment portability | An organization without Cloudflare cannot host the console. |
console-lives-beside — The console lives beside the engine and uses its public read face
Cited bysurface.open-console.engine-facessurface.open-console.engine-facesQuery reaches the governed read face; Admin reaches workflow state and sends edit or apply through a server-held control capability.surface.open-console.source-draftsurface.open-console.source-draftAdmin adds a source through the version-bound edit and apply path of engine-faces, with a source form and a raw TOML fallback.
The console owns presentation and turn orchestration; engine enforcement stays in the engine, so no console path implements a second read policy.
| Option | Lost on | Cost |
|---|
| Separate TypeScript console and client library (chosen) | — | Two runtimes need a shared protocol and coordinated release. |
| The console embedded in the Rust CLI | Browser delivery | The engine binary carries page assets and model-facing session code. |
| The browser calling the engine directly | Credential custody | A page holds store credentials and bypasses the server’s turn choices. |
console-page-ships — Each console page ships as one prerendered, self-contained document
Cited bysurface.open-console.page-routessurface.open-console.page-routesThe console serves Query at /query with /query/api/, Admin at /admin with /admin/api/, and, under public-data, Data at /data with /data/api/.surface.open-console.query-surfacesurface.open-console.query-surfaceQuery presents one composer, one transcript and widgets for returned rows.
Each page is one HTML document served under default-src 'none' plus font-src data:, so the console exposes no asset route to gate.
| Option | Lost on | Cost |
|---|
| Prerendered self-contained documents (chosen) | — | Each page response carries about 750 KiB under no-store. |
| Hashed assets under gated asset routes | Route surface | Every asset route needs the page grant check and its own cache policy. |
| Hand-written HTML strings in the server | Component reuse | Every widget is rebuilt by string concatenation. |
| A full-stack page framework | Server ownership | The framework’s router replaces the server that verifies page grants. |
turn-compatibility-preserves — Turn compatibility preserves the stored transcript and reader scope
Cited bysurface.package.owner-flagsurface.package.owner-flagA process --owner admits the local owner context only with a verified signed claim bound to the selected store and an unrestricted read grant; any other credential raises OwnerCredentialInvalid before protocol framing.surface.plan-turn.overlay-audiencesurface.plan-turn.overlay-audienceA store's prompt overlay reaches the operator-facing synthesis text and stays outside the planner's text.
A transcript stays readable across client releases, and one accountable reader defines each answer.
| Option | Lost on | Cost |
|---|
| Preserve subjects, scope and older views at their readers (chosen) | — | Recall does entity work; a newer widget loses fidelity on an older client. |
| Normalize subjects and components when writing | Reversibility | Old transcripts cannot recover their original labels or view shapes. |
| The overlay and room audience given to the planner | Capability scope | Store-authored text and a composite principal widen the turn. |
store-driven-job — A store-driven job runs host-registered code per row over a pinned input
Cited byrun.journal.store-inputrun.journal.store-inputA store-driven run reads its statement once, through the read face under the job's grant at its as_of, and records the resolved snapshot id per table and the ordered input rows as its first step.run.journal.input-pinrun.journal.input-pinA store-driven run's plan reference hashes its body name, statement, declared as_of and any host-supplied structural identity, which also joins its owner pins, so a resume under a changed one meets pinned-plan-changed before any step replays.
No other job kind takes store rows as input, so without this kind per-row paid work over a snapshot has no resumable home.
| Option | Lost on | Cost |
|---|
| Fixed kind, registered body, pinned input (chosen) | — | A new body is a host release; the operator states concurrency for every job. |
| A body as an argument vector | Trust boundary | A manifest writer gains execution with the store’s credentials and egress. |
| Input re-read on each resume | Resume determinism | A fold or later landing changes the row set mid-run. |
A default max_in_flight | Spend visibility | Paid concurrency rises with no line in the manifest. |
residency-divergence-detected — Residency divergence is detected at push, from the bucket manifest
Cited bysurface.reside.region-entriessurface.reside.region-entriesA residency allow-set holds at most 16 entries.surface.reside.site-regionssurface.reside.site-regionsA push records the pushing site's residency allow-set in the bucket manifest; a push finding a differing set another site recorded, an absent one included, raises ResidencySitesDiverge and commits nothing.
Each site resolves its own [residency], so two sites sharing a bucket can each start cleanly with different allow-sets.
workers-reach-orchestrator — Workers reach the orchestrator only through the awakeable route
Cited bysurface.dispatch.heartbeat-beatsurface.dispatch.heartbeat-beatA worker heartbeats every 15 s with a signed GET on its step's awakeable route, and posts its outcome to that route with a signed POST.surface.dispatch.worker-targetsurface.dispatch.worker-target[control] workers lists worker URLs and [control] relay the URL whose /awake/:token route serve binds; with workers listed, each landing step posts to a worker's POST /submit, keyed by run, step and attempt.surface.visualize.workflow-canvassurface.visualize.workflow-canvasAdmin projects the store-published pipelines, jobs, models, publications and external steps as one node–edge graph under dataflow-edges, with each pipeline's schedule, steps and latest run outcome.
A remote worker reports liveness and outcome through no crossing beyond the three the topology names.
| Option | Lost on | Cost |
|---|
| The awakeable route, attempt-fenced and signed (chosen) | — | A worker needs a route to the relay; one key signs every worker’s messages. |
| A worker-pull queue on the orchestrator | Crossing count | A fourth inbound surface with its own authentication. |
| Unfenced callbacks, last writer wins | Successor safety | A partitioned worker’s late result replaces its successor’s. |
| A pool bound per exclusion key | Concurrency cap | Adding pipelines raises concurrent pulls unseen. |
synced-control-head — A synced control head carries an issuer-signed apply receipt
Cited bystore.push.control-artifactstore.push.control-artifactA push uploads each immutable applied control snapshot and its synced-attestation receipt under <project>/control/, then commits their digests and project-scoped head in the bucket manifest.store.push.control-divergedstore.push.control-divergedA push whose signed control head does not descend from the bucket head raises SyncControlDiverged, naming both heads, and leaves the bucket head unchanged.store.pull.control-headstore.pull.control-headPull downloads the bucket manifest's project-scoped control head, snapshot and receipt ancestry at their listed digests. The local applied pointer stays unchanged for pulled-control.surface.reconcile.pulled-controlsurface.reconcile.pulled-controlA reconciler adopts the project-scoped head control-head carries, descending from its local head, only after verifying the receipt under a locally pinned issuer key and validating the snapshot against this node's declarations.surface.apply.synced-attestationsurface.apply.synced-attestationIn a project with [sync], import and apply admit an admin capability, then sign a receipt over the project, version, predecessor receipt digest and snapshot digest through signing-port.surface.apply.receipt-messagesurface.apply.receipt-messageA JSON control receipt carries format: 1, signer public key and signature over UTF-8 contextful-control-v1\n<project>\n<version>\n<parent-or-minus>\n<snapshot-sha256>\n<signer>\n; its parent is - only for the first version.surface.apply.receipt-digestsurface.apply.receipt-digestA predecessor and the bucket head name the lowercase SHA-256 hex digest of a receipt's RFC 8785 canonical JSON bytes.surface.apply.receipt-filesurface.apply.receipt-fileA synced claim writes immutable receipt@v<N>.json beside its snapshot before advancing the applied pointer.surface.apply.attestation-unavailablesurface.apply.attestation-unavailableA synced import or apply lacking an admitted admin capability or issuer signing port raises ControlAttestationUnavailable and claims no version.
Node-owned run states and local version numbers prove no admin apply. An installation without sync keeps unsigned applies local.
| Option | Lost on | Cost |
|---|
| Signed receipt and project-scoped manifest head (chosen) | — | A synced apply needs an admin credential and signing port. |
| Version in node run state | Authorship | Any node writer claims a version; two nodes reuse one number. |
| The bucket manifest’s control entry trusted as is | Content authenticity | A data writer publishes schedules without an admin apply. |
| The local snapshot directory replicated directly | Claim ordering | Local version counters collide; a copied pointer carries no authorization. |
Revisit: a bucket writer replays an earlier signed head to a never-synced node; freshness needs an independent monotonic witness.
native-model-builds — Native model builds share applied cadence and execution history
Cited bysurface.fire.model-snapshotsurface.fire.model-snapshotImport and full apply retain validated model declarations with file SQL resolved inline; pipeline-only apply preserves applied models, and applied build dispatch reads that version's model, contract and tests without consulting draft definitions.surface.fire.scheduled-buildsurface.fire.scheduled-buildA scheduled build job dispatches the native model publisher through the cadence lease and pool under job:<name>; its execution records starts and outcomes for restart cadence, including failed attempts.
Cooperative stop admission and model pointer CAS give no atomic cross-host fencing.
| Option | Lost on | Cost |
|---|
| Applied model definitions in native cadence (chosen) | — | Each control version carries resolved SQL; source ordering is explicit. |
| Standalone build over mutable files | Applied identity | Draft SQL changes the running schedule. |
| A separate model scheduler | One execution home | Cadence, exclusion and restart history have two implementations. |
applied-jobs-retain — Applied jobs retain structure and check current authority
Cited bysurface.fire.applied-data-contractsurface.fire.applied-data-contractApplied store-driven and build jobs resolve standalone and pipeline table declarations and models from their snapshot; unapplied edits to them change neither input selection nor output landing contracts.surface.apply.draft-table-contractssurface.apply.draft-table-contractsPipeline editing preserves standalone table metadata from the draft's expected immutable version; apply regenerates that metadata and refuses an altered saved draft under validation before advancing the pointer.
Applied structure fixes what a job reads and lands; current authority still decides admission, checked once at attempt start, not throughout the attempt.
| Option | Lost on | Cost |
|---|
| Captured structure, current-authority comparison (chosen) | — | Snapshots missing contracts need full apply; policy changes can refuse attempts. |
| Output contracts resolved from live files | Replay identity | Unapplied edits alter deduplication, types and landing. |
| Replay entirely under historical authority | Revocation | A snapshot keeps access the current declaration removed. |
| Pending owners rewound automatically | Recorded effects | A structural edit repeats paid calls. |
delegated-body-deploy — A delegated body is deploy-bound code reached in two modes
Cited byrun.items.delegated-itemrun.items.delegated-itemUnder a delegated body, each call ordinal is one request under envelope, its Answer recorded under the item's entry key, so a resume replays every recorded answer and sends only the unrecorded call.surface.delegate.bindingsurface.delegate.binding[control.delegates.<name>] binds a delegate by url, a mode of call or submit, and under call a timeout; a store-driven body = { delegate = "<name>" } naming no bound delegate raises JobDelegateUnbound at arm or fire.surface.delegate.call-modesurface.delegate.call-modeUnder call, one request per attempt holds its connection open and the response body is the attempt's answer; a response arriving after the delegate's timeout closes the attempt Transient, and its late body records nothing.surface.delegate.outcomesurface.delegate.outcomeAn answer is a Answer; ok lands as completion, defer parks, and transient and permanent follow retry-budget.
A consumer whose domain code is not Rust has no body to register, so without a delegate its paid work runs outside the journal.
| Option | Lost on | Cost |
|---|
| Named delegate, two modes, closed outcomes (chosen) | — | A second body path; a hanging call delegate holds its slot until timeout. |
| Registered bodies only | Consumer reach | Domain code in another language runs outside the record. |
| A URL in the manifest | Trust boundary | A manifest writer gains egress with the store’s credentials. |
| One mode alone | Delegate classes | submit cannot reach a Worker-class delegate; call has no home for long work. |
due-units-admit — Due units admit by staleness, and a wake refills its freed slots
Cited bysurface.dispatch.not-a-headsurface.dispatch.not-a-headA [[pipeline]] block naming after = "<id>" is a landing step of that entry's dependent run; the run is the unit and cadence rides its head entry. A due id that is a step raises DispatchUnitNotAHead and starts nothing.surface.dispatch.admission-ordersurface.dispatch.admission-orderDue units start with each unit holding neither a last run start nor a last dispatch first, then by earliest next fire, then highest [[pipeline]] priority, an integer defaulting to 0, then least recent of the two, then id.surface.dispatch.refillsurface.dispatch.refillA wake whose fire ends before its answer admits each unit its evaluation left pending into the freed slot, through the cadence lease; a unit falling due after the evaluation waits for the next wake.
Overload misses rotate across a tied cohort.
| Option | Lost on | Cost |
|---|
| Staleness tie-break, catalog record, refill inside the wake (chosen) | — | One catalog write per dispatch; a unit due after evaluation waits for the next wake. |
| Name tie-break | Fairness under overload | Every miss lands on the name-last units. |
| Strict priority across due instants | Starvation | A busy high class holds the pool. |
| Dispatch record in process memory | Fresh processes | A unit failing before its run row wins every cycle at pool 1. |
| Refill from a fire’s end path between wakes | Lease safety | A start after the lease lapsed runs beside another holder. |
never-run-first — A unit with no run and no dispatch starts ahead of every due instant
Cited bysurface.dispatch.admission-ordersurface.dispatch.admission-orderDue units start with each unit holding neither a last run start nor a last dispatch first, then by earliest next fire, then highest [[pipeline]] priority, an integer defaulting to 0, then least recent of the two, then id.
Such a unit falls due at the instant its process armed it, and a serve started on every wake arms it anew at each start.
| Option | Lost on | Cost |
|---|
| Rank it ahead of every due instant (chosen) | — | A newly applied unit precedes overdue units for one fire each. |
| Order it by its arming instant | Restarting processes | Each start re-arms the unit behind every backlogged unit, so it never starts. |
| Due at its schedule’s latest slot before arming | Persistent backlogs | Each restart moves that slot past every unit still due from an earlier one. |
| Persist its first arming instant | Stateless arming | One more catalog row per unit, read on every arm. |
Revisit: when a newly applied unit must wait behind overdue ones, persist each unit’s first arming instant beside its dispatch record.
connections-claim-version — Connections claim one version and share dispatch
Cited bysurface.apply.draft-claimsurface.apply.draft-claimAn Admin apply rechecks the configured store owner, validates its saved draft again, and claims that draft through the owner's version compare-and-swap.surface.connection.createsurface.connection.createA served connection create binds an admitted tenant, principal, source selection, secret name and pipeline id in one versioned control claim under version-race.surface.connection.schedule-scalesurface.connection.schedule-scaleConnection schedules share pool-bound and next-fire-from-history; each connection holds one armed entry rather than one timer or thread.
A consent callback can retry while other connections mutate the same control document.
| Option | Lost on | Cost |
|---|
| Versioned connection claim and shared dispatch (chosen) | — | Each connection adds a control entry and a due-history record. |
| One scheduler thread per connection | Capacity | Thread count grows with tenant count. |
| An unversioned connection map | Concurrent edits | Retried callbacks overwrite a different declaration. |
maintenance-kinds — A maintenance kind dispatches only where a command does its work on a cadence
Cited bystore.fold.job-passstore.fold.job-passcontextful job fire on a fold job runs a pass over its target, or over every table the store holds when it names none, reporting each table under result and exiting non-zero once any table fails.store.push.job-pushstore.push.job-pushcontextful job fire on a sync-push job pushes the store once as contextful sync push does; on a store declaring no [sync] the fire fails, naming the store's config.toml.surface.fire.scheduled-maintenancesurface.fire.scheduled-maintenanceA scheduled fold or sync-push job dispatches contextful job fire <name> through the cadence lease and pool under job:<name>; its next fire follows next-fire-from-history from its dispatch record.surface.fire.kind-undispatchedsurface.fire.kind-undispatchedA [[job]] of kind sweep, rebuild-catalog or validate raises JobKindUndispatched at pipeline validate, job validate, import and full apply, naming the command doing its work; serve arms none an applied snapshot holds.
A declared fold job that serve never fires leaves a store fed by small landings holding one run directory per landing, while the declaration reads as covered. fold and sync-push each reach a command that does their work, sync compact or context compact and sync push, so serve fires them as job fire children. sweep reaches no command. rebuild-catalog repairs a lost derived catalog, a condition an operator observes rather than a cadence. validate checks a declaration before apply, and an applied snapshot already passed it.
| Option | Lost on | Cost |
|---|
Dispatch fold and sync-push; refuse the other three by name (chosen) | — | Three union kinds still parse in an applied snapshot and arm no entry. |
| Dispatch every maintenance kind | Meaning | A sweep fire runs nothing, a scheduled rebuild repeats a repair over a healthy cache, and a scheduled validate rechecks a validated snapshot. |
| Arm none and log each one unarmed | Bounded stores | Landings accumulate until an operator compacts by hand. |
| Remove the three kinds from the union | Applied snapshots | A snapshot applied with one stops parsing, and serve arms nothing from it. |