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
Owner

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 ReplyPushLoop held 11 times in a row:

13:39:28.167 PromptBox - prompt box of term_65d2a09b91f8f3d is DRAFT (29 character(s)), holding delivery 1
...
13:41:59.225 PromptBox - prompt box of term_65d2a09b91f8f3d is DRAFT (29 character(s)), holding delivery 11

Meanwhile ticket task-7da785-4 went failed — 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.
  • Three callers gate on it: ReplyPushLoop.java:413, LeadCoordLoop.java:156, LeadHeartbeatLoop.java:367. The Injector does not (that is #793).
  • So an abandoned draft is visible once in the log and then silent, and nothing reaches that pane.

The blocker: fleetd cannot clear a box today

AgentControl speaks 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.prompt types 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:

  1. Deliver anyway after a timeout. The multiplexer pastes and submits in one step, so this submits the operator's half-written line. That is the exact harm the gate was built to prevent.
  2. Clear the box after a timeout. This destroys text a human typed, with no undo. Logging the text first to keep it is not safe either: a prompt box can hold a credential, and the daemon log is not a place for one. Logging only its length is safe but keeps nothing.

Two further options worth weighing:

  1. Distinguish an abandoned draft from active typing. Clear or bypass only when the character count has not changed for N seconds and the pane is idle. An operator mid-sentence is never touched. This needs the reading to carry more than a length, or a stored previous reading per target.
  2. Change route instead of clearing. A pane running the fleet mod collects its own mail with fleet_inbox and $.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.submit is 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

  • An operator's typed text is never submitted and never destroyed without their action.
  • A message is never lost. If a pane cannot be reached, the payload stays collectable by a route that pane can use.
  • A long hold stops being silent. One warning at 20 holds is too quiet: today's incident ended at 11 holds, under the threshold, so nothing was logged at all.

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?

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 `ReplyPushLoop` held 11 times in a row: ``` 13:39:28.167 PromptBox - prompt box of term_65d2a09b91f8f3d is DRAFT (29 character(s)), holding delivery 1 ... 13:41:59.225 PromptBox - prompt box of term_65d2a09b91f8f3d is DRAFT (29 character(s)), holding delivery 11 ``` Meanwhile ticket `task-7da785-4` went `failed — 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. - Three callers gate on it: `ReplyPushLoop.java:413`, `LeadCoordLoop.java:156`, `LeadHeartbeatLoop.java:367`. The `Injector` does not (that is #793). - So an abandoned draft is visible once in the log and then silent, and nothing reaches that pane. ## The blocker: fleetd cannot clear a box today `AgentControl` speaks 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.prompt` types 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: 1. **Deliver anyway after a timeout.** The multiplexer pastes and submits in one step, so this submits the operator's half-written line. That is the exact harm the gate was built to prevent. 2. **Clear the box after a timeout.** This destroys text a human typed, with no undo. Logging the text first to keep it is not safe either: a prompt box can hold a credential, and the daemon log is not a place for one. Logging only its length is safe but keeps nothing. Two further options worth weighing: 3. **Distinguish an abandoned draft from active typing.** Clear or bypass only when the character count has not changed for N seconds *and* the pane is idle. An operator mid-sentence is never touched. This needs the reading to carry more than a length, or a stored previous reading per target. 4. **Change route instead of clearing.** A pane running the fleet mod collects its own mail with `fleet_inbox` and `$.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.submit` is 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 - An operator's typed text is never submitted and never destroyed without their action. - A message is never lost. If a pane cannot be reached, the payload stays collectable by a route that pane can use. - A long hold stops being silent. One warning at 20 holds is too quiet: today's incident ended at 11 holds, under the threshold, so nothing was logged at all. 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?
Author
Owner

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):

