0036 — Agent-asked detection sources
0036 — Agent-asked detection sources
TL;DR. AgentEvent::Asked remains a server-observed event, but passive
per-agent guessing is not the authority. The shipped phux-ask terminal-title
sentinel is the v1 interoperable trigger; the next authority is an opt-in
agent hook contract that writes the same clean Asked payload. Screen-scrape
manifests stay a fallback only after a phux-owned empirical corpus exists.
Status: Accepted Date: 2026-06-22
Context
ADR-0035 allocated the asked event on the existing EVENT stream and
shipped a clean-room v1 trigger: an agent sets the terminal title to
phux-ask[<id>]:<question>?s=opt1|opt2. The server sees OSC 0 / OSC 2 through
libghostty-vt, parses that sentinel, coalesces repeated markers, and emits
AgentEvent::Asked.
That gets projection consumers unstuck, but it does not answer the wider
question in phux-2sl6.2: should phux infer “agent is asking” from each
agent’s raw screen, rely on an explicit integration contract, or combine both?
The clean-room boundary is strict: external projects can inspire patterns, but phux must not copy AGPL manifests, hook scripts, regexes, or source. The detector contract has to be authored here.
The local spike found claude, codex, and pi installed and
version-probable on the development host, but did not claim a complete
blocked-state corpus. Launching those CLIs into real account flows is
environment- and credential-sensitive; reproducible capture is follow-up work,
not an ADR blocker.
Decision
Use a layered source model:
- Authoritative: opt-in agent hook contract. A first-party or configured
agent integration should report a pending question directly to phux using
the same fields as
AgentEvent::Asked:id,question,suggestions, and optionalelapsed_seconds. The hook owns identity and lifecycle; phux owns validation, coalescing, and event emission. - Interoperable v1:
phux-asktitle sentinel. Keep the shipped title sentinel as the lowest-friction path for any process that can emit OSC 0 / OSC 2. It is explicit, inspectable, and already covered by server andphux watch --jsontests. - Fallback: phux-owned screen evidence manifests. A passive detector may
exist later, but only from a phux-authored corpus captured from real
claude,codex,pi, and other agents. Its role is advisory fallback when hooks and sentinels are absent; it must never outrank an explicit hook. - Not a wire fork. All sources converge on the existing
Askedevent. No new event kind, no tag renumbering, and no protocol minor bump are needed for source changes that preserve the payload.
Consequences
- Projection consumers get one stable event regardless of how the server detected it.
- Plugin and config work can add agent integrations without ratatui or consumer-specific code entering the core substrate.
- Passive detection becomes an evidence problem, not a copied-manifest problem. A detector PR must include the captured local/CI corpus it claims to support.
- If libghostty-vt later exposes OSC 9 / OSC 777 or richer prompt state, that can become another source feeding the same event, below hooks and alongside explicit sentinels.
Follow-up Work
- Define the opt-in hook payload and local command/API surface for agent integrations to report an ask.
- Build a disposable capture harness that launches available agent CLIs inside phux panes, records title, bell, visible grid rows, and stdout/stderr, and exits nonzero when empirical coverage is incomplete.
- Add a passive fallback detector only after the corpus proves stable signals for at least two agents.