ADR-0014: Task authority and delegation
Status: Accepted — 2026-09-24. The project owner approved this architectural direction. The contracts and limits below are selected design rules; implementation checks remain outstanding.
English | Русский
Context and problem
Section titled “Context and problem”ADR-0005 binds identity and permissions to trusted core context. ADR-0012 checks current authority at action admission. An agent using the command model and MCP adapter can nevertheless request a permitted operation for an unrelated purpose, combine operations, or delegate more access than its task needs. A description such as “summarize this folder” is neither a verified identity nor an executable access policy.
The core cannot guarantee that an arbitrary external agent understands a user’s intent or resists prompt injection. It can enforce a bounded set of actions, resources and effects at boundaries it controls. Task authority must remain valid independently of the agent’s text and survive concurrent calls and core restarts without resetting its budget. This does not require an agent runtime, task planner, background service or corporate identity system.
Decision drivers
Section titled “Decision drivers”- Establish authority from owner policy or an authorized person’s trusted input, rather than from the caller’s claimed purpose.
- Distinguish the subject whose rights apply from the actor making a request on that subject’s behalf.
- Keep ordinary local CLI use simple and machine exposure explicitly configured.
- Restrict delegation and aggregate consumption across the entire task tree.
- Bind authorization, budgets and effect commitment at the same final admission boundary.
- State precisely which resources the selected execution boundary can govern.
Considered options
Section titled “Considered options”| Option | Benefit | Limitation |
|---|---|---|
| Treat prompt text or an agent-supplied scope as authority | Little integration work | Lets the requester define its own rights |
| Check only the user’s general permission for each operation | Reuses existing policy | Does not bound the task or consumption across children and parallel callers |
| Require a remote token/delegation server | Central issuance | Unnecessary for local tools; token syntax alone does not enforce scope or budgets |
| Core-owned task authority with local references and optional trusted issuers | One admission rule for local and integrated deployments | Requires trusted issuance, state coordination and explicit limits |
Decision
Section titled “Decision”Every invocation binds to authority created by a trusted core path. Task authority narrows current owner and subject permissions; it never replaces them. An agent may propose a task, operation or narrower scope, but cannot issue, extend, transfer or renew its own authority. CLI, library and MCP entry points use the same rule.
Issuance and the local baseline
Section titled “Issuance and the local baseline”The owner registers supported issuance paths when composing the CLI under ADR-0010. Approved configuration selects their policies. An issuance path is either an owner-approved preset, a trusted interaction with a person authorized to grant the requested scope, or an explicitly registered external authority. An ordinary extension, tool argument, model message, catalog entry or MCP clientInfo value is never an issuer. A human-facing grant must identify the actions, resources, destinations, lifetime and limits being approved; confirming a command’s ordinary dialog is not such a grant.
The smallest deployment remains one static catalog and an explicit local preset under ADR-0009. A direct CLI invocation automatically creates a local task binding for that invocation from the approved preset and validated command inputs; ordinary trusted local use does not require a separate grant interaction. It needs no login, JWT, database server or remote broker. Shared task metadata can use protected local files with locking and crash-consistent publication. The preset grants only its documented scope; selecting public-catalog does not expose every command to an agent or grant all operations requested by its extensions.
Machine callers use an owner-approved entry-point configuration that selects existing task authority or permits bounded issuance from a specific preset. A caller-supplied task ID or free-form purpose cannot select another grant. If that profile requires a human grant and none exists, return interaction_required; do not start a hidden prompt or convert it into preset authority. Preset issuance itself has owner-defined limits on active roots and creation rate where the entry point permits repeated creation. Per-task budgets make no claim of limiting aggregate work across independently authorized root tasks; a deployment needing that bound must enforce a shared owner/subject quota at issuance and admission, or reject the unsupported requirement.
This is a boundary for cooperating cores and their mediated actions. A process with permission to change trusted owner state or to bypass the core using the same OS account is outside that protection. ADR-0015 determines whether stronger restrictions are actually enforced. An unavailable required authority or coordinator never causes issuance from a weaker local preset.
Logical authority record
Section titled “Logical authority record”The following is the core’s logical contract, not a released public schema or a requirement to encode it as a signed token. The baseline resolves an opaque taskAuthorityRef through protected local state. Knowing a reference alone does not authorize its use. A registered external format must validate its issuer, audience, recipient, lifetime and binding, then normalize to this contract; JWT is optional.
| Field | Meaning and validation |
|---|---|
taskId, taskAuthorityRef, taskEpoch | Core-generated task identity, opaque authority reference and monotonic invalidation fence. Never reused or accepted as self-authenticating caller claims. |
issuerBinding, issuanceEvidence | Registered issuer or trusted local issuance path, approved preset/policy revision or exact human grant record, and the authority under which it was issued. Evidence must exist independently of the agent’s requested scope. |
principalBinding | Existing ADR-0005 subject binding, including the verified authentication context when required. A local subject remains explicitly local. |
actorBinding | Core-derived identity of the acting client, launch context or delegated participant, with its trusted entry-point/transport binding and permitted recipient. A display name, claimed agent identity or transport connection alone does not prove a human identity. |
ownerNamespace, accessDomain, ownerConfigRevision | Exact owner, policy domain and issuance configuration. Current policy must still admit these bindings; this recorded revision does not freeze old permissions. |
scope | Finite registered command/action identities and validated resource selectors under ADR-0009, plus supported source/destination and effect restrictions. Unknown operations, omitted wildcard selectors and restrictions the boundary cannot enforce are rejected. |
purpose | Optional bounded explanation for display and audit. It is not evaluated as natural-language policy and cannot increase scope. |
issuedAt, notAfter | Trusted issuance time and finite non-renewable task horizon. Earlier identity, issuer, owner, ancestor and invocation bounds always win. |
parentAuthorityRef, rootAuthorityRef, delegationDepth | Protected lineage, with a tagged absent parent for a root. The core resolves the entire bounded chain; missing or conflicting ancestry prevents use. |
delegationAllowed, delegationLimit | Explicit permission and finite remaining depth/child limits. Defaults prohibit delegation. An allowed invocation does not imply permission to delegate. |
ledgerRef, budgetCeilings | Shared root accounting and finite typed limits; child limits may only narrow ancestor limits. Counters and reservations are authoritative coordinator state, never caller-provided balances. |
An invocation pins taskId, taskAuthorityRef, taskEpoch, actorBinding and principalBinding together with the command, release and owner bindings already required by ADR-0002. A task can cover several invocations only when its issuance policy explicitly permits that use. Starting another process, reconnecting MCP, changing a request ID or refreshing a credential does not create a fresh task allowance.
actorBinding answers who is acting; principalBinding answers whose rights constrain that action. A core service’s own API credentials answer neither question on behalf of the caller. An owner-approved local launch can identify a local actor without asserting an organizational identity. Transfer to a different actor requires the explicit delegation path below, not copying a reference. Request and audit context retain both bindings.
Effective scope and supported restrictions
Section titled “Effective scope and supported restrictions”Admission requires the intersection of current owner policy, the subject’s current permissions, every ancestor’s remaining authority, the current task’s scope, the actor’s binding, the trusted extension and command restrictions, and the invocation’s original bounds. Each can deny; no constituent’s allow overrides another’s denial. Reuse of a broker decision under ADR-0012 still requires this current intersection. An unavailable input needed to establish it yields no admission.
Trusted operation registrations derive actual resources from validated parameters. They specify which input fields, source identities, destinations, redirect handling and effect categories can be checked. Where an owner requires information-flow or sequence restrictions, the registered policy must retain the necessary state and enforce them at the controlled boundary. Permission to read and permission to send are not proof that a particular read-then-send combination is authorized. An opaque external model that has received plaintext is not a provenance-preserving interpreter: Rukh cannot claim to track every transformation or prevent its out-of-band disclosure.
A command’s declared effect or source/destination annotation is a request for policy validation, not an enforcement mechanism. host-trusted execution may explicitly expose trusted native code under the owner’s limits, while acknowledging its ambient OS authority. A machine exposure preset does not imply an OS sandbox. If the owner requires restrictions that this executor or registered operation cannot enforce, return unsupported before launch or effect admission; do not silently use host-trusted. ADR-0015 defines confinement selection and evidence.
Delegation only narrows
Section titled “Delegation only narrows”Delegation is disabled by default. An enabled trusted issuance path validates the delegating actor, current parent chain, requested child actor, exact narrower scope and remaining budgets. The core creates the child record and lineage atomically before returning its reference. It never trusts a child-provided ancestry or a forwarded user token as sufficient delegation evidence.
The child’s scope is an intersection with all ancestors; its deadline is no later than any ancestor’s, and its limits cannot exceed their remaining allowance. A child cannot change issuer, subject, access domain, owner namespace or execution restrictions. Required obligations and denials carry forward. Revoking or expiring an ancestor stops new descendant admissions. A later owner change can further narrow or invalidate existing tasks, but cannot silently enlarge an issued grant.
Sibling allowances are not independently minted copies of the parent budget. Children and all participating core processes debit the same root accounting, additionally enforcing each ancestor and child ceiling. A delegation record and its budget reservation commit together; a partial write or lost reply does not authorize issuing a duplicate child. Recovery inspects the recorded transition rather than assuming no child was created.
This view describes accepted authority flow, not a background task service.
Shared budgets and final admission
Section titled “Shared budgets and final admission”Each budget dimension has a trusted unit, finite ceiling, measurement rule and reservation rule. The local baseline counts command admissions and protected operation admissions; ordinary output/log events retain their existing quotas rather than consuming a task action per byte. Optional dimensions include bytes released through a governed channel or a provider-defined cost unit. Calling a value “cost” does not make it measurable. A hard monetary ceiling requires a trusted maximum charge known before dispatch, including applicable overhead; an estimate or a final invoice after execution is insufficient.
Every counted command or protected operation atomically and durably consumes one admission from the root, each ancestor and the child before dispatch, including ordinary host-trusted invocations. The same transition checks current authority, revocation and applicable deadlines; a queued request cannot reuse an earlier allowance check. A consumed admission counts the attempt, independent of the later result; variable-cost reservations below have separate settlement rules.
For a controlled effect governed by ADR-0016, the admission coordinator atomically checks all current bindings, fences, rights and deadlines, then reserves the operation’s trusted maximum charge against the root, ancestors and child in one ordered transition before dispatch. Parallel cores and siblings cannot both spend the same remaining allowance. The transition uses ADR-0016’s effectId and reservationId; identity/authentication checks and required pre-action audit still apply. An authorization cache never caches a budget reservation or effect permit. A queued request repeats these checks at actual admission. Simple command-admission counters do not wrap a native program’s arbitrary effects: a profile requiring an effect ceiling must select an enforceable controlled-effect contract or reject the operation.
The coordinator durably records consumed and reserved amounts before dispatch. A confirmed non-dispatched attempt may release its reservation; a confirmed measured result settles actual consumption and releases only its proven unused portion. If the effect may have happened, its reservation remains held until ADR-0016’s authoritative reconciliation establishes its outcome and cost. Cancellation, timeout, a dead process, expired task or a lost lock are not evidence that the effect cost is zero. The protective record can outlive both the task and its foreground execution scope. Cleanup or expiry cannot reset the shared balance, and reconnect or restart cannot recreate it from a preset.
For a required hard ceiling, an unknown or unbounded maximum charge makes the operation unsupported before dispatch. If the selected provider cannot cap an ongoing effect, local timeout does not establish that cap. Counters cannot overflow or become negative; unrepresentable charges are rejected. The shared ledger records accounting, not an exact-once execution guarantee or rollback of an external service.
The task coordinator may share the local transactional infrastructure used by ADR-0007/0011/0012; a daemon or database server is not required. It must nevertheless provide durable reservation, invalidation and recovery ordering across every process using this authority. Unreadable, corrupt or incomplete previously initialized state prevents affected admission; it is not an empty budget. Process-local accounting is insufficient for a task that can be used by another core or survive reconnect. Coordination waits fit ADR-0012’s bound and the remaining invocation budget.
Lifetime, limits and errors
Section titled “Lifetime, limits and errors”Task authority is separate from ADR-0004’s ExecutionScope, which owns execution and cleanup. Each invocation or operation checks its own deadline and the task admission horizon without changing the task’s fixed expiration. The authority horizon is not a new process timeout: expiry blocks new admissions without automatically killing already admitted work. A still-valid task does not keep a process alive, detach foreground work or reopen a finalized invocation. Closing an execution scope does not erase accounting or prove an external effect absent. Revocation normally blocks new admissions; stopping running work retains the existing cancellation and finalization rules. No background execution or resumable job API follows from this record.
These are selected defaults for authority handling, not measured implementation guarantees. Owner configuration may tighten them; larger finite bounds require explicitly supported configuration. A selected action or provider may require a smaller bound.
| Bound | Accepted default or rule |
|---|---|
| Local direct-invocation preset | One invocation and at most 256 protected operation admissions; no delegation. Explicit owner policy supplies any additional resource/effect restrictions |
| Task lifetime | At most 1 hour from issuance, further limited by all applicable issuer, identity, ancestor and owner horizons; no sliding renewal |
| Machine/multi-invocation preset | Explicit finite invocation, operation, concurrent-admission and issuance limits required; no implicit unrestricted preset |
| Delegation | Disabled; an explicitly enabled profile allows at most 4 hops and 32 total descendants per root by default. All retain the same root budget |
| Authority record | At most 64 KiB normalized data, 256 action/resource scope entries, 16 budget dimensions and 2 KiB UTF-8 purpose text |
| Logical IDs and references | Opaque core values; external identifier fields at most 2 KiB UTF-8 each. Reject malformed Unicode, controls, unknown required fields, duplicate keys and unresolved references |
| Ledger capacity | At most 1,024 active roots and 10,000 retained effect/delegation records per owner namespace by default; quota pressure rejects new work instead of deleting unresolved reservations |
The direct preset’s limits restrict mediated work; they do not bound a native program’s ambient file/network activity. A task that needs a broader profile selects it through trusted owner policy before issuance. Requests cannot extend an existing task after a budget or deadline is reached. New authorization is explicit and cannot release old uncertain reservations or defeat a required aggregate quota.
Malformed scope, unknown issuer, forged binding or invalid lineage returns invalid_request; an unavailable trusted issuer or coordinator returns unavailable, and corrupt coordinated state uses the existing storage_error vocabulary. A missing required human interaction returns interaction_required; missing required authentication uses authentication_required. Expired, revoked or replaced bindings return context_invalidated; exceeded counters/record bounds return limit_exceeded; an unenforceable restriction returns unsupported. A complete policy denial remains deny, not a transport error. Deadline, cancellation, revision conflict and uncertain commit retain their existing typed meanings. These are operation diagnostics mapped through ADR-0002, not new final invocation outcomes. Late permission or credential replies cannot clear a task fence or rebind its actor.
Consequences
Section titled “Consequences”- An arbitrary caller can propose work without becoming its own authority. Local presets avoid mandatory enterprise infrastructure.
- Trusted code exposure remains useful while the actual enforcement boundary stays explicit.
- Shared accounting and narrowing delegation prevent parallel children from multiplying a task’s allowance; durable uncertainty can legitimately hold capacity until reconciliation.
- Task restrictions cannot guarantee semantic intent, correct generated artifacts or out-of-band behavior beyond the selected confinement boundary.
Confirmation
Section titled “Confirmation”The owner accepted the architecture on 2026-09-24. No task-authority issuer, delegation coordinator or shared-budget implementation is claimed by acceptance. The following checks have not been run:
- Create a task from a local approved preset without login or remote services; reject agent-supplied issuer, actor, subject, scope expansion and another task’s reference. Verify a purpose string has no policy effect.
- Race actor/account changes, task and ancestor revocation, credential renewal, policy commits and late broker responses against final admission. Existing authentication horizons, source barriers and invocation bindings remain intact.
- Delegate narrower authority, then attempt sibling overspend, depth/child overflow, changed subject/domain and fresh-budget recreation after reconnect. Race multiple core processes against the final remaining reservation.
- Crash before/after durable reservation and effect dispatch, lose an effect reply, restart with missing/corrupt state and exhaust ledger storage. No unknown effect releases capacity or executes twice; confirmed reconciliation settles only the proven amount.
- Reject unknown-cost effects under hard cost caps and unsupported source/destination or confinement restrictions. Verify an explicitly approved trusted native profile is possible without claiming OS confinement.
- Separate task lifetime from foreground lifecycle: task expiry blocks new effects, cancellation preserves its first cause, finalization uses its existing budget, and retained reservations do not create background jobs.
- ADR-0002: Core–extension interaction, ADR-0004: Execution lifecycle.
- ADR-0005: Security Broker, ADR-0009: Catalogs and access rules.
- ADR-0011: Credentials and sign-in sessions, ADR-0012: Authorization validity.
- ADR-0013: Command model and MCP, ADR-0015: Execution confinement, ADR-0016: Effect commitment and reconciliation.