ADR-0016: Effect commitment and reconciliation
Status: Accepted — 2026-09-24. The project owner approved this architectural refinement. It defines the contract for controlled effects; it does not claim a completed ledger, service adapter, exactly-once execution or successful conformance checks.
English | Русский
Context and problem
Section titled “Context and problem”An agent may repeat a request after losing a response, choose an action broader than its task or commit an outdated preview. A trusted extension and valid user credentials do not prevent those mistakes. The invocation ID from ADR-0002 identifies one execution attempt; it does not prove whether a payment, publication, deletion or remote submission happened.
Rukh must retain a simple CLI and support MCP tools without requiring a distributed workflow engine. It needs a common boundary for consequential actions, with honest behavior when a remote outcome is unknown. This boundary controls registered operations; an ordinary process with direct OS authority is not automatically covered.
Decision drivers
Section titled “Decision drivers”- Bind permission and any confirmation to the actual target, payload and conditions of an action.
- Prevent a lost response, transport retry or agent wording from authorizing a second execution of the same admitted effect.
- Keep task-wide budgets and current authorization effective at commitment.
- Distinguish command outcomes, external effects, audit and resource cleanup.
- Support a local persistent store and optional service adapters, with no mandatory remote coordinator.
Considered options
Section titled “Considered options”| Option | Benefit | Limitation |
|---|---|---|
| Deduplicate request IDs or identical arguments | Small implementation | Transport IDs change; identical arguments can describe legitimate separate actions; neither identifies an external effect |
| Make every command a distributed transaction | Uniform-looking API | Ordinary programs and remote services cannot generally join it; creates a false rollback/exactly-once promise |
| Trusted effect contracts, one-use authority and bounded reconciliation | Protects explicitly supported operations and preserves uncertainty | Needs durable admission state and operation-specific evidence; unsupported effects remain outside the guarantee |
Decision
Section titled “Decision”A consequential action requiring controlled execution receives a core-owned effect identity and exact trusted binding. Before dispatch, the core durably consumes its one-use authority and reserves the task’s resources. An uncertain outcome is reconciled without replaying the extension or inventing success.
Applicability and registration
Section titled “Applicability and registration”This contract is an optional registered capability for ordinary CLI use and a required capability wherever an owner/task/MCP profile requires controlled consequential effects. There is no heuristic that makes all writes or all tools automatically safe. The owner classifies protected operations and admits their implementations through ADR-0010; extension metadata requests support and describes intent but does not establish the actual action or its authority.
A trusted operation derives action/resource identities, normalizes a typed request, establishes the actual destination and enforces the resulting binding. An admitted owner wrapper may implement this contract for an existing command only when it can truly constrain and observe its effects. Parsing ordinary stdout, trusting an extension’s readOnly claim or adding a fixed executable prefix does not do that. Strict profiles require all protected external effects to cross this boundary, through ADR-0015 when needed.
The registered contract declares preparation, commitment, result/effect evidence, reconciliation support, finite cost bounds, expiration, audit and cleanup requirements. It also declares the protected service’s idempotency scope/retention and conditional-write guarantees, if any. Unsupported properties are explicit; an adapter cannot manufacture them from a local hash. A baseline local ledger is sufficient for local coordination; all processes able to exercise the same authority use the same declared storage domain.
Effect binding and permit
Section titled “Effect binding and permit”The following are logical records, not additional command outcomes or selected wire method names.
| Record | Required meaning |
|---|---|
effectId | Fresh opaque identity issued by the core for one intended external effect. Independent of JSON-RPC, IPC, invocation and process IDs; it is neither a credential nor proof of completion |
| Prepared effect | Exact registered operation/version and implementation binding, command/release, normalized payload or immutable payload reference, actual resource/recipient, expected revision or other preconditions, task/subject/actor bindings, owner revision, maximum costs and expiration |
| Binding digest | Hash of a versioned core-serialized immutable binding body, excluding its own digest, transient request IDs and authorization secrets. Detects substitution; does not prove consent, idempotency or external execution |
| Commit permit | Core-held or opaque protected one-use authority for this effect and binding, issued by an admitted owner policy or trusted human-approval path. Contains no authority selected by the model itself |
| Effect record | Durable state, exact binding, permit-consumption evidence, reservationId and task-ledger binding, originating invocation, provider reference, known result/effect evidence and unresolved obligations |
Subject, actor and taskAuthorityRef retain ADR-0014 meaning. A permit cannot switch accounts, task ancestry, recipients or executable implementations. An opaque effect reference supplied as an operation’s declared input resolves within the authenticated task/actor scope; knowing or copying it grants no access. Another authorized observer may inspect a record only under a separately admitted observation action.
The service implementation determines the resource that will actually be changed. A mutable path, alias, DNS name or display label is insufficient when the approval concerns a particular object. Conditional writes use a service-enforced revision/precondition or an equivalent trusted local binding; check-then-write with a replacement window cannot claim that property. If the target changes, the old binding cannot commit. The adapter requests new preparation and authority, not automatic expansion of the old permit.
Policy may issue a permit automatically for a bounded class of actions already authorized by the owner and task. Other policies require human approval of a safe description of the exact effect. The core binds that approval to the digest and approved costs/expiry. A command’s ordinary dialog, an MCP client’s claimed confirmation, an agent saying “approved” or a hash echoed in arguments is not that approval. A trusted host approval integration must establish the human/issuer evidence before issuing the permit. Human confirmation does not bypass Security Broker or task authorization.
Preparation, preview and commitment
Section titled “Preparation, preview and commitment”Preparation produces the trusted binding without performing the protected effect. It may use separately authorized read operations to resolve a resource or construct a preview. Any preparatory write or charge is itself an effect with its own permission and accounting; calling it preparation does not exempt it. Preparation is bounded and cannot reserve an unlimited service-side resource implicitly.
A visible preview/commit pair is optional per operation. A simple operation can prepare and commit internally under a preapproved policy without adding user-visible steps. An operation that offers a preview must state exactly what it guarantees and which conditions will be rechecked. There is no generic dry run that promises to predict arbitrary executable behavior.
Immediately before dispatch the core validates all of the following against the pinned binding: live invocation/task scope, non-expired permit, unchanged supported operation/release, current permission and revocation state under ADR-0012, object preconditions, mandatory audit readiness, and finite available budget. A prior preview, approval or successful discovery does not extend any of those lifetimes.
The shared admission boundary then atomically associates and durably records permit consumption, the effect’s dispatch intent and the ADR-0014 reservation across root/ancestor/child budgets. Independent local stores without a proven coordination contract are insufficient. No external dispatch occurs until this transition is confirmed. Storage failure, conflict or uncertain commitment prevents dispatch by that caller and requires inspection of the existing record; it never issues a replacement permit automatically.
Only the winning admission can submit the effect. Other requests for the same effect receive its known state or a defined already-consumed/unknown-state error, not a second submission. The durable dispatch-intent state deliberately includes the crash window immediately before the external send: after a crash the core cannot assume nothing happened just because its local completion record is absent.
Revocation ordered before admission prevents dispatch. Revocation or cancellation after admission cannot guarantee that an external action did not occur. A long-running operation checks current authority before additional protected steps and observes its own fixed deadline; previously submitted work may continue in the external service. External submission success means only the declared acceptance/result, not completion of the remote job. It never detaches the extension process from ADR-0004 ownership.
Repetition, uncertainty and reconciliation
Section titled “Repetition, uncertainty and reconciliation”| Situation | Required behavior |
|---|---|
Repeated observation or commit for the same bound effectId | Check observation/commit access, then return known state or an explicit unresolved result; do not create another effect |
| Same reference with changed payload, task, actor or target | Reject the binding mismatch; no reinterpretation as a new command |
| New request with identical arguments | It may be a legitimate new effect. Do not deduplicate by argument equality; it needs a newly issued permit under the applicable policy |
| Confirmed failure before dispatch or authoritative proof of no effect | Mark a known no-effect state and release unused reservation under the task ledger’s rules |
| Dispatch possibly occurred and response is lost | Retain an unknown effect, one-use consumption, maximum unresolved reservation and protective references; no automatic resend |
| Authoritative completion/failure evidence | Record what the service actually proves and settle the measured cost. A failed operation may still have consumed resources or performed partial effects |
| Missing record after corruption or incomplete recovery | Fail closed. Absence of trustworthy state is not proof that the permit is unused or the action did not run |
Reconciliation is a separate authorized, bounded inspection of an existing effect. It does not restart the extension, reopen a finished invocation or run another command to recreate a result. Prefer a service query by its bound effect/idempotency reference. “Not found” is conclusive only if the service contract proves there can be no late acceptance or execution for that reference; eventual-consistency absence alone is insufficient.
A registered adapter may resolve uncertainty through the same service-enforced idempotency operation only when its declared contract proves that reusing the exact bound key cannot create another effect, including concurrent requests, payload mismatch and the full retention interval. This is a separately authorized reconciliation action, not automatic invocation replay. An expired, unverifiable or differently scoped service key does not permit resend. Services without such evidence remain uncertain until an authorized operator can establish the outcome or accept a separately recorded risk; operator acknowledgement cannot rewrite uncertainty as proof of non-execution.
A strict consequential MCP profile requires an admitted operation contract, a bound one-use permit/effect reference and enforceable external semantics. A generic client that cannot preserve the required binding, or an operation that cannot provide the selected guarantee, receives an unsupported/denied result. It does not gain an unrestricted alternative tool. No generic prepare/commit tools are invented for every extension, and transport retries or MCP interaction continuation are not new authority. An operation-specific typed reference may carry an existing effect identity; privileged approval context never becomes arbitrary command data.
The model may request a genuinely new effect with similar arguments. Preventing unwanted repetition across such fresh requests requires the owner’s task rules, budgets and permit-issuance policy, not a claim that the ledger understands intent. A policy that automatically issues unlimited new permits has deliberately not bounded that repetition. Where one publication or payment is intended, the authority identifies that bounded action and allows only its admitted count.
Storage, budgets and final outcomes
Section titled “Storage, budgets and final outcomes”The effect ledger and admission/task ledger share one trusted transaction/coordination boundary. A local durable store satisfies the small-team baseline; no remote database is mandatory. Process locks, persisted state and restart recovery must prevent concurrent cores from consuming the same permit or overspending one root task. Distributed storage is a replaceable owner-admitted implementation with the same contract, not a weaker eventual-consistency substitute.
Store only bounded binding metadata, digests, protected references and safe evidence. Secret values are neither audit text nor ledger fields. Sensitive payloads, if needed for reconciliation, use an explicitly protected immutable store with separate access/retention; a digest cannot reconstruct them. Atomic publication, durability errors, corruption and uncertain commitment retain ADR-0007/0010 principles. Required ledger/audit failure prevents protected dispatch or a false success, without repeating an external action already sent.
The local effect-store profile selects 10,000 retained effect records and 64 MiB of stored metadata, with at most 64 KiB per encoded record; these are conservative design limits, not measured capacities. Secret/payload stores have their own finite owner quota; references do not bypass the record or task limits. The smallest applicable invocation/message bound still applies. At capacity, reject new effects instead of deleting unresolved or live records. A supported owner profile may select other finite tested bounds.
Permit lifetime cannot exceed task, authenticated-context, operation, resource-precondition and service-idempotency horizons. A replay-prevention tombstone for an issued effect/permit remains for at least its whole admissible lifetime and any longer required service window. Unresolved effects, active references and reserved costs are not collected merely because that lifetime expires. A profile must provide a finite storage capacity; exhausted unresolved capacity blocks new effects instead of claiming a finite resolution time. Authenticated expired or unknown references never recreate an effect after collection.
Each reconciliation attempt has an explicit non-renewable deadline no later than its authorized scope; shutdown uses ADR-0004’s unchanged budget. Background reconciliation is not enabled by this decision: the host or an explicitly invoked maintenance operation owns the bounded inspection. A service’s indefinite external work is recorded as such rather than extending an invocation indefinitely.
The common five invocation outcomes remain unchanged. Unsupported/denied requirements before extension startup can yield rejected; a failure during a launched command follows its existing application/execution classification. Missing mandatory effect evidence or cleanup prevents succeeded; accepted cancellation still wins and retains effect uncertainty as diagnostics. A later ledger reconciliation never rewrites the original immutable invocation outcome. Known settled effects can coexist with a cancelled or failed invocation.
Consequences
Section titled “Consequences”- A small CLI can use local policy, local durable accounting and one trusted operation adapter. Enterprise infrastructure is not a prerequisite.
- Controlled effects require operation-specific support; ordinary trusted programs remain usable without claiming those guarantees.
- Previews and human approval can be added without creating a second execution path. They never substitute for current authorization.
- Some failures remain unresolved and consume quota until evidence is obtained. This cost is preferable to silently repeating a possibly completed action.
- There is no general exactly-once execution, automatic rollback or automatic compensation. A compensating action is a new separately authorized effect with its own risks and evidence.
Confirmation
Section titled “Confirmation”The architecture is accepted; the following implementation checks have not been run:
- Altered payloads, replaced resources, changed recipients, expired approvals and forged agent confirmations cannot reuse a permit. Conditional changes bind to the actual object/version at dispatch.
- Concurrent processes and crash points around durable admission, external dispatch and result persistence never consume one permit twice or release an uncertain reservation. Corruption and full storage stop new effects safely.
- A known pre-effect abort refunds only unused allowance; partial effects and lost responses retain the correct reservation and references. Root/ancestor task ceilings remain shared across delegated callers.
- Read-only inspection, eventual-consistency absence, expired service keys and supported idempotent reconciliation produce their defined evidence. Neither extension invocations nor unknown external actions are automatically repeated.
- Cancellation, revocation, audit failure and cleanup timeout retain one invocation outcome and separate effect state. Later reconciliation does not turn a finished cancellation into success.
- A local CLI and supported MCP client use the same operation/authority path; a client or extension without required effect features is rejected under the strict profile, while an explicitly ordinary trusted profile remains usable without that promise.
Earlier IPC measurements and functional checks are not evidence for this ledger or any remote service’s effect semantics.
- ADR-0002: Core–extension interaction contract.
- ADR-0004: Execution lifecycle.
- ADR-0007: Extension loading and updates.
- ADR-0010: Core library and branded CLI composition.
- ADR-0012: Authorization validity and revocation.
- ADR-0013: Command model and MCP.
- ADR-0014: Task authority and delegation.
- ADR-0015: Execution confinement.