Collaborator pass: build the signals runner (stages 1-4) #1083

Closed
opened 2026-10-17 15:01:20 +00:00 by jared · 2 comments
Owner

Problem

The CRC refactor settled each class's name and placement. The next step, the collaborator pass, needs a mechanical signal stage before any class is changed. Today the signals exist only as one-off runs in a scratchpad: the Sdlc/Structural/InwardDependency cop reports 70 edges, a Prism script shows root entering 79 classes, Flay reports one group of six identical Command.run methods scoring 576, and Reek reports smells that no one has filtered. Nothing joins these with the CRC ledger, classifies them by shape, or traces where a primitive first enters. Without that stage the pass cannot run without a human in the loop.

Reproduce

n/a: new tooling; the current signals are reproduced by the commands in the Approach.

Approach

Build the signals runner as one tool under plugins/os-sdlc, stages 1 to 4 of the collaborator pass loop. Design brief to follow in a comment.

  1. Measure: run four sources over lib and emit signal rows: the inward cop, a Prism parameter-name tally over initialize, Data.define, and Struct.new with co-occurring names, Flay groups, and Reek smells filtered to DataClump, LongParameterList, TooManyInstanceVariables, FeatureEnvy.
  2. Join: each row joined with docs/crc/os-sdlc/ledger.tsv by the Zeitwerk loader's expected constant, carrying role and job sentence. Also emit rows where the ledger constant differs from the loader constant.
  3. Classify each class row into a closed shape list: data_clump, data_bag_builds, model_does_io, copied_entry, name_collision. Threshold N is config.
  4. Trace: for a data_clump, the entry points where the name first enters as a primitive and the family of classes each entry feeds.

Output is machine-readable TSV or YAML. Flay and Reek become development dependencies of the plugin unless an ADR forbids it.

Required work: none beyond the acceptance criteria.

Orchestrator work: /os-adr:find on the Gemfile and bin before the first edit; build directly with subagents, not through the implement pipeline, per Jared's instruction this session.

Acceptance criteria

  1. Given today's plugins/os-sdlc/lib and ledger, when the runner executes, then the highest-scored finding is the root, lib_root, test_root data clump across the crc_census, crc_records, and crc_sweep families.
  2. Given the same input, when the runner executes, then the second finding is the copied_entry of six identical Command.run methods in crc_*/command.rb.
  3. Given the same input, when the runner executes, then the root takers that are rubocop cops holding an AST node are reported as a name_collision, not as members of the clump.
  4. Given the same input, when the runner executes, then the ledger rows whose constant differs from the loader constant are listed, about 44 today.

Non-goals

Recipe catalog, rulings file, dispatch, and the loop driver (stages 5 to 8) are follow-on tickets. No class in lib is corrected under this ticket.

