Build the OsGit core objects test-first against Fake and Cli backends #1588
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#1588
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
The call sites in
docs/os-git/call-site-checklist.mdneed one set of domain objects behind one interface. Today four wrappers answer the same questions with different results (four ways to name the current branch, raise versus soft-fail decided per wrapper, two commit models).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: new objects. The disagreements are listed in design section 2.6.
Approach
Write one characterization test per use-case through the public messages (UC-01 to UC-14, UC-22, UC-23, UC-25, UC-27; the worktree use-cases UC-15 to UC-21 belong to the worktree ticket #1589). Write the test first. Run each test against
Backend::Fakefor decisions and againstBackend::Clion aScratchRepofor behavior. Run a shared contract test module against every adapter that exists.Objects and messages come from design sections 3 and 4.3:
Repository,Branch,ChangeSet,Span,Commit::Plan,Commit,History,Remote. The error rule is design section 6: raise on git failure, returnnil,[], orfalsewhen git answers "nothing there". Norescuethat returns""inside the library. AddOsGit::RepoRoot, a process-free root finder (walk up for.git, follow the.gitfile of a linked worktree), for hooks that run on every prompt or edit (design Q3). Rule Q3 with the spike result (#1586).Required work:
Repositorywith open, find, init, clone, root, primary_root, linked?, at_top_level?, branch, branch_named, primary_branch, changes, changes_between, files, tracked?, ignored?, read_at, diff, resolve, exists?, merge_base, ancestor?, history, remote, remotes, add_remote, config, commit, move, remove, tag, tag? — check: presentprimary_branchinplugins/os-git/lib/os_git/repository.rbBranchwith name, detached?, exists?, worktree, merged_into?, and a safedeletethat never forces — check: presentNotMergedinplugins/os-git/lib/os_git/branch.rbChangeSetas a value with no I/O — check: presentall_untracked_within?inplugins/os-git/lib/os_git/change_set.rbSpanwithbetween,since_fork,since— check: presentsince_forkinplugins/os-git/lib/os_git/span.rbCommit::Planthat refuses empty paths and a blank message, andCommit— check: presentArgumentErrorinplugins/os-git/lib/os_git/commit/plan.rbHistorywith last_commit_touching, touching, recent, matching, find, branches_containing — check: presentlast_commit_touchinginplugins/os-git/lib/os_git/history.rbRemotewith fetch, pull_fast_forward, push;timeout:is a required argument — check: presentpull_fast_forwardinplugins/os-git/lib/os_git/remote.rbRepoRootprocess-free finder — check: presentRepoRootinplugins/os-git/lib/os_git/repo_root.rbAcceptance criteria
Repository#branchruns, thenBranch#detached?is true andBranch#nameisnil; the same answer holds on every adapter.Commit::Planwith no paths or a blank message, when it is built, then it raisesArgumentError.Repository, when its public messages are listed, then none stages everything, none runscheckout,restore, orstash, and none runscommit -a.Repository#commit(plan)runs, then the commit holds only the plan paths.Repository#tracked?and#ignored?run, then they returnfalse; given git fails, then they raiseOsGit::Error.Repository#resolveruns, then it returnsnil; givenRepository#merge_baseon an unknown ref, then it raises.Branch#deleteruns, then it raisesNotMergedand the branch remains.History#last_commit_touchingruns, then it returnsnil.Remote#fetch,#pull_fast_forward, or#pushcalled withouttimeout:, then it raisesArgumentError.RepoRoot.findruns from inside it, then it returns the worktree root andprimary_rootreturns the main checkout, and nogitprocess starts.Backend::CliandBackend::Fake, when the shared contract test runs, then both pass.Owner sketch
Non-goals
Worktree, Integration, Sync (own tickets). Any caller migration.
Blocking edges
Blocked by the scaffold ticket (#1587).
Origin
Work started by the #1610 orchestrator. Branch: ticket-1588.
Resolution
Done: Repository, Branch, ChangeSet, Span, Commit, Commit::Plan, History, Remote, RepoRoot built behind the Backend seam; all ticket acceptance criteria met. Hand-finished after escalation bound_exhausted.
Evidence:
592c8851. 165 runs, 461 assertions, 0 failures; rubocop clean. Behavior verifier passed 10 of 12, literal-pathspec fix closed the other two. Design audit found 10 blockers and 4 minors, all fixed test-first. Implementation 243 abandoned as hand-finished.Follow-ups: Three items posted on #1592, whose migration needs them: commit_changes on a merge commit, log(rev:) with a range, original bytes for non-UTF-8 paths.