Lens proposal: A15 does not count a rescue of a raiser-nested error as a caller #1287

Open
opened 2026-10-23 21:23:55 +00:00 by jared · 0 comments
Owner

Problem

Lens heuristic A15 counts a rescue of an error class as a call from the rescuing concept. A nested error that one concept raises and a second concept rescues then counts as called from two concepts, so A15 asks to move it to the top level. The move hides the raiser from the reader. Two contract-auditor dispatches in #1284 flagged Daemon::LspError this way. An earlier signal flagged Adr::Record::ParseError in os-adr the same way, and that clause was deferred.

Observed

LENS lines from implementation 149 (#1284):

LENS: A2 broken at plugins/os-sdlc/lib/os_sdlc/daemon/lsp_error.rb:5 -- BREAKS: nested Daemon::LspError is referenced in Daemon (client.rb:50) and Evidence (lookup.rb:38); JUSTIFIED: yes ... PROPOSAL: EDIT A2, add NOT "a value or error that a concept returns or raises through its public interface, which callers of that concept read or rescue"
LENS: A15 broken at plugins/os-sdlc/lib/os_sdlc/daemon/lsp_error.rb:5 -- BREAKS: Daemon::LspError is named by Daemon (raise) and Evidence (rescue), two concepts, yet it is nested; JUSTIFIED: yes ... PROPOSAL: EDIT A15, add NOT 'counting a rescue of an error as a caller; an error lives in the concept that raises it'

Lens challenge (opus, 2026-10-23), verdict for both lines: edit proposed. One edit to A15 covers both, because A2 defects (2) and (3) count callers as A15 does. The challenge rejected the broader "value or error" wording: it would also excuse Daemon::Location, which Evidence builds itself (evidence/probe/lsp/lookup.rb:25).

Reproduce

n/a: lens heuristic proposal; the LENS lines above are the evidence.

Approach

Add one NOT clause to A15 in plugins/os-sdlc/skills/lens-architecture/SKILL.md: "NOT counting a rescue as a caller when the error class is nested under the object whose public method raises it and every outside reference rescues it around a call to that method; a rescuer is a caller of the raiser." Sources: POODR ch. 4, Ousterhout ch. 10. Add a lens-cases CASE entry with Daemon::LspError and Adr::Record::ParseError. Append signal lines to lens-signals/A15.jsonl (edited) and lens-signals/A8.jsonl (code). Check the earlier A15 signal lines (DesignPlacement, LintRun, WrongCostAssessor); none is an error class.

Required work: none beyond the acceptance criteria.

Acceptance criteria

  1. Given the edited A15, when a reviewer reads Daemon::LspError (raised by Daemon::Client#answer, rescued only around that call in Evidence), then A15 keeps it nested under Daemon.
  2. Given the edited A15, when a reviewer reads Daemon::Location (built by Evidence at lookup.rb:25), then A15 still flags it.

Origin

  • Trigger: /os-sdlc:implement 1284, implementation 149, os-sdlc-implementation-report lens list, then the lens challenge
  • Improvised this session: none
  • Chain: auditor flags a nested raised-and-rescued error ← A15 counts a rescue as a caller ← DESIGN (plugins/os-sdlc/skills/lens-architecture/SKILL.md A15)
  • Root candidate: none found; searched "Lens proposal", "A15", "A2", "rescue", "error class", "ParseError"
  • Where: plugins/os-sdlc/skills/lens-architecture/SKILL.md A15; plugins/os-sdlc/lib/os_sdlc/daemon/lsp_error.rb
  • Session: c1bedec6-7e01-45ab-b9db-22d63652c19f
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-crc-os-sdlc-run-4/c1bedec6-7e01-45ab-b9db-22d63652c19f.jsonl

Ticket: #1284

VERDICT: CREATE

## Problem Lens heuristic A15 counts a rescue of an error class as a call from the rescuing concept. A nested error that one concept raises and a second concept rescues then counts as called from two concepts, so A15 asks to move it to the top level. The move hides the raiser from the reader. Two contract-auditor dispatches in #1284 flagged `Daemon::LspError` this way. An earlier signal flagged `Adr::Record::ParseError` in os-adr the same way, and that clause was deferred. ## Observed LENS lines from implementation 149 (#1284): ``` LENS: A2 broken at plugins/os-sdlc/lib/os_sdlc/daemon/lsp_error.rb:5 -- BREAKS: nested Daemon::LspError is referenced in Daemon (client.rb:50) and Evidence (lookup.rb:38); JUSTIFIED: yes ... PROPOSAL: EDIT A2, add NOT "a value or error that a concept returns or raises through its public interface, which callers of that concept read or rescue" LENS: A15 broken at plugins/os-sdlc/lib/os_sdlc/daemon/lsp_error.rb:5 -- BREAKS: Daemon::LspError is named by Daemon (raise) and Evidence (rescue), two concepts, yet it is nested; JUSTIFIED: yes ... PROPOSAL: EDIT A15, add NOT 'counting a rescue of an error as a caller; an error lives in the concept that raises it' ``` Lens challenge (opus, 2026-10-23), verdict for both lines: edit proposed. One edit to A15 covers both, because A2 defects (2) and (3) count callers as A15 does. The challenge rejected the broader "value or error" wording: it would also excuse `Daemon::Location`, which Evidence builds itself (`evidence/probe/lsp/lookup.rb:25`). ## Reproduce n/a: lens heuristic proposal; the LENS lines above are the evidence. ## Approach Add one NOT clause to A15 in `plugins/os-sdlc/skills/lens-architecture/SKILL.md`: "NOT counting a rescue as a caller when the error class is nested under the object whose public method raises it and every outside reference rescues it around a call to that method; a rescuer is a caller of the raiser." Sources: POODR ch. 4, Ousterhout ch. 10. Add a lens-cases CASE entry with `Daemon::LspError` and `Adr::Record::ParseError`. Append signal lines to `lens-signals/A15.jsonl` (edited) and `lens-signals/A8.jsonl` (code). Check the earlier A15 signal lines (DesignPlacement, LintRun, WrongCostAssessor); none is an error class. Required work: none beyond the acceptance criteria. ## Acceptance criteria 1. Given the edited A15, when a reviewer reads `Daemon::LspError` (raised by `Daemon::Client#answer`, rescued only around that call in Evidence), then A15 keeps it nested under `Daemon`. 2. Given the edited A15, when a reviewer reads `Daemon::Location` (built by Evidence at `lookup.rb:25`), then A15 still flags it. ## Origin - Trigger: `/os-sdlc:implement 1284`, implementation 149, `os-sdlc-implementation-report` lens list, then the lens challenge - Improvised this session: none - Chain: auditor flags a nested raised-and-rescued error ← A15 counts a rescue as a caller ← DESIGN (`plugins/os-sdlc/skills/lens-architecture/SKILL.md` A15) - Root candidate: none found; searched "Lens proposal", "A15", "A2", "rescue", "error class", "ParseError" - Where: plugins/os-sdlc/skills/lens-architecture/SKILL.md A15; plugins/os-sdlc/lib/os_sdlc/daemon/lsp_error.rb - Session: c1bedec6-7e01-45ab-b9db-22d63652c19f - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-crc-os-sdlc-run-4/c1bedec6-7e01-45ab-b9db-22d63652c19f.jsonl Ticket: #1284 VERDICT: CREATE
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#1287
No description provided.