decision-system S2a: DecisionModel port with headless adapter #1242

Closed
opened 2026-10-23 15:17:23 +00:00 by jared · 2 comments
Owner

Problem

The extraction pipeline needs a model call for reply shape. The plan keeps a small port so a shared gem can replace it later (O-7). Without the port, every object calls HeadlessRunner directly and a swap in S8 becomes a rewrite.

Approach

Required work:

  1. Add OsMe::DecisionModel::Question and OsMe::DecisionModel::Answer value objects — check: present class Question in plugins/os-me/lib/**/*.rb
  2. Add OsMe::DecisionModel::Client that takes an adapter and a CriteriaRules and returns an Answer — check: present class Client in plugins/os-me/lib/**/*.rb
  3. Add OsMe::DecisionModel::CriteriaRules — check: present class CriteriaRules in plugins/os-me/lib/**/*.rb
  4. Add the adapter OsMe::DecisionModel::HeadlessClaude, built on HeadlessRunner — check: present class HeadlessClaude in plugins/os-me/lib/**/*.rb

Notes: O-7 AFK default: wait for email-triage #9 and hold a minimal in-plugin port with the same interface. Do not depend on a gem. Name no gem. Follow the AFK rules in docs/decision-system/build-plan.md: never wait for Jared, use the AFK default of each open item, and list each default used in the report.

Acceptance criteria

  1. Given a Question with criteria rules and a fake adapter, when Client#ask runs, then it returns the Answer that the adapter gave.
  2. Given a Question, when HeadlessClaude runs with a stubbed HeadlessRunner, then it passes the question text and returns the parsed Answer.
  3. Given an adapter that raises, when Client#ask runs, then the error reaches the caller and no Answer is returned.

Owner sketch

module OsMe::DecisionModel
  class Question; end
  class Answer; end
  class CriteriaRules; end
  class Client
    def initialize(adapter:); end
    def ask(question, rules); end
  end
  class HeadlessClaude
    def call(question); end
  end
end

Scope and blocking

Shapes are in docs/decision-system/extraction.md and docs/decision-system/decision-model.md.

Non-goals: the gem swap (S8); other adapters (S8).

Origin

  • Trigger: User asked for the decision-system build tickets this session
  • Improvised this session: none
  • Chain: no ticket for this stage ← the build plan names the stage and the user asked for the tickets. Stop at DESIGN (docs/decision-system/build-plan.md).
  • Root candidate: none found; searched DecisionModel, decision, os-me
  • Where: docs/decision-system/build-plan.md S2 group (a); plugins/os-me/lib/os_me/decision_model/
  • Session: 4f3f95ea-3c6f-4d23-a0ea-e349d6ab02a5
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/4f3f95ea-3c6f-4d23-a0ea-e349d6ab02a5.jsonl

VERDICT: CREATE (user-approved; backlog search only)

## Problem The extraction pipeline needs a model call for reply shape. The plan keeps a small port so a shared gem can replace it later (O-7). Without the port, every object calls `HeadlessRunner` directly and a swap in S8 becomes a rewrite. ## Approach Required work: 1. Add `OsMe::DecisionModel::Question` and `OsMe::DecisionModel::Answer` value objects — check: present `class Question` in `plugins/os-me/lib/**/*.rb` 2. Add `OsMe::DecisionModel::Client` that takes an adapter and a `CriteriaRules` and returns an `Answer` — check: present `class Client` in `plugins/os-me/lib/**/*.rb` 3. Add `OsMe::DecisionModel::CriteriaRules` — check: present `class CriteriaRules` in `plugins/os-me/lib/**/*.rb` 4. Add the adapter `OsMe::DecisionModel::HeadlessClaude`, built on `HeadlessRunner` — check: present `class HeadlessClaude` in `plugins/os-me/lib/**/*.rb` Notes: O-7 AFK default: wait for email-triage #9 and hold a minimal in-plugin port with the same interface. Do not depend on a gem. Name no gem. Follow the AFK rules in `docs/decision-system/build-plan.md`: never wait for Jared, use the AFK default of each open item, and list each default used in the report. ## Acceptance criteria 1. Given a `Question` with criteria rules and a fake adapter, when `Client#ask` runs, then it returns the `Answer` that the adapter gave. 2. Given a `Question`, when `HeadlessClaude` runs with a stubbed `HeadlessRunner`, then it passes the question text and returns the parsed `Answer`. 3. Given an adapter that raises, when `Client#ask` runs, then the error reaches the caller and no `Answer` is returned. ## Owner sketch ```ruby module OsMe::DecisionModel class Question; end class Answer; end class CriteriaRules; end class Client def initialize(adapter:); end def ask(question, rules); end end class HeadlessClaude def call(question); end end end ``` ## Scope and blocking Shapes are in `docs/decision-system/extraction.md` and `docs/decision-system/decision-model.md`. Non-goals: the gem swap (S8); other adapters (S8). ## Origin - Trigger: User asked for the decision-system build tickets this session - Improvised this session: none - Chain: no ticket for this stage ← the build plan names the stage and the user asked for the tickets. Stop at `DESIGN` (`docs/decision-system/build-plan.md`). - Root candidate: none found; searched DecisionModel, decision, os-me - Where: docs/decision-system/build-plan.md S2 group (a); plugins/os-me/lib/os_me/decision_model/ - Session: 4f3f95ea-3c6f-4d23-a0ea-e349d6ab02a5 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/4f3f95ea-3c6f-4d23-a0ea-e349d6ab02a5.jsonl VERDICT: CREATE (user-approved; backlog search only)
Author
Owner

Work started on branch ticket-1242 (worktree), AFK decision-system build, session 4f3f95ea.

Work started on branch ticket-1242 (worktree), AFK decision-system build, session 4f3f95ea.
Author
Owner

Resolution

Done: OsMe::DecisionModel port (Question, Answer, CriteriaRules, Client) with HeadlessClaude adapter behind an injected runner; implementation 116, all gates green.

Evidence: Commit b441bfc4 on branch ticket-1242: 7 files, plugins/os-me/test/decision_model_test.rb; suite + required-work + contract audit pass.

Follow-ups: none

## Resolution **Done:** OsMe::DecisionModel port (Question, Answer, CriteriaRules, Client) with HeadlessClaude adapter behind an injected runner; implementation 116, all gates green. **Evidence:** Commit b441bfc4 on branch ticket-1242: 7 files, plugins/os-me/test/decision_model_test.rb; suite + required-work + contract audit pass. **Follow-ups:** none
jared closed this issue 2026-10-23 15:33:25 +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#1242
No description provided.