Add a pattern opportunity detector over the catalog #1430

Closed
opened 2026-10-27 17:48:52 +00:00 by jared · 4 comments
Owner

Problem

The pattern catalog under plugins/os-sdlc/lib/os_sdlc/system_model/catalog/ holds six patterns (hex, layers, pipes_and_filters, command_router, repository, transaction_script) with role predicates, but no detector walks the model and names a near-match. Step 5 of the path to real asks for a pattern opportunity detector over a catalog of a pattern list held as data, with the proof that it names at least one near-match in os-me a human agrees should be a pattern.

Reproduce

plugins/os-sdlc/bin/system-model opportunities plugins/os-me

Output: the usage line, exit 2. No subcommand ranks cards against the catalog.

Approach

Add an opportunities subcommand. For every pattern in Catalog, bind each role predicate to the cards whose ClassFacts satisfy it, score the binding by the share of roles filled and the share of catalog rules the bound cards obey, and print the top bindings as <pattern> <score> <role>=<card> ... with the unmet rules. Grow the catalog toward thirty patterns in later tickets, one pattern per ticket, each with its own role predicates and rules; this ticket adds the detector over the six that exist.

Required work:

  1. Add an Opportunity object that binds one pattern's roles to cards and scores the binding — check: present Opportunity in plugins/os-sdlc/lib/os_sdlc/system_model/pattern/*.rb
  2. Add an OpportunityReport that prints bindings sorted by score — check: present OpportunityReport in plugins/os-sdlc/lib/os_sdlc/system_model/*.rb
  3. Accept opportunities in the system-model argv parser and usage text — check: present opportunities in plugins/os-sdlc/lib/os_sdlc/boot/inputs.rb
  4. Route opportunities through Run with the Tracer step — check: present opportunities in plugins/os-sdlc/lib/os_sdlc/system_model/run.rb

Realigned spec

Spec realigned 2026-11-01 (README section 6 step 10, ruled by Jared 2026-11-01):

  • The pattern list and the thresholds are data. No pattern ID appears in detector code.
  • Convergence is computed for each scale group (pattern-matching.md section 5, amendment 2026-11-01).
  • The output prints a coverage figure for each plugin.
  • Blocked by the step 9 fact spike ticket (#1482) and the forbidden-edge rule evaluator ticket (#1483), which supplies the misfits for each Match.
  • Proof: run over os-me and os-sdlc together and read the top ten findings by hand.

Acceptance criteria

  1. Given a model whose cards satisfy every role predicate of one catalog pattern and obey every rule, when the detector runs, then that pattern scores 1.0 and each role names its card.
  2. Given a model whose cards satisfy two of three roles of a pattern, when the detector runs, then the binding lists the unfilled role by name.
  3. Given a binding whose cards break one catalog rule, when the detector runs, then the output names the broken rule.
  4. Given a seventh stub pattern added to the pattern data, when the detector runs, then it runs with no code change and no pattern ID appears in detector code.
  5. Given a model with several scale groups, when the detector runs, then convergence is computed for each scale group.
  6. Given a run over os-me and os-sdlc together, when the output prints, then it holds a coverage figure for each plugin.
  7. Given plugins/os-me as the target, when system-model opportunities plugins/os-me runs, then it exits zero and prints at least one binding with a score, roles and cards.

Owner sketch

class OsSdlc::SystemModel::Pattern::Opportunity
  def initialize(pattern, model); end
  def score; end
  def roles; end
  def unmet_rules; end
end
class OsSdlc::SystemModel::OpportunityReport
  def initialize(stdout); end
  def print(opportunities); end
end

Non-goals

The thirty-pattern catalog. The human agreement proof runs after this ticket and is recorded in docs/system-design-format/proof/.

Origin

  • Trigger: pattern-detection track handoff 2026-10-27-1540, step 5: capture README section 6 steps 4, 5, 7
  • Improvised this session: none
  • Chain: no named near-match ← no detector over the catalog ← DESIGN (docs/system-design-format/README.md section 6 step 5 not built; #1404 built the predicates only)
  • Root candidate: none found; searched opportunity, near-match, catalog, binding, pattern distance, system-model
  • Where: docs/system-design-format/README.md section 6 step 5; plugins/os-sdlc/lib/os_sdlc/system_model/catalog.rb
  • Session: 47f54f99-e35c-4567-a3e6-581fecf54dc3
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-ticket-1392/47f54f99-e35c-4567-a3e6-581fecf54dc3.jsonl

VERDICT: CREATE

## Problem The pattern catalog under `plugins/os-sdlc/lib/os_sdlc/system_model/catalog/` holds six patterns (hex, layers, pipes_and_filters, command_router, repository, transaction_script) with role predicates, but no detector walks the model and names a near-match. Step 5 of the path to real asks for a pattern opportunity detector over a catalog of a pattern list held as data, with the proof that it names at least one near-match in os-me a human agrees should be a pattern. ## Reproduce ``` plugins/os-sdlc/bin/system-model opportunities plugins/os-me ``` Output: the usage line, exit 2. No subcommand ranks cards against the catalog. ## Approach Add an `opportunities` subcommand. For every pattern in `Catalog`, bind each role predicate to the cards whose `ClassFacts` satisfy it, score the binding by the share of roles filled and the share of catalog rules the bound cards obey, and print the top bindings as `<pattern> <score> <role>=<card> ...` with the unmet rules. Grow the catalog toward thirty patterns in later tickets, one pattern per ticket, each with its own role predicates and rules; this ticket adds the detector over the six that exist. Required work: 1. Add an `Opportunity` object that binds one pattern's roles to cards and scores the binding — check: present `Opportunity` in `plugins/os-sdlc/lib/os_sdlc/system_model/pattern/*.rb` 2. Add an `OpportunityReport` that prints bindings sorted by score — check: present `OpportunityReport` in `plugins/os-sdlc/lib/os_sdlc/system_model/*.rb` 3. Accept `opportunities` in the system-model argv parser and usage text — check: present `opportunities` in `plugins/os-sdlc/lib/os_sdlc/boot/inputs.rb` 4. Route `opportunities` through `Run` with the Tracer step — check: present `opportunities` in `plugins/os-sdlc/lib/os_sdlc/system_model/run.rb` ## Realigned spec Spec realigned 2026-11-01 (README section 6 step 10, ruled by Jared 2026-11-01): * The pattern list and the thresholds are data. No pattern ID appears in detector code. * Convergence is computed for each scale group (pattern-matching.md section 5, amendment 2026-11-01). * The output prints a coverage figure for each plugin. * Blocked by the step 9 fact spike ticket (#1482) and the forbidden-edge rule evaluator ticket (#1483), which supplies the misfits for each Match. * Proof: run over os-me and os-sdlc together and read the top ten findings by hand. ## Acceptance criteria 1. Given a model whose cards satisfy every role predicate of one catalog pattern and obey every rule, when the detector runs, then that pattern scores 1.0 and each role names its card. 2. Given a model whose cards satisfy two of three roles of a pattern, when the detector runs, then the binding lists the unfilled role by name. 3. Given a binding whose cards break one catalog rule, when the detector runs, then the output names the broken rule. 4. Given a seventh stub pattern added to the pattern data, when the detector runs, then it runs with no code change and no pattern ID appears in detector code. 5. Given a model with several scale groups, when the detector runs, then convergence is computed for each scale group. 6. Given a run over os-me and os-sdlc together, when the output prints, then it holds a coverage figure for each plugin. 7. Given `plugins/os-me` as the target, when `system-model opportunities plugins/os-me` runs, then it exits zero and prints at least one binding with a score, roles and cards. ## Owner sketch ```ruby class OsSdlc::SystemModel::Pattern::Opportunity def initialize(pattern, model); end def score; end def roles; end def unmet_rules; end end class OsSdlc::SystemModel::OpportunityReport def initialize(stdout); end def print(opportunities); end end ``` ## Non-goals The thirty-pattern catalog. The human agreement proof runs after this ticket and is recorded in `docs/system-design-format/proof/`. ## Origin - Trigger: pattern-detection track handoff 2026-10-27-1540, step 5: capture README section 6 steps 4, 5, 7 - Improvised this session: none - Chain: no named near-match ← no detector over the catalog ← DESIGN (docs/system-design-format/README.md section 6 step 5 not built; #1404 built the predicates only) - Root candidate: none found; searched opportunity, near-match, catalog, binding, pattern distance, system-model - Where: docs/system-design-format/README.md section 6 step 5; plugins/os-sdlc/lib/os_sdlc/system_model/catalog.rb - Session: 47f54f99-e35c-4567-a3e6-581fecf54dc3 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-ticket-1392/47f54f99-e35c-4567-a3e6-581fecf54dc3.jsonl VERDICT: CREATE
Author
Owner

Waiting on #1482 (step 9 fact spike) and #1483 (forbidden-edge rule evaluator, which supplies the misfits for each Match). Spec realigned to README section 6 step 10: pattern list and thresholds are data, no pattern ID in detector code, convergence per scale group, coverage figure per plugin. Body edited 2026-11-01.

Waiting on #1482 (step 9 fact spike) and #1483 (forbidden-edge rule evaluator, which supplies the misfits for each Match). Spec realigned to README section 6 step 10: pattern list and thresholds are data, no pattern ID in detector code, convergence per scale group, coverage figure per plugin. Body edited 2026-11-01.
Author
Owner

os-backlog cannot add labels yet (#867, the label verb ticket). This ticket stays blocked by #1482 and #1483 per its earlier comments.

os-backlog cannot add labels yet (#867, the label verb ticket). This ticket stays blocked by #1482 and #1483 per its earlier comments.
Author
Owner

Work started 2026-11-01 in worktree branch worktree-agent-ac63aa91edc5b552e (realigned spec: per-component scoring, per-group thresholds, per-finding convergence).

Work started 2026-11-01 in worktree branch worktree-agent-ac63aa91edc5b552e (realigned spec: per-component scoring, per-group thresholds, per-finding convergence).
Author
Owner

Resolution

Done: Pattern opportunity detector shipped with noise fixes

Evidence: d7107d26 + eda2266e, merge 85599697, noise fixes bc6c435a f391cf83 merged 6759ca0c; suite 3061 runs green

Follow-ups: #1494 #1495 #1496 #1497; store/adapter faulted for its own I/O and pattern-vs-signal convergence: pending Jared's ruling in session, no ticket yet

## Resolution **Done:** Pattern opportunity detector shipped with noise fixes **Evidence:** d7107d26 + eda2266e, merge 85599697, noise fixes bc6c435a f391cf83 merged 6759ca0c; suite 3061 runs green **Follow-ups:** #1494 #1495 #1496 #1497; store/adapter faulted for its own I/O and pattern-vs-signal convergence: pending Jared's ruling in session, no ticket yet
jared closed this issue 2026-11-01 17:18:38 +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#1430
No description provided.