One unit, two callers
A browser button and a lemcli invocation should not create
two ways to do the same work. In LEMC, both are clients of one
server-owned job model.
The interface changes for the caller. The action, admission policy, execution, events, terminal proof, and durable output do not.
MCP standardizes integration. LEMC ships the operating model.
For a distributed team with uneven skills and dynamically changing trust, LEMC is the stronger operating model. MCP standardizes how AI applications discover and invoke capabilities. LEMC packages, authorizes, executes, distributes, and proves reviewed computation.
The distinction is not “tools versus everything else.” The current MCP specification includes resources, prompts, tools, elicitation, progress, cancellation, and optional extensions. MCP also defines structured logging, interactive Apps, and experimental Tasks with durable handles, polling, terminal states, cancellation, and deferred results.
MCP deliberately leaves the user interface and much organizational policy to hosts, clients, and servers. It does not prescribe one team release channel, contributor workflow, application ACL model, runner policy, retention plan, artifact provenance chain, or proof standard. LEMC makes those choices as a single product.
LEMC does not use MCP. No MCP client, server, or host appears in LEMC’s execution path. MCP could be used to reach a system that implements these things. LEMC’s advantage is that these things are the system.
Governed supply chain
- Synchronized, reviewed releases. A versioned cookbook points at LEMC-managed, digest-pinned images. Catalog publication is deliberate, and every job records the exact selected computation; capability re-discovery alone is not treated as release proof.
- A contribution path from author to team. An admin grants narrow cookbook authority, an author publishes YAML and a local container through
lemcli, LEMC promotes the digest, and an app owner grants execution. A namespace is not substituted for the team’s review policy. - Image policy before enqueue. Hosted-untrusted jobs require an authorized managed digest. Recipe execution does not build, import, remotely pull, or silently fall back to a mutable image selected by the caller.
- Workflow composition with deterministic failure semantics. Recipes sequence language-independent container steps, pass declared state, enforce timeouts, stop on failure, and produce one terminal reason. MCP can invoke a server that implements a workflow; it does not define LEMC’s team-visible recipe model.
- Language and vendor independence inside the boundary. Go, Python, Bash, Terraform, security tools, and vendor CLIs can all be recipe steps. LEMC governs the digest, inputs, secrets, network, output, and proof rather than prescribing an application language.
Dynamic authority
- Separate authorship from execution. Account permissions govern catalog entry, cookbook ACLs govern view/edit authority, and app ACLs govern individual, shared, and admin use. The person who can click a job does not automatically gain source or publishing rights.
- Secret delegation without secret distribution. A cookbook stores named references only. A separately configured server-side binding stores an AES-256-GCM-encrypted, versioned value scoped to exact cookbook execution context. Jobs receive one-use guest material; users and agents receive the capability, while exact-value redaction covers events, logs, errors, artifacts, caches, and workspace files.
- Trust changes take effect on the next request. LEMC resolves current account membership, ACLs, digest grants, runner state, and owning resources during admission. Revocation does not wait for every client credential to age out.
- The caller cannot choose a weaker path. Browser, CLI, and API callers choose an authorized action and declared inputs. The server owns runner selection, workload class, image preflight, isolation boundary, resource policy, and queue admission; an agent cannot ask to run a hosted-untrusted job on the host.
- Idempotent, centralized admission. Stable action IDs, idempotency keys, queue locks, input validation, image authorization, ACL checks, and runner checks happen before execution. Retrying after an uncertain network result need not create a second infrastructure change.
- Auditable denial as well as success. Rejected elevated execution, invalid service-token use, storage operations, registry activity, image grants, runner-policy decisions, and cleanup failures become evidence. For mixed-trust teams, what LEMC refused matters nearly as much as what it ran.
Isolated execution
- Firecracker capability is earned, not advertised optimistically. Hosted-untrusted execution is admitted only to a ready, drift-free, self-tested Firecracker runner. A deployment must pass the prepared-host hardware validation gate before advertising that capability.
- Network authority is part of the computation contract. Jobs receive narrow, job-scoped registry, storage, DNS, event, and permitted-egress brokers. LEMC records denial proof for host, loopback, private, metadata, Docker-bridge, and primary API targets.
- Scheduling is governed execution, not caller memory.
NOW,IN, andEVERYuse the same authorization, image, isolation, event, storage, and cleanup path. “Create now, destroy in 24 hours” no longer depends on Chris remembering. - Runner-fleet governance. LEMC checks pinned Firecracker, jailer, kernel, rootfs, runtime artifacts, state hashes, self-test results, pool membership, readiness, and drift before leasing work.
- Bounded resources and cleanup proof. Success includes durable synchronization, terminal-event emission, guest teardown, process cleanup, scratch deletion, disk-growth bounds, and lock release. A cleanup failure can turn an otherwise successful recipe into an operational failure.
- Callbacks are governed transition work. Page
on_actionand recipebefore_run,after_run, andon_deactivaterun as ordered hosted-untrusted child jobs around an accepted action. Whole-transition preflight, stable callback identity, immutable cleanup snapshots, idempotent replay, task-scoped proof, and browser/lemcliparity make each hook inspectable.
Human and agent usability
- One operational artifact serves uneven skill levels. Beginners get a wiki, bounded forms, buttons, visible progress, and downloads. Experts get YAML, containers, APIs, structured events, JSON, local development, and administrative controls.
- Browser, CLI, and API converge on one job. The interface changes, but action identity, admission policy, execution, events, terminal reason, logs, artifacts, and cache do not. Agents do not require a second automation implementation.
- Stable discovery for long-running agents. An iterative agent can re-list currently authorized apps and stable action IDs each pass. New capabilities become visible without rewriting the original prompt, while current ACLs and declared inputs remain the hard gate.
- Scoped individual, shared, and persistent workspaces. LEMC distinguishes personal and shared execution, public artifacts, private workspace state, cookbook-global state, render cache, and durable task proof. The data boundary is part of the distributed application.
Durable evidence
- MCP Tasks are durable handles, not LEMC’s retention model. Experimental Tasks specify state, polling, cancellation, TTL, and deferred results. They do not choose the team’s artifact store, provenance chain, audit ownership, retention policy, or cleanup proof.
- State can outlive the machine that produced it. Rendered output, logs, artifacts, cache, private state, terminal proof, and cleanup proof return to LEMC before scratch deletion. A later browser session or agent can hydrate the result without preserving the runner or microVM.
- Storage governance, not simply file output. Logs and artifacts carry account ownership metadata, checksums, audit events, quotas, exact-task selection, retention planning, and guarded physical deletion. Returning a blob from one invocation is not the same operating model.
- One trail joins live work to terminal proof. The server persists structured events before fanning the same authorized stream to
/web/wsand/cli/ws. Humans and agents can later inspect the same system steps, recipe steps, terminal reason, logs, artifacts, and cleanup record.
Parity map
| Capability | Human in browser | Agent with lemcli | Shared server truth |
|---|---|---|---|
| Discover | App page, wiki, form, and recipe button | jobs surface --format=json | Page/action metadata and permissions |
| Supply input | Named form controls | Repeated --set KEY=VALUE | Declared form schema and validation |
| Submit | Click the recipe action | jobs run --action ... | Task ID, queue lock, idempotent admission |
| Follow | Authenticated /web/ws monitor | Bearer-authenticated /cli/ws | Filtered task-scoped event stream |
| Inspect | Monitor steps and terminal reason | jobs status | System/recipe step state and terminal record |
| Retrieve | Rendered output and download links | jobs logs and jobs artifacts | Durable logs, artifacts, cache, and storage |
Shared action identity
The surface response gives an agent a stable action ID. The browser action carries the equivalent page, scope, recipe, and form contract. Both eventually submit the same server request shape.
app UUID
└── page 1
└── individual scope
└── action: run-page-1-individual-check-release-readiness
├── recipe: check release readiness
└── form: environment (required)
Stable IDs remove a fragile translation step. An agent can display the available choices, select one, and use its exact identifier rather than guessing from button labels.
A matched run
Browser path
- Open an authorized app page and read its supporting wiki text.
- Fill the declared fields and click the named recipe action.
- Watch the connected runtime/recipe stepper and rendered output.
- Keep the task ID, terminal reason, logs, and artifact links.
Agent path
lemcli jobs surface app \
--uuid "$APP_UUID" \
--scope individual \
--format=json
lemcli jobs run app \
--uuid "$APP_UUID" \
--action "$ACTION_ID" \
--set environment=production \
--follow \
--render html
The CLI renders the same authorized task-scoped LEMC verb stream in a terminal-appropriate form. It does not invent a second interpretation of recipe output.
Publish tooling to the team
A person can compose a cookbook in the web UI. An agent can perform
the same lifecycle through lemcli: create the record,
push reviewed YAML and digest-pinned recipe images, publish it,
instantiate an app, and grant the narrow execution ACL.
lemcli cookbooks create \
--name "Release operations" \
--description "Reviewed release checks" \
--format=json
lemcli cookbooks push "$COOKBOOK_UUID" \
--file cookbook.yaml \
--dry-run
lemcli cookbooks push "$COOKBOOK_UUID" --file cookbook.yaml
lemcli cookbooks toggle "$COOKBOOK_UUID" \
--type published --value true
lemcli apps create \
--cookbook-uuid "$COOKBOOK_UUID" \
--name "Release operations"
lemcli apps acls add "$APP_UUID" --user-id "$TEAMMATE_ID"
lemcli apps acls toggle "$APP_UUID" \
--user-id "$TEAMMATE_ID" \
--permission individual
Cookbook ACLs protect authorship. App ACLs protect execution. That separation lets a teammate run approved tooling without gaining permission to rewrite its source.
Re-discovery in a Ralph-style loop
An iterative agent should not freeze its tool catalog into the original prompt. At the beginning of each pass it can list the apps currently visible to its identity, inspect a selected app's live action surface, and run an action only when the present task needs it.
# 1. Discover team tooling that is authorized right now.
lemcli apps list --format=json
# 2. Inspect declared actions and inputs before deciding.
lemcli jobs surface app \
--uuid "$APP_UUID" \
--scope individual \
--format=json
# 3. If the task needs it, use the returned stable action ID.
lemcli jobs run app \
--uuid "$APP_UUID" \
--action "$ACTION_ID" \
--idempotency-key "$ITERATION_KEY" \
--follow \
--render json
New does not mean approved for every task. Re-discovery makes new authorized tooling visible; the loop must still read the action contract, choose deliberately, supply declared inputs, and wait for terminal proof. ACL and operator policy remain the hard gate.
ACL model
| Layer | Permissions | What it protects |
|---|---|---|
| Account | View/create apps and cookbooks; administer account | Entry to catalogs and authority to create team resources |
| Cookbook | Owner, view, edit | Source YAML, config, wiki, images, publishing, and collaborator access |
| App | Owner, individual, shared, admin | Runnable scopes and who may manage app execution ACLs |
| Job | Current authorized identity plus target scope/action | Admission, task filtering, live events, status, logs, and artifacts |
The browser session and CLI bearer credential authenticate the same current user. Every request resolves current account membership and permissions, so removing an ACL affects existing credentials rather than waiting for a token to expire.
What should match
- task ID, target app/cookbook, page, scope, recipe, and queue type;
- system-step and recipe-step order, status, and detail text;
- rendered LEMC verb output and user-visible errors;
- terminal status and specific terminal reason;
- durable logs, artifacts, and cache hydration after the live connection ends.
Authentication mechanisms intentionally differ: the browser uses its web session, while lemcli uses bearer credentials. Authorization and task filtering still converge at the server.
Guidance for agent builders
- Re-list authorized apps at the start of an iterative pass so newly distributed tooling can be considered.
- Discover before running; do not hard-code a recipe label when a stable action ID is available.
- Prefer
--format=jsonfor machine decisions and preserve the returned task ID. - Supply only declared fields; treat validation failures as contract feedback.
- Use an idempotency key when retrying admission after an uncertain client/network result.
- Wait for terminal state and inspect terminal reason instead of inferring success from partial output.
- Retrieve logs/artifacts through LEMC rather than reaching into runner scratch space.