Pane Delivery holds on the box gate
lead (term_65d2a09b91f8f3d) 1103
anki (term_65d106559db144) 573
trinotes (term_65d106559d7e43) 480
vms (term_65d106559ba0a2) 75
total 2231
tail -n +107413 fleetd.out | grep -oE 'prompt box of term_[0-9a-f]+ is DRAFT' \
  | awk '{print $4}' | sort | uniq -c | sort -rn

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 = 20 warning 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).

19:21:10.815  prompt box of term_65d106559db144 is DRAFT (32 character(s)), holding delivery 232
19:21:18.527  send to term_65d106559db144 timed out (delivered=true)
19:21:34.712  resolved send to term_65d106559db144 via turn-completion fallback (301 chars scraped)

The receiving session reports that this message never arrived, and that the next message in the sequence arrived first. So the daemon recorded delivered=true for 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:

  1. The harm this issue attributes to option 1 is already shipping through the Injector, so #793 is not a separate nicety — it is the same defect arriving by the other door. Fixing the box gate here while the Injector ignores it leaves the hole open.
  2. A delivered=true receipt 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_send that 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_list or in a metric, not only in a log line a human has to go looking for.

## 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): | Pane | Delivery holds on the box gate | |---|---| | lead (`term_65d2a09b91f8f3d`) | 1103 | | anki (`term_65d106559db144`) | 573 | | trinotes (`term_65d106559d7e43`) | 480 | | vms (`term_65d106559ba0a2`) | 75 | | **total** | **2231** | ``` tail -n +107413 fleetd.out | grep -oE 'prompt box of term_[0-9a-f]+ is DRAFT' \ | awk '{print $4}' | sort | uniq -c | sort -rn ``` 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 = 20` warning 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). ``` 19:21:10.815 prompt box of term_65d106559db144 is DRAFT (32 character(s)), holding delivery 232 19:21:18.527 send to term_65d106559db144 timed out (delivered=true) 19:21:34.712 resolved send to term_65d106559db144 via turn-completion fallback (301 chars scraped) ``` The receiving session reports that this message **never arrived**, and that the *next* message in the sequence arrived first. So the daemon recorded `delivered=true` for 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: 1. The harm this issue attributes to option 1 is already shipping through the `Injector`, so **#793 is not a separate nicety — it is the same defect arriving by the other door.** Fixing the box gate here while the `Injector` ignores it leaves the hole open. 2. A `delivered=true` receipt 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_send` that 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_list` or in a metric, not only in a log line a human has to go looking for.
Author
Owner

Correction to my own reasoning, for the two architects reading this

I briefly suspected these holds were a false positive — PromptBox counting 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. lastBoxLineStart takes 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

Pane Reading Consecutive holds
lead term_65d2a09b91f8f3d DRAFT, 30 chars 84
anki term_65d106559db144 DRAFT, 32 chars 273
trinotes term_65d106559d7e43 DRAFT, 21 chars 148
vms term_65d106559ba0a2 DRAFT, 29 chars 7

anki 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) and task-7da785-46 (19:13:42). The first failed with timed_out_working and an empty body. The second returned a pane scrape in which that session says, to its own operator:

You pasted the fleet lead's message. It came over the fleet channel this time...

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_list and has produced one log line. Whatever is decided about clearing, that is the half with no downside.

## Correction to my own reasoning, for the two architects reading this I briefly suspected these holds were a false positive — `PromptBox` counting 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. `lastBoxLineStart` takes 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 | Pane | Reading | Consecutive holds | |---|---|---| | lead `term_65d2a09b91f8f3d` | DRAFT, 30 chars | 84 | | anki `term_65d106559db144` | DRAFT, 32 chars | 273 | | trinotes `term_65d106559d7e43` | DRAFT, 21 chars | 148 | | vms `term_65d106559ba0a2` | DRAFT, 29 chars | 7 | anki 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) and `task-7da785-46` (19:13:42). The first **failed** with `timed_out_working` and an empty body. The second returned a pane scrape in which that session says, to its own operator: > You pasted the fleet lead's message. It came over the fleet channel this time... 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_list` and has produced one log line. Whatever is decided about clearing, that is the half with no downside.
Author
Owner

