Guard test for concepts whose namespace root is missing or outside model/ (ADR-0222 item 3) #745

Closed
opened 2026-09-26 14:43:21 +00:00 by jared · 3 comments
Owner

Problem

ADR-0222 says a concept's namespace root is defined by its model file, and a concept with role-object files but no model file is a defect. Under plugins/os-sdlc/lib/os_sdlc today, 2 concepts have no root at all (Git, GateHandoff), and 30 concepts have a root outside model/ (for example pipeline/map.rb, which has 15 child files across 4 roles). 17 concepts comply. Zeitwerk creates implicit namespaces for all of these, so none of them fail at load time; nothing catches the drift.

Approach

Write a test shaped like inward_dependency_test.rb: list every concept that has role-object files, locate its root via OsSdlc.loader.all_expected_cpaths, and fail on any entry not in a recorded KNOWN_ROOTLESS baseline. The baseline shrinks as concepts are morphed into ADR-0222 layout, the same pattern inward_dependency_test.rb uses for KNOWN_VIOLATIONS.

Required work:

  1. Enumerate concepts with role-object files under plugins/os-sdlc/lib/os_sdlc and resolve each one's root via OsSdlc.loader.all_expected_cpaths.
  2. Fail the test for any concept whose root is missing or sits outside model/, unless it is listed in a KNOWN_ROOTLESS baseline.
  3. Seed KNOWN_ROOTLESS from the current count: 2 rootless concepts (Git, GateHandoff) plus the 30 with a root outside model/.
  4. Wire the new test into the same suite/gate inward_dependency_test.rb runs under.

Rejected: relying on Zeitwerk to catch this — Zeitwerk's implicit namespaces make a rootless or misplaced-root concept load successfully, so it produces no signal on its own.

Acceptance criteria

  1. Given a concept with role-object files and no model file, when the test runs, then it fails unless that concept is in KNOWN_ROOTLESS.
  2. Given a concept whose root sits outside model/ (for example pipeline/map.rb), when the test runs, then it fails unless that concept is in KNOWN_ROOTLESS.
  3. Given a concept morphed into ADR-0222 layout and removed from KNOWN_ROOTLESS, when the test runs, then it passes without that entry.
  4. Given the 17 concepts that already comply, when the test runs, then none of them appear in KNOWN_ROOTLESS or cause a failure.

Owner sketch

class ConceptRootTest
  def rootless_concepts
  end
end

Origin

  • Trigger: user review of ADR-0222 item 3 compliance across plugins/os-sdlc/lib/os_sdlc, 2026-09-26.
  • Improvised this session: none.
  • Chain: rootless and misplaced-root concepts go undetected ← Zeitwerk's implicit namespaces load them successfully regardless of root location ← DESIGN, ADR-0222 defines the concept-root rule but no test enforces it yet.
  • Root candidate: this ticket.
  • Where: plugins/os-sdlc/lib/os_sdlc (concept roots generally); example plugins/os-sdlc/lib/os_sdlc/pipeline/map.rb
  • Session: d0c72a0b-34c7-4dae-bf3b-7400ef21ad4a
  • Transcript: not available in this invocation
## Problem ADR-0222 says a concept's namespace root is defined by its model file, and a concept with role-object files but no model file is a defect. Under plugins/os-sdlc/lib/os_sdlc today, 2 concepts have no root at all (Git, GateHandoff), and 30 concepts have a root outside model/ (for example pipeline/map.rb, which has 15 child files across 4 roles). 17 concepts comply. Zeitwerk creates implicit namespaces for all of these, so none of them fail at load time; nothing catches the drift. ## Approach Write a test shaped like inward_dependency_test.rb: list every concept that has role-object files, locate its root via `OsSdlc.loader.all_expected_cpaths`, and fail on any entry not in a recorded KNOWN_ROOTLESS baseline. The baseline shrinks as concepts are morphed into ADR-0222 layout, the same pattern inward_dependency_test.rb uses for KNOWN_VIOLATIONS. Required work: 1. Enumerate concepts with role-object files under plugins/os-sdlc/lib/os_sdlc and resolve each one's root via `OsSdlc.loader.all_expected_cpaths`. 2. Fail the test for any concept whose root is missing or sits outside model/, unless it is listed in a KNOWN_ROOTLESS baseline. 3. Seed KNOWN_ROOTLESS from the current count: 2 rootless concepts (Git, GateHandoff) plus the 30 with a root outside model/. 4. Wire the new test into the same suite/gate inward_dependency_test.rb runs under. Rejected: relying on Zeitwerk to catch this — Zeitwerk's implicit namespaces make a rootless or misplaced-root concept load successfully, so it produces no signal on its own. ## Acceptance criteria 1. Given a concept with role-object files and no model file, when the test runs, then it fails unless that concept is in KNOWN_ROOTLESS. 2. Given a concept whose root sits outside model/ (for example pipeline/map.rb), when the test runs, then it fails unless that concept is in KNOWN_ROOTLESS. 3. Given a concept morphed into ADR-0222 layout and removed from KNOWN_ROOTLESS, when the test runs, then it passes without that entry. 4. Given the 17 concepts that already comply, when the test runs, then none of them appear in KNOWN_ROOTLESS or cause a failure. ## Owner sketch ```ruby class ConceptRootTest def rootless_concepts end end ``` ## Origin - Trigger: user review of ADR-0222 item 3 compliance across plugins/os-sdlc/lib/os_sdlc, 2026-09-26. - Improvised this session: none. - Chain: rootless and misplaced-root concepts go undetected ← Zeitwerk's implicit namespaces load them successfully regardless of root location ← DESIGN, ADR-0222 defines the concept-root rule but no test enforces it yet. - Root candidate: this ticket. - Where: plugins/os-sdlc/lib/os_sdlc (concept roots generally); example plugins/os-sdlc/lib/os_sdlc/pipeline/map.rb - Session: d0c72a0b-34c7-4dae-bf3b-7400ef21ad4a - Transcript: not available in this invocation
Author
Owner

Started on branch crc-pass-os-sdlc.

Started on branch crc-pass-os-sdlc.
Author
Owner

Resolution

Done: Added concept_root_test.rb (baseline 33 entries) guarding ADR-0222's model/ namespace-root rule; full suite 1430 runs/3246 assertions, 2 pre-existing failures unrelated to this change (in-progress edit to inward_dependency_test.rb by another agent).

Evidence: commit fc0289fa3b; suite line: 1430 runs, 3246 assertions, 2 failures, 0 errors, 10 skips

Follow-ups: none

## Resolution **Done:** Added concept_root_test.rb (baseline 33 entries) guarding ADR-0222's model/ namespace-root rule; full suite 1430 runs/3246 assertions, 2 pre-existing failures unrelated to this change (in-progress edit to inward_dependency_test.rb by another agent). **Evidence:** commit fc0289fa3bd9c9e4dcaea61a59bc6436215bbc71; suite line: 1430 runs, 3246 assertions, 2 failures, 0 errors, 10 skips **Follow-ups:** none
jared closed this issue 2026-09-26 14:46:40 +00:00
Author
Owner

Withdrawn in effect: concept_root_test.rb deleted in d76058a5. A structure test on constant placement fails on refactors that change no behavior. Ownership heuristic moves to a living principles document.

Withdrawn in effect: concept_root_test.rb deleted in d76058a5. A structure test on constant placement fails on refactors that change no behavior. Ownership heuristic moves to a living principles document.
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#745
No description provided.