ENGINE INTEGRATION — NOT MAPSWIPE-SPECIFIC
Load. Infer.
Unload.
The geoai worker owns the QueueLLM Runtime lifecycle. No ambiguity about model state. No orphaned GPU memory. The worker subscribes to the aerollm-bus, collects telemetry events in real time, and finalizes a deterministic receipt at shutdown. This page is generic engine/control-plane plumbing — it applies the same way whether the resulting predictions go to MapSwipe, a private evaluation, or nowhere at all. For the MapSwipe-specific export and permission path, see MapSwipe Integration.
CONTROL PLANE — DDAC INTEGRATION
INFERENCE REQUEST FLOW
Manifest declares model, imagery, spatial splits, run config
InferenceRun objects published to the queue
Fetches run, processes with QueueLLM, produces receipt
Content-addressed, immutable record of what the machine did — signing is a roadmap step
Receipt recorded in audit trail for provenance
PINNED DDAC CONTRACTS
dac.manifest/v2
Dataset declaration: imagery source, imagery license, spatial splits, model metadata, run parameters
dac.zero-claw-exec/v1
Immutable execution envelope: model digest, sandbox profile, provenance chain, receipt validator
dac.InferenceRun
Task declaration for a single model run: model_path, model_digest, prompt, max_tokens, temperature, sandbox_profile, run_id
GeoAI consumes these as pinned specs from qukaizen-dac; never forks them. See ADR-0001 for boundary discipline.
DATA FLOW — WORKER LIFECYCLE
1. FETCH INFERENCE RUN
Worker fetches next InferenceRun from dac control plane
InferenceRun carries: model_path, model_digest, prompt, max_tokens, temperature, sandbox_profile, run_id. Worker stores run_id for receipt key.
2. UNLOAD PREVIOUS
If a model is loaded, shut it down cleanly via LifecycleController
if let Some(runtime) = self.runtime.take() { drop(runtime); } Drop triggers the destructor, which calls LifecycleController::shutdown(). GPU memory freed. Worker logs ShutdownComplete event with peak_rss and timestamp.
3. LOAD MODEL
Initialize AeroRuntime for the new model
let runtime = AeroRuntime::new(&run.model_path, config).await?; MLX context initializes. Model weights are mmapped (not loaded into RAM yet). Worker observes LoadComplete event on the bus and records it.
4. SUBSCRIBE TO AEROLLM-BUS
Open a channel to the runtime's telemetry stream
let mut subscriber = self.bus_subscriber.subscribe(); Now the worker will receive Init, Loading, LoadComplete, TokenEmitted, PrefetchHit, LayerEvicted, LayerInstalled, ArenaReset events.
5. RUN INFERENCE
Stream tokens and drain telemetry events in the inner loop
let mut token_stream = runtime.generate_streaming(...).await?;
Inner loop: grab next token_id, drain all pending bus events, log each (TokenEmitted → token_id + rss + timestamp; PrefetchHit → layer + timestamp; LayerEvicted → layer + timestamp). Continue until max_tokens or signal.
6. FINALIZE RECEIPT
Mint the geoai.receipt/v1alpha1 with all collected telemetry
Receipt fields: model_digest, prompt_tokens, sampled_tokens, peak_rss, start_time, end_time, telemetry_log (all events collected), status, egress_audit_result. Finalize the receipt (content-addressed; signing lands later as a roadmap step) and write it to durable storage (for audit trail).
7. LOOP
Go back to step 1 and fetch the next run
The worker runs indefinitely. Each iteration: clean unload → fresh load → isolated inference → sealed receipt. No state leaks between runs.
RECEIPT VERIFICATION: THE HASH CHAIN
CANONICALIZATION: M1 · SIGNING: M3 (ADR-0004, DRAFT)A receipt is not a log line. It is a chain of hashes: every input, every code path, every policy, and every output gets fingerprinted, and the fingerprints are checked against each other before a result is ever trusted. This is what turns "prove it ran on the right data" into a command you can run, instead of a promise you take on faith.
THE THREE-WAY MATCH (WHAT PROVES "RIGHT DATASET")
DECLARED
dac InferenceRun
- dataset.expectedDigest
- task.expectedDigest
- model.expectedDigest
MATERIALIZED
bundle manifest, on disk
- per-file sha256 set
- task/ digests
- model.ref.json digest
EXECUTED
geoai.receipt/v1alpha1
- bundle_digest
- task_digest
- model_digest
The worker checks manifest against disk before running (fail closed on any mismatch, symlink escape, or undeclared file). The control plane checks declared against executed after. All three digests must agree, or the run is rejected: using the wrong dataset is not a mistake caught later, it is a run that never gets accepted in the first place.
WHAT ONE SIGNATURE COVERS
The signature (M3) is computed over the whole chain at once, never over a single field alone:
signature = sign( bundle_digest ‖ model_digest ‖ task_digest ‖ engine.build ‖ sandbox.profile_digest ‖ output_digest )
Change any link (swap a tile, nudge a prompt file, downgrade the sandbox) and either a digest stops matching or the signature stops verifying. There is no path to a quiet substitution.
WHAT A RECEIPT PROVES (AND DOES NOT)
Proves: this exact bundle, this exact model, this exact task ran under this exact sandbox at this enforcement level, egress tests passed, and produced exactly these bytes.
Does not prove: that the prediction is correct (review and evaluation own truth), that the model is unbiased, or that the imagery handed to the worker was itself the untampered original the tile provider published. That last gap is the open question below.
OPEN QUESTION: WHO SIGNS, AND WHAT ABOUT THE TILES?
Two different questions get asked as one, and they have two different owners.
EXECUTION INTEGRITY (WE CAN SIGN THIS ALONE)
"This machine ran this model on this bundle in this sandbox and produced these bytes." Every digest in that claim is generated on our own hardware, from our own build, inside our own sandbox. A project key (cosign/DSSE) signing the receipt on acceptance covers this completely; no outside party needs to be involved for this half to be trustworthy.
SOURCE PROVENANCE (WE CANNOT SIGN THIS ALONE)
"The tiles we processed are the same tiles the imagery provider actually published, untampered." Our receipt can only hash what arrived at our door. To prove that hash matches the provider's original, the provider (Maxar, Planet, OSM/HOT's own imagery catalog, etc.) has to publish its own checksum or manifest independently, so a third party can compare the two. That checksum has to come from them, not from us: a self-issued claim cannot verify itself.
The practical shape (matching the SLSA/in-toto pattern of separate source, build, and acceptance attestations, each signed by a different identity) is three links, not one:
- 1. Source attestation (their signature): the imagery/tile provider or HOT's data pipeline publishes a digest for the exact tile set handed off for a given task.
- 2. Execution attestation (our signature): the geoai receipt, proving the bundle we actually ran matches that same digest and ran under a verified zero-egress sandbox.
- 3. Acceptance attestation (control plane or HOT, on ingest): dac (or HOT) countersigns that both of the above were checked before results are trusted downstream.
So: we can, unilaterally, sign and prove everything that happens after the tiles reach our sandbox. We cannot, unilaterally, prove the tiles themselves were untampered before that point; that half needs the imagery source to publish its own digest so ours has something independent to match against. This is tracked as ADR-0004 open question 2, and is a conversation to have with HOT and the imagery-source maintainers (per the COMMUNITY.md outreach plan), not something we can close by ourselves.
CRITICAL PATTERNS
NO AMBIGUITY ON SHUTDOWN
LifecycleController::shutdown() fires on Drop
The runtime doesn't expose shutdown() as a callable method. Dropping the Runtime value triggers the destructor, which calls LifecycleController::shutdown(). No way to forget. No orphaned processes.
TELEMETRY DRAIN IN LOOP
Empty the bus channel every iteration
while let Ok(event) = subscriber.try_recv() { ... } Never block on the bus. Non-blocking recv keeps inference flowing. Events are timestamped at source (aerollm runtime) so clock skew is zero.
RSS MEASUREMENT IS RUNTIME-OBSERVABLE
Log peak memory in every telemetry event
Each event carries rss = get_current_rss_bytes(). Worker tracks peak across all events during inference. Receipt contains peak_rss so operators can audit hardware requirements and catch runaway memory.
RECEIPT IS THE SOURCE OF TRUTH
Every receipt is deterministic
Worker → Receipt → Durable storage (filesystem or DDAC). The receipt is immutable proof. No re-inference needed to audit. Receipts can be shared downstream for provenance verification before predictions are used anywhere.
SMALL MODELS = NO EVICTION
Layer prefetch still runs
If the model fits in VRAM, ring eviction doesn't trigger. LayerEvicted events never fire. Receipt shows this honestly — zero evictions. Prefetch latency is minimal. You're not paying overhead for something you don't need.
OPERATOR EXPERIENCE
Worker is fire-and-forget
Operator runs geoai worker --config=/path/to/config.yaml. Worker loops, fetches runs, manages models, produces receipts. Operator can walk away; everything stops cleanly on interrupt. Next run uses the same binary.
NEXT STEPS — M1
M1.1 — Implement worker loop
Build GeoAIWorker struct with fetch → unload → load → subscribe → infer → finalize cycle. Use aerollm_api crate (PyO3 wheel not needed yet; work in Rust).
M1.2 — Receipt schema + harness
Define geoai.receipt/v1alpha1 in schemas/. Build ReceiptBuilder with telemetry_log serialization. Write a receipt to disk and validate it round-trips.
M1.3 — Sandbox profile + egress audit
Integrate macOS sandbox profile (qukaizen-geoai has the profile YAML). Wire egress test suite results into the receipt.
M1.4 — End-to-end smoke test
Run a small model (Qwen2.5-0.5B) through the full cycle. Verify receipt is well-formed, all telemetry events are logged, shutdown is clean, and peak_rss is reasonable.