OSC 7501: The Agent Status Protocol Your Fleet Dashboard Should Consume

Claude Code 2.1.295 now speaks the OSC 7501 agent status protocol. Stop scraping spinner titles: consume the states, and fail closed when a guard hook breaks.

A Claude Code session declares its own state over the pty while a fail-closed guard hook holds actions whose enforcement cannot run, with illustrative report shapes and operator policy labeled as such.A Claude Code session declares its own state over the pty while a fail-closed guard hook holds actions whose enforcement cannot run, with illustrative report shapes and operator policy labeled as such.
Original illustration: OSC 7501 reports travel on the pty to a terminal consumer that routes working, blocked and done states to operator actions, while onFailure block holds an action whose guard cannot start, times out or exits unexpectedly. Example report keys are illustrative specification shapes, and the restore-and-reassess sequence is operator policy, not documented behavior. Attribution: Claude Code v2.1.295 release notes and the OSC 7501 specification.

Claude Code v2.1.295, released October 8, 2026, adds an agent status protocol to the Claude Code harness itself. The release adds Program Status Protocol (OSC 7501) support, so terminals that implement it can show whether Claude Code is working, waiting on you, or done, and it adds the onFailure block failure policy for command and HTTP hooks, so a guard that cannot start, times out, or exits with an unexpected code blocks the action instead of letting it through. Those two lines describe a shift operators can verify directly: state declared by the program that knows it, and enforcement that fails closed instead of failing open.

Treat this guide as an adoption runbook rather than a release summary. It walks through inventorying the heuristics your dashboard trusts today, commissioning a terminal consumer for the new signal, routing waiting-on-you states to accountable owners, testing the fail-closed hook policy, and keeping a fallback observation path during the upgrade window. A release note establishes that a feature exists. Only your own recorded observations establish that your launcher, relay and dashboard handle it correctly.

What shipped, and what the sources establish

The v2.1.295 release notes list the hook failure policy first and OSC 7501 support second, on an immutable release page dated 08 Oct 19:48. The official changelog records the same two additions under its 2.1.295 heading, which now sits beneath a newer 2.1.296 section; the releases index confirms that ordering and the October 8 date beside the newer entry. For the hook option, the documented behavior is narrow and useful: a command or HTTP hook that cannot start, times out, or exits with an unexpected code blocks the action instead of letting it through, once you configure the policy. That is a configuration choice per guard, not a claim that every existing hook silently became an enforcing boundary. The same release also adds a line on stderr, when stderr is a terminal, that says what a claude -p run is waiting for when it stays open after its last turn; for headless fleets that line is a useful transitional signal beside the protocol, and it belongs in your baseline capture.

GitHub release page for Claude Code v2.1.295 by ashwin-ant showing the What's changed list headed by the onFailure block and OSC 7501 entries.
GitHub (anthropics/claude-code): the immutable v2.1.295 release page, with Program Status Protocol (OSC 7501) support and onFailure: "block" for command and HTTP hooks at the top of the What's changed section, released 08 Oct. · Original source

The capture doubles as a citation template for your change reviews: the immutable badge, the tag name and the commit hash beside it are the three details to record, because a rolling feed that already lists newer releases above this entry will not preserve the dated wording you relied on.

The protocol itself predates the release. The OSC 7501 specification defines the states idle, working, done, blocked and error plus a clear action, requires the state key, replaces each record completely on every report, and ties record lifetimes to events the terminal already sees: process exit and a new shell prompt drop working and blocked records while done and error survive. It also caps report sizes, requires terminals to reject decoded text containing control characters, and treats everything in a report as untrusted input from a program that already controls the screen. Mitchell Hashimoto’s October 6, 2026 introduction explains the motivation and the two alternatives operators use today: screen and window-title heuristics, or inbox-specific socket APIs.

Inventory every heuristic your dashboard relies on today

