Add OsSdlc::Error root and reparent harness and policy errors under it #1182

Closed
opened 2026-10-19 22:35:03 +00:00 by jared · 2 comments
Owner

Problem

The harness has no single error root. HarnessError and about 30 other error classes inherit StandardError directly. A rescue site cannot name "any error this library raises". Ruling S31 designs one OsSdlc::Error root with policy subclasses. Loud::Error stays the exit-3 policy class, so the ADR-0232 exit contract and the ADR-0088 target-list message stay the same. Rulings S32, S33, S83, S85, S86 and S87 reparent the classes.

Reproduce

n/a: structure-wave error design, nothing to reproduce

Approach

Required work:

  1. Create plugins/os-sdlc/lib/os_sdlc/error.rb with class OsSdlc::Error < StandardError. — check: present Error < StandardError in plugins/os-sdlc/lib/os_sdlc/error.rb
  2. In plugins/os-sdlc/lib/os_sdlc/harness_error.rb, change HarnessError < StandardError to HarnessError < OsSdlc::Error. The six class-wide HarnessError rescues catch nothing new. — check: present HarnessError < OsSdlc::Error in plugins/os-sdlc/lib/os_sdlc/harness_error.rb
  3. Change < StandardError to < OsSdlc::Error for each class below. Each keeps its path and name. Paths are under plugins/os-sdlc/lib/os_sdlc/. — check: absent < StandardError in plugins/os-sdlc/lib/os_sdlc/boot/refusal_error.rb
    • Boot::RefusalError (boot/refusal_error.rb)
    • Brief::MissingFileError (brief/missing_file_error.rb)
    • CollaboratorPass::Command::UsageError (collaborator_pass/command/usage_error.rb)
    • Crc::Score::MissingError (crc/score/missing_error.rb)
    • Gate::UnknownError (gate/unknown_error.rb)
    • HandoffContent::MalformedError (handoff_content/malformed_error.rb)
    • Implementation::AlreadyRoutedError (implementation/already_routed_error.rb)
    • Implementation::CompletionIntake::RoleMismatchError (implementation/completion_intake/role_mismatch_error.rb)
    • Implementation::NotActiveError (implementation/not_active_error.rb)
    • Implementation::Reroute::RefusedError (implementation/reroute/refused_error.rb)
    • Implementation::StaleDispatchError (implementation/stale_dispatch_error.rb)
    • Lint::Worklist::UnmappedCopError (lint/worklist/unmapped_cop_error.rb; Class.new(StandardError) becomes Class.new(OsSdlc::Error))
    • Verdict::UnknownError (verdict/unknown_error.rb)
  4. Make Dispatch::UnknownError (dispatch/unknown_error.rb), Dispatch::NotPendingError (dispatch/not_pending_error.rb) and Event::UnknownAgentError (event/unknown_agent_error.rb) subclasses of OsSdlc::Error. They stay in their files. — check: absent < StandardError in plugins/os-sdlc/lib/os_sdlc/dispatch/not_pending_error.rb
  5. In plugins/os-sdlc/lib/os_sdlc/crc/error_lineage.rb:11, add "#{root_constant}::Error" to the policy bases in @bases, before "StandardError". — check: present ::Error" in plugins/os-sdlc/lib/os_sdlc/crc/error_lineage.rb

Acceptance criteria

  1. Given the suite, when run after the change, then it passes with no new failures. The change keeps behavior; the existing suite is the proof.
  2. Given each class in Required work, when its ancestors are listed, then OsSdlc::Error is one of them.
  3. Given OsSdlc::HarnessError, when its ancestors are listed, then OsSdlc::Error is one of them, and each HarnessError subclass inherits it.
  4. Given a rescue site that names one of these classes, when the error is raised, then the same handler runs as before.

Owner sketch

class OsSdlc::Error < StandardError; end
class OsSdlc::HarnessError < OsSdlc::Error
class OsSdlc::Dispatch::UnknownError < OsSdlc::Error

