Migrate os-sdlc git calls to OsGit and remove the second worktree owner #1592
Labels
No labels
P0
P1
P2
P3
bug
category/code-change
category/cross-repo
category/eval-run
category/investigation
category/no-test-target
category/owner-ruling
category/prose-artifact
category/recurring-chore
category/structure
category/umbrella
crc-refactor
create
delete
enhancement
filed-by/agent
filed-by/user
frozen
lint-rule
needs-info
needs-triage
next
plugin/cc-architect
plugin/os
plugin/os-adr
plugin/os-aidd-lint
plugin/os-backlog
plugin/os-context
plugin/os-doc-hygiene
plugin/os-sdlc
plugin/os-vault
project/cc-os
ready-for-agent
ready-for-human
recurring
review
rule-proposal
update
waiting
wayfinder:grilling
wayfinder:map
wayfinder:map
wayfinder:research
wayfinder:task
wayfinder:task
wontfix
worklist/deviations
worklist/lint-rule
worklist/new-implement-build
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jared/cc-os#1592
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
OsSdlc::Git::Repois the closest wrapper to the target, with about 17 callers, but three files run git on their own (lint/autocorrection/changed_files.rb,crc/sweep/files.rb,implementation/mutation_check.rb). Two files hardcode the base branchmain(gate/unchanged_check/base_checkout.rb,report/merged_diff.rb).base_checkout.rbis a second owner of worktree add and remove.Design:
docs/os-git/use-cases-and-domain.md(design) anddocs/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 inplugins/os-gitwith apath:source;git-contextandos:worktreemerge intoos-git; old wrappers go only after all references are updated; design order is use-cases, objects, interfaces;os-contextandos-vaultbecome Ruby; ticket tracking stays out ofos-git.Reproduce
n/a: migration of existing call sites; behavior stays the same unless a criterion says otherwise.
Approach
Groups A-03 (G-013 to G-034) and A-04 (G-035 to G-037). Replace each site with the message from the design Replaced-by table:
project/root_search,project/setup,lint/autocorrection/changed_files):Repository.find,Repository#at_top_level?.project/changes,implementation/commit,lint/autocorrection/changed_fileswith a*.rbglob):Repository#changes(against:, glob:). The lint hook runs on every edit: useRepoRootand keep the number of git processes at or below today's count.fast_gate/changed_files):Repository#changes_between(Span.since_fork(base, branch), renames: true),#read_at,#merge_base.gate/unchanged_check/base_checkout):OsGit::Worktree.temporary(repository, ref). The base is an argument, notmain(design Q6): read a project setting if one exists, otherwise pass"main"as this project's value, not as a library constant.report/merged_diff):History#matching(text, on: base), with the same Q6 rule.crc/*,design/base_check,tracker_lookup):Repository#resolve,#exists?,#files(kind),#remote.implementation/commit):Repository#commit(Commit::Plan).implementation/mutation_check.rbrunsgit apply --include=PATH -. No use-case covers it. Decide: addRepository#apply_patchto the design, or mark the row out of scope with a reason. Record the decision in the design doc.The wiring-only rows (G-025, G-031 to G-034) build
Git::Repoand pass it on: replace the constructor withOsGit::Repository.open.Mark every row in the checklist from the
Donecolumn as it is replaced. Mark the matching test rows in the same change. Runbin/refresh-pluginsafter changes toSKILL.md, hooks, or CLIs.Required work: none beyond the acceptance criteria.
Acceptance criteria
*.rbfiles, then it returns the same files and starts no more git processes than before.main, when the unchanged check and the merged-diff report run, then they use that base, and the string"main"is not a library constant.git!did before.OsGit::Testing::ScratchRepoand the os-sdlc suite passes.plugins/os-sdlc/lib, when it is searched forGit::RepoandGit::Diff, then every reference is updated (the classes themselves are deleted by the retirement ticket #1607).- [x]withReplaced byfilled in, or marked out of scope with a reason, indocs/os-git/call-site-checklist.md.Open3,system(,%x, backticks, andgitargv, then no git call remains outsideOsGitadapters, except sites marked out of scope with a reason.Non-goals
Deleting
OsSdlc::Git::RepoandDiff(the retirement ticket). The ticket-takedown eval harness (its own ticket).Blocking edges
Blocked by the core ticket (#1588). Also needs the worktree ticket (#1589) for
OsGit::Worktree.temporary.Origin
From #1588, for this migration: (1) commit_changes returns nothing for a merge commit. (2) log(rev:) returns [] for a range such as a..b. (3) A non-UTF-8 path or subject is scrubbed, so the original bytes are lost. Fix each in OsGit if a migrated call site needs it. Also: Commit is a class holding a backend, not a Data value, because paths and changes load lazily. Repository#primary_root uses the backend; RepoRoot.primary_root stays for the process-free hook path.
From #1589:
OsGit::Worktree.temporarynever forces removal, so a dirtied temporary checkout raises NotClean. Check callers that dirty the checkout. Rulings rows from #1589 are numbered 56, 57, 58 in docs/decisions/rulings.tsv; the #1589 body says row 39.Resolution
Done: os-sdlc lib and bin call OsGit. Test setup uses ScratchRepo. os-sdlc loads OsGit by a sibling-first path source. Added apply_patch and history messages. Base branch reads optional base_branch, else primary_branch.
Evidence: main
89140417. os-sdlc 3508 runs, os-git 255 runs, 0 failures; rubocop clean on os-git; two stranger reviews; AC 2 measured 3 git processes old, 2 new; rows G-013 to G-037 and G-144 to G-171 marked (G-144 out of scope). Cached os-sdlc boots.Follow-ups: #1627 census and ledger raise on git failure; #1628 settings.rb InwardDependency offenses (both ticket-skeptic verdicts). Fallback edge: a project with no base_branch that runs a feature branch in its primary checkout gets a vacuous unchanged check; report in #1610 summary.