A draft left in a lead's prompt box blocks every delivery for as long as it sits there — decide what the daemon may do about an abandoned draft #797
Closed
opened 2026-10-06 18:06:19 +02:00 by ltms
·
4 comments
No Branch/Tag Specified
main
worker/799-6d217f-4
worker/816-4c03a2-5
worker/808-0c71eb-2
worker/797-disable-box-gate-5b5478-12
worker/799-a76336-9
worker/796-a7911a-5
worker/778-e301b0-1
worker/791-fleet-plugin-0-3-0-9e25b0-2
worker/790-observer-to-lead-send-523d45-1
worker/788-eb7dd0-1
worker/782-styling-probe-4ceb10-9
worker/778-12988a-4
worker/782-18f8bc-5
worker/780-faf58b-3
worker/759-authz-comment-and-role-list-e3f0e5-5
worker/756-758-observer-pane-discovery-7e6ffd-1
worker/759-role-model-comments-5d8409-3
worker/743-pane-discovery-ad5b75-5
worker/743-observer-send-4706db-6
worker/749-edge-baseline-28d1a0-3
worker/748-dead-comment-refs-f42ac5-4
worker/737-9c61d3-4
worker/737-a263f3-3
worker/737-20d1d9-1
worker/737-b038f7-2
worker/726-unit2-75cb13-4
worker/737-owner-key-ff061f-10
worker/736-presence-forget-f35144-9
worker/705-observer-14c258-6
worker/722-024c34-5
worker/726-ea34a0-2
worker/726-10cbf0-1
worker/729-5961c6-3
worker/727-ee14ed-3
worker/719-bdd95e-4
worker/702-4f5c7f-2
worker/715-5c43fc-1
worker/721-70f9ea-5
worker/718-99362b-2
worker/task-15-af0d10-12
worker/task-16-50a702-13
worker/task-12-4d0479-9
worker/task-13-823ce2-10
worker/705-ticket-owner-af9928-8
worker/703-list-collaborators-9c06c2-7
worker/669-example-truth-0b303d-6
worker/669-collab-deliverability-9ba859-3
worker/669-collab-reload-report-2a21bd-4
worker/669-7e80a6-1
worker/669-unit-d-efbbd7-1
worker/669-1b786a-1
worker/669-1d1d9f-1
worker/692-4afb9d-2
worker/689-02fced-13
worker/693-cf23fa-14
worker/677-fix-lead-collision-f69073-12
worker/638-fix-overmask-dbb1bf-11
worker/675-5b7478-4
worker/669-unit-a-70cc8f-3
worker/677-8cdaaf-5
worker/638-a7b391-1
worker/683-4536d6-2
worker/651-a75bbe-8
worker/680-20607d-7
worker/664-c12e95-3
worker/668-08534d-4
worker/672-0f2469-2
worker/670-7d1022-1
worker/661-ac7c28-2
worker/664-37fb9b-3
worker/663-remove-3arg-read-3f6783-1
worker/659-remove-dead-backcompat-ba5e6f-1
worker/637-revision-60a488-23
worker/656-redact-regression-tests-892903-19
worker/637-context-gauge-threshold-466eb5-16
worker/639-redact-line-numbers-de4ac4-17
worker/641-set-reformat-guard-6f96a4-18
worker/642-herdr-guard-scope-5de0e4-15
worker/650-javadoc-scope-95f3b3-14
worker/612-01e9f7-13
worker/612-a-r4-quarantine-outage-7ab0e8-5
worker/612-a-r9-r11-capacity-coverage-peers-cfcc79-7
worker/612-a-r10-loophealth-ccc872-8
worker/612-a-r12-turnregistrar-9e3bb7-9
worker/612-a-r5-leadconfigdir-9e70cf-6
lead/config-edit-redact-anchor-wording
worker/config-edit-seam-ca8dc1-1
worker/612-r67-630-lifecycle-290b8d-3
worker/629-625-ports-seams-da7d5d-4
worker/612-r12-exhaustion-f37cd7-1
worker/612-r38-amqp-24b083-2
worker/fleetd-612-unita-87807e-1
worker/612-b3-mcpwirings-da2b58-3
worker/612-b2-cb185-176d3a-2
worker/612-b1-completion-457459-1
worker/612-agaps-73a926-2
worker/608-sleeps-3a64ff-3
worker/621-b4520b-1
worker/618-b83894-2
worker/fleetd-615-e05481-5
worker/lead-autocompact-5f1ab2-3
worker/fleetd-613-f85deb-3
worker/fleetd-608-flaky-nudge-test-d0c2d1-3
worker/lead-context-gauge-ad404f-1
worker/gauge-wiring-9158c1-4
worker/redeploy-slowstart-ead0e5-5
worker/charter-bytes-13668c-6
worker/rollover-outcome-291483-2
worker/589-f64303-2
worker/593-1a8025-5
worker/589-fcd2aa-1
worker/568-9fdaa2-3
worker/571-attempted-outcome-5739f7-2
worker/581-completionresolver-cas-sites-0542b7-6
worker/562-loop-health-wiring-test-99611c-5
worker/562-surface-loop-health-7df5cc-4
worker/575-waiter-cleanup-sites-62ad80-1
worker/572-answer-lock-release-46a9ae-5
worker/567-probe-channel-leak-a38fc5-6
worker/551-record-before-send-7cbf56-1
worker/561-listener-fanout-survives-a-throw-61d538-2
worker/555-redeploy-main-flow-seam-65c2f5-2
worker/556-injector-owns-registration-e027a5-1
worker/552-post-restart-mktemp-abort-bc2672-4
worker/553-onstatus-completion-leak-0da881-2
worker/550-shasum-linux-196132-1
worker/538-loop-dies-on-error-4a5eeb-6
worker/426-health-coverage-ef1fd4-4
worker/504-failed-reported-clean-3cfd66-3
worker/537-capturedlog-close-e4c437-2
worker/459-broken-link-targets-cadc17-5
worker/535-appender-leak-fe74c1-1
worker/512-part2-shutdown-detection-434701-9
worker/529-logger-level-sweep-2a5533-8
worker/528-drain-gate-call-site-5de83d-7
charter/forge-mcp-vs-token
worker/521-swap-guard-unpinned-28e931-5
worker/519-probe-test-harness-d25ab8-4
worker/525-logger-level-leak-1b4eb0-6
worker/518-fleetmcp-resolver-wiring-8ef96c-1
worker/512-drain-complete-line-7edd71-3
worker/517-abort-branch-and-jar-id-41b641-2
worker/500-9e52c9-3
worker/509-4912f4-2
worker/511-9a4b23-1
worker/493-479f45-2
worker/505-03f8b2-1
worker/492-followup-detect-unclear
worker/501-a31fa0-7
worker/498-451d1c-5
worker/494-1015ce-2
worker/492-209647-1
worker/489-001902-2
worker/480-relative-handover-path-906323-1
worker/480-b-handover-skill-45bf1f-5
worker/474-followup-source-pin-f54a55-17
worker/474-charter-check-on-reload-f54a55-17
worker/466-quarantine-repeatcount-report
worker/393-opencode-skill-seeding-71854b-13
worker/469-canonical-tool-names-2a472a-16
worker/466-quarantine-escalation-5ae9c1-15
worker/446-hot-exhausted-pattern-0af580-6
worker/464-charter-tool-name-guard-a85635-12
worker/463-listfleet-default-fails-open-f1c76c-11
worker/458-invariant-5-by-purpose-862f9a-10
worker/439-coordinator-row-gate-bc032a-8
worker/449-herdr-protocol-576015-4
worker/450-abstract-spawn-599e1c-5
worker/437-ack-refuses-177d91-1
worker/444-placement-window-feb56a-2
worker/440-helddurable-derived-d462d7-13
worker/425-rework-placement-resolve-c58ba1-9
worker/421-lead-peek-held-msgs-cdbad2-10
worker/435-fixed-policy-cap-fe11de-12
worker/422-gate-state-observability-9e79d6-11
worker/431-memberregistry-live-readers-cdbad2-10
worker/424-architect-slot-hot-038b41-7
worker/422-model-gate-spawn-c29f48-6
worker/425-default-profile-live-f55534-8
worker/415-coverage-wording-2cbf9c-5
worker/416-3ad1da-1
worker/418-588283-3
worker/deterministic-stamp-race-409-3cb7b6-10
worker/armed-reads-live-config-404-ed931f-9
worker/reply-peer-refusal-391-5a34bd-7
worker/models-allowlist-aa9e9b-3
worker/ttl-stamp-race-399-f1122f-8
worker/scrub-receipt-400-316b3e-5
worker/exhaustion-detection-395-105105-6
worker/scrub-abort-394-316b3e-5
fix/scrub-uid-abort
worker/task-scrub-517574-2
worker/t386-clock-bd5b78-4
worker/t384-scrub-813790-5
worker/t381-cc-748314-2
worker/t373-336973-2
worker/t365-3920c5-3
worker/t358-6e989b-1
worker/t355-8b321c-1
worker/fleetd-369-hermetic-git-tests-e8b19a-3
worker/fleetd-368-stale-lead-binding-f5682e-2
worker/fleetd-360-deploy-units-0d3793-1
worker/359-dead-lead-tabs-f1253b-4
worker/362-worktree-skills-c03e51-3
worker/361-coord-visibility-655144-1
362-plugin-visibility-and-drift
worker/errscan-bed2ca-2
worker/amqp-log-identity-bed2ca-2
worker/withdefaults-guard-561704
worker/sleepguard-82076d-1
worker/fd334-9ee1b6-5
worker/fd348-f1ab27-4
worker/fd335-a71c35-1
worker/fd342-174a17-2
worker/fd345-490d0f-3
worker/fleetd-337-5ec7d4-21
worker/fleetd-341-af5a6b-24
worker/fleetd-339-5ca0a2-23
worker/fleetd-338-83a4a1-22
worker/fleetd-333-281f46-18
worker/fleetd-329-11bdbb-16
worker/fleetd-330-2770fb-17
worker/fix-326-50506e-15
worker/fix-324-3e9bbf-14
worker/fix-323-b8287d-13
worker/fix-316b-bd0860-11
worker/fix-318-76ca36-9
worker/fix-317-486aec-8
worker/fix-315-ce47c5-6
worker/fix-307-275890-6
worker/fix-308-b4f664-7
worker/fix-309-ec3939-8
worker/fix-310-7a3974-9
worker/fix-302-52ad0e-9
worker/fix-298-ce1acb-8
worker/fix-297-66bd11-7
worker/fix-296-104622-6
worker/fix-293-bare-closetab-eb22b5-3
worker/fix-280-gone-ask-lapse-bca98e-2
worker/fix-290-reapidle-guard-coverage-9b0dd1-1
worker/fix-285-trust-seed-8f3565-10
worker/fix-284-backend-error-seat-85912c-11
worker/fix-282-chained-ask-e6d0bb-8
worker/fix-283-teardown-leaks-f40dfa-9
worker/fix-281-pin-handler-actions-4921ac-7
worker/audit-rendezvous-lifecycle-d072ae-2
worker/audit-health-placement-1a2476-6
worker/audit-teardown-exits-e207a5-3
worker/audit-launcher-asymmetry-27e370-4
worker/audit-rest-authz-6ca53c-5
worker/investigate-275-abandon-asking-fdef52-8
worker/fix-274-worktree-leak-b0095d-7
worker/fix-273-exhausted-pattern-9665b5-6
worker/fleetd-267-model-check-bd8068-1
worker/fleetd-131-archunit-18b834-7
worker/fleetd-266-sshagent-rename-a014ff-6
worker/fleetd-184-uid-claim-8e1f31-4
worker/fleetd-184-warn-b381ee-10
worker/fleetd-184-docs-be1d12-9
worker/fleetd-257-9bf010-7
worker/fleetd-103-23a113-6
worker/fleetd-247-342356-5
worker/fleetd-116-04dea8-4
worker/fleetd-252-a830e0-3
worker/fleetd-111-7e8673-9
worker/fleetd-155c-f8ef4b-8
worker/fleetd-176-b928ca-3
worker/fleetd-249-7a7878-2
worker/cb248-composition-root-b-9acdf7-15
worker/cb148-envrc-default-fa6c82-12
worker/cb201-unit5-wiring-6c12e6-8
worker/cb241-fallback-echo-1175e9-11
worker/cb149-trust-dialog-2392a5-9
worker/cb134-148-overlay-visible-c9b986-10
worker/cb234-session-id-keyed-04e1fc-1
worker/cb201-unit3-nudge-abdf5c-6
worker/cb201-unit2-policy-c1102c-5
worker/cb201-unit4-outcome-a13bfa-7
worker/cb201-unit1-classifier-91b9b1-4
worker/cb201-227-refine-831980-3
worker/cb175-model-readback-0f085f-1
worker/cb222-charter-tmpdir-17f013-1
worker/cb226-architect-slot-race-cd3aa8-3
worker/cb224-worktree-root-group-024523-2
worker/cb-123-role-demotion-c600f7-2
worker/cb-219-opencode-roots-1f677e-1
worker/cb214-claude-session-id-b9eab4-4
worker/cb213-zdotdir-wrong-process-dd6de4-3
worker/cb211-exhaustion-classification-9546e0-2
worker/cb137-ambiguous-task-4df3d8-4
worker/cb209-agentsessionid-4dfdb6-2
worker/cb185-hostenvnames-2692b5-3
worker/cb206-opencode-sqlite-128718-2
worker/cb185-worktree-group-fc0c99-1
worker/cb-137-ask-ticket-e7760c-2
worker/cb-172-broker-uri-d36ae4-4
worker/cb-175-model-readback-76ead6-3
worker/cb-161-pane-ancestry-293510-1
worker/cb-164-rebase-885863-8
worker/cb-164-empty-scrape-false-success-1a80af-3
fix/cb-197-ticket-ttl-from-completion
worker/cb-189-remote-url-coverage-4692f3-1
worker/cb-185-blockers-027756-4
worker/cb-192-gap-log-11b631-2
worker/cb-633-fix-5f4396-3
worker/cb185-router-d6436d-3
worker/cb185-router-routing-gaps-9e9d33-3
worker/cb185-paneids-992586-2
worker/cb-633-allow-list-union-ed374b-1
worker/cb-157-credential-in-remote-url-496e44-2
worker/cb-641-health-herdr-evidence-8f1f54-6
worker/cb-640-health-msg-evidence-99c9cd-1
worker/cb-642-fleets-status-skill-bbbc40-5
cb-634-ide-mcp
worker/lead-comms-wiring-c014b9-7
worker/lead-mailbox-c19577-6
worker/autocompact-window-82bc2f-5
worker/cb-634-probe-18056f-4
worker/cb635-broker-urienv
worker/cb-632-config-retry-8e0efa-7
lead/cb-622e-claude-md
lead/cb-622-followup
worker/cb-622a-165dff-1
lead/cb-622d-opencode-mount
worker/cb-622b-717c67-2
worker/cb-622c-ab7759-3
worker/cb-617b2-20ca4b-3
worker/cb-617a-5c2f4a-1
worker/cb596-4e49ef-3
worker/cb586-10500c-1
worker/cb-606-b9343a-25
worker/cb604-1445f8-24
worker/cb582-477374-21
worker/cb584-8c2281-22
worker/cb600-e6b9a9-20
worker/cb602-ce257f-19
worker/cb601-b42837-18
worker/cb598-6c7ba7-17
worker/cb599-740fe4-16
worker/cb597-282224-15
worker/cb590fix-185e9a-10
worker/cb528-recovery-race
worker/cb594-96bead-8
worker/cb590-916766-2
worker/cb527-997d99-3
worker/cb592-env-leak-3cbf9c-1
worker/cb588-async-ticket-nudge-3218f7-5
worker/cb578b-9dcb13-6
worker/cb581-d24826-5
worker/m2-u5-ef8c42-15
worker/cb578a-516499-2
worker/cb576-01a04b-17
worker/cb579-lead-tab-acba06-20
worker/cb580-terminal-health-ed6058-21
worker/cb577-f36fdc-18
worker/cb573b-3db06f-16
worker/cb568c-f36fdc-18
worker/cb568-drop-cause-c3ac1c
worker/cb575-cancelled-notification-c3ac1c
worker/m4-sol-a2cbec-3
worker/cb574-async-ask-c3ac1c
worker/cb573-health-model-8ca857-14
worker/cb572-unknown-target-7f2e35-13
worker/u4-700706-9
worker/u3-b9fcb6-6
worker/u2-ef5b68-4
worker/u1-469dce-1-clean
worker/u1-469dce-1
worker/cb-564-health-events-70cf7e-2
worker/cb-565-recycle-drops-role-98e58f-3
worker/cb-563-missing-reply-df2866-1
worker/cb-562-readiness-gate-silent-6c23c9-3
worker/cb-560-architect-presence-da8155-1
worker/cb-561-architect-silent-off-a71cab-2
worker/cb-548-bind-architect-slot-fe1b8c-1
worker/parity-overlay-settings-5fb711-1
secrets-central-store
cb-559-hot-key-correction
cb-557-fleet-role-pools
worker/cb-553-maxload-explicit-spawn-305ee3-6
worker/cb-551-idle-lead-heartbeat-f1633c-1
worker/cb-544-drain-preserves-worktree-925fad-3
worker/cb-552-docs-sync-1cb9cf-4
worker/cb-548-rendezvous-guard-rebased
worker/cb-548-rendezvous-guard-116b53-10
worker/cb-548-authz-v2-586df6-8
worker/cb-548-authz-264363-5
salvage/cb-528b-codex-home
salvage/cb-528a-codex-launcher
CB-518-primary-flow
feature/peer-launcher-spi
cb-103-injector
v1.1.0
v1.0.0
Labels
Clear labels
blocked
needs-live-proof
ready-to-delegate
silent-default
Cannot start until something else lands. The body says what.
Merged and green, but never shown working on the running daemon. Not the same as done.
Scope, files and acceptance criteria are written. A worker can be briefed from the body alone.
A feature that compiles, passes tests, and ships turned off. Nine recurrences and counting.
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: fleet/fleetd#797
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Requested by the operator on 2026-10-06: "we should have auto input clean after some time feature".
The problem, measured today
The box gate holds a delivery while a lead's prompt box has unsubmitted text. It has no timeout and no cap. It holds for as long as the text sits there.
Today that lost a worker's report. The operator had 29 characters in the box, and
ReplyPushLoopheld 11 times in a row:Meanwhile ticket
task-7da785-4wentfailed — no reply — timed_out_working. The worker had in fact replied; the reply could not be announced, so it sat until the ticket timed out. The same pattern hit two observer panes earlier the same day (10 holds each).What the code does now
PromptBox.HOLD_WARN_STREAK = 20(PromptBox.java:44). After 20 consecutive holds, one warning is logged. It repeats only after the box has cleared (PromptBox.java:26-28). There is no other consequence.ReplyPushLoop.java:413,LeadCoordLoop.java:156,LeadHeartbeatLoop.java:367. TheInjectordoes not (that is #793).The blocker: fleetd cannot clear a box today
AgentControlspeaks these herdr verbs, and no more:agent.get,agent.list,agent.prompt,agent.read,agent.start,pane.close. There is no verb that clears a pane's input.agent.prompttypes keystrokes rather than setting text, so "clear the box" would mean typing control characters into a human's terminal. I have not checked whether herdr passes control characters at all. So the requested feature needs either a new herdr capability or a keystroke trick, and that choice is part of this ticket.Why this is not a one-line fix
Both obvious versions do damage:
Two further options worth weighing:
fleet_inboxand$.prompt.submit, so the box gate never applies to it. If a held pane could be switched to the pull route, nothing is typed and nothing is destroyed. I have not checked whether$.prompt.submitis safe while a draft is present — if it submits the draft too, this option has the same harm as option 1 and must be dropped.What must be true of any fix
That last point is the cheapest half and holds whatever is decided about clearing. The hold streak should be observable — in
fleet_list, or as a metric — not only as one log line.Status
Not started. I am asking two architects to settle which of the four options to build, because the two the request suggests both break a rule above. The open question for them: may the daemon ever write to or clear a human's prompt box, and if not, what reaches a held pane instead?
Much bigger than the 11 holds this issue was opened on
Re-measured at 19:40 today, bounded to the current daemon run (boot 08:05:42, about 11 hours):
term_65d2a09b91f8f3d)term_65d106559db144)term_65d106559d7e43)term_65d106559ba0a2)The whole file holds 6790, but it spans several days and its timestamps carry no date, so the per-boot number above is the one to quote. 2166 of the file's total belong to
term_65d106559b02e1, a pane that no longer exists.The drafts were tiny: 8, 13, 19, 21, 25, 28, 30, 32 and 35 characters. A few leftover characters stop a pane's mail for hours.
The
HOLD_WARN_STREAK = 20warning did fire today, for three panes (18:31:20, 18:52:32, 18:56:25). So at this volume the warning is reached — but it is still one line per clearing cycle, and it under-reports by design.New evidence: option 1's harm is not hypothetical, and #793 may already be causing it
This issue says that delivering anyway would submit the operator's half-written line. I now have a case that looks like exactly that, from a direct
fleet_send, which bypasses this gate today (#793).The receiving session reports that this message never arrived, and that the next message in the sequence arrived first. So the daemon recorded
delivered=truefor a message the receiver never saw, while 32 characters of draft sat in its box.I have asked that session to check its scrollback for a garbled or merged prompt. Not confirmed yet — the log cannot settle it, because the daemon sees a successful paste either way.
If it is confirmed, two things follow:
Injector, so #793 is not a separate nicety — it is the same defect arriving by the other door. Fixing the box gate here while theInjectorignores it leaves the hole open.delivered=truereceipt is not evidence that a peer received anything. That is worth stating wherever the receipt is documented, because it is the kind of thing a sender reasonably trusts.One more defect found on the way, filed separately
A blocking
fleet_sendthat times out returns[no reply within 25000ms — worker busy; retry or poll status]with no ticket id and no msgId. The daemon did create a ticket for that send and resolved it at 19:21:34, but the caller was never told its id, so "poll status" was not actually possible — and "retry" would have created a duplicate. That is not this issue; I will file it on its own.The cheap half still stands
Whatever is decided about clearing, the third requirement in the description — a long hold must stop being silent — is independent and worth doing first. At 2231 holds in 11 hours, the hold streak belongs in
fleet_listor in a metric, not only in a log line a human has to go looking for.Correction to my own reasoning, for the two architects reading this
I briefly suspected these holds were a false positive —
PromptBoxcounting the pane's dimmed placeholder hint as typed text. I read the code and that is not supported. Do not spend your turn on it.boxContent(PromptBox.java) decodes the box line into glyphs, tracks which SGR-2 (faint) span each sits in, and skips every faint glyph plus padding, the trailing border and the cursor block. Only a character drawn outside a faint span is counted.lastBoxLineStarttakes the lowest line beginning with a box marker (❯or│ >) after leading SGR codes, so scrollback carets do not win. The hint trap is already handled deliberately, and the javadoc says so.So a stable reading is most likely genuine unsubmitted text.
Current state, read at 19:45 — all four panes are holding right now
term_65d2a09b91f8f3dterm_65d106559db144term_65d106559d7e43term_65d106559ba0a2anki has reported exactly 32 characters for 273 consecutive checks. That is what made me suspect a misread. Having read the classifier, the better reading is that the text is real and simply has not been touched. I have asked the operator to confirm by looking at those tabs, and until they answer, both readings are open. Whichever it is, it is worth knowing before a fix is designed: option 3 (distinguish an abandoned draft from active typing) depends on the count being a real count.
A second, independent confirmation that this is the live loss mechanism
Two deliveries to vms today,
task-7da785-40(19:02:41) andtask-7da785-46(19:13:42). The first failed withtimed_out_workingand an empty body. The second returned a pane scrape in which that session says, to its own operator:So the message reached that session because a human pasted it, not because the daemon delivered it. vms also never carried out the request in the brief it was sent, which is consistent with that brief never arriving.
That is the behaviour this issue is about, observed end to end: a pane with a small draft stops receiving, the sender gets either a failure with no body or a receipt that overstates what happened, and the only thing that got through was manual.
Does not change the decision, but narrows it
The third requirement in the description — a long hold must stop being silent — now has a number behind it. A pane at 273 consecutive holds is invisible in
fleet_listand has produced one log line. Whatever is decided about clearing, that is the half with no downside.Operator decision, 2026-10-06: disable the box gate for now
The operator looked at the four tabs and answered:
So the holds were not abandoned drafts. They were the pane's autocomplete suggestion, and
PromptBoxcounted it as typed text. The decision is to turn the gate off until detection can tell the two apart.This supersedes the four options in the description. Nobody needs to decide what the daemon may do about an abandoned draft, because the premise — that there was a draft — was wrong.
Correcting myself twice on this issue
My first comment said the holds might be a false positive. My second said I had read the code and that was not supported. The second was wrong, and it is the one that matters, because I told two architects not to spend their turn on it.
Where my code reading went wrong:
boxContentexcludes a glyph only when it sits inside an SGR 2 (faint) span —FAINT_CODE = "2", andRESET_CODES = {"", "0"}. I read that as "the hint is handled" because the javadoc says the hint is drawn dimmed. But dim in the javadoc and SGR 2 in the code are not the same thing. If the TUI draws the suggestion in a grey colour —ESC[38;5;240mor similar — thenfaintis never set, every glyph is counted, and the reading is a falseDRAFTforever.This is a hypothesis, not a measurement. I have not captured the pane bytes to confirm which escape sequence the suggestion uses. Whoever fixes detection should capture a real box line with styling first and read the actual codes, rather than trusting either the javadoc or me.
Two supporting observations, both consistent with it:
What this issue becomes
fleet_list, not one log line.Architects
task-7da785-90(sol) andtask-7da785-91(opus) were briefed on the old framing, including my wrong "do not spend your turn on it". The decision they were asked to settle no longer needs settling. If you are still mid-turn: stop, and reply with whatever you have on the one question that is still live — can the autocomplete suggestion be distinguished from typed text at all, and by what signal — or simply say you had not got to it. Do not work the four options.Done. Merged as
fcce443; PR #805 is closed. The operator's decision — disable the check rather than guess at a way to tell a suggestion from typed text — is implemented as a config switch rather than a deletion, so it is reversible once #802 fixes detection.promptBoxGateEnabledis a new top-level config key. An absent key andfalseboth leave the gate off; onlytruearms it.grep -n promptBoxGateEnabled fleetd/fleetd.yamlon this host has no match, so it is off in the live config.Verified myself: merged into
mainin a throwaway worktree,BUILD SUCCESS,Tests run: 2232, Failures: 0, Errors: 0, Skipped: 0, confirmed twice.Docs corrected, because this changes what the prompt tells every session:
CLAUDE.mdinvariant 4 claimed "its input box must be empty" as a live rule. It now says the gate is off by default, names the key, carries the 2231-hold measurement and the command to re-check the switch.wiki/11-Features.md#782 entry said "The knob: none — it is always on." Corrected, with the autocomplete gotcha added.The two architect answers are lost. I asked
solandopusthe narrowed question — whether the autocomplete suggestion can be distinguished from typed text, and by what signal — and both tickets (task-7da785-90,-91) expired before I collected them:unknown ticket … (never issued, or expired). A ticket is pruned 10 minutes after it goes terminal, and I was mid-merge. That answer would have fed #802, so it needs asking again when #802 is worked. My own fault, not theirs.Closing this. #802 carries the detection bug, and it must be fixed from real captured pane bytes — the #782 Features entry already warned that both positive controls in
PromptBoxTestare synthetic fixtures, and that is precisely the gap this defect came through.I asked Claude to implement and verify this; the build totals and the config measurement are from this session.