Non-goals

No rescue site changes. Out of scope: the moves and folds in rulings S35 to S50, S89, S90 and S92. They are wave 4 moves with their own tickets. Add no test.

Origin

  • Trigger: os-sdlc CRC run 3, structure-ruling wave step 4 (error design)
  • Improvised this session: none
  • Chain: no common error root ← errors inherit StandardError directly ← DESIGN (docs/crc/os-sdlc/wave0/structure-rulings.tsv S31, S32, S33, S83, S85, S86, S87)
  • Root candidate: none found; searched OsSdlc::Error, error root, error_lineage, ErrorLineage, StandardError, HarnessError, PolicyError, Loud::Exit
  • Where: plugins/os-sdlc/lib/os_sdlc/harness_error.rb
  • Ledger: docs/crc/os-sdlc/ledger.tsv
  • Rulings: docs/crc/os-sdlc/wave0/structure-rulings.tsv
  • Session: 2e167079-f404-4139-9cfa-6c0c937ce9f0
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-crc-os-sdlc-run-3/2e167079-f404-4139-9cfa-6c0c937ce9f0.jsonl

VERDICT: CREATE

## Problem The harness has no single error root. `HarnessError` and about 30 other error classes inherit `StandardError` directly. A rescue site cannot name "any error this library raises". Ruling S31 designs one `OsSdlc::Error` root with policy subclasses. `Loud::Error` stays the exit-3 policy class, so the ADR-0232 exit contract and the ADR-0088 target-list message stay the same. Rulings S32, S33, S83, S85, S86 and S87 reparent the classes. ## Reproduce n/a: structure-wave error design, nothing to reproduce ## Approach Required work: 1. Create `plugins/os-sdlc/lib/os_sdlc/error.rb` with `class OsSdlc::Error < StandardError`. — check: present `Error < StandardError` in `plugins/os-sdlc/lib/os_sdlc/error.rb` 2. In `plugins/os-sdlc/lib/os_sdlc/harness_error.rb`, change `HarnessError < StandardError` to `HarnessError < OsSdlc::Error`. The six class-wide `HarnessError` rescues catch nothing new. — check: present `HarnessError < OsSdlc::Error` in `plugins/os-sdlc/lib/os_sdlc/harness_error.rb` 3. Change `< StandardError` to `< OsSdlc::Error` for each class below. Each keeps its path and name. Paths are under `plugins/os-sdlc/lib/os_sdlc/`. — check: absent `< StandardError` in `plugins/os-sdlc/lib/os_sdlc/boot/refusal_error.rb` - `Boot::RefusalError` (boot/refusal_error.rb) - `Brief::MissingFileError` (brief/missing_file_error.rb) - `CollaboratorPass::Command::UsageError` (collaborator_pass/command/usage_error.rb) - `Crc::Score::MissingError` (crc/score/missing_error.rb) - `Gate::UnknownError` (gate/unknown_error.rb) - `HandoffContent::MalformedError` (handoff_content/malformed_error.rb) - `Implementation::AlreadyRoutedError` (implementation/already_routed_error.rb) - `Implementation::CompletionIntake::RoleMismatchError` (implementation/completion_intake/role_mismatch_error.rb) - `Implementation::NotActiveError` (implementation/not_active_error.rb) - `Implementation::Reroute::RefusedError` (implementation/reroute/refused_error.rb) - `Implementation::StaleDispatchError` (implementation/stale_dispatch_error.rb) - `Lint::Worklist::UnmappedCopError` (lint/worklist/unmapped_cop_error.rb; `Class.new(StandardError)` becomes `Class.new(OsSdlc::Error)`) - `Verdict::UnknownError` (verdict/unknown_error.rb) 4. Make `Dispatch::UnknownError` (dispatch/unknown_error.rb), `Dispatch::NotPendingError` (dispatch/not_pending_error.rb) and `Event::UnknownAgentError` (event/unknown_agent_error.rb) subclasses of `OsSdlc::Error`. They stay in their files. — check: absent `< StandardError` in `plugins/os-sdlc/lib/os_sdlc/dispatch/not_pending_error.rb` 5. In `plugins/os-sdlc/lib/os_sdlc/crc/error_lineage.rb:11`, add `"#{root_constant}::Error"` to the policy bases in `@bases`, before `"StandardError"`. — check: present `::Error"` in `plugins/os-sdlc/lib/os_sdlc/crc/error_lineage.rb` ## Acceptance criteria 1. Given the suite, when run after the change, then it passes with no new failures. The change keeps behavior; the existing suite is the proof. 2. Given each class in Required work, when its ancestors are listed, then `OsSdlc::Error` is one of them. 3. Given `OsSdlc::HarnessError`, when its ancestors are listed, then `OsSdlc::Error` is one of them, and each `HarnessError` subclass inherits it. 4. Given a rescue site that names one of these classes, when the error is raised, then the same handler runs as before. ## Owner sketch ```ruby class OsSdlc::Error < StandardError; end class OsSdlc::HarnessError < OsSdlc::Error class OsSdlc::Dispatch::UnknownError < OsSdlc::Error ``` ## Non-goals No rescue site changes. Out of scope: the moves and folds in rulings S35 to S50, S89, S90 and S92. They are wave 4 moves with their own tickets. Add no test. ## Origin - Trigger: os-sdlc CRC run 3, structure-ruling wave step 4 (error design) - Improvised this session: none - Chain: no common error root ← errors inherit StandardError directly ← DESIGN (docs/crc/os-sdlc/wave0/structure-rulings.tsv S31, S32, S33, S83, S85, S86, S87) - Root candidate: none found; searched OsSdlc::Error, error root, error_lineage, ErrorLineage, StandardError, HarnessError, PolicyError, Loud::Exit - Where: plugins/os-sdlc/lib/os_sdlc/harness_error.rb - Ledger: docs/crc/os-sdlc/ledger.tsv - Rulings: docs/crc/os-sdlc/wave0/structure-rulings.tsv - Session: 2e167079-f404-4139-9cfa-6c0c937ce9f0 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-crc-os-sdlc-run-3/2e167079-f404-4139-9cfa-6c0c937ce9f0.jsonl VERDICT: CREATE
Author
Owner

