Skip to content

ADR-0004: Execution lifecycle

Status: Accepted — 2026-09-22. The project owner approved the common execution lifecycle and foreground processes as the initial mode. Background execution remains a future extension requiring its own decision and validation. Acceptance does not establish a completed implementation or passed lifecycle checks.

Clarification — 2026-09-22: owner shutdown is an explicit cancellation cause. This record fixes final-outcome precedence and timing boundaries shared with ADR-0002/0003; the first accepted cause and the first finalization deadline do not change. The architecture remains accepted, and its implementation checks remain outstanding.

Refinement — 2026-09-24: ADR-0013 adds a long-lived MCP application host with bounded foreground command calls, not background extension workers. ADR-0014 bounds task authority; ADR-0015 specifies execution restrictions; ADR-0016 keeps external-effect evidence separate from this invocation’s immutable outcome. The original acceptance date and outstanding lifecycle checks are unchanged.

ADR-0001 separates the executor from the runtime provider. ADR-0002 defines invocation, outcomes and cancellation. ADR-0003 maps that contract to one supervised process and IPC session per invocation.

The execution lifecycle needs a common model beyond a PID or an open IPC connection. A future executor may run another kind of instance, and future work may outlive the CLI that requested it. Neither change should redefine success, cancellation or ownership of resources.

This decision concerns one execution attempt of a command, including contextual describe where supported. It does not describe installation, the lifetime of a runtime environment or a persistent extension service. Base help does not create an execution attempt.

  • One lifecycle and one final outcome, independent of execution mechanism.
  • A clear owner from preparation through bounded finalization.
  • A small initial implementation: foreground execution with a supervised child process.
  • An explicit extension point for background execution, without introducing it into the current IPC contract.
  • Preserve terminal ownership, permission checks and the prohibition on automatic retries.
OptionBenefitLimitation
Make the process and its exit code the lifecycleMinimal process wrapperCouples ownership and outcomes to one executor; cannot represent preparation and cleanup failures reliably
Implement a persistent job system immediatelyBackground work from the startAdds storage, recovery, identity and output delivery before those requirements are established
A shared lifecycle with explicit execution modesKeeps the process baseline small and preserves a path to other lifetimesBackground mode still needs its own owner, contract and validation

The core owns a logical execution attempt. The executor runs it; an explicit execution mode determines its relationship to the caller. Initially, only foreground execution using a supervised child process is supported.

ConceptMeaning
InvocationThe immutable request from ADR-0002: invocationId, kind, canonical command and release, inputs and selected context
Execution attemptPreparation, launch, work and finalization for that invocation; phases and observations change, identity does not
Lifecycle ownerThe core responsibility that orders transitions, controls admission of operations, handles cancellation and commits the outcome
ExecutorAn owner-approved mechanism that starts work, supplies observations, stops it and releases its resources
CallerThe party requesting the work and receiving its result; being connected is not itself execution authority

An invocation deadline, admission of a protected action, accepted cancellation, entry to finalization and final commitment are ordered by the lifecycle owner. Adapter observations are inputs to that ordering, not independently authoritative outcomes. Core-owned monotonic time is used for budgets; peer timestamps and late timer delivery cannot extend them.

One attempt uses the existing invocationId; no second execution ID is needed now. PIDs, IPC session IDs and future engine handles remain adapter details. An update, alias or late message cannot change the pinned command or release. Repeating a command creates a new invocation; it does not resume or reset the old attempt.

The owner is a responsibility within the core, not a new daemon or service required today. A future background owner must remain responsible after the initiating CLI ends. Runtime preparation remains the provider’s job; installed environments shared with other invocations are not resources to delete when one attempt ends.

These are logical phases, not new IPC messages or a fixed library API. The owner serializes transitions and final commitment. The executor reports observations; it cannot declare the whole lifecycle finished by itself.