Operator decision, 2026-10-06: disable the box gate for now

The operator looked at the four tabs and answered:

they are just auto complete text, they disappear when real input typed - lets disable this "existing text" feature for now because you could not find a good way to differentiate them

So the holds were not abandoned drafts. They were the pane's autocomplete suggestion, and PromptBox counted 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: boxContent excludes a glyph only when it sits inside an SGR 2 (faint) span — FAINT_CODE = "2", and RESET_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;240m or similar — then faint is never set, every glyph is counted, and the reading is a false DRAFT forever.

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:

  • anki read exactly 32 characters for 273 consecutive checks. The suggestion is the pane's own last submitted prompt, so a constant length is expected. Real typing would vary.
  • All four panes read 21–32 characters at once, including the lead's own pane. Four humans abandoning similar-length drafts simultaneously was always the weaker explanation, and I talked myself out of the stronger one.

What this issue becomes

  1. Now: disable the gate, so delivery stops depending on a reading that is wrong. The operator has accepted the risk this gate existed to prevent — a delivery landing while someone is genuinely mid-sentence — because in practice the reading is the suggestion, not a sentence.
  2. Separate issue: fix detection so the suggestion is excluded. That is the prerequisite for ever re-enabling the gate, and it needs the real escape codes measured first.
  3. Still worth doing, unchanged: a long hold must not be silent. If the gate ever comes back, 273 consecutive holds must be visible in fleet_list, not one log line.

Architects

task-7da785-90 (sol) and task-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.

## Operator decision, 2026-10-06: disable the box gate for now The operator looked at the four tabs and answered: > they are just auto complete text, they disappear when real input typed - lets disable this "existing text" feature for now because you could not find a good way to differentiate them So the holds were **not** abandoned drafts. They were the pane's autocomplete suggestion, and `PromptBox` counted 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: `boxContent` excludes a glyph only when it sits inside an **SGR 2 (faint)** span — `FAINT_CODE = "2"`, and `RESET_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;240m` or similar — then `faint` is never set, every glyph is counted, and the reading is a false `DRAFT` forever. **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: - anki read **exactly 32 characters for 273 consecutive checks**. The suggestion is the pane's own last submitted prompt, so a constant length is expected. Real typing would vary. - All four panes read 21–32 characters at once, including the lead's own pane. Four humans abandoning similar-length drafts simultaneously was always the weaker explanation, and I talked myself out of the stronger one. ## What this issue becomes 1. **Now:** disable the gate, so delivery stops depending on a reading that is wrong. The operator has accepted the risk this gate existed to prevent — a delivery landing while someone is genuinely mid-sentence — because in practice the reading is the suggestion, not a sentence. 2. **Separate issue:** fix detection so the suggestion is excluded. That is the prerequisite for ever re-enabling the gate, and it needs the real escape codes measured first. 3. **Still worth doing, unchanged:** a long hold must not be silent. If the gate ever comes back, 273 consecutive holds must be visible in `fleet_list`, not one log line. ## Architects `task-7da785-90` (sol) and `task-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.
Author
Owner

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.

promptBoxGateEnabled is a new top-level config key. An absent key and false both leave the gate off; only true arms it. grep -n promptBoxGateEnabled fleetd/fleetd.yaml on this host has no match, so it is off in the live config.

Verified myself: merged into main in 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.md invariant 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 sol and opus the 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 PromptBoxTest are 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.

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. `promptBoxGateEnabled` is a new top-level config key. An absent key and `false` both leave the gate off; only `true` arms it. `grep -n promptBoxGateEnabled fleetd/fleetd.yaml` on this host has no match, so it is off in the live config. **Verified myself:** merged into `main` in 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.md` invariant 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 `sol` and `opus` the 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 `PromptBoxTest` are 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.
ltms closed this issue 2026-10-07 05:20:48 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: fleet/fleetd#797