Compose selection by kind drops the start of a session: the summary now opens mid-scene #589

Closed
opened 2026-09-10 06:33:25 +00:00 by claude-bot · 1 comment
Contributor

Regression from #568/#587, seen on the first real run. Re-summarised the 2026-09-09 session on dev with Gemma 4 26B: 81 verified events, so select_beats_for_compose capped at 30 and ranked reveal/decision/combat/travel above social/other. The resulting summary opens:

"The journey through the cavern took a treacherous turn as Idani moved to the lower level."

That is the event at 02:38. The session's premise is gone. Here are the first verified events in time order, with their kinds:

[00:04] other   The characters complete a long rest in the caverns.
[00:50] other   The characters wake up to find they are no longer where they fell asleep.
[01:17] other   The characters realize they were in the shifting caverns.
[02:18] other   Idani discovers a river and a rickety bridge.
[02:38] travel  Idani moves to the lower level of the cavern.

Everything establishing the session is typed other, so the kind ranking cut all of it and kept the first travel. On this run other was 35 of 81 verified events and social another 15, i.e. 62% of the session sits in the two demoted tiers. The same shape appeared on the previous run (other 27 of 59).

The rule is wrong, not the cap. A summary must span the session; "most significant" is not the same as "representative", and a two-tier kind sort optimises the wrong one. It also compounds #588 (duplicate beats) and the observation that the extractor's type list fits exploration sessions badly.

Proposed replacement: time-stratified selection. Sort verified beats chronologically, divide the session's span into as many buckets as the cap allows, take the best beat from each non-empty bucket (kind priority as the tiebreak within a bucket, earliest first on a tie), then fill any slack from the remaining beats by kind priority and time, and re-sort chronologically. That guarantees the opening and the ending are both represented, keeps the preference for reveals and decisions where a moment offers a choice, stays pure and deterministic, and keeps the identity property below the cap.

Test it against this run's data, where the answer is known: the three opening other beats must survive, and the selection must contain at least one beat from each fifth of the session.

**Regression from #568/#587, seen on the first real run.** Re-summarised the 2026-09-09 session on dev with Gemma 4 26B: 81 verified events, so `select_beats_for_compose` capped at 30 and ranked `reveal`/`decision`/`combat`/`travel` above `social`/`other`. The resulting summary opens: > "The journey through the cavern took a treacherous turn as Idani moved to the lower level." That is the event at 02:38. The session's premise is gone. Here are the first verified events in time order, with their kinds: ``` [00:04] other The characters complete a long rest in the caverns. [00:50] other The characters wake up to find they are no longer where they fell asleep. [01:17] other The characters realize they were in the shifting caverns. [02:18] other Idani discovers a river and a rickety bridge. [02:38] travel Idani moves to the lower level of the cavern. ``` Everything establishing the session is typed `other`, so the kind ranking cut all of it and kept the first `travel`. On this run `other` was 35 of 81 verified events and `social` another 15, i.e. 62% of the session sits in the two demoted tiers. The same shape appeared on the previous run (`other` 27 of 59). **The rule is wrong, not the cap.** A summary must span the session; "most significant" is not the same as "representative", and a two-tier kind sort optimises the wrong one. It also compounds #588 (duplicate beats) and the observation that the extractor's type list fits exploration sessions badly. **Proposed replacement: time-stratified selection.** Sort verified beats chronologically, divide the session's span into as many buckets as the cap allows, take the best beat from each non-empty bucket (kind priority as the tiebreak *within* a bucket, earliest first on a tie), then fill any slack from the remaining beats by kind priority and time, and re-sort chronologically. That guarantees the opening and the ending are both represented, keeps the preference for reveals and decisions where a moment offers a choice, stays pure and deterministic, and keeps the identity property below the cap. **Test it against this run's data**, where the answer is known: the three opening `other` beats must survive, and the selection must contain at least one beat from each fifth of the session.
Author
Contributor

Fixed in the PR opened alongside this comment, with one correction to the acceptance test I specified above.

"The three opening other beats must survive" cannot hold on this session's shape, and was not made to hold. With 81 verified events over about fifty minutes and a cap of 30, a bucket is 99 seconds wide; the establishing events are at 00:04, 00:50 and 01:17, all inside bucket zero, which is entitled to one slot. Every other bucket on that run is occupied, so there is no slack to rescue the other two. Forcing it would need either a fill that round-robins buckets or a special case for "the first N events", and both are a different rule than the one specified.

What is asserted instead:

  • the summary now opens where the session opened — the 00:04 event is the first selected, which is the regression this issue reported;
  • the cost is pinned explicitly, with the arithmetic in the test's docstring, rather than left to be rediscovered;
  • and a shorter session (45 events over fifteen minutes, so roughly 29-second buckets) does keep the whole opening, which is the case the original assertion describes.

Coverage across every fifth of the session, a floor on how many demoted-kind events survive, determinism under reversed input, and both the one-minute and true zero-length spans are also tested. One test from #568 asserted the behaviour this issue removes and was rewritten into three smaller ones; the rest of #568's tests pass unmodified.

Fixed in the PR opened alongside this comment, with one correction to the acceptance test I specified above. **"The three opening `other` beats must survive" cannot hold on this session's shape, and was not made to hold.** With 81 verified events over about fifty minutes and a cap of 30, a bucket is 99 seconds wide; the establishing events are at 00:04, 00:50 and 01:17, all inside bucket zero, which is entitled to one slot. Every other bucket on that run is occupied, so there is no slack to rescue the other two. Forcing it would need either a fill that round-robins buckets or a special case for "the first N events", and both are a different rule than the one specified. What is asserted instead: - the summary now opens where the session opened — the 00:04 event is the first selected, which is the regression this issue reported; - the cost is pinned explicitly, with the arithmetic in the test's docstring, rather than left to be rediscovered; - and a shorter session (45 events over fifteen minutes, so roughly 29-second buckets) does keep the whole opening, which is the case the original assertion describes. Coverage across every fifth of the session, a floor on how many demoted-kind events survive, determinism under reversed input, and both the one-minute and true zero-length spans are also tested. One test from #568 asserted the behaviour this issue removes and was rewritten into three smaller ones; the rest of #568's tests pass unmodified.
Sign in to join this conversation.
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
rbrooks/Quest-Board#589
No description provided.