Execution lifecycle
Execution lifecycleOne attempt proceeds through preparation, starting, running and bounded finalization. Rejection, failure or cancellation also enter finalization. Cancellation accepted before final commitment changes the pending outcome. Finished retains exactly one outcome and any incomplete-cleanup diagnostics.PreparingStartingRunningFinalizingFinished: immutable outcomeChecks pass and environmentis readyReady to dispatch the selectedinvocationCompletion evidence or failureRejection, preparation failure orcancellationStartup failure or cancellationCancellation acceptedCancellation beforecommitment takes priorityBudgeted finalization and oneoutcome commitExecution lifecycleOne attempt proceeds through preparation, starting, running and bounded finalization. Rejection, failure or cancellation also enter finalization. Cancellation accepted before final commitment changes the pending outcome. Finished retains exactly one outcome and any incomplete-cleanup diagnostics.PreparingStartingRunningFinalizingFinished: immutable outcomeChecks pass and environmentis readyReady to dispatch the selectedinvocationCompletion evidence or failureRejection, preparation failure orcancellationStartup failure or cancellationCancellation acceptedCancellation beforecommitment takes priorityBudgeted finalization and oneoutcome commit
PhaseResponsibility
PreparingPin the invocation and mode; check static support, inputs and access. For execute, prepare a supported environment if necessary. describe only uses an already ready environment, as required by ADR-0002.
StartingEstablish supervision and channels, start the executor and perform required confirmation. No command dispatch before confirmation in the managed process binding. Ordinary process-only work starts with the process; it has no synthetic handshake.
RunningDispatch at most once, supervise work and apply the existing checks to every core operation and interaction.
FinalizingClose admission of new operations/UI; settle or cancel admitted work, stop execution where necessary, account for output, required audit and resource cleanup within one bounded budget.
FinishedClose the invocation context and retain one immutable typed outcome with termination evidence, uncertain effects and cleanup diagnostics. No transition back to running.

The outcome is the existing ADR-0002 value: succeeded, command_failed, rejected, execution_failed or cancelled. Phase and outcome are separate: a command failure is a finished invocation, while a success report during finalization is still only a candidate result. Finished means the owner committed its final record; it does not assert successful cleanup or the absence of external work.

Static incompatibility or denied required access can yield rejected only under ADR-0002’s pre-launch conditions. Preparation/startup failure yields execution_failed. A known unsupported execution mode is rejected before runtime preparation or extension startup. Failed required cleanup prevents success; incomplete cleanup is reported explicitly.

Cancellation accepted before commitment takes priority, including during finalization. The first accepted cause is retained as user_request, owner_shutdown or deadline_exceeded; a later cause cannot replace it. Cancellation after commitment is too late and leaves the outcome unchanged. The invocation deadline remains effective from preparation through final commitment. The owner checks expiry before admission and commitment even if its timer callback is late. Expiry during finalization accepts deadline_exceeded unless an earlier cancellation already governs the outcome.

Finalization has a separate fixed deadline selected once on its first entry. Cancellation during finalization changes the candidate outcome but does not move this deadline. Every stopping, stream, pending-operation, audit and cleanup step uses the same remaining budget. The process mappings retain ADR-0003’s five-second shutdown budget, cooperative-stop limit and exit mapping. Exceeding this finalization budget alone is an execution failure, not invocation cancellation. Ordinary logs may drain during that budget under ADR-0002; they do not reopen operations or extend the lifetime. stdin EOF remains input exhaustion, not cancellation.

The owner applies the following priority when it commits the result. It first observes invocation expiry and pending accepted cancellation; a success observation cannot bypass that check.

PriorityConditionFinal outcome
1Cancellation accepted before commitmentcancelled, with the first accepted cause; other failures remain diagnostics
2Preparation, launch, execution, completion evidence or required finalization failedexecution_failed; preserve the primary failure and uncertain effects
3Static input, compatibility or required-access rejection prevented extension startup, and required cleanup succeededrejected
4Valid application-failure evidence and successful required finalizationcommand_failed
5Valid success evidence and successful required finalizationsucceeded

Missing or contradictory required evidence belongs to priority 2; no implicit default to success exists. These are precedence rules, not a requirement to continue failed work to collect every possible error. Already admitted external actions may have uncertain effects. The owner closes admission to new protected actions with finalization, including queued requests whose action has not started; only established cleanup and audit obligations may proceed within the remaining budget.

