Add entry-point coverage report to system-model #1405

Closed
opened 2026-10-26 20:14:52 +00:00 by jared · 2 comments
Owner

VERDICT: CREATE

Problem

Journeys from bin/* do not reach the whole codebase. Nobody can say what share of classes any journey touches, or which classes no entry point reaches.

Reproduce

plugins/os-sdlc/bin/system-model coverage plugins/os

Output: usage: system-model [generate|build|serve|stop|status] <project-root> [--docs DIR], exit 2.

Approach

Add a coverage subcommand to system-model. It builds the model with the normal steps plus the Tracer (the step that fills Model#journeys; today only build adds it), then prints a CoverageReport instead of the census Report. The report has three parts:

  • Entry points by kind. Extractor::EntryScripts today returns receiver constant names only. Give it an entries message that returns one entry per script path with its kind: bin for bin/*, hook for hooks/*, task for Rakefile and *.rake files. The report lists each entry as <kind> <path>.
  • Coverage ratio. Touched classes are the from and to names of every Journey::Message across Model#journeys, intersected with the class names in Model#cards. Coverage is touched divided by all cards, printed as coverage: <touched>/<all>.
  • Unreached classes. Every card name not in the touched set, one per line, sorted.

Wiring: Boot::Inputs.system_model adds coverage to its subcommand allowlist and usage text; SystemModel::Run#call routes coverage to the new report with the Tracer step added.

Required work:

  1. Add entries with kind to Extractor::EntryScripts — check: present entries in plugins/os-sdlc/lib/os_sdlc/system_model/extractor/entry_scripts.rb
  2. Add CoverageReport under the system-model library — check: present CoverageReport in plugins/os-sdlc/lib/os_sdlc/system_model/**/*.rb
  3. Accept coverage in the system-model argv parser and usage text — check: present coverage in plugins/os-sdlc/lib/os_sdlc/boot/inputs.rb
  4. Route coverage through Run with the Tracer step — check: present coverage in plugins/os-sdlc/lib/os_sdlc/system_model/run.rb

Acceptance criteria

  1. Given a root with a Ruby bin/ script, a Ruby hooks/ script, and a Rakefile, when entries are read, then each path is listed once with kind bin, hook, or task.
  2. Given a model whose journeys touch two of four cards, when the coverage report prints, then it prints coverage: 2/4.
  3. Given a model whose journeys touch two of four cards, when the coverage report prints, then it lists the two untouched class names, each on its own line.
  4. Given plugins/os as the target, when system-model coverage plugins/os runs, then it exits zero and prints the entry-point list, the coverage line, and the unreached classes.
  5. Given system-model with no project root, when it runs, then the usage line names coverage among the subcommands.

Owner sketch

class OsSdlc::SystemModel::CoverageReport
  def initialize(stdout); end
  def print(model); end
end
class OsSdlc::SystemModel::Extractor::EntryScripts
  def entries; end   # [Entry(path:, kind:, receivers:)]
end

Non-goals

Static reachability and graphify community grouping (spec section 6 steps b to d) are later work. Entry kinds Thor subcommand and skill script are dropped from this ticket: no scanner owns them (EntryScripts has no Thor scan and reads no skills directory); a later ticket adds them when a journey needs one.

Retired tests

plugins/os-sdlc/tests/system_model_cli_test.rb#test_system_model_without_a_project_root_prints_usage_and_exits_two

