Project.load plus Crc::Run entry: every CRC class takes project #1093

Closed
opened 2026-10-17 17:57:40 +00:00 by jared · 4 comments
Owner

Problem

Twenty-one bins in plugins/os-sdlc/bin have two entry contracts.

Fourteen os-sdlc-* bins enter through OsSdlc::Boot.run(name, ProcessIO.from_process, ARGV).
That path uses the Boot::Commands::TABLE registry, Boot::Inputs typed parsing, Boot::ProjectBind root lookup, and ProcessIO::Outcome exit handling.

The seven other bins (crc-census, crc-file, crc-jobs, crc-records, crc-sweep, crc-tickets, collaborator-pass) enter through Command.new(ARGV, $stdout, $stderr, Dir.pwd).run.
CommandLine (#1088) and CommandController (#1090) re-implement Boot in small.
These commands take --root, --test-root, and a positional LIB_ROOT.
Those values are project.yaml facts that Project already loads.
The commands thread the three path strings into TestLookup, Files, PathLookup, Requirers, RequiringFile, and Settings.

Run 20261017T165147Z reports this as eleven root-family data_clump findings.
Examples: root+test_root (21), lib_root+test_root (15), lib_root+root (10).
The argv+cwd+err+out clump, ruled rejected-expected, is a copy of ProcessIO::Invocation.

Reproduce

n/a: design ticket

Approach

# bin/crc-census: before
exit OsSdlc::CrcCensus::Command.new(ARGV, $stdout, $stderr, Dir.pwd).run
# after
exit OsSdlc::Boot.run("crc-census", OsSdlc::ProcessIO.from_process, ARGV)
crc-census --root . --test-root tests --exclude lib/x RUN_DIR LIB_ROOT PATH...   # before
crc-census --target os-sdlc --exclude lib/x RUN_DIR PATH...                      # after
# boot/commands.rb, one row per crc command
"crc-census" => CommandSpec.script(
  Inputs.method(:crc_census),
  ->(io, run, project) { Crc::Census::Run.new(io, project, run).call }
),
# boot/inputs.rb
def self.crc_census(io, argv)
  target  = ArgvOption.take!(argv, "--target NAME")
  exclude = ArgvOption.take_all!(argv, "--exclude PREFIX")
  run_dir = argv.shift or raise RefusalError, "crc-census: RUN_DIR is required"
  Input.new(dir: io.cwd, target: target, value: Crc::RunConfig.new(target:, run_dir:, exclude:, paths: argv))
end
# boot/project_bind.rb: #call(dir) is unchanged and still returns the root path for the fourteen existing commands
def project(dir, target:)
  root = call(dir) or raise RefusalError.new("no .sdlc/project.yaml at or above #{dir}", 3)
  Project.load(root, target: target)
end
# boot.rb: prepared passes a Project only when the input names a target
def prepared
  input = @command.prepare.call(@io, @argv)
  third = input.target ? @bind.project(input.dir, target: input.target) : input.root_or(bound(input.dir))
  @command.action.call(@io, input.value, third)
rescue RefusalError => e
  @io.stderr.puts e.message
  e.status
end
# the command after; Settings.for reads lib_root = project.target.path, test_root = project.target.test.path; collaborator-pass gets the same shape
class OsSdlc::Crc::Census::Run
  def initialize(io, project, run) = (@io, @project, @run = io, project, run)
  def call
    settings = Settings.for(@project, @run)
    report   = Crc::Census.new(settings).call
    @io.emit(report.to_h)
    report.ok? ? 0 : 1
  end
end

Each crc parser keeps that command's own value options (--loader, --exclude, --write, and the rest) through ArgvOption.take!; only --root, --test-root, and the positional LIB_ROOT go away.
A parser that sees -h or --help raises RefusalError.new(usage_text, 0) with the usage text on stdout; a parser that sees a missing positional raises RefusalError.new(usage_text, 2). Boot::RefusalError gains an optional status argument, default 1, so the fourteen existing commands do not change.
Boot::Input gains an optional target field.
When target is set, Boot#prepared binds a Project through ProjectBind#project and passes it as the third argument; a missing project root is a RefusalError with exit 3.
The fourteen existing commands leave target nil and keep receiving the root path; ProjectBind#call does not change.

Project.load(root, target:) reads .sdlc/project.yaml under root through Project::Config and Project.from_data, then binds the named target, so project.target with no argument returns it even on a shaped file.
Project#codebase returns target.codebase(root), the existing Project::Codebase.new(code:, test:, root:).
The seven commands are: crc-census, crc-file, crc-jobs, crc-records, crc-sweep, crc-tickets, collaborator-pass.

The seven commands become Run objects that take (io, project, run).
CrcRunPath stays. It is the run, not the project.
collaborator-pass keeps its seven subcommands with their own OPTIONS, POSITIONAL, and INJECT tables and the clock from with_clock. Inputs.collaborator_pass shifts the subcommand name and returns [name, argv]; the action is CollaboratorPass::Run.new(io, project, clock).call(name, argv), and each subcommand parses its own argv with OptionParser directly instead of through CommandLine.

Delete command_controller.rb and command_line.rb.
Delete the seven Command classes, their USAGE strings, and their options(parser) hooks.
Delete the lib_root: and test_root: keywords from TestLookup, Files, PathLookup, Requirers, RequiringFile, and Settings.

The Crc:: namespace move belongs to #1092.
This ticket may land on the unmoved tree (CrcCensus::Run and so on).
#1092 moves it afterwards.

Required work:

  1. Seven rows in Boot::Commands::TABLE for the crc commands — check: present "crc-census" in plugins/os-sdlc/lib/os_sdlc/boot/commands.rb
  2. Seven Boot::Inputs parsers that take --target NAME — check: present def self.crc_census in plugins/os-sdlc/lib/os_sdlc/boot/inputs.rb
  3. Boot::Input carries an optional target; Boot#prepared passes it to bound — check: present target in plugins/os-sdlc/lib/os_sdlc/boot/input.rb
  4. Boot::ProjectBind#project(dir, target:) returns a bound Project and refuses with exit 3 when no root exists; #call is unchanged — check: present Project.load in plugins/os-sdlc/lib/os_sdlc/boot/project_bind.rb
  5. Project.load(root, target:) and Project#codebase = target.codebase(root) — check: present def self.load in plugins/os-sdlc/lib/os_sdlc/project.rb
  6. Seven bins (crc-census, crc-file, crc-jobs, crc-records, crc-sweep, crc-tickets, collaborator-pass) call Boot.run — check: absent Command.new(ARGV in plugins/os-sdlc/bin/*
  7. command_controller.rb and command_line.rb deleted — check: absent class CommandController in plugins/os-sdlc/lib/os_sdlc/*.rb
  8. No CRC class takes test_root: or lib_root: keywords — check: absent test_root: in plugins/os-sdlc/lib/os_sdlc/crc_*/**/*.rb
  9. collaborator_pass/command.rb no longer inherits CommandController and no file under it builds CommandLine — check: absent CommandLine in plugins/os-sdlc/lib/os_sdlc/collaborator_pass/**/*.rb
  10. Boot::RefusalError.new(message, status = 1) — check: present status in plugins/os-sdlc/lib/os_sdlc/boot/refusal_error.rb
  11. The seven parsers handle -h with exit 0 and a missing positional with exit 2 through RefusalError — check: present RefusalError.new in plugins/os-sdlc/lib/os_sdlc/boot/inputs.rb

Orchestrator work: run /os-adr:find on the seven bins and Boot::ProjectBind before the first edit, because the CLI contract changes.
After merge, run collaborator-pass measure and delta-check against run 20261017T165147Z.
Re-rule argv+cwd+err+out with record-ruling.

Acceptance criteria

  1. Given .sdlc/project.yaml with target os-sdlc, when Project.load(root, target: "os-sdlc") runs, then project.target.path and project.target.test.path match the yaml.
  2. Given each of the seven crc bins with --target os-sdlc and its existing positional arguments minus LIB_ROOT, when it runs on the fixture repo, then its stdout and exit code equal today's run with explicit --root, --test-root, and LIB_ROOT.
  3. Given -h on any of the seven bins, when it runs, then it prints that command's usage and exits 0.
  4. Given a missing positional argument on any of the seven bins, when it runs, then it prints usage and exits 2, as today.
  5. Given a crc bin run outside any project, when it runs, then it prints no .sdlc/project.yaml at or above <cwd> on stderr and exits 3; the fourteen existing Boot scripts keep their current fallback.
  6. Given the merged change, when collaborator-pass measure runs, then no data_clump finding names test_root or lib_root, and no finding names CommandController or CommandLine.
  7. Given the os-sdlc suite after the change, then it is green and the existing tests for the fourteen Boot commands are unchanged.

Owner sketch

class OsSdlc::Boot::ProjectBind
  def call(dir)
  def project(dir, target:)
end
class OsSdlc::Project
  def self.load(root, target:)
  def codebase = target.codebase(root)
end
class OsSdlc::CrcCensus::Run
  def initialize(io, project, run)
  def call
end

Retired tests

plugins/os-sdlc/tests/command_controller_test.rb
plugins/os-sdlc/tests/command_line_test.rb

Non-goals

  • The Crc:: namespace move (#1092).
  • The implementation+root, root+runner, and root+tracker clumps.
  • The fourteen existing Boot commands, ProjectBind#call, and their tests: unchanged.

Origin

  • Trigger: collaborator-pass run 20261017T165147Z; ruling 1 of handoff .cc-os/os/handoffs/2026-10-17-1526-collaborator-pass-stages-1-4-shipped.md, section "Back on track"
  • Improvised this session: none
  • Chain: root-family data clumps ← CRC classes take path strings ← bins never load Project ← DESIGN (plugins/os-sdlc/skills/collaborator-pass/SKILL.md)
  • Root candidate: this ticket
  • Where: plugins/os-sdlc/lib/os_sdlc/crc_census/command.rb
  • Session: 909d1bcd-dd81-408f-8581-5c682b1a742d
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/909d1bcd-dd81-408f-8581-5c682b1a742d.jsonl
## Problem Twenty-one bins in `plugins/os-sdlc/bin` have two entry contracts. Fourteen `os-sdlc-*` bins enter through `OsSdlc::Boot.run(name, ProcessIO.from_process, ARGV)`. That path uses the `Boot::Commands::TABLE` registry, `Boot::Inputs` typed parsing, `Boot::ProjectBind` root lookup, and `ProcessIO::Outcome` exit handling. The seven other bins (crc-census, crc-file, crc-jobs, crc-records, crc-sweep, crc-tickets, collaborator-pass) enter through `Command.new(ARGV, $stdout, $stderr, Dir.pwd).run`. `CommandLine` (#1088) and `CommandController` (#1090) re-implement Boot in small. These commands take `--root`, `--test-root`, and a positional `LIB_ROOT`. Those values are project.yaml facts that `Project` already loads. The commands thread the three path strings into TestLookup, Files, PathLookup, Requirers, RequiringFile, and Settings. Run 20261017T165147Z reports this as eleven root-family `data_clump` findings. Examples: root+test_root (21), lib_root+test_root (15), lib_root+root (10). The `argv+cwd+err+out` clump, ruled rejected-expected, is a copy of `ProcessIO::Invocation`. ## Reproduce n/a: design ticket ## Approach ```ruby # bin/crc-census: before exit OsSdlc::CrcCensus::Command.new(ARGV, $stdout, $stderr, Dir.pwd).run # after exit OsSdlc::Boot.run("crc-census", OsSdlc::ProcessIO.from_process, ARGV) ``` ``` crc-census --root . --test-root tests --exclude lib/x RUN_DIR LIB_ROOT PATH... # before crc-census --target os-sdlc --exclude lib/x RUN_DIR PATH... # after ``` ```ruby # boot/commands.rb, one row per crc command "crc-census" => CommandSpec.script( Inputs.method(:crc_census), ->(io, run, project) { Crc::Census::Run.new(io, project, run).call } ), # boot/inputs.rb def self.crc_census(io, argv) target = ArgvOption.take!(argv, "--target NAME") exclude = ArgvOption.take_all!(argv, "--exclude PREFIX") run_dir = argv.shift or raise RefusalError, "crc-census: RUN_DIR is required" Input.new(dir: io.cwd, target: target, value: Crc::RunConfig.new(target:, run_dir:, exclude:, paths: argv)) end # boot/project_bind.rb: #call(dir) is unchanged and still returns the root path for the fourteen existing commands def project(dir, target:) root = call(dir) or raise RefusalError.new("no .sdlc/project.yaml at or above #{dir}", 3) Project.load(root, target: target) end # boot.rb: prepared passes a Project only when the input names a target def prepared input = @command.prepare.call(@io, @argv) third = input.target ? @bind.project(input.dir, target: input.target) : input.root_or(bound(input.dir)) @command.action.call(@io, input.value, third) rescue RefusalError => e @io.stderr.puts e.message e.status end # the command after; Settings.for reads lib_root = project.target.path, test_root = project.target.test.path; collaborator-pass gets the same shape class OsSdlc::Crc::Census::Run def initialize(io, project, run) = (@io, @project, @run = io, project, run) def call settings = Settings.for(@project, @run) report = Crc::Census.new(settings).call @io.emit(report.to_h) report.ok? ? 0 : 1 end end ``` Each crc parser keeps that command's own value options (`--loader`, `--exclude`, `--write`, and the rest) through `ArgvOption.take!`; only `--root`, `--test-root`, and the positional `LIB_ROOT` go away. A parser that sees `-h` or `--help` raises `RefusalError.new(usage_text, 0)` with the usage text on stdout; a parser that sees a missing positional raises `RefusalError.new(usage_text, 2)`. `Boot::RefusalError` gains an optional status argument, default 1, so the fourteen existing commands do not change. `Boot::Input` gains an optional `target` field. When `target` is set, `Boot#prepared` binds a `Project` through `ProjectBind#project` and passes it as the third argument; a missing project root is a `RefusalError` with exit 3. The fourteen existing commands leave `target` nil and keep receiving the root path; `ProjectBind#call` does not change. `Project.load(root, target:)` reads `.sdlc/project.yaml` under `root` through `Project::Config` and `Project.from_data`, then binds the named target, so `project.target` with no argument returns it even on a shaped file. `Project#codebase` returns `target.codebase(root)`, the existing `Project::Codebase.new(code:, test:, root:)`. The seven commands are: crc-census, crc-file, crc-jobs, crc-records, crc-sweep, crc-tickets, collaborator-pass. The seven commands become `Run` objects that take `(io, project, run)`. `CrcRunPath` stays. It is the run, not the project. `collaborator-pass` keeps its seven subcommands with their own OPTIONS, POSITIONAL, and INJECT tables and the clock from `with_clock`. `Inputs.collaborator_pass` shifts the subcommand name and returns `[name, argv]`; the action is `CollaboratorPass::Run.new(io, project, clock).call(name, argv)`, and each subcommand parses its own argv with `OptionParser` directly instead of through `CommandLine`. Delete `command_controller.rb` and `command_line.rb`. Delete the seven `Command` classes, their USAGE strings, and their `options(parser)` hooks. Delete the `lib_root:` and `test_root:` keywords from TestLookup, Files, PathLookup, Requirers, RequiringFile, and Settings. The `Crc::` namespace move belongs to #1092. This ticket may land on the unmoved tree (`CrcCensus::Run` and so on). #1092 moves it afterwards. Required work: 1. Seven rows in `Boot::Commands::TABLE` for the crc commands — check: present `"crc-census"` in `plugins/os-sdlc/lib/os_sdlc/boot/commands.rb` 2. Seven `Boot::Inputs` parsers that take `--target NAME` — check: present `def self.crc_census` in `plugins/os-sdlc/lib/os_sdlc/boot/inputs.rb` 3. `Boot::Input` carries an optional `target`; `Boot#prepared` passes it to `bound` — check: present `target` in `plugins/os-sdlc/lib/os_sdlc/boot/input.rb` 4. `Boot::ProjectBind#project(dir, target:)` returns a bound `Project` and refuses with exit 3 when no root exists; `#call` is unchanged — check: present `Project.load` in `plugins/os-sdlc/lib/os_sdlc/boot/project_bind.rb` 5. `Project.load(root, target:)` and `Project#codebase = target.codebase(root)` — check: present `def self.load` in `plugins/os-sdlc/lib/os_sdlc/project.rb` 6. Seven bins (crc-census, crc-file, crc-jobs, crc-records, crc-sweep, crc-tickets, collaborator-pass) call `Boot.run` — check: absent `Command.new(ARGV` in `plugins/os-sdlc/bin/*` 7. `command_controller.rb` and `command_line.rb` deleted — check: absent `class CommandController` in `plugins/os-sdlc/lib/os_sdlc/*.rb` 8. No CRC class takes `test_root:` or `lib_root:` keywords — check: absent `test_root:` in `plugins/os-sdlc/lib/os_sdlc/crc_*/**/*.rb` 9. `collaborator_pass/command.rb` no longer inherits `CommandController` and no file under it builds `CommandLine` — check: absent `CommandLine` in `plugins/os-sdlc/lib/os_sdlc/collaborator_pass/**/*.rb` 10. `Boot::RefusalError.new(message, status = 1)` — check: present `status` in `plugins/os-sdlc/lib/os_sdlc/boot/refusal_error.rb` 11. The seven parsers handle `-h` with exit 0 and a missing positional with exit 2 through `RefusalError` — check: present `RefusalError.new` in `plugins/os-sdlc/lib/os_sdlc/boot/inputs.rb` Orchestrator work: run `/os-adr:find` on the seven bins and `Boot::ProjectBind` before the first edit, because the CLI contract changes. After merge, run `collaborator-pass measure` and `delta-check` against run 20261017T165147Z. Re-rule `argv+cwd+err+out` with `record-ruling`. ## Acceptance criteria 1. Given `.sdlc/project.yaml` with target `os-sdlc`, when `Project.load(root, target: "os-sdlc")` runs, then `project.target.path` and `project.target.test.path` match the yaml. 2. Given each of the seven crc bins with `--target os-sdlc` and its existing positional arguments minus LIB_ROOT, when it runs on the fixture repo, then its stdout and exit code equal today's run with explicit `--root`, `--test-root`, and LIB_ROOT. 3. Given `-h` on any of the seven bins, when it runs, then it prints that command's usage and exits 0. 7. Given a missing positional argument on any of the seven bins, when it runs, then it prints usage and exits 2, as today. 4. Given a crc bin run outside any project, when it runs, then it prints `no .sdlc/project.yaml at or above <cwd>` on stderr and exits 3; the fourteen existing Boot scripts keep their current fallback. 5. Given the merged change, when `collaborator-pass measure` runs, then no data_clump finding names `test_root` or `lib_root`, and no finding names `CommandController` or `CommandLine`. 6. Given the os-sdlc suite after the change, then it is green and the existing tests for the fourteen Boot commands are unchanged. ## Owner sketch ```ruby class OsSdlc::Boot::ProjectBind def call(dir) def project(dir, target:) end class OsSdlc::Project def self.load(root, target:) def codebase = target.codebase(root) end class OsSdlc::CrcCensus::Run def initialize(io, project, run) def call end ``` ## Retired tests plugins/os-sdlc/tests/command_controller_test.rb plugins/os-sdlc/tests/command_line_test.rb ## Non-goals - The `Crc::` namespace move (#1092). - The implementation+root, root+runner, and root+tracker clumps. - The fourteen existing Boot commands, `ProjectBind#call`, and their tests: unchanged. ## Origin - Trigger: collaborator-pass run 20261017T165147Z; ruling 1 of handoff .cc-os/os/handoffs/2026-10-17-1526-collaborator-pass-stages-1-4-shipped.md, section "Back on track" - Improvised this session: none - Chain: root-family data clumps ← CRC classes take path strings ← bins never load Project ← DESIGN (`plugins/os-sdlc/skills/collaborator-pass/SKILL.md`) - Root candidate: this ticket - Where: plugins/os-sdlc/lib/os_sdlc/crc_census/command.rb - Session: 909d1bcd-dd81-408f-8581-5c682b1a742d - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/909d1bcd-dd81-408f-8581-5c682b1a742d.jsonl
Author
Owner

Reshape from Jared 2026-10-17: Crc::Run is not a new entry contract. Fourteen os-sdlc-* bins already enter through Boot.run(name, ProcessIO.from_process, ARGV): Boot::Commands::TABLE registry, Boot::Inputs typed parsing, Boot::ProjectBind root lookup, ProcessIO::Outcome exit handling. The seven crc bins and collaborator-pass use Command.new(ARGV, $stdout, $stderr, Dir.pwd) instead; CommandLine (#1088) and CommandController (#1090) re-implemented Boot in small. Do this instead: register each crc command in Boot::Commands::TABLE as a script command with an Inputs.crc_* parser; ProjectBind returns a bound Project (Project.load(config, target:) lives there); Crc::Run takes (io, project, run_config); delete CommandController and CommandLine once the seven commands are on Boot. The argv+cwd+err+out clump ruling (rejected-expected) was wrong: that clump is a copy of ProcessIO::Invocation. Update the Approach and Required work before implementation-open.

Reshape from Jared 2026-10-17: Crc::Run is not a new entry contract. Fourteen os-sdlc-* bins already enter through Boot.run(name, ProcessIO.from_process, ARGV): Boot::Commands::TABLE registry, Boot::Inputs typed parsing, Boot::ProjectBind root lookup, ProcessIO::Outcome exit handling. The seven crc bins and collaborator-pass use Command.new(ARGV, $stdout, $stderr, Dir.pwd) instead; CommandLine (#1088) and CommandController (#1090) re-implemented Boot in small. Do this instead: register each crc command in Boot::Commands::TABLE as a script command with an Inputs.crc_* parser; ProjectBind returns a bound Project (Project.load(config, target:) lives there); Crc::Run takes (io, project, run_config); delete CommandController and CommandLine once the seven commands are on Boot. The argv+cwd+err+out clump ruling (rejected-expected) was wrong: that clump is a copy of ProcessIO::Invocation. Update the Approach and Required work before implementation-open.
Author
Owner

Work started in session 909d1bcd on branch ticket-1093 (worktree), via /os-sdlc:implement 1093 --target os-sdlc. ADR find: no one-way door; keep ADR-0166 bin boot line, no Thor (0123/0232), --target through Project#target (0210).

Work started in session 909d1bcd on branch ticket-1093 (worktree), via /os-sdlc:implement 1093 --target os-sdlc. ADR find: no one-way door; keep ADR-0166 bin boot line, no Thor (0123/0232), --target through Project#target (0210).
Author
Owner

Resolution

Done: Seven bins (crc-census, crc-file, crc-jobs, crc-records, crc-sweep, crc-tickets, collaborator-pass) enter through Boot.run with --target; Boot::Inputs parsers plus Inputs::CrcArgv; Boot::ProjectBind#project binds Project.load(root, target:) and refuses with exit 3 outside a project; RefusalError takes a status (-h exit 0, missing positional exit 2); Project#codebase; Run objects replace the Command classes; CommandController, CommandLine and six Crc*::Command deleted; CRC classes take project: (no lib_root/test_root/root+target keywords); CollaboratorPass::Run and Subcommand replace the dispatcher; docs in crc-refactor and collaborator-pass skills updated.

Evidence: main 2026-10-17: 06341507, 2b93c66a, merge of ticket-1093 after main batch #1095; suite 2069 runs 0 failures; rubocop 0 offenses in changed files; collaborator-pass runs 20261017T215950Z and 20261017T220414Z: root-family clumps (root+test_root 21, lib_root+test_root 15, lib_root+root 10, paths+root 9, file+root 6, test_root+write 6) all 0, argv+cwd+err+out gone, data_clump 263 to 230; rulings recorded: io+project+run reject-expected, argv+cwd+err+out superseded; contract-auditor hand-finish audit findings 1-4,6 applied.

Follow-ups: (1) CollaboratorPass::Command::Measure still takes cwd: and builds the ledger path from it; should depend on project.root; behavior change when run from a subdirectory; to be captured with a skeptic verdict. (2) root+target clump remains at 3 pre-existing sites (Boot::Input, DiffTestPlan, Gate::Commands), score 9; next loop iteration will surface it. (3) Boot#prepared selects the stream from RefusalError#status; a RefusalError#stream(io) would be cleaner; note only. (4) Workflow defect: the worktree command guard refused a pipeline agent's os-sdlc-subagent-stop call four times and a placeholder pass was recorded; to be captured. (5) {{LIB_ROOT}} placeholders in crc-refactor references/ledger.md and parameters.md may be stale after the --target change.

## Resolution **Done:** Seven bins (crc-census, crc-file, crc-jobs, crc-records, crc-sweep, crc-tickets, collaborator-pass) enter through Boot.run with --target; Boot::Inputs parsers plus Inputs::CrcArgv; Boot::ProjectBind#project binds Project.load(root, target:) and refuses with exit 3 outside a project; RefusalError takes a status (-h exit 0, missing positional exit 2); Project#codebase; Run objects replace the Command classes; CommandController, CommandLine and six Crc*::Command deleted; CRC classes take project: (no lib_root/test_root/root+target keywords); CollaboratorPass::Run and Subcommand replace the dispatcher; docs in crc-refactor and collaborator-pass skills updated. **Evidence:** main 2026-10-17: 06341507, 2b93c66a, merge of ticket-1093 after main batch #1095; suite 2069 runs 0 failures; rubocop 0 offenses in changed files; collaborator-pass runs 20261017T215950Z and 20261017T220414Z: root-family clumps (root+test_root 21, lib_root+test_root 15, lib_root+root 10, paths+root 9, file+root 6, test_root+write 6) all 0, argv+cwd+err+out gone, data_clump 263 to 230; rulings recorded: io+project+run reject-expected, argv+cwd+err+out superseded; contract-auditor hand-finish audit findings 1-4,6 applied. **Follow-ups:** (1) CollaboratorPass::Command::Measure still takes cwd: and builds the ledger path from it; should depend on project.root; behavior change when run from a subdirectory; to be captured with a skeptic verdict. (2) root+target clump remains at 3 pre-existing sites (Boot::Input, DiffTestPlan, Gate::Commands), score 9; next loop iteration will surface it. (3) Boot#prepared selects the stream from RefusalError#status; a RefusalError#stream(io) would be cleaner; note only. (4) Workflow defect: the worktree command guard refused a pipeline agent's os-sdlc-subagent-stop call four times and a placeholder pass was recorded; to be captured. (5) {{LIB_ROOT}} placeholders in crc-refactor references/ledger.md and parameters.md may be stale after the --target change.
jared closed this issue 2026-10-17 22:06:41 +00:00
Author
Owner

Measure still takes cwd: instead of project.root (auditor finding 7).

Measure still takes cwd: instead of project.root (auditor finding 7).
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#1093
No description provided.