emelex 1.1.1

Apple Silicon local inference toolkit powered by MLX
# bin — context

## Invariants

- `--home` is global and has precedence over `EMELEX_HOME`. Clap does not read
  the environment for this flag; when the flag is absent, the shared library
  resolver handles `EMELEX_HOME`, including empty-as-unset semantics.
- Help and version output do not initialize MLX.
- Commands render library results; durable behavior lives outside this module.
- Stdout and stderr failures propagate without committing successful agent
  presentation state; broken pipes terminate quietly.
- One-shot raw Ctrl-C closes stream backpressure, requests cancellation, and
  awaits inference-job completion. One-shot agent Ctrl-C sets the shared
  cancellation handle and awaits turn cleanup, so shell process groups are
  killed and reaped before exit. Both human paths flush buffered Markdown and
  terminal style state before returning cancellation.
- Untrusted human-facing text cannot inject terminal controls. JSON preserves
  the original typed data through JSON escaping. JSON chat emits a `session`
  envelope first, before recovery and agent events, with `session_id`, immutable
  `model_snapshot`, and whether the Session was `resumed`.
- Non-interactive `chat` and `resume` resolve their prompt from the optional
  positional argument or bounded UTF-8 stdin before validating command mode,
  so human and `--json` invocations share one input contract.
- Top-level `resume` takes an explicit Session only through `--session`.
  `chat --resume=SESSION` requires `=`; bare `chat --resume` means newest, so a
  following positional value remains the prompt.
- Interactive approval owns one nonblocking `/dev/tty` descriptor inside its
  future. Cancellation drops and closes it; no background terminal reader may
  outlive the approval call.
- Attended chat owns one stderr `LiveRegion` only after line editing returns.
  It becomes visible immediately after submission, advances from the same task
  that polls the turn, and is cleared before stream output or approval input.
  Exact native progress drives prompt, cache, output, context-reservation, and
  average decode-speed status. Attended non-JSON terminal Markdown buffers only
  an unfinished raw line suffix, including with color disabled. Complete-line
  flushes occur between live-region erase and immediate redraw; partial deltas
  update a bounded terminal-neutral suffix preview and state for the 120 ms
  animation tick without per-token erase/redraw churn. The final suffix flushes
  when the stream changes or ends. Later styled batches reapply current
  Markdown/base SGR state after the live frame's reset. Answer buffering is used
  only when stdout is itself a terminal; redirected stdout, non-interactive, and
  one-shot renderers remain immediate. Tool checkpoints and final persistence
  retain named states instead of leaving a silent gap.
  Completion, cancellation, output failure, and agent failure all clear the
  region; JSON and non-terminal stderr never create it. A human `TurnFailed`
  event is the sole diagnostic for its error: the interactive loop and the
  top-level one-shot reporter recognize its typed marker and suppress only that
  duplicate while retaining a failing one-shot exit, separate post-checkpoint
  warnings, JSON error behavior, and fatal durable errors.
- Modified Return bindings insert a newline while plain Return remains submit.
  Because Unix terminals do not encode Shift-Return uniformly, the editor also
  accepts Rustyline's LF, Alt-Return, and Alt-LF encodings. Message text is
  blank-checked without trimming; only single-line input can dispatch a slash
  command. Rustyline uses `Behavior::PreferTerm`, keeping prompt redraws off a
  redirected assistant-output stdout stream.
- `/tools` may replace the enabled subset only between turns and only with
  names from immutable Session authority. Deselected tools are neither newly
  advertised nor executable, except that a historical declaration may remain
  visible solely to preserve complete replay protocol. Approval stays
  independent. The inline selector preserves exact tool names, documents its
  movement/toggle/apply/cancel keys, treats Ctrl-C as chat exit, and leaves the
  old subset unchanged on cancellation. The subset is process-local and resets
  on fresh resume.
