Add cop Sdlc/Sequel/InlineDatasetQuery #911

Closed
opened 2026-10-02 16:57:07 +00:00 by jared · 2 comments
Owner

Problem

A query on one model's rows is built outside that model.
Signal: a query on one model's rows is built outside that model, so it has no name and no owner.

Approach

Add the cop Sdlc/Sequel/InlineDatasetQuery under plugins/os-sdlc/lib/os_sdlc/cops/.
Templates: registry_outside_entry_point.rb, row_index_on_model.rb, and the shared sequel_allowed_paths.rb.
Authoring guide: plugins/os-sdlc/skills/mine-lints/references/implement-cop.md.
RuboCop runs with DisabledByDefault: true, so every enabled cop blocks at the gate and every hit must always need a correction.
Do not widen the match lists below.
Receiver test: the chain starts from a *_dataset call.
Direct model queries (Model.where) are out of scope.

Flagged: where filter exclude or order order_by reverse reverse_order limit offset group having called on a *_dataset chain outside a dataset_module.

Not flagged: Left out on purpose (rare, or a hit does not always need a correction): join family, select family, distinct, with_sql, where_all/where_each/where_single_value, first(conditions), eager/eager_graph, invert unordered unfiltered for_update.

Known hits: model/implementation/dispatching.rb:9-10 (where(verdict: "pass")), reroute/draft.rb:29, model/implementation/progress_witness.rb:24 (reverse) (all under plugins/os-sdlc/lib/os_sdlc/).
Correct the existing hits in plugins/os-sdlc/lib/ in the same change.
Intended correction: move the query or decision into a named dataset_module method on the model that owns the rows, and delegate from the caller.

Lesson (ADR-0265): the lesson file is a required part of the cop.
Path: plugins/os-sdlc/lint-lessons/<kebab-cop-name>.md in the plugin (ADR-0266).
Sections in order: The signal; What it is a sign of; Why it matters; Your decision; Correction; Example.
Lesson text uses generic names (for example orders_dataset, Order), never names from this codebase.
Lesson example: before orders_dataset.where(status: "shipped"), after orders_dataset.shipped.
Depends on #908 (Lesson concept move; Lesson::Library reads the plugin lesson directory).

