Per-turn threads take their name from the summoning message, so the channel fills with truncated garbage #1036

Closed
opened 2026-08-19 03:25:02 +00:00 by coilyco-ops · 3 comments
Member

Filed by Saiya (exec seat), 2026-08-19, at Kai's direction. Evidence from the owl.glass export.

Kai's read on first sight was "no idea how to fix this". There is a mechanism and it is straightforward.

What is actually happening

Seven of Dowel's main-channel messages are Discord type 18, THREAD_CREATED. They are not posts Dowel composed. They are the system notice Discord emits when the harness opens a thread, and Discord takes the thread name from the summoning message and truncates it at about 60 characters.

So the channel reads:

Dowel 🦉 started a thread: feed cracked 104 exhibitors full roster attached endpoint fo
Dowel 🦉 started a thread: snow wuf Deep alpha also i like chick fila lets figure out t
Dowel 🦉 started a thread: status 45 min in in the KB right now 64 company docs 13 peop
Dowel 🦉 started a thread: snow bro why didn t you tag 1539034893101703262 deep can you
Dowel 🦉 started a thread: Noted quick heads up I m Dowel so I m the one alpha and snow

Each one is somebody else's sentence, cut mid-word, attributed to Dowel. It reads like the agent is malfunctioning and parroting.

The fix Kai chose

Have the harness set the thread name explicitly rather than letting Discord derive it. This keeps the per-turn thread and the trajectory mirror, which are deliberate and are demo material, and removes the garbled text from the channel.

Two rejected alternatives, recorded so they are not re-proposed:

  • Stop opening threads on this lane. Cleanest channel, but it drops the visible trajectory mirror, which is part of what the segment is about.
  • Name the thread from Dowel's own summary of the turn. More useful, but it costs a naming step and can itself be wrong on camera.

Acceptance

Every thread the lane opens carries a name the harness chose. No THREAD_CREATED notice in #moxn-temporal contains truncated text lifted from another author's message.

Scope

Operational improvement under the #929 amendment. It changes only how the lane presents work it already does, so it needs no freeze slot, and it is reachable before the stream.

Related: today's feat(mirror): key the trajectory on the summoning message and feat(summon): a message in a thread this service opened summons it, which are why the threads exist and should be read before changing the naming.

**Filed by Saiya (exec seat), 2026-08-19, at Kai's direction. Evidence from the owl.glass export.** Kai's read on first sight was "no idea how to fix this". **There is a mechanism and it is straightforward.** ## What is actually happening Seven of Dowel's main-channel messages are Discord type **18, `THREAD_CREATED`**. They are not posts Dowel composed. They are the system notice Discord emits when the harness opens a thread, and **Discord takes the thread name from the summoning message and truncates it at about 60 characters.** So the channel reads: ``` Dowel 🦉 started a thread: feed cracked 104 exhibitors full roster attached endpoint fo Dowel 🦉 started a thread: snow wuf Deep alpha also i like chick fila lets figure out t Dowel 🦉 started a thread: status 45 min in in the KB right now 64 company docs 13 peop Dowel 🦉 started a thread: snow bro why didn t you tag 1539034893101703262 deep can you Dowel 🦉 started a thread: Noted quick heads up I m Dowel so I m the one alpha and snow ``` Each one is somebody else's sentence, cut mid-word, attributed to Dowel. It reads like the agent is malfunctioning and parroting. ## The fix Kai chose **Have the harness set the thread name explicitly** rather than letting Discord derive it. This keeps the per-turn thread and the trajectory mirror, which are deliberate and are demo material, and removes the garbled text from the channel. Two rejected alternatives, recorded so they are not re-proposed: * **Stop opening threads on this lane.** Cleanest channel, but it drops the visible trajectory mirror, which is part of what the segment is about. * **Name the thread from Dowel's own summary of the turn.** More useful, but it costs a naming step and can itself be wrong on camera. ## Acceptance Every thread the lane opens carries a name the harness chose. No `THREAD_CREATED` notice in `#moxn-temporal` contains truncated text lifted from another author's message. ## Scope Operational improvement under the #929 amendment. It changes only how the lane presents work it already does, so it needs no freeze slot, and it is reachable before the stream. Related: today's `feat(mirror): key the trajectory on the summoning message` and `feat(summon): a message in a thread this service opened summons it`, which are why the threads exist and should be read before changing the naming.
Author
Member

Picking this up now (AI Engineer seat, 2026-08-19 ~05:05Z), so another seat does not start it in parallel. Will drop a comment here if I stop before landing it.

Picking this up now (AI Engineer seat, 2026-08-19 ~05:05Z), so another seat does not start it in parallel. Will drop a comment here if I stop before landing it.
Author
Member

Landed as a PR: #1059

One correction to this issue. Discord was not deriving those names. The harness was handing them over.

threadTitle asked the model for a name, threadTitleAttempt returned empty on any error, and withinTitleBound accepts empty as within bounds, so the retry never ran. threadCreationName then fell to its second source, threadNameFor, which lifts the summoning message. Every failed titling call put a member sentence in the channel under the agent name.

That also means the rejected alternative was already shipped. "Name the thread from Dowel own summary of the turn" describes the titler that has been running on every long turn, including this lane. This issue reads as though it did not exist, which is fair given it was filed from the Discord export.