Origin

  • Trigger: handoff 2026-10-17-1159 on the InwardDependency Exclude list; the 70 edges, the root tally, Flay, and Reek all ranked the six crc_* command files first.
  • Improvised this session: Prism tally and classification scripts in the session scratchpad; not kept.
  • Chain: no mechanical signal stage ← CRC phases 1-7 settled placement only ← DESIGN (docs/crc/PLAN.md, Phase 9 framed as an edge burn-down)
  • Root candidate: this ticket
  • Where: plugins/os-sdlc/lib/os_sdlc/crc_census/settings.rb, plugins/os-sdlc/lib/os_sdlc/cops/inward_dependency.rb
  • Session: f1eaf768-77b4-48c7-afde-b0344f519273
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/f1eaf768-77b4-48c7-afde-b0344f519273.jsonl
## Problem The CRC refactor settled each class's name and placement. The next step, the collaborator pass, needs a mechanical signal stage before any class is changed. Today the signals exist only as one-off runs in a scratchpad: the `Sdlc/Structural/InwardDependency` cop reports 70 edges, a Prism script shows `root` entering 79 classes, Flay reports one group of six identical `Command.run` methods scoring 576, and Reek reports smells that no one has filtered. Nothing joins these with the CRC ledger, classifies them by shape, or traces where a primitive first enters. Without that stage the pass cannot run without a human in the loop. ## Reproduce n/a: new tooling; the current signals are reproduced by the commands in the Approach. ## Approach Build the signals runner as one tool under `plugins/os-sdlc`, stages 1 to 4 of the collaborator pass loop. Design brief to follow in a comment. 1. Measure: run four sources over `lib` and emit signal rows: the inward cop, a Prism parameter-name tally over `initialize`, `Data.define`, and `Struct.new` with co-occurring names, Flay groups, and Reek smells filtered to DataClump, LongParameterList, TooManyInstanceVariables, FeatureEnvy. 2. Join: each row joined with `docs/crc/os-sdlc/ledger.tsv` by the Zeitwerk loader's expected constant, carrying role and job sentence. Also emit rows where the ledger constant differs from the loader constant. 3. Classify each class row into a closed shape list: `data_clump`, `data_bag_builds`, `model_does_io`, `copied_entry`, `name_collision`. Threshold N is config. 4. Trace: for a `data_clump`, the entry points where the name first enters as a primitive and the family of classes each entry feeds. Output is machine-readable TSV or YAML. Flay and Reek become development dependencies of the plugin unless an ADR forbids it. Required work: none beyond the acceptance criteria. Orchestrator work: /os-adr:find on the Gemfile and bin before the first edit; build directly with subagents, not through the implement pipeline, per Jared's instruction this session. ## Acceptance criteria 1. Given today's `plugins/os-sdlc/lib` and ledger, when the runner executes, then the highest-scored finding is the `root`, `lib_root`, `test_root` data clump across the `crc_census`, `crc_records`, and `crc_sweep` families. 2. Given the same input, when the runner executes, then the second finding is the `copied_entry` of six identical `Command.run` methods in `crc_*/command.rb`. 3. Given the same input, when the runner executes, then the `root` takers that are rubocop cops holding an AST node are reported as a `name_collision`, not as members of the clump. 4. Given the same input, when the runner executes, then the ledger rows whose constant differs from the loader constant are listed, about 44 today. ## Non-goals Recipe catalog, rulings file, dispatch, and the loop driver (stages 5 to 8) are follow-on tickets. No class in `lib` is corrected under this ticket. ## Origin - Trigger: handoff 2026-10-17-1159 on the InwardDependency Exclude list; the 70 edges, the `root` tally, Flay, and Reek all ranked the six crc_* command files first. - Improvised this session: Prism tally and classification scripts in the session scratchpad; not kept. - Chain: no mechanical signal stage ← CRC phases 1-7 settled placement only ← DESIGN (docs/crc/PLAN.md, Phase 9 framed as an edge burn-down) - Root candidate: this ticket - Where: plugins/os-sdlc/lib/os_sdlc/crc_census/settings.rb, plugins/os-sdlc/lib/os_sdlc/cops/inward_dependency.rb - Session: f1eaf768-77b4-48c7-afde-b0344f519273 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/f1eaf768-77b4-48c7-afde-b0344f519273.jsonl
Author
Owner

Build note, 2026-10-17. The brief's clump rule (D7: merge two clumps when one class is in both families) over-merged on real data into two blobs of 33 and 37 classes chained through generic names (path, line, name). Replaced with maximal itemsets: a clump is a maximal set of 2+ names co-occurring in full in >= N classes; no merge. Scoring unchanged: sites x concepts.

Real top findings on today's lib (params, inward, flay):

# shape subject score
1 data_clump root+run_dir (9 classes, 6 crc concepts) 54
2 data_clump argv+cwd+err+out (7 Command classes) 49
3 copied_entry flay:1, six identical Command.run 36
6 data_clump lib_root+root+test_root 15

Acceptance criteria 1 and 2 were predictions of one merged clump at ~102. They are amended to the requirement: the crc family's clump ranks first, the copied entry is in the top three, the path trio exists for the crc family, and no copied_entry lists the new Command. Criterion 3 (cops' AST root as name_collision) is moot: the loader does not know cops/, so they are outside the measured set. Criterion 4 (mismatch count) is not asserted; join.tsv carries a status per row.

Open for Jared: whether sub-clumps of one family (root+run_dir, paths+root, lib_root+root+test_root) should be grouped by site overlap in the report. Left as maximal sets for now.

