Decide and migrate the os-doc-hygiene Python git classes #1597

Open
opened 2026-11-06 16:53:35 +00:00 by jared · 2 comments
Owner

Problem

os-doc-hygiene runs git from Python in three separate classes: RealGit and RealGitState in scripts/patch_applier.py, and RealGitStateProvider in scripts/report_builder.py (a copy of the second), plus scripts/scanner.py (log --follow). os-doc-hygiene is not on the list of plugins that will become Ruby. Ticket #1554 asks whether to port it.

Design: docs/os-git/use-cases-and-domain.md (design) and docs/os-git/call-site-checklist.md (call sites). Settled decisions are in design section 1 (docs/os-git/use-cases-and-domain.md): the gem lives in plugins/os-git with a path: source; git-context and os:worktree merge into os-git; old wrappers go only after all references are updated; design order is use-cases, objects, interfaces; os-context and os-vault become Ruby; ticket tracking stays out of os-git.

Reproduce

n/a: migration of existing call sites; behavior stays the same unless a criterion says otherwise.

Approach

Group A-09. This ticket needs the Q7 ruling first (design section 8): port to Ruby or call an os-git CLI. The recommended ruling is: leave the Python classes until os-doc-hygiene is ported to Ruby, then use the gem directly, because a CLI bridge adds a second interface for one plugin. The orchestrator makes the ruling with /os-me:predict and records it in the design doc. If the ruling is "defer", comment on this ticket, mark rows G-047 to G-050 and G-182 and G-183 as deferred with a reason and a link to #1554, and leave the ticket open. If the ruling is "call a CLI", replace the three classes with one Python wrapper that calls the os-git CLI and merge the duplicate state classes into one.

Mark every row in the checklist from the Done column as it is replaced. Mark the matching test rows in the same change. Run bin/refresh-plugins after changes to SKILL.md, hooks, or CLIs.

Required work: none beyond the acceptance criteria.