Start from the dashboard you actually operate, not from the protocol. List every rule that converts a spinner glyph, a window title, a quiet-output timer, a process state or a desktop notification into a fleet status. For each rule record the owner, the session classes it covers, and the operator consequence when it fires. A cosmetic badge and a production wake-up alert need different migration evidence even when they read the same observation.

  1. Record the installed build. Run the documented version check in each managed environment, not only on your laptop; the Claude Code overview states that a working installation prints a version number. Save the output next to the launcher and terminal path used for that session.
  2. Trace the transport. Note which component owns the pty, where output is consumed, and which component currently classifies activity. A release that supports a terminal protocol does not prove that a particular relay or multiplexer preserves the sequences.
  3. Map consequences. For each rule, name the downstream badge, alert, approval queue or automation, and assign an owner who can confirm the intended response survives a signal change.
  4. Set a baseline. In a disposable session, capture ordinary work, a deliberate request for attention, and completion. Keep the observation and the operator outcome together so old and new paths can be compared.
claude --version

Use a small inventory table rather than a speculative compatibility claim:

Inventory field Evidence to record Decision it supports
Installed version Actual version output from the managed environment Which documented release to investigate
Launch path Terminal, relay and dashboard components Where a declared signal could be lost
Current detector Rule name, owner, covered session class What stays available during the trial
Operator consequence Badge, page, approval or escalation How much verification the change needs
Trial observation Controlled scenario and resulting status Whether this exact path is ready

Hashimoto documents one inbox implementation carrying sixteen detection rules for Claude Code and ten changes to that detection file in three months, including a spinner glyph change at version 2.1.228. Those figures describe maintenance work under heuristics; they are not a measured cost comparison against protocol integration, and this guide makes no such comparison. Your inventory should reveal which brittle observations create real operator burden, so you replace those first and leave stable detectors alone until the replacement proves itself. Keep the stall flags and keepalive guide beside this inventory: transport and liveness checks remain necessary even after a program starts declaring state. Record the inventory where reviewers can read it, because the migration argument will be made twice: once before the trial and once before retirement.

Consume OSC 7501 as a first-class signal

Choose the component that already owns the relevant terminal stream and ask its maintainer three questions: does it implement an OSC 7501 consumer, which installed version provides it, and how does it expose records to your dashboard? The specification’s feature detection query, an OSC 7501 report whose body is a question mark, is the only authoritative support check; a missing terminfo capability proves nothing because entries go stale across ssh and multiplexers. Prefer a consumer whose behavior has been reviewed against the complete specification, including malformed pairs, unknown keys, repeated keys, base64 decoding and record replacement. The introductory post explains motivation and basic states; it is not enough detail to publish a production parser here, and this guide deliberately does not invent one.

Run the migration observably. Add the declared signal beside the existing detector before any consequential decision depends on it, and label every displayed status with its origin and session identity. Declared activity and inferred activity answer different questions and fail in different ways.

  1. Choose one trial path. Fix the launcher, installed version, terminal consumer and disposable workload in writing so a successful test is reproducible.
  2. Exercise ordinary transitions. Observe work starting, a deliberate request for attention, and completion; record what the program emits, what the consumer exposes and what the dashboard shows.
  3. Test missing observation. Restart or disconnect the consumer in the test environment and verify the dashboard marks the observation unavailable instead of presenting a stale status as fresh confirmation.
  4. Retain provenance. Store the claimed state separately from observation timestamps, session ownership and recorded outcome. A reassuring label is never permission to execute another action.

Commission conformance evidence from the consumer maintainer before the path drives alerts or approvals:

Consumer test area Evidence to request before adoption
Sequence framing Fixtures for complete, interrupted and unsupported reports on the actual transport
Message decoding Tests for invalid base64 and control characters, plus safe display behavior
State validation Defined handling for missing or unknown states without manufacturing a reassuring status
Record handling Tests for replacement, clear, child records and the documented lifetimes
Resource bounds Recorded limits and tests that oversized reports cannot exhaust the consumer
Observation loss A dashboard response that distinguishes unavailable observation from current activity

Fleets that run several things at once can use the specification’s hierarchical record ids: a root record can say working while a child record for one region says blocked waiting on approval, and both are true at the same time. Ask your consumer how it surfaces parent and child records before you design dashboard cards around them, and keep the deploy-style example in the introduction as illustration rather than as a promise about Claude Code’s own record layout.

Timeline of four dated milestones from the OSC 7501 specification's first draft to Claude Code v2.1.295 shipping support.Timeline of four dated milestones from the OSC 7501 specification's first draft to Claude Code v2.1.295 shipping support.
Original chart: dated sequence recorded in the OSC 7501 revision history (2026-09-28, 2026-10-06, 2026-10-07) ending at the immutable v2.1.295 release page dated 08 Oct 2026. No cost comparison is claimed.