- `shell`, `web_search`, and `web_fetch` approval arguments must fit as complete
  canonical JSON within the 2,048-character preview. Oversized actions are
  automatically denied and must be split. Other tool previews preserve bounded
  head and tail content, state the exact omitted-character count, neutralize
  terminal controls, and retain a complete SHA-256.
- Agent prompts do not embed the invocation pathname. The harness enforces the
  invocation directory through its opened root descriptor and recorded
  device/inode identity. Prompts describe the workspace-first boundary:
  likely-secret reads, outside-root paths, all file mutations, and shell
  invocations require one-shot approval; displayed path labels remain
  untrusted data.
- `-C`/`--directory` and its visible `--root` alias select the invocation root
  for workspace-scoped Sessions, Knowledge, tools, and project configuration,
  without claiming to change process cwd or unrelated relative-path
  resolution.
- New-chat sampling/thinking overrides are validated through public
  `Config::validate` and become immutable Session semantics. A new chat
  materializes unresolved auto as on before snapshotting; explicit off remains
  off. Resume rejects semantic overrides and uses its exact stored mode, so a
  historical v2 auto is not migrated or reinterpreted and retains prior
  auto/off behavior. New on semantics require `interaction:thinking_toggle`;
  stored auto does not. `interaction:reasoning_history` is never an invocation
  requirement; the agent strips prior-turn reasoning from each model request
  for models whose templates do not preserve it. Each new or resumed chat load
  requests the largest model-declared context that fits the active Metal
  budget. Missing exact weights, sizing, or
  a declared maximum retains configured context. The attended header uses load
  policy provenance to label the effective result `machine-fit` or `configured
  fallback`, never inferring provenance from the token count. Per-request max
  tokens use the loaded `Client` ceiling, so stored semantics cannot re-expand
  checkpoint- or machine-clamped load policy.
- CLI web search is explicit, approval-gated, bounded, credential/proxy-free,
  and identified solely by its provider implementation. A policy-disabled
  explicit request fails rather than silently omitting the tool. Known
  interactive provider challenges fail visibly instead of masquerading as an
  empty result set.
- Human color capability is detected separately for stdout and stderr.
- Hub download Ctrl-C handling runs in an independent watcher task, so the
  atomic cancellation flag changes even while the download future executes a
  synchronous local phase on another runtime worker.
- Hub auth login reads either a hidden terminal prompt or, with
  `--token-stdin`, one bounded UTF-8 stdin line. Token argv is forbidden.
  Status reveals only effective credential source. Logout clears stored global
  state but does not override a present environment token.
- At the CLI boundary, present `HF_TOKEN` has three-state semantics: nonempty
  overrides with that token, empty explicitly disables authentication, and
  absence permits stored global credentials.
- `hub capabilities` renders the library's complete `REMOTE_FILTERS` catalog;
  its displayed syntax and accepted remote predicates cannot drift apart.
- Every CLI Hub search implicitly requires `interaction:tools`, enables
  `HubSearch::mlx_library` independently of user text, and uses the
  model-manager client's local Metal/storage fit. Zero-installed chat
  onboarding preserves the same tool-use requirement through its invocation
  filters. Library `HubSearch` remains generic and adds no CLI requirements.
  Human results render compact model-name, quantization, weights, memory,
  context, and task rows. Local status combines one verified installed
  inventory pass with exact-revision durable transfer records: installed
  revisions carry a checkmark, a held transfer lock is downloading, and a
  valid unlocked resumable workspace is paused. Quantization and sizing come
  only from validated exact-revision evidence.
  A human stdin/stdout/stderr terminal turns those same results into one
  stdout-owned inline viewport; it must never append a second selector list.
  The selected card carries a visible rail, frames fit the current terminal
  height, reserve one cursor row, and stay below its wrap column. Up/down moves
  within a page. Left/right traverses cached opaque-cursor pages, but human
  output exposes only `< Prev | Page N | Next>`. Enter on an exact installed
  revision dispatches through normal `chat --model` semantics. Otherwise it
  revalidates and downloads the displayed revision, reports readiness, and
  offers chat. Escape or `q` exits successfully; raw Ctrl-C becomes the
  explicit interrupt action. Buffered redraws recompute prior-frame height at
  the current terminal width, preserve scrollback, and restore cursor
  visibility on every exit path.
  Redirected or JSON searches never read selection input. Default diagnostics
  show only a count, verbose diagnostics group by sanitized candidate ID, and
  JSON stays complete.