Acceptance criteria

  1. Given the Q7 ruling, when design section 8 is read, then the Q7 row records the ruling and the reason.
  2. Given the ruling is "defer", when the ticket is read, then it states the deferral, links #1554, and the checklist rows are marked deferred with a reason.
  3. Given the ruling is "call a CLI", when patch_applier.py and report_builder.py run their state checks, then both use one class and the results equal the results before the change.
  4. Given rows G-047 to G-050 and the test rows G-182 and G-183, when the ticket closes, then each row is marked - [x] with Replaced by filled in, or marked out of scope with a reason, in docs/os-git/call-site-checklist.md.
  5. Given the touched code, when it is searched for Open3, system(, %x, backticks, and git argv, then no git call remains outside OsGit adapters, except sites marked out of scope with a reason.

Non-goals

The skill text in os-doc-hygiene (rows G-109 to G-116 are in the prompt-text ticket #1605). The reset --hard rollback check (its own ticket #1609).

Blocking edges

Blocked by the core ticket (#1588). Also depends on #1554 (whether os-doc-hygiene is ported to Ruby).

Origin

  • Trigger: User request in session 1a5b2630-09c9-46cb-aee4-a5a98e2e7d24 on 2026-11-06: one os-git gem for all local git work in cc-os and the user's projects.
  • Improvised this session: none
  • Chain: three Python git classes, two duplicates ← plugin is Python and not on the Ruby port list ← DESIGN (docs/os-git/use-cases-and-domain.md Q7)
  • Root candidate: none found; searched open issues for git, worktree, octokit, ruby port, python, statusline, reset --hard. Related but not a match: #845, #853, #857, #1527, #1554.
  • Where: plugins/os-doc-hygiene/scripts/patch_applier.py, report_builder.py, scanner.py
  • Session: 1a5b2630-09c9-46cb-aee4-a5a98e2e7d24
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/1a5b2630-09c9-46cb-aee4-a5a98e2e7d24.jsonl
## Problem `os-doc-hygiene` runs git from Python in three separate classes: `RealGit` and `RealGitState` in `scripts/patch_applier.py`, and `RealGitStateProvider` in `scripts/report_builder.py` (a copy of the second), plus `scripts/scanner.py` (`log --follow`). `os-doc-hygiene` is not on the list of plugins that will become Ruby. Ticket #1554 asks whether to port it. Design: `docs/os-git/use-cases-and-domain.md` (design) and `docs/os-git/call-site-checklist.md` (call sites). Settled decisions are in design section 1 (`docs/os-git/use-cases-and-domain.md`): the gem lives in `plugins/os-git` with a `path:` source; `git-context` and `os:worktree` merge into `os-git`; old wrappers go only after all references are updated; design order is use-cases, objects, interfaces; `os-context` and `os-vault` become Ruby; ticket tracking stays out of `os-git`. ## Reproduce n/a: migration of existing call sites; behavior stays the same unless a criterion says otherwise. ## Approach Group A-09. This ticket needs the Q7 ruling first (design section 8): port to Ruby or call an `os-git` CLI. The recommended ruling is: leave the Python classes until `os-doc-hygiene` is ported to Ruby, then use the gem directly, because a CLI bridge adds a second interface for one plugin. The orchestrator makes the ruling with `/os-me:predict` and records it in the design doc. If the ruling is "defer", comment on this ticket, mark rows G-047 to G-050 and G-182 and G-183 as deferred with a reason and a link to #1554, and leave the ticket open. If the ruling is "call a CLI", replace the three classes with one Python wrapper that calls the `os-git` CLI and merge the duplicate state classes into one. Mark every row in the checklist from the `Done` column as it is replaced. Mark the matching test rows in the same change. Run `bin/refresh-plugins` after changes to `SKILL.md`, hooks, or CLIs. Required work: none beyond the acceptance criteria. ## Acceptance criteria 1. Given the Q7 ruling, when design section 8 is read, then the Q7 row records the ruling and the reason. 2. Given the ruling is "defer", when the ticket is read, then it states the deferral, links #1554, and the checklist rows are marked deferred with a reason. 3. Given the ruling is "call a CLI", when `patch_applier.py` and `report_builder.py` run their state checks, then both use one class and the results equal the results before the change. 4. Given rows G-047 to G-050 and the test rows G-182 and G-183, when the ticket closes, then each row is marked `- [x]` with `Replaced by` filled in, or marked out of scope with a reason, in `docs/os-git/call-site-checklist.md`. 5. Given the touched code, when it is searched for `Open3`, `system(`, `%x`, backticks, and `git` argv, then no git call remains outside `OsGit` adapters, except sites marked out of scope with a reason. ## Non-goals The skill text in `os-doc-hygiene` (rows G-109 to G-116 are in the prompt-text ticket #1605). The `reset --hard` rollback check (its own ticket #1609). ## Blocking edges Blocked by the core ticket (#1588). Also depends on #1554 (whether os-doc-hygiene is ported to Ruby). ## Origin - Trigger: User request in session 1a5b2630-09c9-46cb-aee4-a5a98e2e7d24 on 2026-11-06: one os-git gem for all local git work in cc-os and the user's projects. - Improvised this session: none - Chain: three Python git classes, two duplicates ← plugin is Python and not on the Ruby port list ← DESIGN (docs/os-git/use-cases-and-domain.md Q7) - Root candidate: none found; searched open issues for git, worktree, octokit, ruby port, python, statusline, reset --hard. Related but not a match: #845, #853, #857, #1527, #1554. - Where: plugins/os-doc-hygiene/scripts/patch_applier.py, report_builder.py, scanner.py - Session: 1a5b2630-09c9-46cb-aee4-a5a98e2e7d24 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/1a5b2630-09c9-46cb-aee4-a5a98e2e7d24.jsonl
Author
Owner

Skipped in the #1610 build: blocker #1554 is open. Rows G-047 to G-050, G-182, G-183 are marked deferred in docs/os-git/call-site-checklist.md. RealGit and RealGitState stay until the os-doc-hygiene Python code is ported.

Skipped in the #1610 build: blocker #1554 is open. Rows G-047 to G-050, G-182, G-183 are marked deferred in docs/os-git/call-site-checklist.md. RealGit and RealGitState stay until the os-doc-hygiene Python code is ported.
Author
Owner

Ruling (os-me predict, 84, ruling 96 confirms ruling 35): defer. The Python git classes stay until os-doc-hygiene is ported to Ruby (#1554). The port then calls the os_git gem directly. No os-git CLI verbs and no subprocess bridge, because that would add a second interface for one plugin, and the port removes it. Design section 8 already records Q7. Checklist rows G-047 to G-050, G-182, and G-183 are already marked deferred with a link to #1554. The ticket stays open, waiting on #1554.

Ruling (os-me predict, 84, ruling 96 confirms ruling 35): defer. The Python git classes stay until os-doc-hygiene is ported to Ruby (#1554). The port then calls the `os_git` gem directly. No `os-git` CLI verbs and no subprocess bridge, because that would add a second interface for one plugin, and the port removes it. Design section 8 already records Q7. Checklist rows G-047 to G-050, G-182, and G-183 are already marked deferred with a link to #1554. The ticket stays open, `waiting` on #1554.
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#1597
No description provided.