Docs/Concepts

Concepts

Session-scoped enable

How does Tama change what runs in a live agent session — and why can it only ever make policy stronger there? Through one narrow mutation: enable a hook, or every hook, in exactly one session, applied not by Tama but by that session's own supervisor. There is no per-session disable, by contract (core-contracts).

How does Tama change what runs in a live agent session — and why can it only ever make policy stronger there? Through one narrow mutation: enable a hook, or every hook, in exactly one session, applied not by Tama but by that session's own supervisor. There is no per-session disable, by contract (core-contracts).

#What it is

A private file-based request/response exchange in ~/Library/Application Support/Tama/session-control/ (directory mode 0700, files 0600). Tama writes <controlKey>.<requestId>.request.json and polls every 0.05 s, for at most 10 s, for the matching <controlKey>.<requestId>.response.json. The request carries schema (ai.wisent.tama.session-control.v2), sessionId, controlKey, requestId (UUID), confirmed: true, operation, and for set-hook the hookId with enabled: true. The response carries schema, requestId, ok, error, and state — the authoritative session record after the change.

Two operations exist, but they are not interchangeable:

  • set-hook — enable one registered hook id in this session. During a global emergency disable, the preflight and write must observe the same nonempty emergency changedAt generation;
  • enable-all — outside a global emergency disable, enable every registered hook and schedule one runtime reload after the active agent turn settles. Concurrent reloads coalesce, and a failure restores the preceding override state. While the global emergency disable remains active, this operation is refused with global-emergency-disable-active.

Retrying the same single-hook enable in the same emergency generation is idempotent.

#Who applies it

The session's own supervisor — never Tama. The supervisor validates the envelope against the exact identity tuple in its session record (enforcement-control): the controlKey is a 64-hex secret, the agentId must start with an ASCII letter and be 1–32 characters, and the record must be live (process mode: the pid answers kill(pid, 0); heartbeat mode: updatedAt within the heartbeatTTLSeconds its launcher stated in TAMA_SESSION_HEARTBEAT_TTL_SECONDS; a record in unknown mode, whose launcher stated neither, is never live). It applies the override atomically as <controlKey>.override.json and answers with the resulting state.

#What can refuse it

Every failure is actionable, never optimistic. The public refusal states include:

FailureSentence or reason
Malformed session identityTama rejected an invalid agent session control endpoint.
Unparseable responseThe agent runtime returned an invalid session-control response.
Only v1 records on diskTama found only legacy v1 session records. Reinstall the verified bundled runtime, then stop or resume the affected agent session to publish v2 state.
Supervisor said noThe agent runtime rejected the session-control request: <reason>
Session-control directory cannot be watchedTama could not watch the session-control directory <path>: <reason>
Session exited mid-requestThe agent session ended before the session-control request completed.
Disabled state has no usable generationglobal-emergency-state-missing-generation
Emergency state changes during one-hook activationemergency-state-changed-during-activation
Enable-all requested during global disableglobal-emergency-disable-active

#Composition with machine enforcement

Session enablement is additive to the machine policy (enforcement-control):

  • in all-hooks mode, every registered hook already runs;
  • in selected-hooks mode, a hook runs when its id is in the machine selection or this session's enabledHookIds. A session cannot remove an id from the machine selection;
  • during a global emergency disable, the machine selection is bypassed. enabledHookIds is the session's explicit allowlist, but only when the override's emergencyChangedAt exactly equals the active emergency state's nonempty changedAt. Those are the only hooks that run.

The supervisor persists that generation binding beside the allowlist and in the OMP session's retained override entry. Reloading or resuming the same session preserves the exact enable while the emergency generation is unchanged. A fresh global disable creates a new generation: legacy overrides with no binding and stale overrides from an earlier generation contribute no enabled hooks or capability. tama sessions and the desktop therefore render the supervisor's already-sanitized enabledHookIds, not an old allowlist copied from disk.

Runtime status

The runtime status is one JSON document, schemaVersion 1: the session record carries it under runtime, and tama_hook_runtime_status answers with it.

