S9: the lesson-candidate question names the cluster topic, not the headline #1294

Closed
opened 2026-10-23 21:58:21 +00:00 by jared · 2 comments
Owner

Problem

After #1289 and #1293, the live S9 refresh on the real Store (2026-10-23) writes 2 eligible lesson candidates. Both questions read In 3 sessions you ruled on "## Prediction". Is this a rule? (y/n). LessonCandidate#question uses PatternCluster#headline, the stored first line of the seed moment, but the clusters now group moments by topic text (MomentTopic). The S9b SessionStart hook asks this question word for word, and Jared cannot answer a question that names no topic. The candidate file was moved out of the Store until this ships.

Approach

PatternClusterer already computes the topic text of each ruling moment. It gives each PatternCluster the topic text of its seed moment, without the clustering: prefix. PatternCluster#topic returns it. LessonCandidate#question uses topic in place of headline. PatternCluster#headline has no other caller and is removed.

Required work:

  1. PatternCluster takes the seed topic text and answers #topic — check: present attr_reader :topic in plugins/os-me/lib/os_me/pattern_cluster.rb
  2. LessonCandidate#question names the cluster topic — check: present @cluster.topic in plugins/os-me/lib/os_me/lesson_candidate.rb
  3. Remove PatternCluster#headline — check: absent def headline in plugins/os-me/lib/os_me/pattern_cluster.rb

Acceptance criteria

  1. Given three accepted ruling moments in three sessions, each with the stored headline ## Prediction and a transcript AI message whose topic text is Use option B for the cache. (the fake embedder maps them to one vector), when CandidateRefresh#run runs, then the candidate row's question is In 3 sessions you ruled on "Use option B for the cache.". Is this a rule? (y/n).
  2. Given an eligible cluster whose seed moment's transcript no longer exists and whose stored headline is Decision: cache the index, when CandidateRefresh#run runs, then the question names Decision: cache the index.
  3. Given a cluster from 4 sessions, when LessonCandidate#question is read, then the question text holds no clustering: prefix.

All criteria run in Minitest under plugins/os-me/test, with fixture transcripts in a temp dir and a fake embedder. No model call, no network. Update existing tests that build PatternCluster or read its headline.

Owner sketch

module OsMe
  class PatternCluster
    def initialize(moments, topic:); end
    def topic; end
  end

  class LessonCandidate
    def question
      "In #{@cluster.sessions.size} sessions you ruled on \"#{@cluster.topic}\". Is this a rule? (y/n)"
    end
  end
end

Scope and blocking

In scope: plugins/os-me/lib/os_me/pattern_cluster.rb, pattern_clusterer.rb, lesson_candidate.rb, and tests under plugins/os-me/test. Out of scope: candidate ids (they hash moment ids and do not change); the moved-aside candidate file, which the orchestrator regenerates after merge. Blocked by: none.

Origin

  • Trigger: live S9 refresh after #1293 merged on 2026-10-23 wrote candidates whose question names a markdown heading
  • Improvised this session: moved the candidate file out of the Store so the SessionStart hook asks nothing
  • Chain: unanswerable One Thing question ← question built from the stored headline ← clusters moved to topic text in #1289 but the question did not. Stop at CODE (plugins/os-me/lib/os_me/lesson_candidate.rb).
  • Root candidate: none found
  • Where: plugins/os-me/lib/os_me/lesson_candidate.rb; plugins/os-me/lib/os_me/pattern_cluster.rb
  • Session: 4f3f95ea-3c6f-4d23-a0ea-e349d6ab02a5
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/4f3f95ea-3c6f-4d23-a0ea-e349d6ab02a5.jsonl