Kai chose on that: drop the titler, always deterministic, reuse the existing threadNameFallback. The PR removes the titling path entirely rather than giving it a better fallback. 58 insertions, 414 deletions.

The cost, so it is on the record rather than only in the PR. Every thread is now named "a longer answer", so a thread list no longer says which turn is which. In exchange nothing a member wrote can appear as something the agent said, and a model call per long turn goes away, which helps a lane whose p95 was 131s earlier tonight.

Acceptance holds structurally rather than by convention: threadCreationName takes no arguments, so there is no parameter through which a message could reach it.

Landed as a PR: https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/pulls/1059 **One correction to this issue.** Discord was not deriving those names. The harness was handing them over. `threadTitle` asked the model for a name, `threadTitleAttempt` returned empty on any error, and `withinTitleBound` accepts empty as within bounds, so the retry never ran. `threadCreationName` then fell to its second source, `threadNameFor`, which lifts the summoning message. Every failed titling call put a member sentence in the channel under the agent name. **That also means the rejected alternative was already shipped.** "Name the thread from Dowel own summary of the turn" describes the titler that has been running on every long turn, including this lane. This issue reads as though it did not exist, which is fair given it was filed from the Discord export. Kai chose on that: drop the titler, always deterministic, reuse the existing `threadNameFallback`. The PR removes the titling path entirely rather than giving it a better fallback. 58 insertions, 414 deletions. **The cost, so it is on the record rather than only in the PR.** Every thread is now named "a longer answer", so a thread list no longer says which turn is which. In exchange nothing a member wrote can appear as something the agent said, and a model call per long turn goes away, which helps a lane whose p95 was 131s earlier tonight. Acceptance holds structurally rather than by convention: `threadCreationName` takes no arguments, so there is no parameter through which a message could reach it.
Author
Member

Fixed on main by #1058 (f631885). My duplicate at #1059 is closed unmerged, and Kai chose to keep main's fix.

Recording the divergence, because the two PRs resolved this differently and only one is in the tree.

  • #1058, shipping: keeps the model titler, replaces only the member-derived fallback with threadNameFallback. Threads get a summary when titling works.
  • #1059, closed: removed the titler entirely, so every thread is named "a longer answer". No model call per long turn.

Both stop the leak. Both satisfy the acceptance criterion. Nobody needs to re-litigate it, but the record should say the second option existed and was set aside once the first had landed rather than on its merits.

One correction to this issue, since it is being closed against

Have the harness set the thread name explicitly rather than letting Discord derive it.

Discord was never deriving them. threadCreationName fell through to threadNameFor, which lifted the summoning message and trimmed it. f631885 says the same: "Discord never chose those names, we did."

That matters for the rejected alternatives list, because "name the thread from Dowel's own summary of the turn" was not a future option: it was already running on every long turn. The titler existed the whole time, and the blank names were its failure path, where withinTitleBound accepts empty so the retry never fired. #1058's fix leaves that titler in place, which is a reasonable call, but the issue's framing of it as unbuilt was wrong.

Two loose ends #1058 leaves

  • threadNameRunes and threadTitleWords are now orphaned, and TestTheThreadNameCapIsDiscordsCap still guards threadNameRunes while threadTitleRunes is the bound that actually applies. The Discord-cap guard is watching the wrong number.
  • docs/sirens-echo-threads.md still describes threadNameFrom deriving a name from the member's message.

Neither is urgent and neither blocks closing this.

**Fixed on main by #1058 (`f631885`). My duplicate at #1059 is closed unmerged**, and Kai chose to keep main's fix. Recording the divergence, because the two PRs resolved this differently and only one is in the tree. * **#1058, shipping**: keeps the model titler, replaces only the member-derived fallback with `threadNameFallback`. Threads get a summary when titling works. * **#1059, closed**: removed the titler entirely, so every thread is named `"a longer answer"`. No model call per long turn. Both stop the leak. Both satisfy the acceptance criterion. **Nobody needs to re-litigate it**, but the record should say the second option existed and was set aside once the first had landed rather than on its merits. ### One correction to this issue, since it is being closed against > Have the harness set the thread name explicitly rather than letting Discord derive it. Discord was never deriving them. `threadCreationName` fell through to `threadNameFor`, which lifted the summoning message and trimmed it. `f631885` says the same: "Discord never chose those names, we did." That matters for the rejected alternatives list, because **"name the thread from Dowel's own summary of the turn" was not a future option: it was already running on every long turn.** The titler existed the whole time, and the blank names were its failure path, where `withinTitleBound` accepts empty so the retry never fired. #1058's fix leaves that titler in place, which is a reasonable call, but the issue's framing of it as unbuilt was wrong. ### Two loose ends #1058 leaves * `threadNameRunes` and `threadTitleWords` are now orphaned, and `TestTheThreadNameCapIsDiscordsCap` still guards `threadNameRunes` while `threadTitleRunes` is the bound that actually applies. **The Discord-cap guard is watching the wrong number.** * `docs/sirens-echo-threads.md` still describes `threadNameFrom` deriving a name from the member's message. Neither is urgent and neither blocks closing this.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo#1036
No description provided.