The session record and tama_hook_runtime_status publish enforcementMode (all or only) and machineEnabledHookIds, the validated and sorted enabled list from the durable machine state ([] in all mode). These sit beside enabledHookIds, which remains the session's additive state. Under emergency disable, the machine ids stay visible as retained configuration but do not run.

It also names what holds the runtime, so a session can see a stall instead of waiting behind it: runtimeHolder is the queued operation running now (reload, reload enabling every hook or close, with its start time) or null, and inFlightDispatches lists every hook dispatch still waiting on the core, each with its event, tool, start time and runningMs. While an operation holds the runtime, tama_hook_runtime_status answers at once without asking the core: core is null, coreNotAsked says which operation holds it since when, and the answer is an error. tama hooks running names the hook process itself from any terminal.

lastDecision.results carries, for every hook that ran, ms (how long the hook ran once its process existed) and startMs (how long it took to get there: the supervisor spawned and its lifetime and dispatch registered). A dispatch whose runningMs is far above every ms is slow in starting its hooks, and startMs says which ones; one slow ms names the slow gate.

#Where it surfaces

  • The Session screen renders the live record and can request one-hook or enable-all mutations. Enable-all remains a normal-state reload operation and reports the supervisor's refusal during a global emergency disable (desktop/session).
  • The Hooks inspector calculates Enabled from enabledHookIds when the selected session is globally disabled, and from disabledHookIds otherwise. Its single-hook action uses the same generation-bound control path (desktop/hooks).
  • Inside an OMP session, the bundled adapter exposes the same plane as session tools: tama_set_session_hook, tama_enable_all_session_hooks, tama_hook_runtime_status, tama_request_session_capability, tama_reload_hook_runtime — and states that session hook disablement is prohibited.

#Reload support and refusals

The reload tool and slash command await the native shared engine's reload; they do not insert a prompt or restart OMP. Registry validation failure retains the preceding generation and returns the actual path and error. Installation does not replace JavaScript already loaded by a legacy OMP adapter. Only that initial transition needs /tama_reload_hook_runtime through OMP's command handler; later reloads use the native operation directly.

Read tama_hook_runtime_status after the operation. Installed and loaded identities and checksums must match, and the requested hooks must be effectively enabled. Neither an installed file nor an unchanged process id proves the new rules ran. Reload never lifts the global emergency disable.

#Completion hooks enabled through this control

Installed prompt text can tell an agent to keep working, but prose does not execute the completion contract. A completion rule runs only when its registered Stop hook is enabled and the runtime dispatches that event. For the repaired completion contract, block-stop-with-open-work first replays the latest successful tracker snapshot and subsequent successful tracker calls. Pending or in-progress items block Stop. An empty, completed or locally blocked plan then requires a fresh read of the authoritative Oko ledger for the native OMP session id. Every actionable task still marked not done blocks completion, including older requests outside the most recent conversation window. A read failure also refuses Stop and names the failed operation. check-open-items-with-model uses the same Oko verdicts when that existing hook is enabled; it does not ask a second model to overrule them. No new hook or policy enablement is required.

After delivering and checking the actual result, run oko tasks verify --before-stop --session SESSION_ID. Oko independently judges the saved answer and tool results through Brama and persists its verdict. A claim, heading, tracker update or operator acknowledgement is not a replacement. A qualified external obstacle allows an honest blocked report, not a claim that the work was completed.

A missing session identity, transcript, ledger or valid task status prints TAMA_HOOK_INFRASTRUCTURE: check-open-items-with-model: <reason> and exits 70. Activation checks ledger availability separately from permission to finish and reports pending tasks. The hook's existing id is unchanged; see completion enforcement for the real-session qualification and required OMP behavior.

#Not to be confused with

  • Disabling. The opposite direction exists only as the machine-global, operator-confirmed emergency disable. Agent-facing controls never weaken policy.
  • A capability. Enabling changes which hooks run; a capability grants what the session may do under the hooks that run. They travel in the same session record and are otherwise independent.
  • Installing. Outside global emergency disable, enable-all binds its override to the installed release and checksum, but it does not install anything; a session running an older hook release needs the native reload, not a new install.