Sdlc/Sequel/RegistryOutsideEntryPoint: match the Sequel Db by constant path, carve out by shape not path #1381
Labels
No labels
P0
P1
P2
P3
bug
category/code-change
category/cross-repo
category/eval-run
category/investigation
category/no-test-target
category/owner-ruling
category/prose-artifact
category/recurring-chore
category/structure
category/umbrella
crc-refactor
create
delete
enhancement
filed-by/agent
filed-by/user
frozen
lint-rule
needs-info
needs-triage
next
plugin/cc-architect
plugin/os
plugin/os-adr
plugin/os-aidd-lint
plugin/os-backlog
plugin/os-context
plugin/os-doc-hygiene
plugin/os-sdlc
plugin/os-vault
project/cc-os
ready-for-agent
ready-for-human
recurring
review
rule-proposal
update
waiting
wayfinder:grilling
wayfinder:map
wayfinder:map
wayfinder:research
wayfinder:task
wayfinder:task
wontfix
worklist/deviations
worklist/lint-rule
worklist/new-implement-build
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jared/cc-os#1381
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The cop
Sdlc/Sequel/RegistryOutsideEntryPointmatches any constant namedDband skips code by path, not by shape.It flags a non-Sequel
Dband misses the real registry reached throughmethod(:connect_project!).Found by the #1325 zero-false-positive audit (docs/plans/class-length-family/sdlc-cop-audit.md).
Smell analysis:
docs/lint-lessons/analyses/sdlc-sequel-registry-outside-entry-point.md.Observed
Counterexample 1: the cop flags a non-Sequel registry.
Counterexample 2: a non-test class under
tests/is skipped by the**/tests/**/*glob (registry_outside_entry_point.rb:14-17).Counterexample 3:
Db.method(:connect_project!)is missed. The real uses areplugins/os-sdlc/lib/os_sdlc/boot.rb:7andplugins/os-sdlc/lib/os_sdlc/boot/project_bind.rb:6; both are in the entry layer (Boot), so they must not fire.The allowed path
**/controller/**/*matches no directory underplugins/os-sdlc/lib; the real entry layer islib/os_sdlc/boot.rbandlib/os_sdlc/boot/.0 hits on the repo (2026-10-28, 1885 files).
Reproduce
n/a: the cop matcher is at
plugins/os-sdlc/lib/os_sdlc/cops/sequel/registry_outside_entry_point.rb:23-29; run the cop on the snippets above.Approach
Carve-outs go in the cop matcher, never in a config Exclude list or a test-path exclusion.
Match
(const {nil? cbase (const {nil? cbase} :OsSdlc)} :Db)andDb.method(<registry symbol>).Replace the stale
**/controller/**/*entry-layer glob with the real entry layer,Boot(**/os_sdlc/boot.rb,**/os_sdlc/boot/**/*), so thatBoot's injectedDb.method(:connect_project!)default does not fire.Required work:
Dbby constant path (bare,::Db, orOsSdlc::Db) — check: present:OsSdlcinplugins/os-sdlc/lib/os_sdlc/cops/sequel/registry_outside_entry_point.rbDb.method(<registry symbol>)— check: present:methodinplugins/os-sdlc/lib/os_sdlc/cops/sequel/registry_outside_entry_point.rb**/controller/**/*inplugins/os-sdlc/lib/os_sdlc/cops/sequel/registry_outside_entry_point.rbAcceptance criteria
Cache::Db.for(:users)in a query file, when the cop runs, then it reports no offense.OsSdlc::Db.method(:connect_project!)in a query file outside the entry layer, when the cop runs, then it reports an offense.Db.dbinlib/os_sdlc/controller/entry.rb, when the cop runs, then it reports an offense (nocontroller/folder is an entry point).Owner sketch
Deferred: needs Jared's ruling (same question as #1450)
The original approach also asked to replace the
**/tests/**/*and**/*_test.rballowances with a shape carve-out (for example "inside a Minitest::Test subclass"), with the criterion "a non-test class undertests/that calls the registry reports an offense".On main, the non-test classes under
tests/that call the registry are test infrastructure called by test cases:tests/test_helper.rb(RollbackPerTest),tests/support/subagent_stop_scenario.rb,tests/support/subagent_start_scenario.rb,tests/support/cli_next_instruction_helpers.rb,tests/support/repeated_next_row_check.rb, plusDispatchTestCaseandUnboundDbTestCase(indirect Minitest::Test subclasses).Whether a helper class called by an entry point (a test case, or
Boot::Commands) is itself an entry point is the open ruling on #1450. This ticket does not decide it; the test globs stay until that ruling.Origin
VERDICT: CREATE
Work started on branch ticket-1381 (worktree .claude/worktrees/ticket-1381). Ticket body corrected first: cop path is cops/sequel/; test-glob shape carve-out deferred to the #1450 ruling.
Resolution
Done: RegistryOutsideEntryPoint matches Db by constant path only (Db, ::Db, OsSdlc::Db; Cache::Db passes), flags Db.method(), and replaces the stale /controller//* glob with the Boot entry layer (boot.rb, boot/). Message and lesson now say 'only db and boot'. Smell analysis section 6 updated.
Evidence: Pipeline implementation 206 complete (8 dispatches, 8 min 13 s, 0 retries); main
e2588c72pushed (48928fdd+e2588c72). Suite 2865 runs, 0 failures. Cop over plugins/os-sdlc: 0 hits before, 0 after (1885 files). True-case probe: Db.db in lib/os_sdlc/query fires. Regression tests: Db.method(:connect_project!) in boot.rb and boot/project_bind.rb passes.Follow-ups: Original AC3 (test-glob shape carve-out) not done: the non-test classes under tests/ that reach the registry are test support called by test cases; whether such helpers are entry points is the #1450 ruling. Predicted row: Boot (boot.rb, boot/) is the entry layer.
Needs review: Jared: rule on #1450 (are helper classes called by an entry point, incl. tests/support classes and Boot::Commands thin classes, entry points?). Then replace the /tests//* and **/*_test.rb globs by shape. Also confirm predicted row: Boot is the entry layer.
Note from session a48658d5-b566-40ce-8257-ebeabf56f7e1: ruling 134 (docs/decisions/rulings.tsv) deleted the registry check of Sdlc/Sequel/RegistryOutsideEntryPoint that this ticket describes; Boot is deleted on main (
031244657). The cop now holds only the lookup-by-id check; #1684 renames it. This ticket is a close-or-rewrite candidate.Ruling 134 deleted the registry check that this ticket concerns. The one remainder of this ticket (replace the test globs in
DEFAULT_ALLOWED_PATHSby shape) moved to #1684. This ticket stays open.Update 2026-11-12: #1684 is closed (cop renamed to Sdlc/Sequel/LookupByIdOutsideInitialize,
a2996eb8e). The one remainder of this ticket was not done there and returns here: replace the test globs in DEFAULT_ALLOWED_PATHS (lib/os_sdlc/cops/sequel/lookup_by_id_outside_initialize.rb) by shape. It needs a ruling on the shape; #1450 calls it a separate ruling. One candidate, 'inside a Minitest::Test subclass', would make the support classes under test/support report offenses.