Work started on branch crc-os-sdlc-run-3 (os-sdlc CRC run 3), structure-change map.

Work started on branch crc-os-sdlc-run-3 (os-sdlc CRC run 3), structure-change map.
Author
Owner

Resolution

Done: Added OsSdlc::Error < StandardError (lib/os_sdlc/error.rb); reparented HarnessError, the 13 listed classes, Dispatch::UnknownError, Dispatch::NotPendingError and Event::UnknownAgentError under it; ErrorLineage counts OsSdlc::Error as a policy base.

Evidence: Runner commit 43829353 (19 files), implementation 94, dispatch 780 gate green: required-work, lint, test-lint, suite, unchanged.

Follow-ups: none; error classes outside S31-S33/S83-S87 that still inherit StandardError are judged in the wave 0 re-measure of this run

## Resolution **Done:** Added OsSdlc::Error < StandardError (lib/os_sdlc/error.rb); reparented HarnessError, the 13 listed classes, Dispatch::UnknownError, Dispatch::NotPendingError and Event::UnknownAgentError under it; ErrorLineage counts OsSdlc::Error as a policy base. **Evidence:** Runner commit 43829353 (19 files), implementation 94, dispatch 780 gate green: required-work, lint, test-lint, suite, unchanged. **Follow-ups:** none; error classes outside S31-S33/S83-S87 that still inherit StandardError are judged in the wave 0 re-measure of this run
jared closed this issue 2026-10-19 23:13:01 +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#1182
No description provided.