Place your own verification dates beside these four checkpoints in the trial record: a milestone you have not observed in your own launcher, consumer and dashboard remains unverified for your fleet, no matter how settled the upstream dates look on the page above.

Put the resulting records where an operator can inspect them. A multi-agent command center works only if it preserves the distinction between observed activity, required attention and verified outcome, and makes a missing observation obvious enough that someone investigates it.

Promote waiting-on-you to a pageable event

Decide which requests deserve immediate interruption before you enable any notification. The specification’s blocked state carries a kind: permission means approval to do something, question means the user must type an answer, and auth means a login, token or credential. Routing all three to one generic toast wastes exactly the meaning the protocol adds.

Observed condition Suggested owner Required next step
blocked, kind permission Person authorized for that action Inspect the action and record an explicit decision
blocked, kind question Task owner Read the question with its task context and answer
blocked, kind auth Account or environment owner Restore access through the approved login process
done Reviewer or task owner Inspect the result and record whether it meets the task
error Task owner or on-call operator Read the failure evidence and choose a recovery action
Observation unavailable Terminal or dashboard operator Restore the observation path and reassess the session

This matrix is an operating recommendation, not a claim that the protocol implements queues or escalation. Attach enough context to make each notification actionable: session identifier, task owner, repository or workspace, first and latest observation times, and a link to the relevant interaction. Treat program-supplied messages as untrusted display text: never execute their content, never convert one into an approval, and never treat a claimed application name as proof of sender. The specification also advises terminals to rate-limit anything a record causes outside the terminal, such as notifications or sounds; mirror that advice in your paging policy so one flapping session cannot flood the on-call channel.

  1. Assign queue ownership. Name the person or team accountable for each category and document the handoff when they are unavailable.
  2. Set explicit response targets. Choose targets by consequence and staffing, and review overdue requests in the operator queue rather than letting them dissolve behind a changing badge.
  3. Separate acknowledgement from resolution. Recording who saw a notification is not recording what resolved it; capture the answer, the restored access or the approval decision in the surrounding workflow.
  4. Review noisy cases. When a notification repeatedly arrives with too little context, fix the presentation or the task setup before widening its audience.

Completion deserves the same discipline. A done record survives process exit and the next shell prompt by design, which makes it a durable prompt to review output; it is not a certificate that the work meets acceptance criteria. The approval queue hygiene guide covers the ownership side of this problem: keep protocol state handling inside the consumer and human decisions inside the approval workflow.

Configure hooks that fail closed

Status reporting and action enforcement need separate acceptance criteria. OSC 7501 surfaces what a program declares; a guard decides whether a particular action may proceed. Clear status reporting cannot compensate for an unavailable enforcement check, and a successful guard call does not prove the task completed.

Inventory the checks you intend to enforce: each protected action, the decision the guard returns, and who owns its availability. Then obtain the official configuration reference for your installed release and verify the relevant event and hook type before editing live configuration. This guide supplies no unverified nesting, timeout defaults or lifecycle exceptions; the checklist below is the commissioning requirement for that configuration review.

  1. Separate enforcement from advice. A formatter, telemetry emitter or optional notification must not become an authorization boundary by accident. Identify which checks actually protect an action.
  2. Enable the documented failure policy deliberately. Apply the onFailure block policy to the intended command or HTTP guard only after checking the applicable configuration contract, and record the reviewed configuration with its version.
  3. Test an affirmative decision. In a disposable environment confirm the protected action executes when the guard explicitly allows it, and save the decision and action evidence.
  4. Test a refusal. Confirm the action does not execute when the guard denies it; a visible badge or log line is insufficient if execution continues.
  5. Test unavailability. Exercise a guard that cannot start, a timeout, and an unexpected exit where applicable; confirm the chosen policy holds the action and that the operator receives enough information to recover.
  6. Document restoration. Record who restores the guard, how the held action is reassessed, and which fresh decision is required before it may proceed.

Where a guard protects a consequential action, treat an unavailable guard as an incident, not as an inconvenience: the held action is evidence that enforcement worked as configured.