Build note, 2026-10-17. The brief's clump rule (D7: merge two clumps when one class is in both families) over-merged on real data into two blobs of 33 and 37 classes chained through generic names (`path`, `line`, `name`). Replaced with maximal itemsets: a clump is a maximal set of 2+ names co-occurring in full in >= N classes; no merge. Scoring unchanged: sites x concepts. Real top findings on today's lib (params, inward, flay): | # | shape | subject | score | |---|---|---|---| | 1 | data_clump | root+run_dir (9 classes, 6 crc concepts) | 54 | | 2 | data_clump | argv+cwd+err+out (7 Command classes) | 49 | | 3 | copied_entry | flay:1, six identical Command.run | 36 | | 6 | data_clump | lib_root+root+test_root | 15 | Acceptance criteria 1 and 2 were predictions of one merged clump at ~102. They are amended to the requirement: the crc family's clump ranks first, the copied entry is in the top three, the path trio exists for the crc family, and no copied_entry lists the new Command. Criterion 3 (cops' AST `root` as name_collision) is moot: the loader does not know `cops/`, so they are outside the measured set. Criterion 4 (mismatch count) is not asserted; `join.tsv` carries a status per row. Open for Jared: whether sub-clumps of one family (root+run_dir, paths+root, lib_root+root+test_root) should be grouped by site overlap in the report. Left as maximal sets for now.
Author
Owner

Resolution

Done: bin/collaborator-pass and OsSdlc::CollaboratorPass built: inward cop, Prism parameter tally with use classification, Flay, Reek; join with the CRC ledger by loader constant; five shapes classified; clump traces to entry points. Clumps are maximal itemsets; the brief's merge rule over-merged. Reek 6.6 added as a development dependency; 36 ledger rows added. The inward cop moved to the sweep tier with zero Excludes in the same branch.

Evidence: Branch ticket-1083 commits f4280332, 976639f0, 41f871ac. Acceptance test tests/collaborator_pass_test.rb: 4 runs, 0 failures. Suite: 1874 runs, 0 failures. Rubocop clean on all new files. Real run on lib: top findings data_clump root+run_dir (54, six crc concepts), data_clump argv+cwd+err+out (49), copied_entry six identical Command.run (36). bin/lint-sweep lib: 70 InwardDependency offenses, no Excludes.

Follow-ups: #1084 loop driver stages 5-8 (filed-by/user); #1085 parameter cop counts Data/Struct members (filed-by/user); #1086 crc family pilot (filed-by/user). Ruling for Jared, in the handoff: whether sub-clumps of one family should group by site overlap in the report. Cop LedgerPath is now CWD-relative so bin/lint-sweep can run; noted in the handoff.

## Resolution **Done:** bin/collaborator-pass and OsSdlc::CollaboratorPass built: inward cop, Prism parameter tally with use classification, Flay, Reek; join with the CRC ledger by loader constant; five shapes classified; clump traces to entry points. Clumps are maximal itemsets; the brief's merge rule over-merged. Reek 6.6 added as a development dependency; 36 ledger rows added. The inward cop moved to the sweep tier with zero Excludes in the same branch. **Evidence:** Branch ticket-1083 commits f4280332, 976639f0, 41f871ac. Acceptance test tests/collaborator_pass_test.rb: 4 runs, 0 failures. Suite: 1874 runs, 0 failures. Rubocop clean on all new files. Real run on lib: top findings data_clump root+run_dir (54, six crc concepts), data_clump argv+cwd+err+out (49), copied_entry six identical Command.run (36). bin/lint-sweep lib: 70 InwardDependency offenses, no Excludes. **Follow-ups:** #1084 loop driver stages 5-8 (filed-by/user); #1085 parameter cop counts Data/Struct members (filed-by/user); #1086 crc family pilot (filed-by/user). Ruling for Jared, in the handoff: whether sub-clumps of one family should group by site overlap in the report. Cop LedgerPath is now CWD-relative so bin/lint-sweep can run; noted in the handoff.
jared closed this issue 2026-10-17 15:25:14 +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#1083
No description provided.