code-yeongyu / code-yeongyu/senpi

TTSR paragraph-repeat detector misses near-repeat drift (exact hash match); needs normalized match gated by progress

Open
#1,330 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
429
Forks
98
Avg merge
5h 3m
Merged PRs (30d)
526

Description

## Summary

The TTSR paragraph-repeat detector landed in #1326 (`packages/coding-agent/src/core/extensions/builtin/ttsr/detectors/collapse-paragraphs.ts`) matches paragraphs by exact content: two hashes (FNV-1a style + djb2) plus the UTF-16 length (`isSameParagraph`), counted over a 64-entry ring, threshold 3, paragraphs >= 64 chars / 24 word chars.

Because the match is exact, a near-repeat loop escapes it: a model that re-narrates the same paragraph while only a counter, timestamp, or clause order drifts ("Now writing step 3...", "Now writing step 4...") produces distinct hashes, so the repeat count never reaches 3 and the stream runs until the user aborts. Interleaved repeats (A B A B A B) are already covered because the ring is windowed, not consecutive.

## Constraint on the fix

Loosening the match alone (whitespace/number masking before hashing) re-creates the false positive this detector was tuned to avoid: a legitimate list traversal that prints "processing item N" for N = 1..k collapses to one hash and would be interrupted as a loop. So a normalized match needs a progress gate as a precondition, e.g. treat a candidate repeat as a real loop only when no tool call was emitted between the repeats (the incident stream had 0 tool calls over 38K chars) or when tool arguments/checkpoints did not advance. Both halves belong in one change.

## Evidence

- Incident and replay analysis: sionicai session 01a06648 (2026-09-03), 38,193-char single text part, 7-paragraph cycle repeated ~9x, 0 tool calls; the exact-cycle case is what #1326 now catches.
- Source: `collapse-paragraphs.ts` `isSameParagraph` (hashA/hashB/utf16Length equality), `PARAGRAPH_REPEAT_THRESHOLD = 3`, `PARAGRAPH_RING_CAPACITY = 64`.

Surfaced while answering a community question in the Ultraworkers Discord (#chat-ko, 2026-09-03).

Contributor guide

Open the contributing guide

Research direction

Start in packages/coding-agent/src/core/extensions/builtin/ttsr/detectors/collapse-paragraphs.ts, reading isSameParagraph and the 64-entry ring, threshold, and length limits. Trace how repeats relate to emitted tool calls or advancing checkpoints before deciding how the progress gate fits. Done means near-repeat drift is detected without interrupting legitimate progressing lists, while exact repeats and interleaved repeats retain their intended behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
ai
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.