os-sdlc tests start git 3,381 times: move Git behind OsGit with a recorded fixture #1645

Closed
opened 2026-11-09 16:06:49 +00:00 by jared · 3 comments
Owner

Problem

The os-sdlc test suite starts git 3,381 times in 99 test files. Ruling 88 (docs/decisions/rulings.tsv) and .claude/rules/ruby-external-calls.md forbid this: no test starts a real process, and os-sdlc does not test Git. os-git owns Git (ADR-0305). These process starts make the suite slow and make mutation testing reach its time limit.

Observed

A one-time list run of the suite recorded each process start. It found 4,173 process starts in 163 test files. 3,381 are git. About half start from test code, for example the scratch repository in test/support/git_repo_scenario.rb. The others start from library code: lib/os_sdlc/project/changes.rb 514, implementation/commit.rb 209, project_shell.rb 130, project/base_branch.rb 91, implementation/state_dump.rb 87, fast_gate/changed_files.rb 81, crc/ledger/commits/commit.rb 69, crc/sweep/files.rb 67.

Reproduce

n/a: structure ticket.

Approach

Library Git calls go through the OsGit interface. The entry passes it in, as commit 737d2e13 does for the tracker (ProcessIO carries trackers; tests pass SeededTicketTracker). Tests receive an OsGit double that returns recorded answers. No os-sdlc test builds a scratch repository.

Acceptance criteria

  1. Given the os-sdlc suite, when a list run records each process start, then it records zero git starts.
  2. Given the os-sdlc suite, when it runs, then it is green.

Origin

  • Trigger: mutation pass timeouts in lib/os_sdlc/map (91 of 330 mutants), then a list run of process starts on 2026-11-09
  • Improvised this session: none
  • Chain: mutation timeouts ← slow covering tests ← tests start real processes ← DESIGN (library code and test scenarios call git directly; .claude/rules/ruby-external-calls.md, ADR-0305)
  • Root candidate: none found; searched OsGit, git fixture, real process, ruling 88, adapter
  • Where: plugins/os-sdlc/lib/os_sdlc/project/changes.rb, plugins/os-sdlc/test/support/git_repo_scenario.rb
  • Session: 19f78576-9fa5-4fd3-9984-a9e58ef897ad
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os-plugins-os-sdlc/19f78576-9fa5-4fd3-9984-a9e58ef897ad.jsonl

VERDICT: CREATE (ticket-skeptic, 2026-11-09): ruling 88 is a stated requirement; no open ticket covers os-sdlc git calls.

## Problem The os-sdlc test suite starts `git` 3,381 times in 99 test files. Ruling 88 (`docs/decisions/rulings.tsv`) and `.claude/rules/ruby-external-calls.md` forbid this: no test starts a real process, and os-sdlc does not test Git. os-git owns Git (ADR-0305). These process starts make the suite slow and make mutation testing reach its time limit. ## Observed A one-time list run of the suite recorded each process start. It found 4,173 process starts in 163 test files. 3,381 are `git`. About half start from test code, for example the scratch repository in `test/support/git_repo_scenario.rb`. The others start from library code: `lib/os_sdlc/project/changes.rb` 514, `implementation/commit.rb` 209, `project_shell.rb` 130, `project/base_branch.rb` 91, `implementation/state_dump.rb` 87, `fast_gate/changed_files.rb` 81, `crc/ledger/commits/commit.rb` 69, `crc/sweep/files.rb` 67. ## Reproduce n/a: structure ticket. ## Approach Library Git calls go through the `OsGit` interface. The entry passes it in, as commit 737d2e13 does for the tracker (`ProcessIO` carries `trackers`; tests pass `SeededTicketTracker`). Tests receive an `OsGit` double that returns recorded answers. No os-sdlc test builds a scratch repository. ## Acceptance criteria 1. Given the os-sdlc suite, when a list run records each process start, then it records zero `git` starts. 2. Given the os-sdlc suite, when it runs, then it is green. ## Origin - Trigger: mutation pass timeouts in `lib/os_sdlc/map` (91 of 330 mutants), then a list run of process starts on 2026-11-09 - Improvised this session: none - Chain: mutation timeouts ← slow covering tests ← tests start real processes ← DESIGN (library code and test scenarios call git directly; `.claude/rules/ruby-external-calls.md`, ADR-0305) - Root candidate: none found; searched OsGit, git fixture, real process, ruling 88, adapter - Where: `plugins/os-sdlc/lib/os_sdlc/project/changes.rb`, `plugins/os-sdlc/test/support/git_repo_scenario.rb` - Session: 19f78576-9fa5-4fd3-9984-a9e58ef897ad - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os-plugins-os-sdlc/19f78576-9fa5-4fd3-9984-a9e58ef897ad.jsonl VERDICT: CREATE (ticket-skeptic, 2026-11-09): ruling 88 is a stated requirement; no open ticket covers os-sdlc git calls.
Author
Owner

