Move the three os-sdlc YAML file readers to the shared loader (ADR-0268) #914

Closed
opened 2026-10-02 17:39:43 +00:00 by jared · 2 comments
Owner

Problem

os-sdlc has three YAML file readers and each behaves differently on bad input.
The map loader rescues Psych::Exception into InvalidMapError.
The project config and the rubocop delta report let the raw Psych error out.
ADR-0268 decides one shared loader; this ticket is stage 2.

Approach

Move each reader to OsSdlc::YamlFile (from ticket A), one at a time, in the order below.
Each reader decides what an empty file means.
The delta report keeps || {}: the code (delta ||= ... || {}) and classify, which also returns an empty report when the file is absent, show that an empty delta file means {}.
The map loader keeps InvalidMapError by translating YamlFile::Error in one rescue, because command/dispatch_commands.rb and reroute/draft.rb branch on that type and its defect code.
String parsing (parser/handoff_content.rb, the base YAML string in the delta report) stays as it is.

Required work:

  1. Move the project config reader to YamlFile, and keep the HarnessError for an empty file — check: present YamlFile in plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb
  2. Move the rubocop delta report reader to YamlFile, and keep an empty file as {} — check: present YamlFile in plugins/os-sdlc/lib/os_sdlc/command/rubocop_delta_report.rb
  3. Move the map loader to YamlFile, and translate YamlFile::Error into InvalidMapError in one rescue — check: present YamlFile in plugins/os-sdlc/lib/os_sdlc/adapter/map/loader.rb
  4. Remove the file-reading YAML.safe_load_file call from the project config — check: absent YAML.safe_load_file in plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb
  5. Remove the file-reading YAML.safe_load(File.read call from the delta report — check: absent YAML.safe_load(File.read in plugins/os-sdlc/lib/os_sdlc/command/rubocop_delta_report.rb

Acceptance criteria

  1. Given a project config, a rubocop delta file, or a map file that does not parse, when it loads, then the failure message names the file.
  2. Given an empty rubocop delta file, when the report runs, then it treats the file as {} as before.
  3. Given an empty project config, when it loads, then it raises HarnessError as before.
  4. Given a map file that does not parse, when it loads, then the error is InvalidMapError with its defect code as before.
  5. Given plugins/os-sdlc/lib, when searched, then no YAML.safe_load_file and no YAML.safe_load(File.read remains outside the loader.

Owner sketch

module OsSdlc
  class Map::Loader
    def load(path)
      YamlFile.read(path)
    rescue YamlFile::Error => e
      raise InvalidMapError, e.message
    end
  end
end

Depends on ticket A (the loader).

Origin

  • Trigger: user ruling 2026-10-02: shared YAML loader, staged; this ticket is stage 2 of ADR-0268.
  • Improvised this session: none
  • Chain: three readers with three behaviors ← no shared helper (DESIGN: docs/adr/0268-*)
  • Root candidate: ticket A
  • Where: plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb, command/rubocop_delta_report.rb, adapter/map/loader.rb
  • Session: 9ee7805f-a4e4-470e-af50-5020e5c524a4
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/9ee7805f-a4e4-470e-af50-5020e5c524a4.jsonl
## Problem os-sdlc has three YAML file readers and each behaves differently on bad input. The map loader rescues `Psych::Exception` into `InvalidMapError`. The project config and the rubocop delta report let the raw Psych error out. ADR-0268 decides one shared loader; this ticket is stage 2. ## Approach Move each reader to `OsSdlc::YamlFile` (from ticket A), one at a time, in the order below. Each reader decides what an empty file means. The delta report keeps `|| {}`: the code (`delta ||= ... || {}`) and `classify`, which also returns an empty report when the file is absent, show that an empty delta file means `{}`. The map loader keeps `InvalidMapError` by translating `YamlFile::Error` in one rescue, because `command/dispatch_commands.rb` and `reroute/draft.rb` branch on that type and its defect code. String parsing (`parser/handoff_content.rb`, the base YAML string in the delta report) stays as it is. Required work: 1. Move the project config reader to `YamlFile`, and keep the `HarnessError` for an empty file — check: present `YamlFile` in `plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb` 2. Move the rubocop delta report reader to `YamlFile`, and keep an empty file as `{}` — check: present `YamlFile` in `plugins/os-sdlc/lib/os_sdlc/command/rubocop_delta_report.rb` 3. Move the map loader to `YamlFile`, and translate `YamlFile::Error` into `InvalidMapError` in one rescue — check: present `YamlFile` in `plugins/os-sdlc/lib/os_sdlc/adapter/map/loader.rb` 4. Remove the file-reading `YAML.safe_load_file` call from the project config — check: absent `YAML.safe_load_file` in `plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb` 5. Remove the file-reading `YAML.safe_load(File.read` call from the delta report — check: absent `YAML.safe_load(File.read` in `plugins/os-sdlc/lib/os_sdlc/command/rubocop_delta_report.rb` ## Acceptance criteria 1. Given a project config, a rubocop delta file, or a map file that does not parse, when it loads, then the failure message names the file. 2. Given an empty rubocop delta file, when the report runs, then it treats the file as `{}` as before. 3. Given an empty project config, when it loads, then it raises `HarnessError` as before. 4. Given a map file that does not parse, when it loads, then the error is `InvalidMapError` with its defect code as before. 5. Given `plugins/os-sdlc/lib`, when searched, then no `YAML.safe_load_file` and no `YAML.safe_load(File.read` remains outside the loader. ## Owner sketch ```ruby module OsSdlc class Map::Loader def load(path) YamlFile.read(path) rescue YamlFile::Error => e raise InvalidMapError, e.message end end end ``` Depends on ticket A (the loader). ## Origin - Trigger: user ruling 2026-10-02: shared YAML loader, staged; this ticket is stage 2 of ADR-0268. - Improvised this session: none - Chain: three readers with three behaviors ← no shared helper (DESIGN: docs/adr/0268-*) - Root candidate: ticket A - Where: plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb, command/rubocop_delta_report.rb, adapter/map/loader.rb - Session: 9ee7805f-a4e4-470e-af50-5020e5c524a4 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/9ee7805f-a4e4-470e-af50-5020e5c524a4.jsonl
Author
Owner

Work started on branch ticket-914 through the os-sdlc pipeline.

Work started on branch ticket-914 through the os-sdlc pipeline.
Author
Owner

Resolution

Done: The three os-sdlc YAML file readers (project config, rubocop delta report, map loader) read through OsSdlc::YamlFile. A parse failure names the file. The map loader keeps InvalidMapError by translation. Empty-file behavior is unchanged (ADR-0268 stage 2).

Evidence: Branch ticket-914; os-sdlc implementation 19: 13 dispatches, 1 retry (suite-check failed once, programmer-repair, suite green on the second check in 18.4 s), required-work gate green, contract-auditor pass.

Follow-ups: none; History row added after merge, and a live check that a pipeline command still reads the map after the plugin refresh.

## Resolution **Done:** The three os-sdlc YAML file readers (project config, rubocop delta report, map loader) read through OsSdlc::YamlFile. A parse failure names the file. The map loader keeps InvalidMapError by translation. Empty-file behavior is unchanged (ADR-0268 stage 2). **Evidence:** Branch ticket-914; os-sdlc implementation 19: 13 dispatches, 1 retry (suite-check failed once, programmer-repair, suite green on the second check in 18.4 s), required-work gate green, contract-auditor pass. **Follow-ups:** none; History row added after merge, and a live check that a pipeline command still reads the map after the plugin refresh.
jared closed this issue 2026-10-02 18:15:12 +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#914
No description provided.