fibers.dev
Join the waitlist

What is captured

Hook by hook, what fires, what leaves the machine, and what never does.

Capture is deterministic. The runtime fires a hook, the hook runs the CLI once, the CLI emits at most one small observation and exits 0. No agent is prompted to do bookkeeping and no tokens are spent on it. State observations (registered, stop, compact, notification, answered) are spooled locally when the service is unreachable and replayed later. Heartbeats are best effort and never replayed, since stale liveness would be a lie. Most tool-call hooks return before the CLI even starts. A session is never blocked and never broken by the service being down.

The rule for what travels

Every field on the wire belongs to one of three classes, and the schema says which.

Class What it is Where it may appear
Structural Enums, numbers, hashes, ids, timestamps, branch names, the worktree’s absolute path Everywhere. This is almost all of what hooks send.
Authored Prose a person or an agent composed on purpose: the --note on a claim or log, a message sent with fibers msg, and one label, the session title The coordination verbs you type, plus the title field on registered and stop. Checked by a local secret scan before it leaves.
Local Raw text, paths, tool input and output from the runtime Read in-process by the CLI and never serialised to the wire.

So a hook payload carries two things that are not enums or hashes. The absolute path of the worktree, because machine plus path is the session’s identity. And the session title where the runtime has one: it is read from the local session index, scanned for secrets on your machine, and dropped if the scan finds any. Everything else, the runtime’s notification message, your transcript path, the tool input and output, is classified or fingerprinted locally and only the resulting enum or hash travels. Which modules are on is a fact about your machine and is never sent.

Hook by hook

Runtime event What the CLI emits What stays local
SessionStart registered: opens the session and refreshes the worktree row. Travels: machine, worktree path, session id, the source enum, and the session title if one exists. The response may carry waiting messages, which the CLI prints into the session. Everything else on stdin.
SubagentStart registered with the parent session id, so sub-agent work is attributed rather than lost. The child’s title is its agent type as the runtime names it. Everything else on stdin.
Stop, SubagentStop stop, refreshing the session title each turn. “Waiting for you” is inferred from a stop plus silence plus age, and rendered as an inference. A crashed terminal never sends it, which is why nothing asserts liveness. The turn’s content.
SessionEnd stop with an end-reason enum. Its presence is what ends the session row on the service. As above.
PreCompact compact with a trigger enum, manual or auto. A mid-session moment, not an end. The context being compacted.
Notification notification with a reason classified in-process to permission_request, idle or unknown. The notification text itself.
PreToolUse notification with reason question, only when the tool is the ask-the-user tool. Every other tool is nothing. A cheap shell sieve in the launcher returns before the CLI even starts for most calls. The tool input.
PostToolUse A heartbeat, throttled to one per five minutes per session, so an hours-long turn reads as active. When the tool was the ask-the-user tool, answered instead, never throttled, which clears the needs-you state. When a shell tool reported an error inside an otherwise successful result that the fingerprinter recognises, a friction record to the local store. Tool output, the error text, the fingerprinted excerpt.
PostToolUseFailure Nothing on the wire. The failure is fingerprinted and a friction record goes to the local store. The whole payload.
StopFailure Nothing on the wire. Fingerprinted into the local friction store like a tool failure. The whole payload.
UserPromptSubmit Nothing on the wire. Off unless this machine opts in with fibers features on asides; then a message you typed while the agent was working is appended to a local spool, with the agent’s last prose beside it, and a turn-start prompt is nothing. The launcher starts the CLI only for an opted-in machine and a prompt that is not a system envelope or a slash command. The whole payload, the prompt included.

What the coordination verbs send

claim, log, release, bump, msg and the work and decisions verbs are typed by a person or an agent on purpose. They carry the ref, the kind and, where you give one, the note. The note is authored text and passes the local secret scan first. A note with no value, or with another flag where its value should be, is refused rather than recorded empty.

Friction

Repeated failures are counted on your machine. fibers friction ls reads the local store and sends nothing. The only friction facts that leave are a hash of the signature and, when you record one, the ref of the PR or work item that fixes it.

Where the schemas are

The wire schemas are JSON Schema files in the repository under docs/spec/, one per payload kind, with the content class annotated on every non-structural field. Golden tests assert that each fixture payload matches its schema, so the allowlist in the schema is the thing that decides, not the prose on this page.