Synchronous means the CLI waits for the final outcome before returning to its caller. It does not require blocking the core’s event loop, serializing IPC or preventing concurrent stream handling. A library can expose an asynchronous handle internally while retaining this same lifetime rule.

The core creates one supervised child process per invocation, native or scripted, using the accepted mappings. It stays responsible through finalization. A completion report, exit of the main child or closure of a stream alone is insufficient: all required evidence must agree. The process-only mapping uses its own exit evidence and does not acquire an IPC requirement.

The logical control surface needs to support starting an attempt once, observing its current phase, waiting for the final outcome and requesting cancellation. These are responsibilities, not prescribed method names. A cancellation acknowledgement means the request was accepted or was too late; it is not proof of termination. Observation does not consume or replace the final result, and observations are not a durable event log.

On orderly CLI shutdown or loss of its execution scope, the core requests owner_shutdown for active foreground work and performs bounded cleanup. An explicit user’s or caller’s stop request instead uses user_request; a scope ending does not rewrite a cause already accepted. Both map to CLI status 130, while deadline_exceeded maps to 124. A library returns the same typed outcome and cause even when no CLI process exits. Losing an observer alone is not loss of the execution scope.

If the core itself crashes, process supervision must provide the termination behavior declared by the platform adapter; a dead owner cannot accept cancellation or commit a final result. An observer may report owner loss and unknown execution state, but cannot fabricate cancelled, succeeded or another committed invocation result. The initial mode has no durable execution recovery, reattachment or automatic restart. Separate resource reconciliation may later confirm termination and release protective references; it does not resume work or reconstruct a missing final outcome.

The core continues to own the terminal and any UI. Closing an observer or returning a library handle is not a detach operation. Extensions may use supervised descendants as part of their work, but cannot convert them into background Rukh tasks. Containment still has ADR-0001/0003’s limits: an ordinary process is not a sandbox, and stopping it cannot undo effects in external services.

Foreground MCP ownership and external effects

Section titled “Foreground MCP ownership and external effects”

For the accepted CLI/MCP host, foreground ownership is relative to one command-call scope, not the lifetime of a single shell process. The MCP host may remain alive between calls and own concurrent scopes within ADR-0010 limits. Each scope waits for its final outcome; the host does not retain an extension as a background worker, and an observer disconnect does not by itself define scope loss. ADR-0013 specifies the transport/host binding. Closing the owning scope still requests owner_shutdown and uses the same non-renewable cleanup budget.

An effect ledger can retain uncertainty after the invocation finishes under ADR-0016. A separately authorized inspection may later settle that evidence, but cannot reopen this invocation, replay its command or change its committed outcome. Task-authority expiry stops new protected-action admission according to ADR-0014; it is not permission to invent a different cancellation cause or reset the invocation’s deadline. Confinement violations follow ADR-0015 failure/cleanup rules without weakening the selected profile.

Execution mode and executor kind are independent. A future background task may still use a process; a future WASM executor is not automatically background-capable. Effective support requires a compatible command declaration, owner policy, lifecycle owner and executor mapping. Declaring a mode requests support and permission; it does not grant them. The mode is pinned before preparation and cannot change mid-invocation. Today, requests for background mode fail explicitly; there is no detach flag or unobserved fallback.

The diagram compares ownership. The group labelled “Future mode: background” describes future requirements, not an implemented component or an accepted transport.

Ownership boundary for execution modes
Ownership boundary for execution modesIn the initial foreground mode, the CLI owns execution and waits for its outcome. A future background mode requires an independent lifecycle owner; the CLI submits and observes work through it. Both paths retain an owner between the caller and the executor.Future mode: backgroundInitial mode: foregroundInitiating CLIIndependent lifecycle ownerCompatible executorCLI and lifecycle ownerProcess executorStart and superviseEvidence for final outcomeSubmit, observe, requestcancellationStart and superviseEvidence for final outcomeOwnership boundary for execution modesIn the initial foreground mode, the CLI owns execution and waits for its outcome. A future background mode requires an independent lifecycle owner; the CLI submits and observes work through it. Both paths retain an owner between the caller and the executor.Future mode: backgroundInitial mode: foregroundInitiating CLIIndependent lifecycle ownerCompatible executorCLI and lifecycle ownerProcess executorStart and superviseEvidence for final outcomeSubmit, observe, requestcancellationStart and superviseEvidence for final outcome

