Fix Pattern#forbidden_rule NameError #1518

Closed
opened 2026-11-02 23:48:25 +00:00 by jared · 2 comments
Owner

Problem

Pattern#forbidden_rule raises NameError on every call that reaches the predicate.
Inside the Data.define block, constant lookup uses the lexical scope OsSdlc::SystemModel, not Pattern.
The constant Rule lives at Pattern::Rule, so Rule does not resolve.
No test calls the method, and no library code calls it, so nothing caught the error.

Observed

plugins/os-sdlc/lib/os_sdlc/system_model/pattern.rb:12:

def forbidden_rule(id) = rules.forbidden.find { |candidate| candidate.is_a?(Rule) && candidate.id == id }

Callers: none. A grep for forbidden_rule over plugins/*/lib, bin, tests finds only the definition and two test names (test_every_pattern_has_at_least_one_forbidden_rule, test_every_forbidden_rule_has_an_id, test_every_forbidden_rule_has_a_sentence in system_model_catalog_test.rb:44-52) that do not call it.
It appears in design/generated/facts.json only as a generated fact.
It came in with commit f84a4cb3 (2026-10-27, #1404).

Reproduce

ruby -e 'require "/home/jared/dev/cc-os/plugins/os-sdlc/lib/os_sdlc"; OsSdlc::SystemModel::Catalog::Hex.forbidden_rule("R1")'

Output:

NameError: uninitialized constant OsSdlc::SystemModel::Rule

An empty forbidden list does not raise, because find never calls the block.

Approach

Change Rule to Pattern::Rule on pattern.rb:12, as catalog/*.rb already writes it. Add a test that calls forbidden_rule.

Required work:

  1. Qualify the constant — check: present is_a?(Pattern::Rule) in plugins/os-sdlc/lib/os_sdlc/system_model/pattern.rb
  2. Add a test that calls the method — check: present forbidden_rule("R1") in plugins/os-sdlc/tests/system_model_catalog_test.rb

Acceptance criteria

  1. Given Catalog::Hex, when forbidden_rule("R1") is called, then it returns the rule whose id is R1.
  2. Given Catalog::Hex, when forbidden_rule("nope") is called, then it returns nil.

Owner sketch

OsSdlc::SystemModel::Pattern#forbidden_rule(id)

Origin

  • Trigger: reading pattern.rb while capturing the leaks_io? ticket; reproduced with the command above.
  • Improvised this session: none
  • Chain: NameError ← Rule resolves in lexical scope SystemModel, not Pattern ← no caller and no test ← DESIGN (plugins/os-sdlc/lib/os_sdlc/system_model/pattern.rb:12)
  • Root candidate: none found; searched forbidden_rule, Pattern#, pattern.rb, Pattern::Rule, NameError
    VERDICT: CREATE
  • Where: plugins/os-sdlc/lib/os_sdlc/system_model/pattern.rb:12
  • Session: d077e084-9195-4803-b761-6ce01eca0249
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/d077e084-9195-4803-b761-6ce01eca0249.jsonl
## Problem `Pattern#forbidden_rule` raises `NameError` on every call that reaches the predicate. Inside the `Data.define` block, constant lookup uses the lexical scope `OsSdlc::SystemModel`, not `Pattern`. The constant `Rule` lives at `Pattern::Rule`, so `Rule` does not resolve. No test calls the method, and no library code calls it, so nothing caught the error. ## Observed `plugins/os-sdlc/lib/os_sdlc/system_model/pattern.rb:12`: ``` def forbidden_rule(id) = rules.forbidden.find { |candidate| candidate.is_a?(Rule) && candidate.id == id } ``` Callers: none. A grep for `forbidden_rule` over `plugins/*/lib`, `bin`, `tests` finds only the definition and two test names (`test_every_pattern_has_at_least_one_forbidden_rule`, `test_every_forbidden_rule_has_an_id`, `test_every_forbidden_rule_has_a_sentence` in `system_model_catalog_test.rb:44-52`) that do not call it. It appears in `design/generated/facts.json` only as a generated fact. It came in with commit `f84a4cb3` (2026-10-27, #1404). ## Reproduce ``` ruby -e 'require "/home/jared/dev/cc-os/plugins/os-sdlc/lib/os_sdlc"; OsSdlc::SystemModel::Catalog::Hex.forbidden_rule("R1")' ``` Output: ``` NameError: uninitialized constant OsSdlc::SystemModel::Rule ``` An empty `forbidden` list does not raise, because `find` never calls the block. ## Approach Change `Rule` to `Pattern::Rule` on `pattern.rb:12`, as `catalog/*.rb` already writes it. Add a test that calls `forbidden_rule`. Required work: 1. Qualify the constant — check: present `is_a?(Pattern::Rule)` in `plugins/os-sdlc/lib/os_sdlc/system_model/pattern.rb` 2. Add a test that calls the method — check: present `forbidden_rule("R1")` in `plugins/os-sdlc/tests/system_model_catalog_test.rb` ## Acceptance criteria 1. Given `Catalog::Hex`, when `forbidden_rule("R1")` is called, then it returns the rule whose id is `R1`. 2. Given `Catalog::Hex`, when `forbidden_rule("nope")` is called, then it returns nil. ## Owner sketch ```ruby OsSdlc::SystemModel::Pattern#forbidden_rule(id) ``` ## Origin - Trigger: reading `pattern.rb` while capturing the leaks_io? ticket; reproduced with the command above. - Improvised this session: none - Chain: NameError ← `Rule` resolves in lexical scope `SystemModel`, not `Pattern` ← no caller and no test ← DESIGN (`plugins/os-sdlc/lib/os_sdlc/system_model/pattern.rb:12`) - Root candidate: none found; searched forbidden_rule, Pattern#, pattern.rb, Pattern::Rule, NameError VERDICT: CREATE - Where: plugins/os-sdlc/lib/os_sdlc/system_model/pattern.rb:12 - Session: d077e084-9195-4803-b761-6ce01eca0249 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/d077e084-9195-4803-b761-6ce01eca0249.jsonl
Author
Owner

Work started on branch ticket-1518 through /os-sdlc:implement.

Work started on branch `ticket-1518` through /os-sdlc:implement.
Author
Owner

Resolution

Done: Pattern#forbidden_rule no longer raises NameError: it checks candidate.is_a?(Pattern::Rule). It returns the rule for a known id and nil for an unknown id.

Evidence: Commit on ticket-1518 (implementation 226). Two tests in plugins/os-sdlc/tests/system_model_catalog_test.rb through Catalog::Hex.forbidden_rule. Suite gate green (dispatch 2074); contract audit pass (2075).

Follow-ups: none

## Resolution **Done:** Pattern#forbidden_rule no longer raises NameError: it checks candidate.is_a?(Pattern::Rule). It returns the rule for a known id and nil for an unknown id. **Evidence:** Commit on ticket-1518 (implementation 226). Two tests in plugins/os-sdlc/tests/system_model_catalog_test.rb through Catalog::Hex.forbidden_rule. Suite gate green (dispatch 2074); contract audit pass (2075). **Follow-ups:** none
jared closed this issue 2026-11-03 15:35:39 +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#1518
No description provided.