Origin

  • Trigger: pattern-distance method validated by fast-batch-17 (main 80a39130)
  • Improvised this session: none
  • Chain: no automated pattern detection ← build-plan step 4/5 not built ← DESIGN (docs/system-design-format/pattern-matching.md section 8)
  • Root candidate: none found; searched coverage, entry point, unreached, journey, reach, catalog, system-model
  • Where: docs/system-design-format/pattern-matching.md section 6; plugins/os-sdlc/bin/system-model
  • Session: 4e988e4b-0efd-4090-9e80-c4ccd99e73b6
  • Criteria rewritten 2026-10-27 (session 47f54f99): first rewrite gave CLI wiring its own check; change-auditor (run 186, dispatch 1634) found the check glob named no file and two unproduced inputs (entry kinds, journeys). Second rewrite names the real wiring files, adds entry kinds to EntryScripts, routes coverage through the Tracer, and retires the usage-text pin.
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-fast-batch-15/4e988e4b-0efd-4090-9e80-c4ccd99e73b6.jsonl
VERDICT: CREATE ## Problem Journeys from `bin/*` do not reach the whole codebase. Nobody can say what share of classes any journey touches, or which classes no entry point reaches. ## Reproduce ``` plugins/os-sdlc/bin/system-model coverage plugins/os ``` Output: `usage: system-model [generate|build|serve|stop|status] <project-root> [--docs DIR]`, exit 2. ## Approach Add a `coverage` subcommand to `system-model`. It builds the model with the normal steps plus the `Tracer` (the step that fills `Model#journeys`; today only `build` adds it), then prints a `CoverageReport` instead of the census `Report`. The report has three parts: * Entry points by kind. `Extractor::EntryScripts` today returns receiver constant names only. Give it an `entries` message that returns one entry per script path with its kind: `bin` for `bin/*`, `hook` for `hooks/*`, `task` for Rakefile and `*.rake` files. The report lists each entry as `<kind> <path>`. * Coverage ratio. Touched classes are the `from` and `to` names of every `Journey::Message` across `Model#journeys`, intersected with the class names in `Model#cards`. Coverage is touched divided by all cards, printed as `coverage: <touched>/<all>`. * Unreached classes. Every card name not in the touched set, one per line, sorted. Wiring: `Boot::Inputs.system_model` adds `coverage` to its subcommand allowlist and usage text; `SystemModel::Run#call` routes `coverage` to the new report with the Tracer step added. Required work: 1. Add `entries` with kind to `Extractor::EntryScripts` — check: present `entries` in `plugins/os-sdlc/lib/os_sdlc/system_model/extractor/entry_scripts.rb` 2. Add `CoverageReport` under the system-model library — check: present `CoverageReport` in `plugins/os-sdlc/lib/os_sdlc/system_model/**/*.rb` 3. Accept `coverage` in the system-model argv parser and usage text — check: present `coverage` in `plugins/os-sdlc/lib/os_sdlc/boot/inputs.rb` 4. Route `coverage` through `Run` with the Tracer step — check: present `coverage` in `plugins/os-sdlc/lib/os_sdlc/system_model/run.rb` ## Acceptance criteria 1. Given a root with a Ruby `bin/` script, a Ruby `hooks/` script, and a `Rakefile`, when entries are read, then each path is listed once with kind `bin`, `hook`, or `task`. 2. Given a model whose journeys touch two of four cards, when the coverage report prints, then it prints `coverage: 2/4`. 3. Given a model whose journeys touch two of four cards, when the coverage report prints, then it lists the two untouched class names, each on its own line. 4. Given `plugins/os` as the target, when `system-model coverage plugins/os` runs, then it exits zero and prints the entry-point list, the coverage line, and the unreached classes. 5. Given `system-model` with no project root, when it runs, then the usage line names `coverage` among the subcommands. ## Owner sketch ```ruby class OsSdlc::SystemModel::CoverageReport def initialize(stdout); end def print(model); end end class OsSdlc::SystemModel::Extractor::EntryScripts def entries; end # [Entry(path:, kind:, receivers:)] end ``` ## Non-goals Static reachability and graphify community grouping (spec section 6 steps b to d) are later work. Entry kinds `Thor subcommand` and `skill script` are dropped from this ticket: no scanner owns them (`EntryScripts` has no Thor scan and reads no skills directory); a later ticket adds them when a journey needs one. ## Retired tests plugins/os-sdlc/tests/system_model_cli_test.rb#test_system_model_without_a_project_root_prints_usage_and_exits_two ## Origin - Trigger: pattern-distance method validated by fast-batch-17 (main 80a39130) - Improvised this session: none - Chain: no automated pattern detection ← build-plan step 4/5 not built ← DESIGN (docs/system-design-format/pattern-matching.md section 8) - Root candidate: none found; searched coverage, entry point, unreached, journey, reach, catalog, system-model - Where: docs/system-design-format/pattern-matching.md section 6; plugins/os-sdlc/bin/system-model - Session: 4e988e4b-0efd-4090-9e80-c4ccd99e73b6 - Criteria rewritten 2026-10-27 (session 47f54f99): first rewrite gave CLI wiring its own check; change-auditor (run 186, dispatch 1634) found the check glob named no file and two unproduced inputs (entry kinds, journeys). Second rewrite names the real wiring files, adds entry kinds to EntryScripts, routes coverage through the Tracer, and retires the usage-text pin. - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os--claude-worktrees-fast-batch-15/4e988e4b-0efd-4090-9e80-c4ccd99e73b6.jsonl
Author
Owner

Work started on branch ticket-1405 via /os-sdlc:implement (session 47f54f99). Criteria: CLI wiring got its own check and criterion.

Work started on branch ticket-1405 via /os-sdlc:implement (session 47f54f99). Criteria: CLI wiring got its own check and criterion.
Author
Owner

Resolution

Done: system-model gains a coverage subcommand: EntryScripts#entries lists entry points by kind (bin, hook, task), CoverageReport prints coverage touched/all and the unreached classes, Run routes coverage through the Tracer, Inputs accepts coverage in argv and usage.

Evidence: Implementation 186 complete, commit 4e3b8854 on branch ticket-1405; 13 dispatches, 2 retries, suite green twice; behavior-verifier passed all five criteria; tests system_model_coverage_test.rb and the rewritten usage pin in system_model_cli_test.rb.

Follow-ups: 1) #1427 captured (ticket-skeptic CREATE): entry kind read from the absolute path misclassifies roots under a hooks directory; 2) Thor subcommand and skill-script entry kinds dropped to Non-goals, no ticket until a journey needs one; 3) the contract-auditor LENS line (A4, Model held presenter text) was resolved in-run by the refactorer.

## Resolution **Done:** system-model gains a coverage subcommand: EntryScripts#entries lists entry points by kind (bin, hook, task), CoverageReport prints coverage touched/all and the unreached classes, Run routes coverage through the Tracer, Inputs accepts coverage in argv and usage. **Evidence:** Implementation 186 complete, commit 4e3b8854 on branch ticket-1405; 13 dispatches, 2 retries, suite green twice; behavior-verifier passed all five criteria; tests system_model_coverage_test.rb and the rewritten usage pin in system_model_cli_test.rb. **Follow-ups:** 1) #1427 captured (ticket-skeptic CREATE): entry kind read from the absolute path misclassifies roots under a hooks directory; 2) Thor subcommand and skill-script entry kinds dropped to Non-goals, no ticket until a journey needs one; 3) the contract-auditor LENS line (A4, Model held presenter text) was resolved in-run by the refactorer.
jared closed this issue 2026-10-27 17:04:46 +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#1405
No description provided.