Flow diagram with three guard outcomes: affirmative allow proceeds, explicit deny refuses, and unavailable enforcement holds the action under onFailure block, with restore and reassess labeled as operator policy.Flow diagram with three guard outcomes: affirmative allow proceeds, explicit deny refuses, and unavailable enforcement holds the action under onFailure block, with restore and reassess labeled as operator policy.
Original diagram of the three-branch guard contract operators must test. The failure branch records the documented onFailure block behavior from the v2.1.295 release notes; the restore-and-reassess sequence beneath it is recommended operator policy, not a documented lifecycle.

Test the branches in the order drawn, and record the third branch with extra care: the release notes document that a failed guard blocks the action, while what happens to the held action afterwards is your team’s policy to define, document and rehearse before any consequential workflow depends on it.

Use the pre-action gates guide to review where enforcement actually occurs, check hook persistence risks when deciding who may change a guard, and keep those controls aligned with your permission-mode policy so a status integration cannot quietly become a new authority path.

Keep a fallback heuristic path during the upgrade window

Publish a readiness matrix for the installed combinations you have actually checked, classifying each launcher and consumer path as verified, trial or unverified. Unknown support stays unknown until documentation and a controlled observation say otherwise; never mark an entire provider family unsupported because one version or launch path lacks evidence.

  1. Roll out in rings. Disposable sessions first, then a small group of ordinary tasks, then consequential workflows after the signal and guard tests pass.
  2. Keep independent observation available. Retain the existing detector for unverified paths and for diagnosing the new integration, and show its origin so operators know whether a status is declared or inferred.
  3. Investigate disagreements. Compare program, transport, consumer and heuristic evidence; either path can be wrong, and a disagreement should open an investigation record rather than automatically condemning the old rule.
  4. Define rollback ownership. Name who can restore the previous observation path and document how the dashboard represents incomplete evidence during that change.
  5. Retire rules selectively. Remove a heuristic only after the replacement passes the team’s acceptance cases for the specific path it covered, keeping the retirement reason with the inventory.

Measure outcomes you can observe: missed attention requests, unowned queue entries, inconsistent session mapping, stale observations, and guard tests that let an action execute unexpectedly. Set the review period and success criteria before the trial begins, and avoid presenting an illustrative checklist as a benchmark. The cluster mode versus stall flags guide helps keep orchestration choices distinct from activity detection in your rollout notes.

The decision to make this week

Choose one managed Claude Code path and commission a bounded adoption trial: recorded version, verified terminal consumer, operator response matrix, and controlled guard outcomes including the unavailable-guard case. Keep unverified combinations visible and leave the current detector in place until the replacement earns its place. Write the trial’s success criteria before the first session runs, so the decision to expand rests on recorded outcomes rather than on momentum. The durable change is fewer ambiguous handoffs backed by inspectable evidence, not a dashboard that merely displays a newer label.

FAQ

Does the release make every fleet session protocol-aware?

No. The release establishes support in one Claude Code version. Your installed build, launcher, terminal path and consumer each still need verification. Record a successful observation for every managed combination, keep unknown paths marked unverified, and retain the existing detector while the replacement earns its place.

Can a done status replace result review?

A done status is a useful prompt to inspect output, not a certificate of correctness. Keep the result artifact, the verification outcome and the accountable reviewer decision beside the activity record. If the result falls short, open an explicit follow-up instead of treating a quiet terminal as proof.

What should happen when an enforcing guard is unavailable?

For a guard configured with the documented blocking failure policy, unavailable enforcement should hold the protected action. Exercise the cannot-start, timeout and unexpected-exit cases in a disposable environment, name who restores the guard, and require a fresh decision on the held action before anything executes.

Sources

  1. Claude Code v2.1.295 release notes — dated release evidence for the hook failure policy and OSC 7501 support.
  2. Claude Code official changelog — the versioned 2.1.295 entries beneath the newer 2.1.296 section.
  3. OSC 7501 Program Status Protocol specification — states, record semantics, lifetimes, limits, feature detection and security rules.
  4. Mitchell Hashimoto’s protocol introduction — motivation, heuristic and socket alternatives, dated October 6, 2026.
  5. Claude Code overview documentation — the documented version command and general hook context.
  6. Claude Code releases index — the release listing confirming the October 8 date beside newer releases.
YOU'RE THROUGH THIS ONE.

Keep connecting the dots.

Back to the library