- Human TTY downloads start in a truthful preparing phase, consume exact
  transfer lifecycle totals, coalesce state into an independently animated live
  region, show overall progress plus every active file, and remain in
  finalizing after transfer until certification and publication return. At
  most four files are active. Resumed prefixes contribute to completion but
  not throughput. Redirected output is deterministic and excludes chunk-level
  progress; existing JSON event records remain byte-compatible.
- Preferred local import uses singular `model import PATH`, with an optional
  `--name`; other lifecycle commands remain plural `models`. Import defaults to
  an owned immutable copy. Move publishes before selectively retiring only
  unchanged selected source files; changed or unselected files remain and
  cleanup warnings do not hide the committed install.
- Symlink import stores a managed record pointing to one canonical external
  target. Every resolve/load revalidates its link, runtime inventory, and full
  hashes; load also checks compatibility and opens the runtime. Removal
  deletes only the record.
- Attachment UX advertises only formats decoded by the embedded runtime.
- Media onboarding maps runtime image/audio requirements to remote
  advertised-input evidence, labels that evidence as provisional, and requires
  downloaded models to pass local certification before selection.
- Zero-model onboarding presents one bounded candidate page at a time across
  user-driven Hub cursors. Empty-page messages must distinguish one page from
  catalog exhaustion, and local certification failure must leave next-page
  discovery available.
- New-chat selection honors explicit model then configured default. Otherwise
  it groups healthy installed snapshots by stable reference and chooses by
  installed-reference cardinality before capability validation: zero enters
  onboarding, one is automatic, and multiple use the terminal selector.
  Redirected and JSON invocations never prompt. A selected model may combine
  positive current static inspection evidence with runtime-only manifest
  evidence; a real capability mismatch remains an error.
- Thinking-on selection (raw, agent, and chat) requires only
  `interaction:thinking_toggle`; historical stored chat auto does not.
  `interaction:reasoning_history` is never required at selection time — a
  model without it runs with prior-turn reasoning stripped by the agent. A
  generate-command override reaches model selection, load policy, and request
  policy as one resolved value.
- `doctor` records every independent facet result before returning aggregate
  failure; corrupt model entries do not hide healthy snapshots.
- Memory-model generation renews its durable worker lease every 60 seconds from
  the same async task. No detached heartbeat can race completion or survive
  cancellation.
- Empty `memory work` returns before model selection/load. Nonempty work starts
  with compaction and alternates queues. Source/output budgets use the loaded
  Client's effective checkpoint-clamped ceilings and conservative byte
  accounting.
- Interactive Session execution preempts a claimed maintenance completion.
  The worker releases that job to pending without incrementing failure count.
- Retryable worker failures are persisted with bounded diagnostics and
  backoff. `memory status` reports terminal counts, `memory failures` inspects
  them, and `memory retry JOB` is the only operator reset.
- Chat close queues distillation and releases its Session lease only. It never
  runs post-chat model inference; `memory work` is the explicit worker action.
- Session deletion is logical durable-store cleanup, not secure erasure.
  SQLite free pages or WAL bytes can persist until `memory gc`, and the global
  interactive `cache/prompt_history` is intentionally outside Session scope.
- `/compact` only queues while the chat lease is live. Exit chat, run
  `emelex memory work`, then resume so compaction can complete and replay can
  install the verified Summary.
- `translate` is stateless per line: every input builds one
  `Message::translation` request; slash-state (the language pair) lives in
  the process only and is never persisted into Session semantics.
- The implicit `interaction:tools` Hub-search requirement is skipped only
  when the explicit `--require` set contains `task:translation`; every
  other search keeps today's behavior.