Architecture
LEMC keeps selection at the edges and execution in one server-owned
job path. Web, API, scheduler, and lemcli callers converge
before a recipe reaches a runner.
System shape
human browser ── web session ─┐
lemcli / agent ─ bearer token ├──► LEMC web/API server
scheduler ───── server state ─┘ │
├─ authenticate + authorize
├─ validate action + inputs
├─ preflight managed image
├─ acquire queue lock
└─ enqueue task
│
▼
hosted runner coordinator
│
fresh jailed Firecracker guest / job
│
┌───────────────────────────┴───────────────────────────┐
▼ ▼
structured recipe events logs + artifacts
│ │
▼ ▼
LEMC server store durable storage
│ │
▼ ▼
/web/ws /cli/ws
browser lemcli
Server authority
The server owns decisions that must not vary by client:
- authentication, account scope, authorization, and action visibility;
- form validation, idempotency, queue admission, and scheduling;
- execution mode, runner/pool selection, isolation, and resource limits;
- image authorization and digest-pinned managed registry references;
- event persistence, filtering, websocket fanout, and terminal mapping;
- durable log/artifact/cache sync and terminal cleanup proof.
The browser, API payload, and CLI do not carry a per-request “run this on Docker/Firecracker/runner X” switch.
Hosted job lifecycle
- Job started: record target, caller, queue type, task ID, and policy.
- Image preflight: require an authorized digest from the managed image path.
- Provision and boot: create one fresh jailed Firecracker guest for this job.
- Prepare brokers: expose only job-scoped DNS, registry, storage, events, proof, and allowed egress surfaces.
- Verify denials: prove host, private, metadata, and Docker-bridge targets are unreachable.
- Prepare runtime and load image: ready the guest runtime without host Docker as a server fallback.
- Run recipe: execute ordered steps and send structured output back to the server.
- Finalize: persist terminal state and verify durable logs/artifacts/cache.
- Cleanup: destroy guest resources and release the queue lock on success, failure, cancel, timeout, or lost heartbeat.
Queue shape
| Queue type | Admission | Runtime shape |
|---|---|---|
NOW | Run as soon as capacity/policy allow. | The due job uses the same system steps, recipe execution, event path, storage finalization, and cleanup proof. |
IN | Become due after a delay. | |
EVERY | Create recurring due instances. |
Queue type changes timing and lock semantics; it does not create a weaker execution path.
Events and fanout
Runners and guests post job events to the server. The server validates and persists them before authorized clients consume the task-scoped stream.
/web/wsauthenticates through the browser's web session./cli/wsauthenticates with bearer credentials.- Both receive matching LEMC verbs, system steps, recipe steps, terminal status, and terminal reason.
- Raw stdout/stderr diagnostics remain durable and bounded rather than flooding the user-visible stream.
Storage and cleanup
Local files are scratch. Rendered output, logs, artifacts, cache, and workspace state synchronize to durable object storage before local scratch is removed. A later browser refresh or CLI read hydrates from durable state first.
A job is not clean merely because the recipe process exited. Finalization must prove durable sync, guest teardown, process cleanup, bounded disk growth, and lock release.
Network boundary
Hosted-untrusted guests receive narrow job-scoped broker endpoints, not the host network or primary LEMC web/API listener. Public egress is policy-controlled and tested separately from denial of host, loopback, private, metadata, and Docker-bridge targets.
Continue with LEMC verbs to see how recipe output crosses this boundary.