Background support requires a subsequent decision covering the following boundaries. They are compatibility requirements for the extension point, not a job-system implementation selected by this ADR.

BoundaryRequired before background mode can be supported
Ownership and admissionAn independent owner must accept responsibility before the CLI reports submission as accepted. A submission receipt is not the command’s final success. Resolve uncertain submission without silently creating another attempt.
Identity and recoveryA stable work reference identifies retained state and results, separately from each attempt’s invocationId and transport session. Define storage, retention and owner-crash behavior; neither a reconnect nor a retry may repeat work implicitly.
AuthorizationAuthenticate submission, observation and cancellation separately; a work ID is not a credential. Define the subject and restricted authority after logout, credential expiry, permission changes or broker failure. Keep operation-level checks and required audit.
Input and outputSelect explicit input sources and owned output destinations before starting, independent of the initiating terminal. It cannot remain an implicit input, output or secret source. Define noninteractive requirements and any separately authorized future attachment; the owner still controls presentation.
Cancellation and resultLoss of the initiating CLI is distinct from an authorized cancellation. The owner continues to apply deadlines, bounded cleanup and the same final outcomes. Define how observers retrieve that authoritative result.
CompatibilityDeclare and check background support separately from process/engine support. The owner-to-executor mapping must preserve ADR-0002. Caller-to-owner submission is a separate contract; ADR-0003 does not become reconnectable or reusable.

A deliberately declared operation may submit work to an external service and return a reference today. Its success confirms only what that operation promises, such as accepted submission; it does not imply that the remote work finished or that Rukh supervises it. This does not enable background extension processes by implication.

  • The initial implementation keeps the current process/IPC boundaries. It does not need a daemon, persistent queue or new wire messages.
  • The core can replace an executor without replacing lifecycle semantics. Each mapping must still demonstrate its stopping, completion and resource guarantees.
  • Background support remains possible through a separate owner and execution mode, rather than weakening foreground cleanup. Scheduling, retries, migration, persistent workers and durable recovery remain separate work.

The project owner accepted this architecture on 2026-09-22 with the implementation checks below still outstanding. They remain required validation of a reference lifecycle owner, not completed evidence:

  1. Native, scripted and process-only attempts reach one outcome; an unsupported mode is rejected before preparation/launch. Contextual help keeps ADR-0002’s restrictions.
  2. All three cancellation causes race with preparation, startup, completion and final commitment. The first accepted cause remains fixed, including when a timer is late; no new protected action is admitted after finalization begins, and no action is automatically repeated.
  3. Main-process exit, outstanding calls, blocked output, descendants and required-audit/cleanup failures use one unchanged shutdown deadline. Invocation expiry during finalization accepts cancellation, while shutdown-budget expiry alone fails execution. A stopped observer is not mistaken for stopped execution.
  4. Orderly owner shutdown cancels foreground work; abrupt owner loss exercises the adapter’s declared supervision guarantees without manufacturing a completed result.
  5. A model with a separate caller and owner confirms the future boundary: caller disconnection does not itself cancel work, a receipt is not a final outcome, and observation/cancellation require authorization. This is a model check, not proof of background-mode support.

The ADR-0001–0003 experiments are prior evidence for their recorded process/contract scope. They do not validate this generalized owner model or background execution. The checks above have not been run for ADR-0004. The accepted scope is the common lifecycle and ownership rules with foreground processes as the initial mode; it does not declare background support, durable recovery or a production implementation ready.

Diagram

Drag to move · + / − to zoom · 0 to fit · Esc to closeDrag to move and pinch to zoom

100%