fix(phrases): one invocation is a phrase, several are a concatenation #615

Merged
coilyco-ops merged 1 commit from fix/one-invocation-is-a-phrase-claude into main 2026-08-13 17:16:34 +00:00
Member

closes #613

Quail's finding, and their framing settled the fix.

func Terminal(reply string) bool {
	return strings.TrimSpace(phraseInvocation.ReplaceAllString(reply, "")) == ""
}

Stripping every invocation and finding nothing left is also true of two. So a reply carrying several was terminal, RenderPhrases resolved all of them, and the member received the concatenation — including the same phrase twice.

The commit that built this said "a phrase is the whole reply or it is not a phrase." Terminal was reading that as "nothing but phrases." The two differ by exactly the case Quail found.

Counted, not length-bounded

A ceiling on the concatenation would still admit two short phrases, and two phrases is not a phrase at any length. The 15-word ceiling in #175 is a separate check on a separate question, and conflating them would leave both half-enforced.

What is pinned

Four groups: one invocation with surrounding whitespace is terminal; several in every arrangement are not; prose beside an invocation stays non-terminal, which is what this function was built for and the thing counting could have traded away; and a reply with no invocation — including {{}} — is not a phrase.

ward exec gate green.

closes #613 **Quail's finding**, and their framing settled the fix. ```go func Terminal(reply string) bool { return strings.TrimSpace(phraseInvocation.ReplaceAllString(reply, "")) == "" } ``` Stripping every invocation and finding nothing left is **also true of two**. So a reply carrying several was terminal, `RenderPhrases` resolved all of them, and the member received the concatenation — including the same phrase twice. The commit that built this said *"a phrase is the whole reply or it is not a phrase."* `Terminal` was reading that as *"nothing but phrases."* The two differ by exactly the case Quail found. ## Counted, not length-bounded A ceiling on the concatenation would still admit two short phrases, and **two phrases is not a phrase at any length**. The 15-word ceiling in #175 is a separate check on a separate question, and conflating them would leave both half-enforced. ## What is pinned Four groups: one invocation with surrounding whitespace is terminal; several in every arrangement are not; **prose beside an invocation stays non-terminal**, which is what this function was built for and the thing counting could have traded away; and a reply with no invocation — including `{{}}` — is not a phrase. `ward exec gate` green.
fix(phrases): one invocation is a phrase, several are a concatenation
All checks were successful
ci / image-build (pull_request) Successful in 22s
ci / test (pull_request) Successful in 33s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
f46a5ef57f
Terminal stripped every invocation and asked whether anything remained. That is
also true of two, so a reply carrying several resolved all of them and the
member received them joined together, including the same phrase twice.

The commit that built this said a phrase is the whole reply or it is not a
phrase. Terminal was reading that as nothing but phrases, and the two differ by
exactly the case Quail found.

Counted rather than length-bounded. A ceiling on the concatenation would still
admit two short phrases, and two phrases is not a phrase at any length. The
word ceiling in issue 175 is a different check on a different question.

The prefix case this function exists for is pinned alongside, because counting
must not trade it away.

Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
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!615
No description provided.