VERDICT: CREATE (drafter follow-up of user-ruled #1289; backlog search only)

## Problem After #1289 and #1293, the live S9 refresh on the real Store (2026-10-23) writes 2 eligible lesson candidates. Both questions read `In 3 sessions you ruled on "## Prediction". Is this a rule? (y/n)`. `LessonCandidate#question` uses `PatternCluster#headline`, the stored first line of the seed moment, but the clusters now group moments by topic text (`MomentTopic`). The S9b SessionStart hook asks this question word for word, and Jared cannot answer a question that names no topic. The candidate file was moved out of the Store until this ships. ## Approach `PatternClusterer` already computes the topic text of each ruling moment. It gives each `PatternCluster` the topic text of its seed moment, without the `clustering: ` prefix. `PatternCluster#topic` returns it. `LessonCandidate#question` uses `topic` in place of `headline`. `PatternCluster#headline` has no other caller and is removed. Required work: 1. `PatternCluster` takes the seed topic text and answers `#topic` — check: present `attr_reader :topic` in `plugins/os-me/lib/os_me/pattern_cluster.rb` 2. `LessonCandidate#question` names the cluster topic — check: present `@cluster.topic` in `plugins/os-me/lib/os_me/lesson_candidate.rb` 3. Remove `PatternCluster#headline` — check: absent `def headline` in `plugins/os-me/lib/os_me/pattern_cluster.rb` ## Acceptance criteria 1. Given three accepted ruling moments in three sessions, each with the stored headline `## Prediction` and a transcript AI message whose topic text is `Use option B for the cache.` (the fake embedder maps them to one vector), when `CandidateRefresh#run` runs, then the candidate row's `question` is `In 3 sessions you ruled on "Use option B for the cache.". Is this a rule? (y/n)`. 2. Given an eligible cluster whose seed moment's transcript no longer exists and whose stored headline is `Decision: cache the index`, when `CandidateRefresh#run` runs, then the question names `Decision: cache the index`. 3. Given a cluster from 4 sessions, when `LessonCandidate#question` is read, then the question text holds no `clustering: ` prefix. All criteria run in Minitest under `plugins/os-me/test`, with fixture transcripts in a temp dir and a fake embedder. No model call, no network. Update existing tests that build `PatternCluster` or read its `headline`. ## Owner sketch ```ruby module OsMe class PatternCluster def initialize(moments, topic:); end def topic; end end class LessonCandidate def question "In #{@cluster.sessions.size} sessions you ruled on \"#{@cluster.topic}\". Is this a rule? (y/n)" end end end ``` ## Scope and blocking In scope: `plugins/os-me/lib/os_me/pattern_cluster.rb`, `pattern_clusterer.rb`, `lesson_candidate.rb`, and tests under `plugins/os-me/test`. Out of scope: candidate ids (they hash moment ids and do not change); the moved-aside candidate file, which the orchestrator regenerates after merge. Blocked by: none. ## Origin - Trigger: live S9 refresh after #1293 merged on 2026-10-23 wrote candidates whose question names a markdown heading - Improvised this session: moved the candidate file out of the Store so the SessionStart hook asks nothing - Chain: unanswerable One Thing question ← question built from the stored headline ← clusters moved to topic text in #1289 but the question did not. Stop at CODE (`plugins/os-me/lib/os_me/lesson_candidate.rb`). - Root candidate: none found - Where: plugins/os-me/lib/os_me/lesson_candidate.rb; plugins/os-me/lib/os_me/pattern_cluster.rb - Session: 4f3f95ea-3c6f-4d23-a0ea-e349d6ab02a5 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/4f3f95ea-3c6f-4d23-a0ea-e349d6ab02a5.jsonl VERDICT: CREATE (drafter follow-up of user-ruled #1289; backlog search only)
Author
Owner

Work started on branch ticket-1294 (os-sdlc implement).

Work started on branch ticket-1294 (os-sdlc implement).
Author
Owner

Resolution

Done: LessonCandidate#question names the seed topic via PatternCluster#topic; PatternCluster#headline removed

Evidence: Implementation 154 escalated (bound_exhausted suite-check, required-work check 1 literal def topic vs attr_reader); hand-finished: suite 372 runs 0 failures, rubocop clean, opus design audit pass

Follow-ups: none; live candidates rerun reported in session

## Resolution **Done:** LessonCandidate#question names the seed topic via PatternCluster#topic; PatternCluster#headline removed **Evidence:** Implementation 154 escalated (bound_exhausted suite-check, required-work check 1 literal def topic vs attr_reader); hand-finished: suite 372 runs 0 failures, rubocop clean, opus design audit pass **Follow-ups:** none; live candidates rerun reported in session
jared closed this issue 2026-10-23 22:13:13 +00:00
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
jared/cc-os#1294
No description provided.