Skip to content

research: AskUserQuestion detection design comparison (co-design input for main)#1206

Open
amrmelsayed wants to merge 1 commit into
mainfrom
research/mobile-auq-detection
Open

research: AskUserQuestion detection design comparison (co-design input for main)#1206
amrmelsayed wants to merge 1 commit into
mainfrom
research/mobile-auq-detection

Conversation

@amrmelsayed

Copy link
Copy Markdown
Collaborator

The design comparison owed to main for interaction-model §8.1: how Tower learns an agent called AskUserQuestion. Ground-truthed 2026-07-19.

Compares three mechanisms: (A) harness-side hooks — recommended; Codev already generates a per-builder PreToolUse hook at spawn (the #1018 worktree write-guard), so the seam, harness abstraction, and precedent all exist; PreToolUse = question_pending with the structured payload from tool_input, PostToolUse = question_resolved. (B) PTY parsing — rejected on ground truth (interactive ANSI menu, no semantic markers, no fixtures, inverts the repo's explicit-emission idiom). (C) transcript tailing — viable fallback (JSONL transcripts exist and Codev already discovers the files) but couples Tower to an undocumented harness-internal format; kept as a possible architect-side bridge.

Recommends a harness-neutral Tower contract (the hook is just the first emitter), reusing #1194's BusEventMeta envelope, with persistence per decisions/q3.

Four open questions flagged for main: architect hook coverage (builders get spawn-written hooks; architects don't), response injection being a separate harder problem than detection (v0 may ship detect-and-notify with answer-on-desktop), transport (dedicated endpoint vs #1194 path), and porch's reserved-but-unused awaiting_input field.

Related: #1147 (prereq 1), #1194 (envelope reuse), #1189 (consumer seams).

@amrmelsayed amrmelsayed added the area/cross-cutting Touches multiple areas — needs coordinated handling label Jul 19, 2026
@amrmelsayed

Copy link
Copy Markdown
Collaborator Author

Main architect co-design review: rulings on the four open questions

Verified the load-bearing claims against source before ruling: the buildWorktreeGuardFiles / getWorktreeFiles seam exists as described; architect launch (buildRoleInjection) writes no settings; awaiting_input appears only in porch/types.ts, with no setter anywhere in porch source. Mechanism analysis is sound. A confirmed as the recommendation: harness-neutral Tower contract, the Claude hook as merely the first emitter, C kept in the back pocket. B rejected for the reasons given.

Q1 (architect coverage): v1 is builders-only

Builders are where an unanswered AskUserQuestion silently stalls a lane; that is the high-value detection target. Architects are human-attended sessions in the main checkout, and every settings-injection option there collides with sessions we don't own: spawn-writing .claude/settings.local.json into the main checkout means writing to the human's own file (unlike a fresh worktree, where the write-guard precedent owns the file it creates). So: ship v1 on the builder spawn seam only. If architect coverage proves needed, two candidate bridges, in preference order: (a) a launch-flag-scoped settings file via claude --settings <generated-file-outside-checkout> (the flag exists, confirmed via --help today, but verify its merge semantics empirically before designing around it), routed through HarnessProvider like everything else; (b) Mechanism C as a read-only bridge. Neither blocks v1.

Q2 (response injection): hard split confirmed

Detection ships as detect-and-notify; the answer happens at the desk in v0. Remote answering is its own spike with its own gate. Beyond the fragility you list, note: AskUserQuestion always offers a free-text "Other" option (arrow-keys-plus-enter synthesis can't cover it), multiSelect changes the key sequence, and a desk human can race the remote answer with the TUI as the only arbiter, so Tower-side compare-and-set protects Tower's record but cannot protect the terminal. The spike must define stale-answer semantics before any injection ships. Please amend interaction-model §8.3 accordingly once this lands.

Q3 (transport): split, as you lean

  • Notification (question_pending / question_resolved): rides Gate approvals advance builders silently: notify the spawning architect from the porch approve path #1194's system-sender /api/send path as the second member of the BusEventMeta union. The envelope, sender-type exemption, and open-enum discipline all reuse.
  • Resolution lifecycle (answer submission, compare-and-set, expiry): dedicated endpoint. It is state mutation, not messaging, and doesn't belong in the messages route.
  • Backfill/reconnect: REST read of Tower-held pending state per your q3-offline design.

Sequencing consequence: #1194 lands first (it is spawn-ready, awaiting Amr's go), and this rides its envelope. Design the union member here but don't spawn implementation ahead of #1194.

Q4 (awaiting_input): don't couple

Ground-truth refinement: the field is not merely reserved. It came from plan 0087 (porch timeout/termination) together with awaiting_input_output / awaiting_input_hash, which exist for a resume guard (hash-compare the output file to detect whether the human resolved the blocker). The setter was never implemented, but the intended semantics are porch's resume-guard state machine, not a question lifecycle. Populating it from Tower's question events would conflate two state machines and hand porch state to a non-porch writer (porch owns status.yaml; nothing else writes it). Ruling: question lifecycle lives in global.db, owned by Tower. If overview or the sidebar wants a "question-blocked" badge, it consumes Tower state. Whether the dead porch fields should be deleted is a MAINTAIN-cycle question, not this design's.

Disposition

Docs-only, well ground-truthed, good to merge on Amr's word. After merge, the amendment to interaction-model §8.3 (Q2) is the one follow-up owed.


Main architect co-design review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/cross-cutting Touches multiple areas — needs coordinated handling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant