Skip to content
All posts
Agents3 min read

The Question State Machine

How pending, answered, expired, and cancelled states keep the Question flow safe and understandable.

The Question primitive only works if its state machine is strict.

Humans will tap stale notifications. Agents will retry requests. Mobile devices will deliver duplicate actions. Expiry sweeps may run near the same time as an answer. A room-scope question might receive multiple taps in the same second.

The protocol needs to turn that messy reality into one clear outcome.

The Four States

The full state machine is:

pending -> answered
pending -> expired
pending -> cancelled

The terminal states are:

answered
expired
cancelled

There is no transition out of a terminal state. No endpoint should resurrect a question, change an answer, or convert an expired question into an answered one after the deadline.

Pending

pending means the question is open.

The system has persisted it, enqueued or delivered the Ping, and is waiting for a valid answer, cancellation, or expiry. During pending, the app can show answer buttons, the notification can show actions, and the asker can long-poll the wait endpoint.

Pending is the only state where an answer is accepted.

Answered

answered means one valid responder chose one valid option.

For direct scope, the responder must be the target user. For room scope, the responder must be an eligible room member. For v1, the first valid room answer wins.

The server must record the chosen option, responder identity, and timestamp atomically. The responder identity must come from authentication, never from the request body.

Expired

expired means the deadline passed with no valid answer.

This is a real result, not an absence of result. The asker needs to distinguish "human chose no" from "human did not answer." Those outcomes drive different workflows.

An expiry sweep should safely flip overdue pending rows to expired. It should be idempotent and safe to run repeatedly.

Cancelled

cancelled means the asker withdrew the question before it was answered or expired.

Cancellation is useful when the workflow changes. Maybe the deploy was cancelled from another system. Maybe the agent found a safer path. Maybe the question was sent to the wrong room.

After cancellation, notification actions become no-ops and waiters receive a cancelled result.

Race Handling

The hard part is not the diagram. It is concurrency.

The answer operation should be an atomic conditional update:

update questions
set state = 'answered', answer = ...
where id = ? and state = 'pending'

Only one caller can win. Everyone else receives the already-resolved state.

Expiry and cancellation use the same pattern. They only transition rows that are still pending. If an answer committed first, the sweep skips it. If cancellation committed first, the answer path returns cancelled.

Human Experience

Race handling should not punish the human.

If a person taps a stale notification, they should see that the question was already answered, expired, or cancelled. That is not an error in the human sense. It is just the state of the workflow.

The app should update the in-app cell and, where possible, the notification state so the stale action does not keep inviting taps.

Agent Experience

The agent should get the same terminal envelope from every result path.

Long-poll wait, fetch, list, and outgoing-webhook events should all represent the same final state. That consistency lets SDKs stay simple.

The Rule

Every Question has exactly one terminal story.

It was answered by this responder with this option, expired without an answer, or was cancelled by the asker. The protocol should make that story impossible to confuse.

Mahdi Salmanzade

The Ping that cuts through.

Keep reading

Agents

The Full Potential of the Question Protocol

One primitive, a question a human answers with a tap, covers deploy gates, environment routing, team decisions, and typed replies. Here is everything it unlocks, and how to reach it from the SDK, the CLI, and MCP.

5 min read
Product

PingRoom v1.2: Questions Are Here

Our biggest update yet. Connected agents and integrations can now ask questions in your rooms, answer from the lock screen with one tap, first response wins. Plus an interactive Watch widget, room folders, free templates, every sound free, link Pings, and more.

2 min read