Attribute mid-stream repetition aborts to model and detector (CL-6775) - #580
Merged
TheGreatAxios merged 1 commit intoAug 23, 2026
Conversation
Repetition aborts in the intervention log (CL-6938) were all filed under one generic "repetition" id with no way to tell which of the three detectors fired or see the measured value against its threshold. Fold the detector name into the intervention id (repetition-raw-text-periodicity, repetition-digit-folded-thinking, repetition-contentless-growth) and record the measured value with its threshold for each. The contentless growth guard previously logged no measurement at all. scripts/intervention-forensics.ts already buckets by class/id and splits by family; add a per-model breakdown (family groups multiple models together) and a dedicated repetition-aborts-by-model summary so "which model loops most" reads directly off the report. No stream content is logged: repetitionStopDetail now reports period length and repeat count instead of the looped window text. No threshold values changed.
TheGreatAxios
added a commit
that referenced
this pull request
Aug 27, 2026
…nerate-repetition-aborts-per-model-and Attribute mid-stream repetition aborts to model and detector (CL-6775)
TheGreatAxios
added a commit
that referenced
this pull request
Aug 27, 2026
…nerate-repetition-aborts-per-model-and Attribute mid-stream repetition aborts to model and detector (CL-6775)
TheGreatAxios
deleted the
cl-6775-track-mid-stream-degenerate-repetition-aborts-per-model-and
branch
August 27, 2026 23:59
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes CL-6775.
What's recorded
src/subagent/repetition.ts aborts a run for one of three reasons: a raw-text periodicity hit, a digit-folded thinking-stream hit, or the contentless/zero-width growth guard. Until now every abort landed in the intervention log (CL-6938) under one generic
id: "repetition", and the contentless-growth path logged nomeasurementat all.This PR keeps writing into the existing
interventions.jsonlsink and:idinstead of adding a new field:repetition-raw-text-periodicity,repetition-digit-folded-thinking,repetition-contentless-growth. Model, provider, and family are already carried on every record by the log's per-run context (CL-6938), so this alone gives per-model, per-detector attribution.measurementfor every abort:{ metric: "repeats", value, threshold }for the two periodicity detectors,{ metric: "visibleChars", value, threshold }for the contentless guard (previously missing).detail(both in the log and the parent-facing "Stopped:" line) content-free:repetitionStopDetailnow reportsperiod <n>ch × <repeats> (threshold <t>)instead of a slice of the looped text, and the newcontentlessGrowthDetailreports raw/visible char counts instead of stream content. The looped-window sample the parent needs to judge the abort still travels separately viapartial(the Findings section of the salvage report), capped as before — that path is unchanged.Reuse vs. new file
Reused
src/subagent/intervention-log.tsrather than adding a new logging mechanism. The record shape (InterventionRecord) didn't need to change at all — model/provider/family/measurement/state were already there from CL-6938 for stop events; the only gap was that the repetition abort site collapsed three distinct detectors into one id and dropped the measurement for one of them. A distinct id per detector was enough to get separable per-model, per-detector rows without touching the type or the sink.Reading the rate back
scripts/intervention-forensics.tsalready aggregates byclass/idand breaks each downbyFamily; this PR adds:byModelon top ofbyFamily(family groups every grok variant together; model doesn't).repetition-*ids per model — reads directly as "which model loops most".This surfaces counts, not a dispatch-normalized rate: the log's
outcomerecords (total completed dispatches, CL-6938) are written from the parent side without a model tag, so a per-model denominator isn't tracked yet. Counts by model already answer the issue's stated question ("which model loops most this week"); wiring a true per-model rate would mean tagging outcome records with model, which is a separate, larger change to the parent-side dispatch path and is left as a follow-up if the raw counts turn out to be insufficient.Thresholds
No threshold value changed.
DEFAULT_REPETITION_CONFIG,DEFAULT_TEXT_FOLDED_REPETITION_CONFIG,DEFAULT_THINKING_REPETITION_CONFIG, andDEFAULT_CONTENTLESS_GROWTH_CONFIGare read to report the threshold that was crossed, never written.Gate
bun run check(lint, typecheck, build, full test suite) is green: 5345 tests pass, 0 lint errors (pre-existing warnings only, unrelated to this change).