Provider-hosted web search runs inside the selected inference provider and does
not cross Tau's registered-tool dispatch boundary. Search queries, actions,
returned content, URLs, titles, and citation metadata are untrusted external
data; none grant Tau identity, instruction, authorization, or routing authority.
Cached hosted access still contacts the provider and is not an offline or
privacy boundary.
allowed_domains is not a network sandbox. Hosted filtering and model-chosen
browsing are delegated to the inference provider. External fetch gates only the
requested target before extractor contact; redirects and subresources may leave
the allowlist. A nonempty allowlist makes ordinary candidates without declared
enforcement unavailable. The default external search pool declares no such
enforcement, so Tau omits it rather than calling and post-filtering; configured
Tavily or Firecrawl adapters can carry their provider-side filters.
Durable semantic filesystem mutation belongs to one Harness-lifecycle
SemanticPersistenceOwner. Stores pass generation capabilities and staged
replacements to its sole worker; configured local extensions receive neither
journal handles nor persistence capabilities. Read-only inspection constructors
cannot acquire live mutation authority. This does not change the documented
cooperative local-extension threat model.
The tau agent unload control RPC is restricted to an authenticated attached
same-user socket UI. Its request and result are directed, transient,
non-broadcast, non-intercepted, and non-journaled control messages; configured
extensions receive only the ordinary committed session.agent_unloaded fact.
Admission rejects any target with accepted work, and the command preserves agent
transcripts and session history rather than editing or deleting durable state.
The disabled-by-default std-rostra extension is a trusted same-user
executable, but every synchronized Rostra field is untrusted external content.
Rostra signatures authenticate an author key, not instructions or Tau
authority. It derives one identity from a declared Tau-managed mnemonic secret,
keeps that signing authority in its trusted same-user process after lazy first
write activation, and exposes bounded reads plus explicitly signed social
writes. The extension uses relay-only Iroh peer transport plus Pkarr HTTPS/DNS
discovery without direct peer-IP transport, owns an exclusive owner-private
per-instance redb containing public graph data, signed local events, and an
Iroh node secret. Signed effects are locally durable but remotely asynchronous;
unknown timeout/cancellation outcomes can have taken effect. Its only inbound
model-visible path is the separately opted-in, bounded following-notification
report: it projects hostile Rostra content into an extension-owned checkpointed
batch and has no arbitrary inbound message or reply route. It has no identity
creation, direct-IP public mode, shared database, or memory-only fallback. The
separately maintained tau-ext-rostra project owns its detailed architecture
and security documentation.
The optional std-swarm configured extension is a trusted same-user local
executable. Its remote Iroh peer is cooperative but authenticated and
identity-pinned before the worker credential is sent; externally supplied
prompts, answers, identifiers, and collections remain size-validated inputs.
Tau is early-stage software, but security issues are important. Please report suspected vulnerabilities through GitHub private vulnerability reporting for dpc/tau (https://github.com/dpc/tau/security/advisories/new) when available. If that path is unavailable, contact the maintainer privately first and avoid filing a public issue with exploit details.
Foreground serve bootstrap sources are local configuration authority and may contain secrets. Tau reads the selected file only after readiness and never logs its contents, but the path can appear in process metadata or operational errors. Use owner-private service-manager credentials rather than Nix-store paths. Bootstrap submission reuses the authenticated same-user local UI boundary; a harness-private request registration alone may create the reserved durable bootstrap marker, and public metadata producers cannot set or inherit it.
For technical trust boundaries, start with ARCH-external-message-boundary and the applicable project and component records under specs/ and crates/*/specs/.
Before launching any configured process, Tau accepts one normalized effective
HarnessSettings snapshot. Missing optional user configuration leaves the
built-in layer valid, while an existing unreadable or invalid layer and malformed
private override transport fail startup with context instead of selecting
built-in fallback authority. Extension launch, provider and secret inputs, roles,
tool policy, retention, prompts, and runtime baselines derive from that snapshot.
An already-running harness retains it and does not hot-reload or partially reread
settings. This authority-selection invariant does not change the trusted
same-user extension threat model.
See
ARCH-tau-config and
ARCH-tau-harness.
Revisit this invariant when changing loader fallback or error semantics, snapshot
plumbing, configured-process launch ordering, or runtime settings lookups.
Registered session-context providers may delay session initialization, but only
within a non-renewable thirty-second absolute cap. Exact readiness or disconnect
from each outstanding provider owns early completion; provider silence and
generic, stale, wrong-session, or non-outstanding traffic cannot complete or
extend the wait. Final waiter removal and harness-owned synchronous finalization
take precedence over timeout classification, while absolute expiry returns
SessionInitTimeout rather than process StartupTimeout. Deterministic deadline
and classification boundaries are covered in
crates/tau-harness/src/session_init_deadline/tests.rs and
crates/tau-harness/src/error/tests.rs; lifecycle tests cover admission and
finalization wiring. Revisit these safeguards when changing waiter identity,
admission filtering, event ordering, finalization, or timeout classification.
The governing contract is
SPEC-session-discovery-declarations-and-readiness.
A configured extension's process-local client writer retains detached outbound
frames in one FIFO capped at 64 frames and 8 MiB of aggregate encoded data, with
an independent 8-MiB limit per frame. This is an availability safeguard inside
the trusted same-user extension boundary, not hostile local-IPC containment.
Accepted pre-Ready frames drain in order after Ready, ConfigError, or graceful
shutdown; bounded drain batches prevent continuous detached production from
starving synchronous writer commands. Exact boundary, ordering, refill/recovery,
and blocked-writer tests protect these properties. Revisit them when changing
writer notification, FIFO budget release, startup activation, ConfigError
ordering, or writer shutdown.
A connected consumer generation that stops advancing may pin shared live-event payload retention indefinitely. Tau emits only a rate-limited warning; it does not backpressure or reject publication because of egress lag, spool the suffix to disk, or expire/disconnect the component solely for lag. Revisit this accepted trusted-component risk when changing live routing, cursor identity, target freezing, pruning, or lag diagnostics and lifecycle.
A connected trusted interceptor may leave an intercept request unanswered and thereby stall that publication plus every globally serialized publication behind it indefinitely. Deferred publications retain their full events and may consume memory without bound. Tau deliberately applies no timeout, admission budget, rejection, quarantine/disconnect, or backpressure mitigation. Revisit this accepted authority and availability risk when changing interception, pending-intercept resolution, deferred-publication ownership, or component lifecycle.
Disabled-by-default decoded-delivery memory diagnostics report only process class, fixed ownership-cut labels, counts, encoded bytes, recursive logical and requested-capacity estimates, expansion, shared-allocation fanout, and high-water aggregates. They emit no payload, protocol/runtime identity, cursor, path, model, account, or error value and create no event, journal, debug-JSON, wire, or cross-process authority. Requested capacity is explicitly an enabled-only diagnostic projection estimate; allocator usable size, RSS, and kernel/socket buffer ownership remain unobserved. Exact aggregate sizes, ratios, fanout, and timestamps may still reveal workload metadata or permit heuristic cross-process correlation; treat enabled operational trace files as private.
Disabled-by-default provider backend-stage diagnostics use the dedicated
provider.backend-stages TRACE target. They report only closed backend,
transport, and outcome classes plus scalar durations, byte counts, occurrence
counts, presence flags, and accounted/unattributed totals. They never retain or
emit prompts, response content, model or prompt identifiers, endpoints, paths,
accounts, credentials, status bodies, or raw errors, and create no event,
journal, capture artifact, wire field, or protocol authority. Exact timing and
size values remain private workload metadata. With the target disabled,
backends retain only inert None checks and perform no diagnostic clock reads,
allocation, byte sizing, hashing, I/O, or trace-state construction.
Disabled-by-default provider/client output-cost diagnostics use the dedicated
provider-builtin.output-cost and tau_client::output_cost TRACE targets.
They report only fixed phase/lane/outcome classes, process-local numeric
correlation, item and queue counts, encoded byte counts, and scalar durations
for sampler materialization, worker admission/queue/drain, client admission,
writer wait, encoding, and flush. They never retain or emit prompt, response,
tool, error, model, endpoint, account, session, protocol-field, or credential
values and create no event, journal, capture, wire field, debug JSON, or
protocol message. Like other extension tracing, enabled provider observations
can flow through extension stderr into the owner-private per-session component
log and optional operational mirror; client observations use the process's
configured tracing sink. Exact sizes, timing, ordinal correlation, and nearby
log context remain private workload metadata and can permit heuristic
cross-correlation. With both targets disabled, the
paths retain only inert Option::None checks/moves and perform no
diagnostic-specific clock read, allocation, traversal, queue accounting, or
trace construction.
Overall harness shutdown closes configured in-process extension transport first, then gives all such runners one shared finite grace to return on EOF. A runner still alive after that grace is left to a detached join-reaper, not force-cancelled; it can retain arbitrary resources and continue side effects until host-process exit. Normal Tau process exit reclaims those resources, but embedded or reusable hosts can accumulate detached runners across shutdown/restart cycles. Revisit this accepted configured-component availability risk when changing extension lifecycle, the shared cleanup grace, or embedding/reusable-host behavior.
Supervised extension state isolation is defense in depth inside the configured
same-user executable boundary, not hostile-code containment. hidden and
read_only prevent ordinary discovery or mutation of unrelated Tau state while
preserving exact extension-owned state; they do
not defend against procfs, ptrace, pre-opened descriptors, unrelated host data,
or authorized secret RPC delivery.
read_only is the persistent-harness default: it improves debugging and
cooperative extension introspection, but every configured supervised extension
in a persistent harness can therefore read other Tau session and agent state
unless its policy is explicitly hidden. Memory-only harnesses force hidden,
create no host state, and mask an existing state root if one exists.
Supervised components also receive an empty bind-mounted harness runtime socket
directory by default. A per-component tau_runtime_socket_access: legacy
opt-out restores ambient socket discovery for a trusted component without
changing its state or secret access.
The launcher covers its temporary real-state staging tree with an empty
read-only mount before exec, after installing the exact destination binds, so
the child cannot bypass the selected view through the staging source path.
Provider debug captures cross the cooperative configured-extension protocol as
dedicated non-journaled messages. The Provider zstd-compresses opaque artifacts
off its request path and supplies only typed session/prompt attribution; the
harness authenticates the Provider connection, derives the instance-specific
durable-session path, and writes without parsing or decompressing payload bytes.
Both transport and filesystem queues are bounded and best-effort. Capture
payloads never enter events, journals, debug JSONL, or generic Debug output.
Historical explicitly enabled compact HTTP failure captures preserve bounded causal
provider evidence, including an allowlisted header set and a credential-redacted
64-KiB decoded body prefix. Reqwest content decoding precedes accounting; captures
hash exactly the decoded bytes delivered and distinguish complete decoded-body
from partial coverage. Treat these owner-only local artifacts as
sensitive: provider error bodies can reflect prompt, account, or service-internal
data even after configured credentials are removed. Configurable diagnostic
retention defaults to thirty days; disabling cleanup can retain them
indefinitely.
Default-on Codex, public Responses and Chat Completions inference and
standalone-compaction scalar cache diagnostics use the same
private opaque path and retention. Metadata has an independent startup-frozen
profile opt-out and is forced off with existing nonpersistable capture policy.
Existing exact captures remain default-on for durable activity; native Codex
successful raw compact responses remain unretained and advertise
exact_response=false.
Scalar records omit payloads, credentials, routes, cache keys, provider IDs and
error prose, but retain bounded model identities and workload correlation, so
they remain private rather than public-safe. The metadata budget reserves at
most 64 records / 16 MiB including in-flight serialized data, with a 256-KiB
per-record cap. Sequence holes and known-loss counters never prove complete
capture history. Neither capture failures nor metadata observations affect
provider execution, canonical accounting, cache eligibility, or canonical
compaction outcome. Public Responses and Chat Completions local-summary attempt
ends describe the finite backend result before extension-owned narrative
validation.
Codex warm backend calls use scalar-only operation captures, with no prompt
identity and no retained exact request/response. Their closed operation
attribution is permitted only for cache diagnostics and uses a distinct managed
filename. Backend completion is not authenticated refresh-terminal acceptance.
Disabled-by-default cache refreshes resend an exact previously successful
Provider-visible prefix. The harness keeps that content in process memory and
sends refresh/cancel requests point-to-point only to the captured configured
Provider generation. Sensitive requests are excluded from broadcast,
interception, journals, replay, debug JSONL, generic Debug output, watchers, and
UI projection. Content-free terminal reports and canonical facts may remain
observable. The Codex warm path receives the prefix through trusted directed IPC
and sends it upstream, but retains no exact warm request or response capture.
Its private scalar operation evidence does not retain prefix content.
The distinct deterministic and live/VCR test-fixture boundaries are documented
in tau-e2e-tests/SECURITY.md.
The disabled-by-default test-dummy extension's capability and worker-lifecycle
boundary is documented in
tau-ext-test-dummy/SECURITY.md.
Authenticated ChatGPT quota acquisition and its credential-free lifecycle are
documented in
tau-provider-codex/SECURITY.md
and
tau-ext-provider-builtin/SECURITY.md.
The same component records cover the split provider trust boundary: generic
OpenAI-compatible Chat Completions uses HTTP/SSE, private ChatGPT/Codex inference
is WebSocket-only, and all built-in provider egress shares the immutable policy
documented in
tau-provider/SECURITY.md.
The generic public Responses parser's validated reasoning, sensitive replay
sidecar, and configured-endpoint boundary are documented in
tau-provider-responses/SECURITY.md.
Tool, provider, extension, and user-derived presentation text is not trusted
terminal control. Themes resolve to structured styles rather than inline escape
bytes, and terminal cell conversion sanitizes control characters before output.
The serve-only --mirror-extension-stderr option similarly treats arbitrary
supervised-child stderr as untrusted display bytes: it emits bounded escaped
records with validated extension, immutable generation, and PID attribution,
never raw child bytes. The authoritative private file is written and flushed
first. A bounded nonblocking queue may drop mirror records, and process-stderr
failure disables the mirror, so its worker cannot backpressure extension
draining or protocol progress. It writes through an independent duplicate of
inherited stderr where descriptor duplication succeeds; setup failure disables
only mirroring. Mirror traffic can still consume shared fd-2 sink capacity, and
the existing synchronous harness tracing may block on a full sink under
ARCH-logging-io-analysis.
The mirror is default-off because custom extension stderr is
unredacted and journal readers are a wider audience. It never inspects
extension stdout/protocol, events, journals, debug JSONL, provider captures,
Configure payloads, or secrets by category.
The one-shot --prompt-stdin path checks inherited stdout and stderr
independently. It sanitizes dynamic answer text only when stdout is a terminal,
and sanitizes dynamic reasoning, role, and PromptStdinError bodies only when
stderr is a terminal. Pipes and files preserve semantic UTF-8 body bytes inside
the existing framing; that raw nonterminal output is not terminal-safe and
should not be forwarded to a terminal without equivalent sanitization.
When changing one-shot rendering or terminal detection, re-check final-item and
streaming-fallback output, role and error bodies, crossed stdout/stderr terminal
policies, and exact nonterminal body bytes, prefixes, separators, and trailing
newlines.
Adaptive one-row layout measures complete Unicode graphemes by terminal display
columns and middle-truncates only at grapheme boundaries. Tool headers treat
identity and explicit lifecycle/result status as one essential set: a terminal
too narrow for that set shows neither the header nor its owned payload/diff body
rather than exposing anonymous details or obscuring success versus failure.
Re-check control sanitization, zero- and multi-column graphemes, exact
minimum/maximum boundaries, tiny widths, owned-body suppression, and resize
restoration whenever terminal layout or tool presentation changes. See
ARCH-tau-term-screen
and ARCH-tau-cli.
The harness alone stamps prompt provenance at the configured-extension boundary:
an accepted internal-prompt request produces one canonical prompt fact with the
authenticated configured extension name, never a request-supplied name. CLI
attribution escapes that bounded name as visible metadata and does not create a
second transport message or model activation.
The built-in Swarm task_blocker tool has a narrower presentation boundary: the
CLI permits only its finite add, cancel, or list action discriminant from
the start arguments, and strips all other start, progress, and terminal display
fields in compact and full modes. Missing, malformed, or unknown actions fail
closed. Re-check valid and invalid actions across live, progress, result, error,
cancellation, replay, and cold attachment whenever blocker presentation changes.
Interactive frontend progress diagnostics contain only process-local delivery
ids, typed event names, agent routing ids, selected/hidden classification,
queue item/encoded-byte counts and ages, stage durations, output block counts,
and cancel target resolution. They never retain prompt, response, tool, event,
terminal-output, or disconnect-reason bodies. Trace-level paired stage markers
localize an operation that never returns; warnings for completed stages at or
above 500 ms are rate-limited per frontend component to one per five seconds.
Interactive prompt-latency traces additionally use one wrapping fixed-size,
process-local submission sequence and fixed prompt-traffic classes. That
sequence is diagnostic correlation only: it never enters protocol messages,
events, journals, settings, or persistence. These records must never include
prompt or payload bodies, paths, credentials, durable observation identifiers,
or protocol correlation identifiers.
Opt-in trace logging may also carry bounded, content-free selected-presentation
facts from CLI-local socket delivery through redraw generation and successful
writer flush. It retains at most 64 exact facts per pass; additional facts
become count-only overflow. The allowlist is exactly
agent.prompt_queued/prompt_queued,
agent.prompt_submitted/prompt_submitted,
agent.prompt_steered/prompt_steered,
provider.response_updated/response_updated,
provider.response_finished/response_finished, and
agent.prompt_terminated/prompt_terminated. Its finite field inventory is
delivery id, that invariant label, wrapping mutation/frame generation,
monotonic duration, omitted/indeterminate count, and output failure kind/stage.
Counters saturate where they represent omitted work and wrap where they are
process-local generations. The existing tracing subscriber is a
transport-neutral operational diagnostic exception: an interactive UI currently
writes enabled records to its ui.log, while other entry points may use stderr
or a sink. These records do not enter event journals, settings, protocol
messages, replay state, or semantic persistence and have no durability
guarantee. The UI writer keeps one line-buffered descriptor behind a mutex; it
drains complete lines into the OS cache but does not call File::flush,
fsync, fdatasync, sync_all, or sync_data, and shutdown performs no
explicit drain.
The CLI socket-to-renderer FIFO is bounded at 1,024 items and 64 MiB, but
backpressure can migrate backlog to the harness writer queue. These bounds
therefore do not promise whole-process or end-to-end slow-client memory limits.
For interactive input, first-non-whitespace : selects non-provider command
authority. Unknown or malformed colon commands fail locally, while slash-prefixed
text—including obsolete command spellings—is ordinary provider input. A doubled
:: escape keeps a typed literal marker through every harness-owned command
consumer even though history, durable prompt text, and provider projection contain
only the canonical single-colon text. This prevents canonical :skill prompt
text from being reinterpreted after the CLI removes the escape. --prompt-stdin
instead preserves its complete stdin text and marks it literal, so its initial
agent prompt bypasses CLI commands/actions and harness skill expansion.
The Gmail OAuth finish exception still applies after interactive literal
canonicalization: ::email auth google finish ... becomes the fixed redacted
literal and never sends its code or state as a model prompt.
Only attached socket UIs may send ui.create_agent. The harness returns its
bounded, sanitized admission result directly to that live connection without
publication or replay. Distinct bounded request and prompt correlation ids keep
creation admission separate from later prompt processing. Pre-materialization
prompt failures publish only bounded sanitized diagnostics and correlation
metadata as transient agent.prompt_failed terminals; canonical provider
failures retain their existing prompt-id lifecycle. See
SPEC-ui-create-agent-admission.
The active editor temporarily contains Gmail OAuth finish arguments while the
user types them. After submission, they remain raw only on the immediate
parse/routing stack and in the single successful ActionInvoke delivered to
the exact owning PIM extension. The CLI uses exactly :email auth google finish <redacted> for command echo, in-process and persistent history,
external-editor context, and content-enabled ui.prompt_draft publication.
Content-free drafts remain content-free. The harness excludes transient inbound
invokes from debug JSONL and redacts the published debug-log copy. Re-check stale
user-facing command instructions, interactive/headless parity, completion
precedence, literal escape handling around skills, and both debug-log paths
whenever command routing or action logging changes. See
GATE-colon-command-mode,
SPEC-tau-cli-command-mode,
and
SPEC-tau-harness-session-state.
This exact-owner rule governs recognized interactive actions. --prompt-stdin
remains an explicitly literal model-prompt interface and does not invoke this
OAuth action classifier.
Peer harness messaging is cooperative same-UID local IPC, not a hostile-process sandbox or per-sender ACL. Harness instances for one user are mutually trusted and may deliberately connect to each other's ordinary UI sockets. Together they form the harness side of the boundary that hides state and runtime sockets from agent-controlled configured components; Tau does not claim procfs, ptrace, or hostile same-UID containment. Harness-owned cross-session messaging retains runtime socket discovery. A dedicated external-message connection is admitted only to its message, callback-authentication, and session-probe RPCs and cannot reach UI or Action handlers. Callback correlation prevents accidental sender/route confusion before bounded admission or model-spending auto-start, while peer text remains model input rather than a harness instruction. An authenticated bare-peer auto-start immediately receives the target's configured role- and policy-filtered tool surface so cooperative handovers can operate without a second UI prompt; peer payload cannot select or expand that authority and retains extension provenance. The hot dispatch and cold marker behavior are governed by SPEC-tau-harness-prompt-dispatch. Delivery is best-effort at-least-once: an ambiguous crash or retry can duplicate receive occurrences, agents, model work, and spend. Each accepted directional occurrence is its owning journal's sole canonical payload projection. Local inbound provider context exact-close-frames peer text inside a sender-labelled wrapper; live activation uses a payload-free sequence wake, and replay restores context without waking. The target's complete foreground framed write remains ACK authority; ACK does not wait for background filesystem sync. An ACK or provider effect can therefore survive a crash that loses its journal fact. Tau adds no restart deduplication, distributed WAL, or cross-journal transaction. See SPEC-semantic-journal-writeback-durability.
tau dev print-prompt and print-tools keep session and preview-agent semantic
state, journals, transcripts, debug artifacts, and retention state process-local
or omit them, so they create no resumable session or agent and do not create or
open the durable agent store. They configure ordinary extensions and therefore
preserve User, Cache, Secret, direct-state, filesystem, network, and
external-service reads and writes. They load one fresh ephemeral agent through
bounded context readiness, resolve an effective model/tool snapshot, and never
call a provider. print-system-prompt retains the separate immutable MemoryOnly
storage policy. Each preview's unique runtime socket and discovery metadata may
exist only while its owned daemon runs; handled diagnostic exits remove that
exact pair after child reap, including forced-exit fallback.
Per-agent events.cbor journals are authoritative durable identity and
transcript state. Their meta.json files are content-minimized, atomically
replaced derived checkpoints, not routing authority. Checkpoints bind an exact
frame boundary and sequence to journal file identity and a boundary witness;
stale or invalid checkpoints are repaired only under nonblocking byte, record,
and time budgets. Metadata-only, empty, corrupt, or otherwise unvalidated
artifacts reserve ids but cannot receive routed facts.
Agent events.cbor and session events.cbor/restore-events.cbor use
length-prefixed CBOR frames. Prefix or payload-write failure triggers truncation
to the exact pre-append EOF before the caller receives the original append
error. Only failure to restore that EOF poisons the journal path in the live
store. On reopen, a locked writer truncates only an incomplete frame header or
payload at EOF, which represents a crash tail. A complete frame that fails typed
decode, source-shape validation, sequence validation, or semantic validation
fails closed without changing that frame or any following bytes. A valid
complete frame immediately advances folded state and sequence.
A lifecycle-owned worker coalesces dirty journals and required directory coverage, syncs in the background, tracks generations to avoid lost wakes, and retries failures without retracting accepted facts. Locked recovery truncates only an incomplete EOF crash tail and invalidates derived metadata after that repair. Complete invalid frames fail closed without mutation. Re-check byte-boundary, rollback-failure, retry-sequence, restore-journal, writeback, and suffix regressions whenever framed I/O changes.
The opted-in generic local compactor reuses the ordinary provider request
prefix for the immutable cut, including its system prompt, tools, messages,
images, raw tool-call arguments, and cache controls, then appends a
harness-authored <tau_internal> user message that forbids tool use and requests
only a summary. This deliberately does not create a separate compactor authority
or privacy-reduced transcript. The configured provider has already received the
same ordinary context; cache alignment avoids a second cold prefill when the
provider cache retains that prefix.
The extension rejects any tool call or other semantic output without execution, accepts exactly one nonempty bounded assistant final text, and discards reasoning and opaque replay items. The harness persists that text exactly once as one synthetic user-role checkpoint, with no deterministic supplement or wrapper. Before that terminal validation, standalone local-summary attempts publish only the existing bounded content-free response byte/timing statistics and status/activity signals at their existing cadence. Assistant text, reasoning, tool, and opaque output do not cross in transient updates; invalid and canceled attempts publish no content-bearing update. The validated narrative crosses once in the private terminal envelope. Ordinary inference streaming and opted-in private provider debug capture are unchanged. Events committed after the immutable cut remain suffix history. Ordinary opted-in provider debug captures apply to compaction; they are sensitive, best-effort observability artifacts and never journal, transcript, replay, or recovery authority.
Provider work leaves the harness only after its inference or compaction owner
and one matching source-free agent.prompt_started frame have completed
foreground semantic appends. Delivery does not wait for background sync, so a
crash can preserve provider effects while losing journal facts. The fact's
one-shot continuation rechecks the session,
loaded runtime incarnation, unresolved owner, exact identity, and captured route
before directing the transient full prompt; an owner-only or owner-plus-start crash
cut never resends work. Persisted old full prompts are unsupported. Debug JSONL
represents full prompts only as bounded content-free summaries. Re-check these cuts
whenever prompt persistence, interception, replay, routing, or diagnostics change;
see
SPEC-provider-prompt-materialization-authority
and
SPEC-tau-harness-prompt-dispatch.
Session debug events.jsonl producers redact and serialize a complete line,
then attempt immediate nonblocking admission to one lazy process-wide FIFO
bounded at 1,024 retained lines and 64 MiB of line-plus-path bytes including
in-flight work. The detached worker holds <session>/events.jsonl.lock for each
line through handle selection/open, exact-EOF append, flush, and rollback.
Overflow and recoverable lock/open/write failures omit rows; uncertain rollback
globally poisons the worker. The worker never fsyncs. No session/process shutdown
path requests or waits for a drain or joins the worker; it may continue draining
while the process remains alive, and exit may interrupt queued or in-flight work.
This mirror is an ordered best-effort subsequence, not
authoritative evidence: absence never proves an event was absent, termination
can lose queued/OS-cached rows or tear the final line, and restart neither
repairs nor salvages it. Re-check bounds under held locks, path switching,
per-line lock reacquisition, overflow recovery, I/O retry, global poison,
warning coalescing, and nonjoining exit whenever debug-log I/O changes.
Startup retention uses one ordered detached worker and one wall-clock snapshot.
It finalizes committed detached session and agent trees, removes expired
unlocked sessions, strictly derives every durable agent ever loaded by each
surviving canonical session, removes only exact old unreferenced agents after a
durable permanent ID tombstone, then removes expired session events.jsonl
regular files and exact compressed .json.zst provider request/response
captures. Session and agent deletion are disabled by default; diagnostics
default to thirty days. Manifest or journal I/O uncertainty aborts agent
deletion; missing or malformed manifests remain noncanonical. Reference
discovery streams bounded records and reuses validated journal boundaries so
candidate rescans consume only appended suffixes. Locked, stale, future,
corrupt, replaced, or symlinked artifacts remain untouched. Atomic detach is
logical deletion, but recursive removal starts only after synchronizing the
staging parent before the canonical source parent. Completed removal
synchronizes staging again, and restart finalization first re-establishes the
same durable boundary. Any session finalization or cleanup failure suppresses
agent eligibility deletion for that pass, because an incompletely committed
session detach may return after a crash. Focused filesystem, reference,
tombstone, and ordering oracles live beside session_cleanup, agent_cleanup,
retention_cleanup, and diagnostic_cleanup.
Summary files intentionally omit prompt previews. Legacy preview-bearing sidecars are unverified hints and are scrubbed when strict journal migration can acquire the agent lock. Bounded checkpoint repair never rewrites journal facts. Writer recovery may truncate only an incomplete EOF crash tail; complete invalid frames and their suffix remain unchanged and fail closed. Failure to publish derived metadata does not invalidate an already committed record. This is cooperative same-UID crash consistency, not tamper detection: arbitrary same-inode/same-size journal mutation is outside the append-only store contract.
Global prompt history uses a bounded best-effort FIFO worker. Its queue has 64 pending slots, and its queued plus in-flight prompt text is capped at 1 MiB; the worker can hold one of those accepted entries in flight while it writes. The newest entry drops when either bound is full or the worker is unavailable. Admission does not mean the record reached the filesystem or is durable. The worker does not flush, fsync, or drain at shutdown, so a crash or normal exit can lose accepted history.
The worker retains cooperative cross-process locking and repair. A process-local device/inode/EOF/final-boundary witness avoids rescanning an unchanged framed prefix under the cross-process lock and falls back on ordinary replacement, truncation, or tail mismatch. The witness is not cryptographic tamper evidence; a same-UID process deliberately preserving its identity and witnessed tail while rewriting older bytes remains outside the prompt-history contract.
Cold restore detaches completed start-agent workers only from validated journal evidence that matches warm side-conversation terminalization. Explicitly continuing recovery is not completion; terminal compaction failures are completion when their originating side request matches. Histories without unambiguous terminal evidence retain prior behavior and do not recover transient result routes. Re-check this classifier and its two-boot positive/negative regressions whenever provider-response, compaction, or side-conversation terminalization changes.
Agent display/task names are presentation-only metadata, never routing or trust
identity and never provider context or semantic message content. Local names are
authoritative only within the session whose agent metadata supplied them; remote
names are eligible only when carried by a typed peer endpoint. Message labels
keep the stable id visible, escape controls, bidi/structural Unicode, delimiter
characters, quotes, and backslashes, then apply byte and terminal-column bounds
after escaping. Revisit these invariants whenever adding a new name source or
using names outside UI presentation.
For newly created agents, the built-in default leaves agents without an
explicit task or rename unnamed. Operator-configured templates may still
generate names, and durable display-name facts remain authoritative on replay
even when an older generated name is indistinguishable from an explicit one.
See
SPEC-tau-cli-agent-message-labels
for the rendering and session-provenance behavior.
The harness accepts only acyclic current-session agent-watch topology to prevent
reciprocal or longer feedback paths from amplifying watch-derived interactions.
For each genuinely new enable, Live-target validation and iterative reverse-path
rejection occur before any watch state or event changes; the check and mutation
share one synchronous, exclusively mutable harness event-loop operation.
Repeated enables preserve their existing edge, while disables remain available
to remove relations and bypass cycle analysis. Re-check this ordering and the
no-mutation failure contract whenever watch topology ownership or event-loop
serialization changes. See
GATE-agent-watch-acyclic-topology.
Work-status titles are model-authored cross-agent content, not trusted routing
or instruction data. The harness keeps their typed phase and epoch separate and
applies visible trusted-frame escaping before prompt interpolation, while the
CLI applies the same escaping before placing titles in its one-line status
frame. Long-wait
notifications contain only harness-derived numeric thresholds. Their scheduler
uses actual monotonic installed-wait intervals, advances even without watchers,
and never reconstructs runtime clocks or re-fans committed thresholds on replay.
Late watchers receive no historical threshold activation. Overdue catch-up
captures crossed thresholds and their current subscriptions compactly, advances
the timer cursor before later watch changes, and materializes at most 64 recipient
occurrences per runtime scheduler cycle. A queued event runs between batches;
without one, the remaining compact backlog schedules another immediate cycle.
Only the model-owned, policy-authorized status call may mutate its calling
agent. Configured extensions cannot invoke it directly or select a target agent.
The harness validates the closed phase, including self-resolving Waiting versus
intervention-required Blocked, and canonical 160-byte, single-line title
at both tool and durable boundaries. A challenged successful response remains
permanently withheld from watch, delegated-result, and detach projection even
though its semantic append remains in the transcript; post-commit handling only
queues guidance. The same guard applies while status remains Unreported only
when the immutable dispatched prompt surface exposed model-visible status.
After an accepted Waiting, Done, or Blocked transition, a distinct later successful final
may project and complete the outer turn, but only after its own exact append
commits. Each unresolved phase has its own bounded escape: it challenges at most
two successful finals, and the third within that phase projects even if status
remains unresolved. Entering Working resets the budget even after Unreported
challenges in the same outer turn. Escape invalidates Working to Unknown but
leaves Unreported unchanged. Prompts without status bypass this guard.
Waiting, Done, Blocked, an unsuccessful terminal that invalidates Working to Unknown,
budget escape, unload, and final shutdown release that runtime ownership;
append failure and interception rejection cannot project a challenged candidate. Work-status state
tests, harness gated-final/interception tests, and the deterministic current-status
provider scenario cover these boundaries. Revisit them whenever internal-tool
ownership, response interception, final projection, or agent teardown changes.
Repeated activating-input wait protection derives only from typed timeout
settlements at terminal publication. Focused supplied-clock tests cover ordinary
and compaction-rollback timeout publication, one-shot and Waiting suppression,
substantive-admission reset even without status, and non-timeout wait
exclusion. Revisit these oracles when settlement correlation, compaction claims,
tool admission, or work-status phase handling changes.
The harness's immutable post-policy, provider-filtered prompt snapshot is the
sole authority for tool definitions, call authorization, and capability-derived
prompt guidance. Revoking agent_start must remove both available-role catalog
text and its fragment entry from custom-template data; conditionally empty
ordinary fragments are therefore omitted after rendering. Re-check capability
filtering and custom-template regressions whenever prompt fragment projection or
effective tool policy changes. See
SPEC-tau-harness-prompt-dispatch.
Harness-stamped prompt provenance is also provider-presentation authority.
Only PromptSubmissionSource::HumanUi receives the fieldless <user> envelope,
and only exact </user> collisions are replaced before the trusted close is
appended. The body remains the authenticated user's instruction
channel, not external untrusted-message metadata. Canonical journal facts,
UI/history/navigation, and watch fanout retain raw accepted text; replay derives
the same provider form from the typed source and never infers provenance from
text. Only exact outer Tau-stamped sentinels establish model-facing provenance;
nested or delimiter-like payload text does not change enclosing source or trust.
This prevents exact lexical breakout, not semantic prompt injection. Re-check
submitted/steered source preservation, exact-close replacement,
compaction suffix handling, and non-HumanUi exclusions whenever prompt folding
or provider assembly changes. See
SPEC-interactive-user-prompt-envelope.
Configured extensions, including Providers, are trusted same-user executables
under
GATE-configured-extension-trust-boundary.
“Less-trusted extension” means protocol authority is limited—the harness still
validates phase, source ownership, routing identity, configuration, and
collisions—not that the stdio stream is a hostile availability boundary or
process sandbox. Operation quotas do not promise to bound protocol
deserialization; see
SPEC-tau-harness-session-state
and ARCH-tau-supervisor.
Every configured extension kind may request per-agent metadata mutations, while
attached socket UIs have the same narrow authority. Requests commit before
target/key/value validation, then the exact still-live extension generation or
attached UI is revalidated before the harness publishes a durable canonical
fact. Other socket peers and peer-authored canonical facts are rejected. Metadata
is extension-visible coordination state, not a secret store; invalid requests
currently have no outcome event. See
SPEC-agent-metadata-requests-and-canonical-facts.
Only an attached socket UI may send ui_debug_event_stats_request to inspect
configured-extension protocol counters. Dedicated external-message peers,
non-UI sockets, and embedded/non-socket UIs receive only a content-free
authorization error. The request is omitted from debug JSONL and its result is a
requester-directed, non-published notice. Configured extensions are silently denied
without a response, warning, or disconnection.
Every authenticated configured extension kind may send
extension_notice_request, but the request carries no kind, target, transience,
visibility, publisher, correlation, or provenance authority. The harness caps
critical to warning and publishes a harness-sourced, live-only
extension.notice through ordinary interception. Unconfigured and disconnected
origins are silently denied, and generic extension Emit(harness.notice) remains
forbidden. Pre-Ready requests retain normal activation ordering and bounded
admission. ConfigError remains a separate mandatory replayable path. Security
review must preserve those distinctions and the non-persistence guarantee. See
SPEC-extension-notice-requests.
Only an attached socket UI may send the payload-free ui_shutdown_request that
unconditionally enters canonical harness shutdown. Other socket peers,
embedded/non-socket UIs, dedicated external-message peers, and configured
extensions are silently denied; they cannot stop the session. The request does
not become a published or persisted event.
Only an attached socket UI may send ui_tree_request and inspect agent prompt
anchors/previews. The harness returns exactly one requester-directed multiline
notice and does not publish the request or result. Other client origins and
configured extensions are silently denied; extension attempts retain normal
phase validation and metering but are denied before activation staging.
Tree prompt previews are untrusted terminal text. The harness encodes them
before constructing the common requester-directed notice, so interactive and
headless clients receive identical terminal-inert text without TTY-dependent
rewriting. Focused harness and CLI regressions protect the encoding, directed
routing, interactive VT result, and exact headless bytes. Security review must
revisit this boundary when changing the preview window or encoding,
requires_visible_escape, directed routing, or either client's tree rendering.
See
SPEC-tau-harness-session-state.
Only authenticated configured Tool/Core peers may publish transient tool
registration/unregistration declarations; canonical tool.register and
tool.unregister state is harness-authored. After declaration commit, the
harness binds processing to the captured configured identity and live connection,
then enforces assigned prefixes, schema/example bounds, ownership, and startup
collision policy. Pre-Ready reservations are bounded and released on
drop/disconnect, and neither declarations nor canonical runtime state enters
semantic journals. Security review must revisit this boundary when changing the
authority matrix, interception replacement/drop behavior, activation accounting,
disconnect/respawn identity checks, or persistence classification. See
SPEC-tool-declarations-and-canonical-state.
When enabled, std-utils papercut reports persist unredacted model-supplied
operational text plus harness-routed agent/session identity and an operation
timestamp as plaintext per-instance ExtensionDataScope::User data. It is
shared across sessions that use one Tau state root and configured instance.
Tau-state operators can read these records, there is no automatic redaction,
and agents must not put secrets in reports. The harness serializes User-scope
appends across harness processes sharing that state root and instance. This is
explicitly best-effort diagnostic data: memory-only denial, quota/RPC failure,
and a final-shutdown race can lose a record; ephemeral sessions intentionally
use the same durable file. These
limitations do not expand the configured-local extension boundary or imply
hostile-process hardening.
tau dev papercut list [--markdown] and clear form a narrow local operator
exception for the normal std-utils instance's canonical papercuts.jsonl
file. They never enumerate arbitrary extension data. List opens the final
records file without following a symlink, requires one bounded regular UTF-8
v1 JSONL file with validated harness identifier fields and a renderable
timestamp, and renders only the recorded report plus its recorded attribution.
Plain output escapes controls; Markdown uses literal report blocks. Malformed,
unsupported, oversized, symlinked, non-regular, or unrenderable records fail
closed without exposing raw data.
Clear takes the same exclusive extension-directory lock as harness User-scope
appends, validates the same file, and removes it only while holding that lock.
It reports the number in its locked snapshot. An append that completed before
the lock boundary is cleared; an appender that waits for or starts after it
creates a new file and remains visible. A rejected input is never cleared.
Review this boundary when changing the papercut record schema, extension-data
file limit, User-scope lock, normal std-utils instance naming, or CLI output
sanitization.
The same configured-peer boundary admits transient tool.progress_reported
observations. The report commits before routed-call authorization; only the
downstream consumer may validate the captured live source, suppress backgrounded
calls, and publish immutable harness-sourced tool.progress. Parked reports
retain their original configured identity, and stale generations cannot produce
canonical progress. See
SPEC-tool-progress-reports-and-canonical-facts.
Terminal Tool/Core reports use the same captured configured-generation
boundary. Mutable tool.result_reported, tool.error_reported, and
tool.cancelled_reported observations commit before exact routed-call
authorization and terminal state changes. Valid reports produce only immutable
harness-sourced terminal/provider/background facts; stale generations,
non-owners, completed calls, and direct canonical spoofs cannot close a call.
Reports and raw canonical result/error facts stay out of semantic journals,
while existing provider/cancellation/background transcript persistence is
unchanged. Ephemeral-agent classification suppresses raw reports and every
projection from durable debug JSONL. See
SPEC-terminal-tool-reports-and-canonical-outcomes.
Configured Tool/Core shell providers use the same captured-generation boundary
for shell.command_progress_reported and shell.command_finished_reported.
Reports commit before exact private-route and echoed-identity validation; only
the harness publishes canonical shell progress/completion. A stale, replaced,
non-owning, or identity-altered report cannot consume a route or inject
transcript output, and injection follows immutable canonical completion commit.
The publication envelope captures original-route ephemerality before
interception, replacement routes are reclassified from harness-owned pending
state or process-lifetime harness-generated ephemeral-route tombstones, and
unknown peer-chosen routes retain ordinary debug audit treatment. The tombstone
set grows only with accepted ephemeral user-shell routes until process exit.
The original frame-admission session must still match before a staged report
can derive canonical state.
See
SPEC-shell-command-reports-and-canonical-facts.
Configured Provider/Tool/Core peers may also publish tool.request routing
intents. The request commits before live generation, call-id correlation, and
registry routing checks; only harness-sourced derived facts assert acceptance
or terminal closure. Durable requests retain stable configured publisher
identity as a typed configured-extension provenance distinct from run-local
ConnectionId. Replay never interprets that provenance as a live source, never
routes it, and never executes work. See
SPEC-tool-requests-and-routing.
Configured local extensions are trusted to supply request agent correlation.
Internal-route correlation remains runtime/accounting state and never grants
agent-transcript ownership; its terminal projections are ownerless.
Separate pending correlation accepts progress and terminal reports only from the
exact routed owner; every accepted terminal or routed-owner disconnect clears
live request state and retains the completed-call tombstone. Re-check
request-to-terminal and internal-route closure tests whenever pending-call
ownership or report consumers change.
Every authenticated configured extension kind may publish transient prompt-fragment
declarations without a separate capability. The declaration commits before the
harness updates prompt assembly state; interception drop and stale connection
generations cannot mutate that projection. Pre-Ready declarations reserve bounded
activation capacity until commit, drop, or disconnect, and no declaration enters semantic
history or replay. See
SPEC-prompt-fragment-declarations-and-projection.
Every authenticated configured extension kind may also publish transient
session-provider registration, complete session/agent discovery source snapshots,
per-agent keyed context, and readiness without a capability. Post-commit consumers
revalidate the exact connection generation plus applicable session, agent, and
process-unique initialization id before mutating state. Only registered live
non-socket Tool subscribers participate in captured waits; per-agent readiness
cannot release session readiness or another agent. A connected effective
per-agent waiter has no deadline and can hold initialization until
acknowledgement or disconnect.
Pre-Ready declarations reserve bounded activation count/bytes, and snapshot
validation additionally bounds item count, decoded bytes, and individual AGENTS.md
content. Invalid items are diagnosed and omitted before one atomic source swap.
Raw declarations never enter semantic journals or replay. Re-check reservation
cleanup, wait admission, atomic source replacement, and disconnect/respawn
generation checks whenever this flow changes. See
SPEC-session-discovery-declarations-and-readiness.
The harness treats
agent.initialization_context_set, harness.agent_context_initialized, and
harness.session_skills_available as protected harness-authored events:
configured extensions and attached UIs cannot publish them, and interceptors
cannot drop or mutate them. Only agent.initialization_context_set defaults to
durable publication and folds as replaceable agent side state rather than
transcript history; every finalization appends the exact fresh initialization-ID
replacement even when effective content is unchanged. Both harness.* events
are transient current projections synthesized for late subscribers.
Finalized agents consume one frozen snapshot for prompt skill listing, model/user
skill lookup, and AGENTS.md bootstrap materialization.
Skill metadata snapshots file paths and mtimes, not file bodies. A local file may
change between scan and later skill loading, so discovery is not a content-integrity
or filesystem sandbox boundary. AGENTS.md content is carried in the snapshot and
frozen at initialization. Treat all discovered files as trusted local prompt input.
See
SPEC-per-agent-context-declarations-and-readiness.
Every configured extension kind may publish transient internal-prompt requests.
The harness commits them before loaded-agent validation, revalidates the exact
connection generation, and excludes raw requests from semantic replay. Invalid
targets remain observable but cannot create prompt facts; stale generations
cannot submit work. See
SPEC-internal-prompt-submit-requests.
Every configured extension kind may also publish transient start-agent requests.
The harness commits the raw request before revalidating the exact live generation
and admission session, then applies role, parent/tool-owner, duplicate rebinding,
and child-creation logic. Accepted startup is bounded to 64 concurrent operations
and 4 MiB of aggregate retained instruction, span, task, and routing data; agent-id
reservations and requester query ids are bounded before storage side effects.
Each successful phase owns one ordinary committed or rejected publication outcome.
After acceptance, exactly one compact agent.start_failed terminal owns failure
projection and runtime cleanup; no cross-event reservation or journal transaction
is implied.
Clean process shutdown terminalizes every accepted start before revoking admission and rejects a still-uncommitted acceptance without inventing a failure fact. A hard crash can leave only the already committed durable prefix. Cold restore keeps that prefix inspectable but never reconstructs requester routes, buffered wakes, coordinator state, or initial-prompt dispatch. Only a committed startup inference checkpoint permits ordinary post-start inference recovery. Stream-local terminal persistence diagnostics target the exact agent generation; whole-owner exit affects only durable starts bound to that current owner, not memory-only or ephemeral starts. Retryable open, lock, write, and sync diagnostics do not independently terminalize startup.
Unconfigured/socket peers are denied; stale generations or sessions are
observation-only, and raw requests never enter semantic replay. Deterministic
startup regressions preserve every pre/post-accept interception cut, canonical
prompt replacement, dispatch rejection, persistence-owner exit, cancellation and
shutdown boundary, terminal retry, bounded-index cleanup, and cold-restart prefix.
Revisit these safeguards when changing event interception, semantic persistence
generation ownership, agent-id templates, prompt dispatch, session shutdown, or
restore activation. See
SPEC-start-agent-requests.
Every live configured extension kind and attached local UI may publish terminal
bell and OSC side-effect events through ordinary interception and commit.
Unconfigured, disconnected, and dedicated external-message peers cannot. The
events never enter semantic stores, and terminal UIs independently reject replay
delivery before writing terminal bytes. OSC name validation and bounded,
base64-encoded values remain defense in depth. See
SPEC-terminal-output-side-effect-events.
Every live configured extension kind and attached local UI may also publish
custom events under extension-owned categories. Unconfigured, disconnected,
non-UI socket, and dedicated external-message peers cannot. Structural name
validation prevents custom payloads from spoofing typed first-party event names;
opaque payloads remain live/debug-only and never enter semantic stores. Existing
trusted-local frame, activation, and diagnostics-cardinality bounds apply. See
SPEC-custom-extension-events.
Only harness-assigned attached socket UIs may publish prompt-draft and focus
liveness observations. Dedicated external-message, non-UI, disconnected, and
extension-path peers cannot. Drafts contain the full current prompt buffer and
remain visible to privileged interceptors, subscribed live peers, and debug
logging, but neither liveness event enters semantic stores or replay for either
persist value. The shared decoded-message bound applies; no smaller trusted-UI
payload bound is promised. See
SPEC-ui-prompt-draft-and-focus-events.
Configured Provider peers likewise submit transient
provider.quota_*_reported observations before any account-state acceptance.
Only the post-commit consumer may validate the captured live generation,
provider/model-route ownership, bounded records, and epoch/sequence transition,
then publish protected harness-sourced harness.provider_quota_changed.
Unowned or stale reports may remain observable as committed observations but
cannot mutate current quota state. Neither reports nor canonical snapshots enter
semantic journals or cold replay; they contain no credentials or account IDs.
See SPEC-provider-quota-pacing.
Configured Provider execution uses five transient _reported observations through the
same trusted local boundary. Reports commit before exact live-generation and
prompt/retry correlation; only harness-sourced successors assert canonical execution
facts or directed retry outcomes. Reports are excluded from semantic journals for
either supplied persist value. Raw terminal report delivery/debug projections clear
provider-image bytes. This boundary validates routing and lifecycle ownership; it does
not treat configured provider payloads as hostile extension input or add spoofing
hardening. Standalone-attempt accounting is a separate harness-sourced durable
fact: it carries required session correlation and normalized usage/rates/cost but
no credential or provider account identity. Its retry authority is bounded to 64
attempts, reserving attempt 65 for the terminal; larger configured-Provider
statuses remain transient diagnostics and cannot drive accounting or watcher
attempt state. A post-dispatch cancellation first publishes an Unknown awaiting
observation. Only the same live provider generation can publish its one durable
terminal correction; restart preserves the observation but restores no
correction authority. Provider disconnect, graceful shutdown, and agent unload
instead close still-dispatched owners as Final Unknown before discarding their
routes. See
SPEC-provider-execution-reports-and-canonical-facts.
Committed terminal result reports may carry typed provider images for downstream
validation, but every debug JSONL projection clears image bytes under
SPEC-typed-image-tool-results; only
validated provider transcript storage and directed provider prompts retain
canonical bytes.
Generic configured-extension spawn diagnostics treat the configured instance
name, resolved executable, and explicitly configured cwd as non-secret metadata;
do not place credentials or tokens in those fields. Diagnostics bound and escape
those fields, include cwd only when configured, and preserve the underlying
operating-system error/source chain. They never retain or render command
arguments, full extension configuration, environment values, or resolved secret
values. Re-check this contract whenever extension spawn configuration or
startup/respawn logging changes.
Per-agent shell-instance workdirs are committed coordination state, not an
access-control boundary. Paths are interpreted only by the configured extension
instance that owns them. Malformed or unavailable remembered paths fail closed
until explicitly repaired, and user-shell routing failures remain local command
failures rather than changing extension authority. Directory locks remain
advisory coordination.
Robust framing and cleanup improvements are welcome when scoped, but unrelated
features must not be expanded into slowloris, connection-flood, or sandbox
hardening without an approved threat-model design.
Runtime discovery is non-destructive under the cooperative local boundary.
Each durable session maps to one deterministic full-BLAKE3 lock basename and
socket basename. The daemon holds the lifetime flock before binding the socket
and keeps it through transport and durable-store teardown. The lock winner may
reclaim that session's stale socket; scanners never unlink it. PIDs are
diagnostic only and do not participate in lookup, routing, or liveness.
Targeted lookup bounds raw traversal and total time and fails closed when an
exact admitted connection cannot be proven.
Local running-session listing isolates bounded raw traversal from its caller and
uses runtime paths only as socket candidates. Each responsive daemon returns its
in-memory current session id and immutable canonical startup project root
through a correlation-matched, per-probe-deadline local socket RPC; adjacent
metadata and persisted session directories supply neither records nor fields.
The CLI escapes record separators and terminal controls before writing
line-oriented output, and uses JSON string escaping for structured output.
Inter-harness/session communication is likewise cooperative same-UID IPC, with
correlation and bounded model-spend admission rather than hostile-sender ACLs.
Genuinely untrusted ingress is external network/service content received through
Slack, XMPP, Telegram, providers, web fetches, and similar adapters. Authenticate
and bound that adapter boundary where applicable and keep payloads untrusted model
content; proxying them through an extension does not make the local extension
transport itself adversarial. The boundary summary is recorded in
ARCH-external-message-boundary.
Successful tau-ext-websearch results remain ordinary invocation-correlated
tool-result strings. The extension places optionally authenticated Exa/Parallel
search/fetch, anonymous or optionally authenticated You.com search,
credentialed Brave search, and credentialed Tavily/Firecrawl search/fetch
results inside one exact-close-framed <tau_web_content> boundary with closed
adapter, operation, and external-trust labels, and enforces its result bound
after framing and closure. Exa, Parallel, and You.com retain anonymous paths;
configured You.com authentication selects its authenticated endpoint by
default. Credentialed adapters resolve API keys only from named Tau secrets and
send them in provider authentication headers; logs and model-visible errors
redact credential and endpoint material. Adapter
identity authenticates neither page authorship nor truth; provider titles,
URLs, ranks, sources, and prose remain untrusted body claims capable of prompt
injection. The envelope prevents exact closing-sentinel breakout but is not a
sandbox or instruction-authority change. See
SPEC-tau-ext-websearch-provider-boundary
and
SPEC-tau-ext-websearch-runtime-safeguards.
Hybrid calls can send the same query or URL to as many as three configured
hosted providers sequentially, so one call has multiple external recipients and
each issued attempt can consume quota. Cancellation prevents later attempts,
but the blocking HTTP transport may retain an already issued request until its
admission-anchored deadline slice ends.
The disabled-by-default std-slack bridge is the separately installed
tau-ext-slack executable, supervised through Tau's normal trusted same-user
stdio extension route. It requires exact configured conversation/kind/thread
policy and verified live-human admission. Receive permission creates only
Tau-issued source-bound reply authority; proactive permission is a separate
alias-only grant. Dynamic DMs remain bounded, allowlist/exact-user-bound, and
reply-only.
Slack submits transient message reports through ordinary interception; the
harness retains each raw publisher claim losslessly for observation and audit.
The harness publishes an immutable canonical fact only when the top-level claim
is grammar-valid and exactly matches the authenticated configured extension
name, then stamps canonical provenance from that captured identity. A malformed
or mismatched claim remains only a transient report. Nested message references
remain opaque and follow projection validation rather than report admission.
Actionable reply and reaction authority stays in extension-local runtime state.
The Slack extension drops
recently repeated native occurrence ids with a bounded process-local cache before
report submission. Generic event infrastructure does no native deduplication or
ownership resolution: each canonical fact is a new immutable occurrence.
Cache eviction, restart, or races may therefore duplicate delivery.
Slack records an occurrence before identity lookup, local effects, capacity
admission, and local report write; a later transient failure consumes that
occurrence until eviction or restart rather than retrying it.
Use one Slack extension instance for one receiving agent. The separately
maintained tau-ext-slack project owns the detailed architecture and routing
contract.
Re-check record-before-submission ordering, Slack-local cache bounds, and
disconnect/session route cleanup whenever Slack report submission changes.
Report flush acknowledges only submission to the local protocol writer, not
canonical commit. Interception, append failure, or a crash can therefore leave a
remote/local effect without a canonical fact.
The separately authorized, default-off Slack reaction tool accepts only locally
retained exact-message refs from submitted reports/results, requires current route
and role authority, and permits removal only of same-agent runtime-owned
reactions. It adds reactions:write without reaction listing; reactions are
externally visible and can trigger notifications or workflows.
The separately authorized Slack discovery tool reveals all static model-facing
aliases and configured policy, including receive-only routes, but excludes native
routes, dynamic links, identities, runtime state, and Slack-fetched metadata.
security_mode: lax materially widens prompt-injection exposure on static
routes and must not be treated as control authority. Slack, workspace
administrators, Slack Connect participants, and conversation members may read
transported text; this is not an end-to-end encrypted channel.
Slack additionally binds auth.test bot/workspace identity to each supported
Events API wrapper and fails closed on missing, ambiguous, or mismatched
installation evidence. Native U/W ids remain authoritative; fetched display
names and operator aliases are presentation only. Agent sends reject raw Slack
mention/control markup; the optional source-mention field can name only the
verified human already bound to a live reply selector and is frozen with the
bounded retry body.
The separately maintained tau-ext-slack project owns its Slack-specific
review triggers, failure/replay invariants, operational guidance, and tests.
The disabled-by-default std-telegram bridge is the separately installed
tau-ext-telegram executable, supervised through the same trusted same-user
stdio extension route. Local-poll mode admits only configured numeric users and
one configured or allowlisted-user-linked chat; registration grants routes only
to explicitly registered loaded agents, and sending never accepts a
model-chosen native destination. Gateway-client mode gives the sidecar only its
configured socket endpoint and per-instance authentication secret; the
separately supervised tau-telegram-gateway retains bot-token, polling,
allowlist, chat, durable checkpoint, and outbound-routing authority. The
standalone project owns Telegram-specific review triggers, replay and
durability invariants, operational guidance, and tests.
The disabled-by-default std-zulip bridge is the separately installed
tau-ext-zulip executable, supervised through Tau's normal trusted same-user
stdio extension route. It uses bot HTTP Basic authentication and native
event-queue long polling. Exact numeric sender allowlists and configured DM or
stream/topic policies gate ingress; separately configured proactive-DM aliases
fix outbound recipient authority. Queue identifiers and native participant,
stream, topic, and message routes remain extension-local authority; model tools
accept only current configured aliases or bounded Tau-issued source references.
Opt-in send-only mode declares only the send tool for one fixed proactive-DM
alias and rejects every inbound route, allowlist, queue, reply, reaction, and
catch-up surface. With the default
offline_message_catch_up: false, queue expiry
reconnects at a fresh live tip and warns about a possible gap rather than
fetching missed backlog. Opting into offline_message_catch_up: true uses the
extension-local CheckpointRuntime to recover bounded newly created messages
after its durable position. Successful sends report before
their tool result, while ambiguous provider outcomes are not automatically
retried. The separately maintained tau-ext-zulip project owns its detailed
architecture, routing, testing, and security documentation.
Standalone compaction and its continuation are harness-owned durable work. Every new provider cut must be a closed transcript prefix; a tool-calling assistant response and its complete terminal results node are indivisible. Native Codex transient standalone failures use the shared scheduler for at most five total attempts only before semantic compact output is accepted. An error processed first in an event accepts no content and remains retryable. Once compact output is accepted, any later failure discards that uncommitted output and terminalizes without automatic retry; recovery requires a distinct explicit request. Deterministic failures terminalize immediately. After terminal continuation or background completion, ordinary input proceeds, while durable failure history suppresses automatic threshold, policy, continuation, and reactive recovery for the same provider-qualified model and branch. Model or branch drift permits fresh independent work; returning restores suppression until a successful matching explicit successor clears the failed chain.
An explicit successor may retreat its cut to retain more exact suffix, but it
must preserve same-branch coverage of any resume watermark and cannot replace
that watermark with an ancestor or sibling selected by later head navigation.
Ordinary input and :cancel do not clear durable failure authority. Core
validation and warm/cold exact-once replay regressions prevent duplicate provider
dispatch, terminal delivery, and continuation checkpoints.
The production-path safeguards
compact_pre_progress_failure_remains_retryable,
compact_same_event_error_first_remains_retryable,
compact_post_progress_failure_is_terminal,
compact_exact_success_returns_one_item, and
compact_explicit_new_request_dispatches_after_post_progress_failure preserve
the native Codex retry/cost boundary.
Revisit them when adding any explicit abandon/rewind operation or changing
compaction replay ownership, retry limits, failure classification, parser
precedence, semantic-progress correlation, pool repair, compact scheduler
mapping, or automatic suppression qualification.
Exact committed publication envelopes create or transfer activation ownership.
A retained completion envelope or standalone AwaitingCheckpoint tuple represents
durable work and remains bound to its owning branch. Queue/in-flight attempt
markers are ephemeral: every prevalidation or persistence rejection clears them,
and agent unload or final shutdown discards all warm-process retry state.
Transaction-owned publications carry their enqueue-time session generation and
must still match an exact live runtime owner before commit. Destructive lifecycle
cancellation suspends that interceptor's registration until its one outstanding
uncorrelated stale reply is consumed, so the reply cannot bind to later work
without changing the extension connection lifecycle. Registration
replacement remains suspended, no timeout applies, exactly one reply is consumed,
and disconnect clears suspension. The interface contract is specified by
SPEC-tau-harness-event-processing.
Unrelated accepted publications retain FIFO order and complete or fail through
their normal path.
Final shutdown advances the session admission generation before quiescence. Raw
session-bound events whose contracts require observation may still commit, but a
central post-commit peer guard suppresses their semantic effects and releases
activation reservations. Process-global tool/prompt-fragment/model declarations
and provider-quota current-state reports may finish only while exact captured
connection-generation identity remains current.
The model-callable self compact capability is enabled by default and can act
only on the calling agent. Effective role policy may revoke it by exact tool
name, compaction group, or matching tag. The cross-agent agent_compact
capability remains independently disabled by default; explicitly granting it
authorizes compaction of another loaded same-session agent but does not alter
self-compaction policy.
V1-marked ordinary-inference cancellation journals the exact matching
AgentPromptTerminated(Canceled) before it releases placement ownership. Cold
replay folds that private closure and rejects a late response, subject to the
existing asynchronous-writeback loss boundary. Legacy and unmarked ordinary
termination remains transient. Standalone-compaction ownership remains covered by
the separate durable rules above. See
SPEC-agent-message-delivery and
GATE-asynchronous-journal-durability.
Named context-size alerts are operator-configured, model-visible advisory
prompts. Provider token usage may trigger an alert only for an accepted,
successful, non-compacting ordinary response under the policy captured for that
prompt. Canceled, stale, duplicate, failed, and compaction responses create no
alert work. Alert messages grant no tool authority: compact remains separately
controlled by effective tool policy.
Crossing suppression and still-queued alert delivery are daemon-local
best-effort state, not durable recovery obligations. A crash can lose an
uncommitted queued alert, and a later successful response after cold replay can
evaluate restored high usage again. Once delivery commits, the submitted or
steered prompt fact is durable and cold replay preserves its journal position.
Its harness-owned internal_kind=context_size_alert tag and exact configured
text are protected against interceptor addition, removal, or rewrite; missing
tags remain hidden, and neither ctx_id nor text can infer the tag. Tau creates
no synthetic replay event. Warm-process regressions cover threshold crossings,
failure exclusion, tool-round deferral, accounting resets (including stale
queued-alert removal), and prompt-owned role policy; cold-resume regressions
cover both submitted and steered tagged delivery facts.
The universal release binary's accepted build-time, memory, size, and runtime
tradeoffs, measurements, temporary adoption limits, and re-evaluation triggers
are documented in docs/release-builds.md.
When reporting a vulnerability, include:
- affected Tau version or commit;
- operating system and relevant configuration;
- minimal reproduction steps;
- whether an extension, provider, UI client, or daemon boundary is involved;
- any logs that do not contain secrets.
Avoid sharing API keys, OAuth tokens, email contents, or other private data in reports.
Navigation modes are same-user UI control state with presentation-only effects.
The harness accepts absolute mutations only through authenticated attached-local
UI intake; extensions and external peers cannot mutate them. This authority
covers explicit navigation requests and the implicit active write after a
visible human prompt is durably admitted for an existing target. Payload
originator, submission provenance, durable prompt replay, and later queue/steer
processing are not authentication and cannot independently cause the write.
The authenticated cooperative bare peer-entrypoint auto-start has one
harness-internal exception: after durable identity and current-session membership
setup, the harness writes active only for its newly created recipient and
publishes complete stats. The peer never chooses a mode, and exact/existing
recipients and all other start paths cannot acquire this write. The runtime-only
classification is forgotten on unload or process exit; cold
restore recomputes the extension-origin active_auto default. Receive-commit ACK
authority remains independent of this UI-only state.
Modes do not authorize loading, routing, prompt delivery, watches, execution, or
model access and are intentionally not durable.
The directed agent-roster RPC is available only to same-user local connections
classified as UI clients. It exposes stable ids, lifecycle/persistence,
navigation/runtime status, creation role/parent/time, and a verified display
name, including unloaded history when requested. Live rows also include the
agent's current self-reported work-status phase and model-authored title. Titles
are untrusted presentation metadata; the picker visibly escapes them before
passing roster rows to the trusted local fzf. These are content-minimized
coordination labels, not secrets or an authorization boundary. Results go only
to the requester and never enter event publication, interception, subscription
replay, or extension delivery.
The harness seeds roster caches atomically from validated committed membership
before runtime restoration and updates them only after later membership commits;
any restore/commit failure invalidates the projection. Entry count is checked
before ids are cloned. Creation records, checkpoint reads,
in-memory ephemeral projections, intermediate encoding, and the final protocol
message are bounded before allocation or transmission. Malformed creation facts
remain categorical without repair, locking, or writes; a cold display name is
used only when its checkpoint identity and boundary still bind it to the exact
journal. Snapshot failures return no partial rows.
The optional picker resolves fzf through the same user's PATH and therefore
treats it as trusted local code. Tau invokes fixed arguments directly, bounds its
stdin/stdout and runtime, checks foreground restoration after settling the child,
and revalidates the selected agent. Restoration failure preserves the primary
picker outcome and the restoration error; Drop retries only as best-effort
cleanup. When foreground ownership remains unconfirmed, Tau does not resume raw
input, redraw, or terminal cleanup, disconnects only that UI attachment, and
leaves an owned harness daemon running. Checked restoration retries only EINTR,
binds handoff and restoration to Tau's actual process group, rejects an initial
foreground mismatch, accepts only that actual group as already restored, and
otherwise retains the fail-stop. Before teardown, the private UI log records one fixed restoration
class and optional numeric errno for non-ephemeral UIs; failures without a
syscall errno use the exact bounded value restoration_errno=none. Ephemeral
mode retains its no-artifact sink behavior. Neither field enters protocol, replay, or semantic
persistence. Cancellation, ordinary subprocess/RPC
errors after confirmed restoration, and stale selection are no-mutation outcomes.
Focused safeguards cover bounded settlement and group cleanup, the high-level
no-resume guard, attachment-fatal routing, and raw-terminal paused Drop/no-write
behavior. Revisit them together when changing picker subprocess ownership,
terminal pause/resume, input-loop error routing, or daemon exit disposition.
Picker membership follows live lifecycle/navigation authority independently of
missing, invalid, or unreadable creation-fact enrichment. Selection never
changes navigation mode, runtime state, or agent loading.
Session activity reports trust only harness-authored canonical journal facts.
Provider-supplied accounting fields are discarded before canonical publication;
captured response-local usage, effective rates, and increments are immutable
authority. Outer-turn lifecycle and prompt joins are immutable must-pass facts.
Stats traversal is read-only and performs no repair, migration, configuration
lookup, or inferred backfill. Missing accounting authority makes complete false;
malformed or corrupt journals fail closed. An unmatched crash-cut start remains
reported as unterminated but does not block a later boot's fresh turn.
Changes to this boundary must re-check strict replay lifecycle joins, cross-session prompt/response/tool isolation (including reused call IDs), interception drop/replacement and peer-forgery rejection, response-local rather than cumulative usage accounting, and the no-write behavior of offline inspection.
tau agent cache and tau session cache perform offline inspection only. Their
content-free reports omit bodies, provider IDs, endpoint/account/cache-key values,
and source paths, but retain local navigation IDs and workload accounting. They
write no state or indexes, never contact providers, and do not enable captures.
Legacy private capture files provide only partial inventory evidence, not an
exhaustive attempt ledger or exact terminal joins. See
docs/agent-cache.md for the initial coverage and
conservative resource-admission limits.
tau agent trace can export unredacted durable journals. Native, OTLP, and
compact output can contain full
prompts, reasoning, images, tool arguments and results, messages, model
parameters, usage, and cost data. Treat native, OTLP, compact JSONL, and compact
TOON output as sensitive as the original state directory; redirect or transmit
it only to trusted destinations. Compact lite mode exposes tool names, arguments,
commands, statuses, output sizes, and up to 4 KiB of unredacted normalized output
per terminal call, including bounded rendered error details. Full mode exposes
complete normalized output and rendered error details.
The exporter opens only existing state and never repairs or writes it. Only writer-lock contention selects checkpoint mode. Inactive journals acquire their shared locks before opening the journal and selecting EOF; lock-held journals retain one exact opened journal identity and select a finite prefix through the existing bound checkpoint. A small bounded retry tolerates only an atomic journal/checkpoint replacement observation race. Bounded positional reads and strict replay validate every selected prefix, descendant discovery is rechecked after capture, and all failures occur before stdout. Capture never waits for lock release or includes records committed after its selected cuts. A snapshot retains one journal file descriptor per included agent plus lock descriptors for inactive agents until private staging finishes. A very large selected workflow can exhaust process file descriptors and fail before output.
agent-performance-jsonl is the preferred content-free audit projection, but it
still exposes identifiers, models, timing, usage/cost, membership, and work
patterns. Keep it private even though it omits prompt, tool, response, error, and
provider-body content.
Descendant discovery accepts only a valid matching sequence-zero
AgentStarted.creator record as an authenticated edge. Missing, unreadable,
unsupported, or invalid candidate first records establish no edge and remain
outside the rooted workflow. Every selected prefix still requires strict
semantic validation, so unsupported or corrupt content inside that prefix fails
before output. Keep agent_trace_descendants_ignore_unrelated_legacy_creation_record
and agent_trace_descendants_reject_reachable_corrupt_journal as regression
safeguards when this boundary changes.
Private staging is an anonymous process-owned file with no pathname to survive termination and is never durable trace state. Validation and projection stream journal records. OTLP keeps every correlated occurrence in anonymous staging, including auxiliary occurrences whose offsets are not retained; heap correlation state retains compact offsets and identifiers, one per unique typed operation key.
Heap use is proportional to unique operation-ID count and bytes in the largest included journal; IDs have no separate cap beyond the record framing limit. A pathological journal can therefore exhaust exporter process memory. The exporter never truncates accepted records.
Compact projections materialize selected source events and projected records in memory. Lite bounds each semantic text and terminal output projection to 4 KiB, but declaration arguments and retained selected events remain bounded only by journal framing. Full mode retains complete semantic text and rendered output. Heap can therefore grow with selected journal payload bytes and projected record bytes. TOON escapes multiline strings and must never print payload C0/C1 controls raw.
The performance projection emits no prompt, tool, response, or error bodies, but its agent/prompt/model IDs, descendant membership, timing, token/cache counts, estimated cost, call/observation/turn/transaction identities, and work patterns remain sensitive metadata. It streams each event into a compact content-free classification: per-occurrence identity/timestamp, declaration and canonical terminal call identities, typed tool/wait/activation/outer-turn boundaries, and standalone accounting counters. It drops provider payloads, tool names and arguments/results, errors, model parameters, endpoint/backend/rate metadata, and cumulative usage snapshots. Heap remains proportional to selected occurrence and correlation cardinality plus retained identifier bytes, not selected journal payload bytes. Changes must recheck zero and decreasing wall timestamps, duplicate terminals, checked aggregate overflow, zero/fractional cache-ratio boundaries, typed reference integrity, and structural output-field privacy.
One pathological frame-valid selected journal can exhaust memory or temporary storage. Projection failure remains before stdout, and the final anonymous file remains delete-on-close.
Changes to compact projection must re-check zero/many-call framing, arbitrary strings and controls, strict TOON semantic round trips, exact tagged-CBOR and float-bit reconstruction, multiline full output, and parity with independently parsed JSONL items across all semantic families.
Revisit this boundary before adding user-selected output files, redaction modes, provider HTTP-body or streaming-delta capture, new timing authority, or any persisted trace state.
ProviderStopReason::Length is never semantic success. Tau permits at most one
successor in an ordinary user outer turn, and only when the accepted response
contains only reasoning the selected adapter can replay exactly. Chat Completions
requires non-empty full reasoning; generic public Responses requires at least one
opaque reasoning item with no encrypted_content, an absent or empty summary,
and a non-empty content array consisting only of string reasoning_text parts.
It permits only the matching non-empty full display companion. Summary-bearing,
encrypted, empty, and mixed reasoning cannot acquire continuation authority.
Private ChatGPT/Codex Responses does not acquire this authority.
The durable authority chain is
provider.response_finished(plan) → exact trusted internal steer → matching
inference owner → agent.prompt_started. Each append must complete before its
successor begins. After the owner commits, restart never reconstructs or resends
the provider request. A successor terminal may repair one missing settled
outer-turn finish only when its validated outer_turn_finish_owed bit says so.
Cancellation, branch-lineage loss, and missing or changed logical model routes fail closed. They neither redirect retained reasoning nor reset the one-shot budget. Branch loss closes the dormant original lineage with its exact steer, owner, pre-start failure, and owed finish; it never dispatches the successor or folds those facts into the selected sibling. A reserved successor's reactive context recovery carries only recovery authority, while its exact transaction-owned descendant retains the spent output-length lineage. This dormant synthetic failure is authorized only before the reserved successor's durable prompt-start. After prompt-start, branch movement cannot mint a competing failure; the already-dispatched owner remains the sole terminal authority.
Each accepted response keeps its own usage, cost increment, and harness-derived finite provider attempt, including the incomplete source and successor. Cold recovery may repair the plan-to-steer and steer-to-owner cuts, reconstruct sticky terminal-incomplete attempt state, and apply the separately stamped terminal-to-finish cut above. Malformed, duplicate, or unrelated lineage facts block without dispatch. Revisit this boundary before adding provider-native continuation, more than one successor, unchanged-request retry, or any broader replay capability.
std-swarm is a configured local extension that connects to one
cryptographically pinned Iroh endpoint. The configured credential is sensitive;
Tau supplies it only through the declared Configure secret and the extension
must not log it. Relay and direct addresses are reachability hints and do not
weaken endpoint identity verification.
Remote prompts and blocker answers reach agents only through Tau's canonical
internal-prompt path. The extension retains command deduplication, blocker
history, unacknowledged updates, and replaceable current task metadata in process
memory under configured bounds. Task metadata accepts at most 4,096 current
entries and 8 MiB of aggregate canonical task-ID, title, and description bytes;
the authenticated Swarm peer independently enforces the same ceilings.
Task IDs have no ownership model. Ordinary Tau role tool policy is the whole
grant boundary: any loaded agent granted task_info may replace metadata for
any valid task ID in its current session. Revisit this authority boundary if
task ownership or narrower grants are introduced.
Tau Swarm binds commands and active lifecycle state to a collision-resistant
extension-process incarnation. Ordinary reconnects retain the process command
table; a replacement process declares a fresh incarnation,
so the server fences ambiguous old commands and supersedes old active lifecycle
state. A peer that sends many unique, otherwise valid commands can fill the
no-eviction command table and deny later remote commands until process restart. Large
configured bounds can exhaust extension memory; they are operator trust and
capacity choices rather than untrusted local-IPC hardening boundaries.
Ordinary Iroh reconnect retains current task metadata. An extension-process restart loses it; the fresh process's complete snapshot converges the peer by omitting the old incarnation's metadata. Revisit this accepted non-durability if task metadata gains journaling, persistence, or different session/process lifecycle ownership.
Each Swarm worker generation owns publication authority. Worker return or panic
unwind retires that authority synchronously before any optional terminal
notice; panic-abort builds terminate the extension process instead.
task_info, task_blocker add/cancel, and task_update serialize their full admission and mutation
sections against retirement; after retirement they fail before changing
process-memory state or reporting success. Revisit this synchronization when
changing worker lifecycle, mutating tool paths, health ownership, or terminal
notice ordering. Deterministic worker-return, panic, mutation-ordering,
tool-authority, saturation, and cleanup regressions protect this boundary.
Compact lite traces expose up to 4 KiB each of unredacted assistant prose, displayable reasoning, explicit sent/received message text, and tool output, in addition to complete tool arguments. Full mode exposes complete text and output. Reasoning and messages can contain secrets, private communications, user data, or model-derived sensitive content; paired directional records can duplicate the same sensitive body across included journals. Absolute timestamps, agent/session/message/prompt IDs, membership, and activity patterns are sensitive metadata. Cross-agent wall-clock order is not causality.
Compact identity, sequence, and timestamp fields remain facts of the captured
journals when those journals move between sessions; export never rebinds them to
the containing session. Original-host wall-clock samples can regress or differ
across hosts and do not establish delivery order, latency, or happens-before.
Tau keeps extension credentials in harness-mediated configured-instance Secret
scope. Supervised extensions run in mandatory fail-closed Linux user and mount
namespaces that hide the whole Tau secret root. Only configured Provider
instances receive credential-free provider settings from a bounded disjoint union
of XDG config and state. Config leaf symlinks may target bounded regular
Nix/dotfiles deployment files outside the canonical config instance root; broken,
non-regular, invalidly named, and oversized profiles fail closed. Mutable state
retains no-symlink restrictions. Persistent instances get an
ephemeral read-only materialization of the exact Configure.settings_files
snapshot, while memory-only previews get only that immutable snapshot. Tool instances receive
neither. This is defense in depth for trusted configured same-UID executables, not containment
from malicious same-UID code or misuse of credentials returned to an authorized
extension. Secret payloads remain absent from logs, events, journals, generic
debug output, and errors. See
SPEC-extension-secret-storage.
The separately installed tau-ext-telegram executable receives gateway-client
credentials through the same configured-instance secret mechanism. Its
separately installed tau-telegram-gateway peer uses that key for mutual local
protocol authentication. This removes ambient authority from socket-only peers,
but does not prevent malicious same-UID code from extracting an authorized
extension's in-memory key through /proc, ptrace, or direct memory access.
Named-secret environment discovery matches the exact TAU_SECRET_ prefix in
the OS-native key representation and ignores unrelated raw entries. A matching
suffix or value that cannot enter the UTF-8 schema returns a typed,
value-redacted error. Harness source capture removes every matching native key
before returning either its snapshot or a source error; provider setup retains
the caller's entries. Every production supervised spawn and respawn
independently removes matching native keys from the child environment.
Changes to that predicate, disposition, spawn ordering, or error formatting
must recheck the Unix raw-entry regressions in tau-config secret-source tests
and the tau-harness extension and lifecycle tests.
The default-enabled, policy-authorized self_info tool exposes the calling
model agent's agent/session identifiers, exact prompt-owned model and effort,
call-time work status, and—only in durable mode—the local session path. It also
exposes current provider model metadata, the latest selected-branch
model-qualified provider input/cache observation, effective role compaction
configuration, and the validated transient quota snapshot for the prompt
model's provider when that provider has reported quota capability. Context
counts are explicitly the latest provider observation, not a reconstructed
current transcript size. Quota fields contain provider-normalized pool/window
identifiers, percentages, timestamps/ages, and model applicability, but no
credentials, account identifiers, plan, balance, raw provider prose, or pacing
decision.
The line-oriented response enters the transcript as an ordinary tool result and is therefore persisted with that agent's normal durable history even though provider quota current state is otherwise transient and excluded from semantic journals. Configured extensions cannot invoke the tool directly; the harness requires a model-owned call and correlates it with the invoking prompt-start fact. The tool reads only the calling agent's context baseline and prompt model, plus harness-wide provider metadata and quota for that model's provider; it does not grant cross-agent transcript access or expose another provider's quota.
Header values use a line-safe byte encoding: printable ASCII remains readable,
backslash is doubled, and controls, non-ASCII bytes, and invalid path bytes use
\xNN. This prevents model names or local paths from injecting apparent
headers while preserving exact path bytes. Revisit this disclosure boundary and
its focused regressions when changing tool policy, prompt/call correlation,
storage modes, exposed fields, or the header encoding.
Startup, setup inspection, and development-copy paths share the 4,096-profile-per-instance, 1-MiB-per-profile, and per-instance merged snapshot byte limits. They validate the opened descriptor, using nonblocking Unix opens so a raced special-file target cannot stall discovery.
Named provider API-key bindings use one closed parser shared by setup, harness,
and provider runtime. The harness consumes the configured declaration without
forwarding its value in Configure.secrets, refreshes only canonical API-key
records, and replaces unavailable bindings with empty typed records plus
value-redacted warnings. Cross-layer duplicates fail rather than overriding or
coalescing. Tau never locks an external config or symlink-target inode; a
per-instance private-state providers lock precedes the
Secret-scope lock in setup, removal, and startup, binding source selection and
credential publication to the exact retained Configure snapshot. Typed
Tau-component identity, rather than executable argv resemblance, grants this
authority. Source read/decoding failures preserve older records and fail or skip
the provider according to its required policy. Memory-only startup forwards no
built-in provider declaration values.
Model-facing generic user-payload framing follows SPEC-exact-sentinel-prompt-envelopes; payload-local XML-like tags do not establish Tau provenance.