os-git track: the coverage list is in docs/os-git/os-sdlc-coverage.md (main cf551aa36).

Result: every git call in os-sdlc lib/, bin/, and hooks/ already goes through an OsGit message. No file starts git by hand. This pass added no gem operation. OsGit::Backend::Fake answers every message that Backend::Cli answers, so each site can take a fake backend with a recorded answer.

The git starts in the tests come from setup: GitRepoScenario#run_git! calls @scratch.backend.capture (commit 16, add 13, switch 4, rev-parse 3, and others). When a site takes the recorded fixture, that setup goes away. Two direct Open3.capture3("git", "status") strings in cop tests are cop input, not process starts.

Nothing in os-git blocks this ticket.

os-git track: the coverage list is in `docs/os-git/os-sdlc-coverage.md` (main cf551aa36). Result: every git call in os-sdlc `lib/`, `bin/`, and `hooks/` already goes through an `OsGit` message. No file starts git by hand. This pass added no gem operation. `OsGit::Backend::Fake` answers every message that `Backend::Cli` answers, so each site can take a fake backend with a recorded answer. The git starts in the tests come from setup: `GitRepoScenario#run_git!` calls `@scratch.backend.capture` (commit 16, add 13, switch 4, rev-parse 3, and others). When a site takes the recorded fixture, that setup goes away. Two direct `Open3.capture3("git", "status")` strings in cop tests are cop input, not process starts. Nothing in os-git blocks this ticket.
Author
Owner

Start (session bc5ad309, 2026-11-09): mutation track works #1645 with #1627 and the last two #1647 items (runtime process guard, mirror_tickle pbm sync adapter) in worktree ticket-1645. The entry passes an OsGit collaborator through ProcessIO; tests pass an OsGit double.

Start (session bc5ad309, 2026-11-09): mutation track works #1645 with #1627 and the last two #1647 items (runtime process guard, mirror_tickle pbm sync adapter) in worktree ticket-1645. The entry passes an OsGit collaborator through ProcessIO; tests pass an OsGit double.
Author
Owner

Resolution

Done: Git behind OsGit: the entry passes the repository; tests pass an in-memory git fake; real-git test setup removed; runtime process guard on in test_helper

Evidence: main 38b3284d (pushed); suite 3,676 runs green with the guard on, 26.6 s at load 1.4; git starts 3,371 -> 0; cops ProcessStartOutsideAdapter and AdapterBuiltOutsideEntry 0 hits

Follow-ups: #1652 (os_git ships the repository fake; skeptic CREATE)

## Resolution **Done:** Git behind OsGit: the entry passes the repository; tests pass an in-memory git fake; real-git test setup removed; runtime process guard on in test_helper **Evidence:** main 38b3284d (pushed); suite 3,676 runs green with the guard on, 26.6 s at load 1.4; git starts 3,371 -> 0; cops ProcessStartOutsideAdapter and AdapterBuiltOutsideEntry 0 hits **Follow-ups:** #1652 (os_git ships the repository fake; skeptic CREATE) <!-- os-backlog kind: resolution -->
jared closed this issue 2026-11-09 20:46:56 +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#1645
No description provided.