Required work:

  1. Add the cop file — check: present InlineDatasetQuery in plugins/os-sdlc/lib/os_sdlc/cops/*.rb
  2. Add the lesson file — check: present The signal in plugins/os-sdlc/lint-lessons/sdlc-sequel-inline-dataset-query.md

Acceptance criteria

  1. Given a call in the flagged list on a *_dataset chain, when the cop runs, then it flags it.
  2. Given a call in the not-flagged list, when the cop runs, then it does not flag it.
  3. Given the existing hits in plugins/os-sdlc/lib, when the gate runs, then none remain.
  4. Given a gate reply for a flagged offense, when the gate renders, then the lesson file text appears.

Owner sketch

class RuboCop::Cop::Sdlc::Sequel::InlineDatasetQuery < RuboCop::Cop::Base
  def on_send(node)
end

Origin

  • Trigger: user request this session, from a review of Sequel dataset use.
  • Improvised this session: none
  • Chain: query or decision outside owning model ← no cop covers it (DESIGN: ADR-0265)
  • Root candidate: none
  • Where: plugins/os-sdlc/lib/os_sdlc/cops/
  • Session: 9ee7805f-a4e4-470e-af50-5020e5c524a4
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/9ee7805f-a4e4-470e-af50-5020e5c524a4.jsonl
## Problem A query on one model's rows is built outside that model. Signal: a query on one model's rows is built outside that model, so it has no name and no owner. ## Approach Add the cop `Sdlc/Sequel/InlineDatasetQuery` under `plugins/os-sdlc/lib/os_sdlc/cops/`. Templates: `registry_outside_entry_point.rb`, `row_index_on_model.rb`, and the shared `sequel_allowed_paths.rb`. Authoring guide: `plugins/os-sdlc/skills/mine-lints/references/implement-cop.md`. RuboCop runs with `DisabledByDefault: true`, so every enabled cop blocks at the gate and every hit must always need a correction. Do not widen the match lists below. Receiver test: the chain starts from a `*_dataset` call. Direct model queries (`Model.where`) are out of scope. Flagged: `where filter exclude or order order_by reverse reverse_order limit offset group having` called on a `*_dataset` chain outside a `dataset_module`. Not flagged: Left out on purpose (rare, or a hit does not always need a correction): join family, `select` family, `distinct`, `with_sql`, `where_all`/`where_each`/`where_single_value`, `first(conditions)`, `eager`/`eager_graph`, `invert unordered unfiltered for_update`. Known hits: `model/implementation/dispatching.rb:9-10` (`where(verdict: "pass")`), `reroute/draft.rb:29`, `model/implementation/progress_witness.rb:24` (`reverse`) (all under `plugins/os-sdlc/lib/os_sdlc/`). Correct the existing hits in `plugins/os-sdlc/lib/` in the same change. Intended correction: move the query or decision into a named `dataset_module` method on the model that owns the rows, and delegate from the caller. Lesson (ADR-0265): the lesson file is a required part of the cop. Path: `plugins/os-sdlc/lint-lessons/<kebab-cop-name>.md` in the plugin (ADR-0266). Sections in order: The signal; What it is a sign of; Why it matters; Your decision; Correction; Example. Lesson text uses generic names (for example `orders_dataset`, `Order`), never names from this codebase. Lesson example: before `orders_dataset.where(status: "shipped")`, after `orders_dataset.shipped`. Depends on #908 (Lesson concept move; `Lesson::Library` reads the plugin lesson directory). Required work: 1. Add the cop file — check: present `InlineDatasetQuery` in `plugins/os-sdlc/lib/os_sdlc/cops/*.rb` 2. Add the lesson file — check: present `The signal` in `plugins/os-sdlc/lint-lessons/sdlc-sequel-inline-dataset-query.md` ## Acceptance criteria 1. Given a call in the flagged list on a `*_dataset` chain, when the cop runs, then it flags it. 2. Given a call in the not-flagged list, when the cop runs, then it does not flag it. 3. Given the existing hits in `plugins/os-sdlc/lib`, when the gate runs, then none remain. 4. Given a gate reply for a flagged offense, when the gate renders, then the lesson file text appears. ## Owner sketch ```ruby class RuboCop::Cop::Sdlc::Sequel::InlineDatasetQuery < RuboCop::Cop::Base def on_send(node) end ``` ## Origin - Trigger: user request this session, from a review of Sequel dataset use. - Improvised this session: none - Chain: query or decision outside owning model ← no cop covers it (DESIGN: ADR-0265) - Root candidate: none - Where: plugins/os-sdlc/lib/os_sdlc/cops/ - 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-911 through the os-sdlc pipeline.

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

Resolution

Done: Cop Sdlc/Sequel/InlineDatasetQuery added and enabled, with its lesson file plugins/os-sdlc/lint-lessons/sdlc-sequel-inline-dataset-query.md. Seven existing hits corrected by delegation to named dataset_module methods on Dispatch, StepResult, Reroute, and Violations.

Evidence: Branch ticket-911; os-sdlc implementation 17: 10 dispatches. suite-check escalated once with green_report_nonzero_exit (all tests passed, wall time 64.6 s, load average 9.03); after the load dropped, a reroute re-entered at suite-check and the suite passed in 17.5 s. Required-work gate green, contract-auditor pass.

Follow-ups: Lesson converts to YAML under #913. History row added after merge.

## Resolution **Done:** Cop Sdlc/Sequel/InlineDatasetQuery added and enabled, with its lesson file plugins/os-sdlc/lint-lessons/sdlc-sequel-inline-dataset-query.md. Seven existing hits corrected by delegation to named dataset_module methods on Dispatch, StepResult, Reroute, and Violations. **Evidence:** Branch ticket-911; os-sdlc implementation 17: 10 dispatches. suite-check escalated once with green_report_nonzero_exit (all tests passed, wall time 64.6 s, load average 9.03); after the load dropped, a reroute re-entered at suite-check and the suite passed in 17.5 s. Required-work gate green, contract-auditor pass. **Follow-ups:** Lesson converts to YAML under #913. History row added after merge.
jared closed this issue 2026-10-02 17:50:08 +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#911
No description provided.