emelex 1.1.1

Apple Silicon local inference toolkit powered by MLX
# Agent context

The agent module is an in-memory orchestration boundary over native Emelex
generation. It does not own durable storage, terminal presentation, project
instructions, or model selection.

Invariants:

1. `Client` remains the production model implementation. `AgentModel` exists
   so the loop can be tested without MLX and adapted to another local
   scheduler.
2. A turn is sequential. One `&mut AgentSession` runs at most one model or
   tool step at a time.
3. Model text deltas must form a prefix of terminal answer text. The harness
   emits any missing terminal suffix before completion, so presentation
   concatenation equals the terminal field; a non-prefix fails the turn.
   Reasoning uses the same prefix/suffix reconciliation, including when no
   reasoning delta arrived before the terminal response. Only a terminal
   response containing answer text or tool calls becomes history.
4. Provider tool-call IDs are untrusted. The session mints UUIDv7 IDs and
   prevents reuse within its complete history.
5. Tool definitions and implementations are immutable after build and form the
   durable authority ceiling. All available names begin enabled. The active
   name subset may shrink or restore only names inside that ceiling; replacement
   rejects unknown names atomically and never changes the authority snapshot.
   Generation advertises active definitions plus disabled definitions needed to
   replay committed or current-turn calls. The execution gate rejects every
   disabled call with a synthetic result before approval or invocation.
   Definitions use the same bounded JSON Schema vocabulary as generation, and
   proposed arguments are rechecked before dispatch.
6. Assistant tool calls and their results commit as one complete ordered batch.
   Before invocation, failures roll the batch back. Once an invocation may have
   produced effects, failures checkpoint a matching result for every call so
   history stays structurally complete and retry cannot silently repeat work.
7. Successful `AgentTurn::messages` and failure-time tool checkpoints are the
   durable message boundaries. A memory adapter journals invocation state,
   persists complete batches, and replays them through
   `AgentSessionBuilder::history`.
8. Approval is exact, asynchronous, one-shot, and process-local. The default
   policy denies. No persistent grant exists in this module. Approval and
   denial reasons are non-empty, bounded, single-line text.
9. Workspace tools are descriptor-anchored, reject parent traversal, never
   follow symlinks, and bound traversal, input, output, and process time.
10. Failed turns roll back history and newly issued UUIDs to the latest safe
    checkpoint. With no possible tool effect that is the entry cursor. After a
    tool starts, the complete call/result checkpoint and its UUIDs remain in
    history across cancellation, fatal tools, sink failure, protocol errors,
    and model-round exhaustion.
11. `web_fetch`, `datetime`, and provider-backed `web_search` are explicit
    opt-ins. Network tools require approval and never select hidden vendors.
    Built-in HTTP clients identify the exact compiled package version.
    `WebSearchResult::new` is the public construction boundary; the generic
    tool still validates provider result count, bounds, and HTTP(S) URLs. A
    provider future may be dropped when its supplied cancellation fires; it
    cannot detach I/O/effects, and internally spawned work must observe the
    token.
12. File and shell registration are independent. Resolved project policy can
    remove shell without removing file tools. Shell timeout/output and web
    response ceilings enter through public builder setters and remain bounded
    by hard module maxima. Shell timeout defaults remain conservative while
    the explicit hard ceiling permits one bounded 20-minute build/test gate.
13. `run_message` accepts only user-role messages and preserves multimodal
    content in the returned commit batch. Failure before possible tool effects
    rolls back that complete attachment message; a later tool checkpoint
    retains it with the structurally complete call/result batch.
14. Shell approval is not a sandbox promise. The child process executes on the
    host with a cleared environment plus fixed locale and PATH/HOME captured at
    tool construction. Values keep only absolute non-traversing paths; PATH
    also receives fixed system fallbacks. Domain-separated digests enter
    durable tool identity, so path/order configuration drift fails resume
    authority comparison without exposing raw directories. Executables and
    configuration files inside those directories remain mutable host state.
15. Session generation options are the base; fields set by one turn override
    them, including thinking policy. Unset turn fields retain session values.
16. A configured `system_prompt` and a resumed system message are mutually
    exclusive. The builder rejects ambiguous instruction precedence.
17. Filesystem mutation writes and syncs a descriptor-relative sibling temp,
    atomically installs it, then syncs the parent. Existing-target swaps verify
    the previous inode before deletion.
18. A fallible event sink is a cancellation boundary. Sink failure cancels the
    model stream and commits neither history nor newly issued tool IDs. For a
    native `GenerationStream`, every early model, sink, or protocol exit closes
    receiver backpressure and awaits inference-job completion before returning.
    Custom `AgentGeneration::new` streams have no completion hook and are
    drop-only; their implementations must not detach work that survives Drop.
    Native model progress is forwarded losslessly with turn/round identity and
    never enters committed history.
19. `authority_snapshot` and `build` share one borrowed resolution path. The
    versioned snapshot contains canonical workspace path plus descriptor
    device/inode identity, exact name-sorted tool definitions, built-in
    enablement, and effective configured ceilings. Approval policy is
    intentionally absent and the builder remains reusable.
20. A loaded `Client` reports exact-template system-role, tool,
    reasoning-history, and thinking-toggle capabilities. Authority resolution
    fails closed before execution when configured or resumed state requires a
    capability the checkpoint did not prove. Thinking-on agents require only a
    proven thinking toggle; disproven reasoning-history preservation is not an
    error. Instead, reasoning is stripped from every outgoing request message
    (resumed history included) and from committed replay messages, so it never
    reaches the model's request boundary; the stored transcript keeps its
    recorded reasoning. An unknown capability defers with no stripping.
    Per-turn overrides are revalidated before the input checkpoint.
    Explicit `Off`/`Auto` clears a session reasoning budget. Reasoning emitted
    by a template lacking history preservation stays in presentation output
    but is stripped from committed replay messages.
21. Every resolved tool has one immutable `ToolCancellationPolicy` recorded in
    `AgentAuthoritySnapshot`. `FinishOnceStarted` is the default and stops the
    remaining batch after checkpointing one terminal result. `Interruptible`
    is allowed only for invocation futures whose Drop cannot detach work.
22. Approved write/edit work runs outside the async executor and has a
    join-on-Drop completion guard. Forced future cancellation cannot return
    while a bounded atomic mutation remains active.

Cancellation wins ties through biased `tokio::select!`. Cancelling model work
cancels `AgentGeneration`; a native `GenerationStream` sets its inference
cancellation flag, closes the bounded receiver, and establishes a completion
barrier before the turn returns.
`AgentCancellation::cancelled()` is public for tool/provider I/O. The shell
tool adds a drop guard that kills its dedicated process group.

The binary should treat `AgentEvent` as presentation only. For durable
sessions, the memory adapter journals active turns and tool invocation state,
persists each complete tool batch before another model round, closes terminal
success or failure atomically, and reconstructs the harness from strict
replayed messages.