Work Unit 008: Remove Legacy Git/File Refs System
Status: Specification
Estimated Effort: 2-3 days
Dependencies: Work Unit 003 (libs/refs OCI Backend), Work Unit 006 (Ref Installation), Work Unit 007 (CLI Integration)
Behavioral Goal
As a sow maintainer,
I need to remove the legacy git-based and file-based refs implementations after the OCI refs system is complete,
So that the codebase is simplified, maintenance burden is reduced, and users have a single, consistent refs mechanism (OCI) without lingering dead code or confusion about which system to use.
Success Criteria
- All files implementing
GitType and FileType are deleted
- The legacy type registry pattern (
registry.go) is removed
- Legacy URL parsing functions for git/file schemes are removed from CLI (replaced by
libs/refs/url.go)
github.com/jmgilman/go/git dependency is removed from cli/go.mod (unless still needed by other code)
cli/internal/refs/manager.go works exclusively with the new OCI-only system via libs/refs
- All CLI commands function correctly with only OCI refs
go build ./... succeeds after removal
go test ./... passes with no references to deleted code
- No orphaned imports or references to deleted files remain (verified via grep)
- Documentation referencing git/file refs is updated or removed
Existing Code Context
Explanatory Context
The current refs system in cli/internal/refs/ implements a type registry pattern where multiple ref types (git, file) can be registered and used interchangeably. The RefType interface (types.go:23-79) defines the contract that each type must implement, and registry.go provides a global registry for type lookup.
With the OCI refs implementation (Work Units 002-007), this multi-type architecture becomes unnecessary. The new system uses libs/refs exclusively for OCI operations, and the CLI will only support OCI refs going forward. This is a "clean break" decision - no migration tooling, no deprecation period, no backward compatibility.
The CacheManager in manager.go and Manager in index_manager.go currently depend on the legacy type system via InferTypeFromURL(), GetType(), and the RefType interface. After OCI migration, these managers will delegate to libs/refs instead of calling type-specific implementations.
The git dependency github.com/jmgilman/go/git is used by GitType in git.go for repository caching. After removal, this dependency should be removed from cli/go.mod unless other CLI code still requires it (e.g., worktree commands via go-git/go-git/v5).
Key Files to Delete
| File |
Lines |
Purpose |
cli/internal/refs/git.go |
1-226 |
GitType implementation using github.com/jmgilman/go/git/cache |
cli/internal/refs/git_test.go |
full |
Unit tests for GitType |
cli/internal/refs/file.go |
1-165 |
FileType implementation using filesystem symlinks |
cli/internal/refs/file_test.go |
full |
Unit tests for FileType |
cli/internal/refs/types.go |
1-100 |
Legacy RefType interface and RefTypeInfo struct |
cli/internal/refs/registry.go |
1-116 |
Type registry pattern (global map, Register, GetType, etc.) |
cli/internal/refs/registry_test.go |
full |
Unit tests for registry |
cli/internal/refs/url.go |
1-199 |
Legacy URL parsing (InferTypeFromURL, NormalizeGitURL, etc.) |
cli/internal/refs/url_test.go |
full |
Unit tests for URL parsing |
Key Files to Update
| File |
Lines |
Required Changes |
cli/internal/refs/manager.go |
1-239 |
Replace type inference/dispatch with libs/refs client calls |
cli/internal/refs/index_manager.go |
1-599 |
Remove type-based logic, use libs/refs for all operations |
cli/cmd/refs/add.go |
full |
Update to use OCI-only flow, remove git/file-specific flags |
cli/cmd/refs/update.go |
full |
Update to use libs/refs for OCI update operations |
cli/cmd/refs/remove.go |
full |
Ensure compatibility with OCI-only cache structure |
cli/cmd/refs/status.go |
full |
Update status display for OCI refs |
cli/cmd/refs/init.go |
full |
Initialize OCI refs only |
cli/go.mod |
14 |
Remove github.com/jmgilman/go/git if no longer needed |
Existing Documentation Context
ADR-003 (Decision Rationale)
ADR-003 (.sow/knowledge/adrs/003-oci-refs-distribution.md) documents the decision to replace git-based refs with OCI packages. This is a strategic architectural decision, not incremental improvement. The ADR's "Alternatives Rejected" section explicitly notes "Keep git - doesn't solve pain points" as rejected.
The decision includes "Migration effort (tooling provided)" as a trade-off, but the task description specifies "No backward compatibility or deprecation period - this is a clean break." Users with existing git refs will need to manually re-add them as OCI refs.
Discovery Analysis (Current State)
Section 1 of the discovery analysis (.sow/project/discovery/analysis.md) documents the existing refs architecture:
- Type Registry Pattern (lines 18-32):
RefType interface with Name(), IsEnabled(), Cache(), Update(), etc.
- Current Implementations (line 35-37):
GitType uses github.com/jmgilman/go/git/cache, FileType uses filesystem symlinks
- Cache Structure (lines 130-139):
~/.cache/sow/refs/git/checkouts/ and ~/.cache/sow/refs/file/
The analysis recommends (Section 10.3) that OCI implementation go in libs/refs/ following recent patterns, which Work Units 003-006 implement. The removal of legacy code follows naturally.
Design Document (OCI Architecture)
The OCI Refs Design Document (.sow/knowledge/designs/oci-refs/oci-refs-design.md) describes the new architecture that replaces the legacy system:
- Single Cache Structure (lines 182-186):
~/.cache/sow/refs/{id}-{short-digest}/ (no subdirectories per type)
- URL Detection (lines 351-358): OCI URLs detected via
oci:// prefix or known registry patterns
- No Type Registry: The design doesn't mention multiple types - OCI is the only mechanism
Detailed Requirements
Phase 1: Delete Legacy Type Implementations
Delete the following files completely:
cli/internal/refs/
├── git.go # DELETE
├── git_test.go # DELETE
├── file.go # DELETE
├── file_test.go # DELETE
├── types.go # DELETE
├── registry.go # DELETE
├── registry_test.go # DELETE
├── url.go # DELETE
└── url_test.go # DELETE
After deletion, cli/internal/refs/ should contain only:
manager.go (updated)
index_manager.go (updated)
options.go (if still needed for functional options)
ref.go (if still needed for Ref wrapper)
Phase 2: Update Manager to Use libs/refs
CacheManager Updates (manager.go)
Current CacheManager.Install() flow (lines 53-91):
InferTypeFromURL(ref.Source) → type name
TypeForScheme(ctx, typeName) → RefType implementation
refType.ValidateConfig(ref.Config)
refType.Cache(ctx, m.cacheDir, ref) → cache path
- Create workspace symlink
New flow using libs/refs:
- Call
libs/refs.IsOCIRef(ref.Source) to validate
- Create
libs/refs.Installer via libs/refs.NewInstaller()
- Call
installer.Install(ctx, ref.Source, opts...) → InstallResult
- Create workspace symlink from
result.CachePath
The Update() and Remove() methods need similar updates.
Manager Updates (index_manager.go)
The Manager orchestrates refs operations at a higher level. Updates needed:
Add() (lines 28-142): Remove type inference, use libs/refs.IsOCIRef() for validation
normalizeURLForType() (lines 318-367): Remove git/file-specific logic, normalize OCI URLs only
generateRefID() (lines 370-414): Simplify for OCI URL pattern only
InitRefs() (lines 269-313): Install using libs/refs.Installer instead of type-based loop
Remove any imports of deleted files and replace with libs/refs imports.
Phase 3: Update CLI Commands
Each command in cli/cmd/refs/ needs review:
add.go:
- Remove
--branch flag (git-specific)
- Keep
--path flag (repurposed for OCI selective extraction globs)
- Update validation to require OCI URL format
- Update help text to reflect OCI-only support
update.go:
- Update to use
libs/refs.Installer for digest comparison and re-pull
- Remove any git-specific update logic
remove.go:
- Update cache cleanup to use
libs/refs cache structure
- Remove git/file-specific cleanup paths
status.go:
- Update to show OCI-specific status (digest, selective extraction info)
- Remove git staleness checks
init.go:
- Update to initialize OCI refs only
- Remove type enumeration logic
Phase 4: Clean Up Dependencies
Check if github.com/jmgilman/go/git is still needed:
# Search for remaining uses
grep -r "jmgilman/go/git" cli/
# Expected matches (keep):
# - cli/cmd/worktree.go (uses go-git/go-git, not jmgilman/go/git)
# If no matches besides deleted files, remove from go.mod
Note: go-git/go-git/v5 is different from jmgilman/go/git. The former is used for worktree commands and should remain.
Phase 5: Update Documentation
Review and update any documentation referencing git/file refs:
- Remove examples showing
git+https:// URLs
- Remove examples showing
file:// URLs
- Update command help text
- Update any README or user guides
Testing Requirements
Build Verification
-
After all deletions and updates:
Must succeed with no errors.
-
Verify no orphaned imports:
grep -r "internal/refs/git" cli/
grep -r "internal/refs/file" cli/
grep -r "internal/refs/types" cli/
grep -r "internal/refs/registry" cli/
grep -r "internal/refs/url" cli/
All should return empty.
Test Verification
-
Run all tests:
Must pass with no failures.
-
Run specific refs tests:
cd cli && go test ./internal/refs/... -v
cd cli && go test ./cmd/refs/... -v
Functional Verification
- Add OCI ref:
sow refs add ghcr.io/org/ref:v1.0.0 --link myref --description "Test"
- List refs:
sow refs list (should show only OCI refs)
- Update ref:
sow refs update myref
- Remove ref:
sow refs remove myref
- Init refs: Clone repo with refs, run
sow refs init
Regression Verification
Ensure that attempting to add non-OCI URLs fails gracefully:
sow refs add git+https://github.com/org/repo → Error: "OCI URL required"
sow refs add /local/path → Error: "OCI URL required"
Implementation Notes
Dependency Order
This work unit MUST be executed AFTER Work Units 003, 006, and 007 are complete:
- Work Unit 003 provides
libs/refs module with OCI client
- Work Unit 006 provides
libs/refs.Installer for installation
- Work Unit 007 provides CLI integration and
OCIType adapter
Only after these are complete and functioning can the legacy code be safely removed.
Clean Break Strategy
Per the task description, this is a "clean break":
- No migration tooling
- No deprecation warnings
- No backward compatibility
- Users with existing git/file refs must manually re-add as OCI
This simplifies implementation significantly - we delete code without providing alternatives for legacy formats.
Cache Cleanup
The old cache directories (~/.cache/sow/refs/git/ and ~/.cache/sow/refs/file/) are NOT automatically deleted. Users can manually clean these up. The new OCI cache uses ~/.cache/sow/refs/oci/ (or flat ~/.cache/sow/refs/{id}-{digest}/ per design).
Consider adding a note to release notes: "Run rm -rf ~/.cache/sow/refs/git ~/.cache/sow/refs/file to clean up legacy cache."
Error Messages
Update error messages to reflect OCI-only support:
- "Invalid URL: OCI registry URL required (e.g., ghcr.io/org/ref:tag)"
- "Unknown URL format. Use oci://registry/path:tag or a known registry like ghcr.io"
Out of Scope
- Migration tooling: No tools to convert git refs to OCI refs
- Deprecation period: No warnings before removal
- Backward compatibility shims: No code to read legacy index formats
- Automatic cache cleanup: Users manually clean old cache
- Git/file support as plugins: Complete removal, not modularization
Implementation Standards
All code produced in this work unit MUST adhere to the following standards:
Code Quality Standards
- STYLE.md Compliance: All Go code modifications must follow the conventions documented in
.standards/STYLE.md
- TESTING.md Compliance: All tests must follow the patterns documented in
.standards/TESTING.md
- golangci-lint: Code must pass
golangci-lint run with zero errors after removal
Verification Checklist
Before marking this work unit complete, verify:
Acceptance Criteria
Work Unit 008: Remove Legacy Git/File Refs System
Status: Specification
Estimated Effort: 2-3 days
Dependencies: Work Unit 003 (libs/refs OCI Backend), Work Unit 006 (Ref Installation), Work Unit 007 (CLI Integration)
Behavioral Goal
As a sow maintainer,
I need to remove the legacy git-based and file-based refs implementations after the OCI refs system is complete,
So that the codebase is simplified, maintenance burden is reduced, and users have a single, consistent refs mechanism (OCI) without lingering dead code or confusion about which system to use.
Success Criteria
GitTypeandFileTypeare deletedregistry.go) is removedlibs/refs/url.go)github.com/jmgilman/go/gitdependency is removed fromcli/go.mod(unless still needed by other code)cli/internal/refs/manager.goworks exclusively with the new OCI-only system vialibs/refsgo build ./...succeeds after removalgo test ./...passes with no references to deleted codeExisting Code Context
Explanatory Context
The current refs system in
cli/internal/refs/implements a type registry pattern where multiple ref types (git, file) can be registered and used interchangeably. TheRefTypeinterface (types.go:23-79) defines the contract that each type must implement, andregistry.goprovides a global registry for type lookup.With the OCI refs implementation (Work Units 002-007), this multi-type architecture becomes unnecessary. The new system uses
libs/refsexclusively for OCI operations, and the CLI will only support OCI refs going forward. This is a "clean break" decision - no migration tooling, no deprecation period, no backward compatibility.The
CacheManagerinmanager.goandManagerinindex_manager.gocurrently depend on the legacy type system viaInferTypeFromURL(),GetType(), and theRefTypeinterface. After OCI migration, these managers will delegate tolibs/refsinstead of calling type-specific implementations.The git dependency
github.com/jmgilman/go/gitis used byGitTypeingit.gofor repository caching. After removal, this dependency should be removed fromcli/go.modunless other CLI code still requires it (e.g., worktree commands viago-git/go-git/v5).Key Files to Delete
cli/internal/refs/git.goGitTypeimplementation usinggithub.com/jmgilman/go/git/cachecli/internal/refs/git_test.goGitTypecli/internal/refs/file.goFileTypeimplementation using filesystem symlinkscli/internal/refs/file_test.goFileTypecli/internal/refs/types.goRefTypeinterface andRefTypeInfostructcli/internal/refs/registry.goRegister,GetType, etc.)cli/internal/refs/registry_test.gocli/internal/refs/url.goInferTypeFromURL,NormalizeGitURL, etc.)cli/internal/refs/url_test.goKey Files to Update
cli/internal/refs/manager.golibs/refsclient callscli/internal/refs/index_manager.golibs/refsfor all operationscli/cmd/refs/add.gocli/cmd/refs/update.golibs/refsfor OCI update operationscli/cmd/refs/remove.gocli/cmd/refs/status.gocli/cmd/refs/init.gocli/go.modgithub.com/jmgilman/go/gitif no longer neededExisting Documentation Context
ADR-003 (Decision Rationale)
ADR-003 (
.sow/knowledge/adrs/003-oci-refs-distribution.md) documents the decision to replace git-based refs with OCI packages. This is a strategic architectural decision, not incremental improvement. The ADR's "Alternatives Rejected" section explicitly notes "Keep git - doesn't solve pain points" as rejected.The decision includes "Migration effort (tooling provided)" as a trade-off, but the task description specifies "No backward compatibility or deprecation period - this is a clean break." Users with existing git refs will need to manually re-add them as OCI refs.
Discovery Analysis (Current State)
Section 1 of the discovery analysis (
.sow/project/discovery/analysis.md) documents the existing refs architecture:RefTypeinterface withName(),IsEnabled(),Cache(),Update(), etc.GitTypeusesgithub.com/jmgilman/go/git/cache,FileTypeuses filesystem symlinks~/.cache/sow/refs/git/checkouts/and~/.cache/sow/refs/file/The analysis recommends (Section 10.3) that OCI implementation go in
libs/refs/following recent patterns, which Work Units 003-006 implement. The removal of legacy code follows naturally.Design Document (OCI Architecture)
The OCI Refs Design Document (
.sow/knowledge/designs/oci-refs/oci-refs-design.md) describes the new architecture that replaces the legacy system:~/.cache/sow/refs/{id}-{short-digest}/(no subdirectories per type)oci://prefix or known registry patternsDetailed Requirements
Phase 1: Delete Legacy Type Implementations
Delete the following files completely:
After deletion,
cli/internal/refs/should contain only:manager.go(updated)index_manager.go(updated)options.go(if still needed for functional options)ref.go(if still needed for Ref wrapper)Phase 2: Update Manager to Use libs/refs
CacheManager Updates (
manager.go)Current
CacheManager.Install()flow (lines 53-91):InferTypeFromURL(ref.Source)→ type nameTypeForScheme(ctx, typeName)→RefTypeimplementationrefType.ValidateConfig(ref.Config)refType.Cache(ctx, m.cacheDir, ref)→ cache pathNew flow using
libs/refs:libs/refs.IsOCIRef(ref.Source)to validatelibs/refs.Installervialibs/refs.NewInstaller()installer.Install(ctx, ref.Source, opts...)→InstallResultresult.CachePathThe
Update()andRemove()methods need similar updates.Manager Updates (
index_manager.go)The
Managerorchestrates refs operations at a higher level. Updates needed:Add()(lines 28-142): Remove type inference, uselibs/refs.IsOCIRef()for validationnormalizeURLForType()(lines 318-367): Remove git/file-specific logic, normalize OCI URLs onlygenerateRefID()(lines 370-414): Simplify for OCI URL pattern onlyInitRefs()(lines 269-313): Install usinglibs/refs.Installerinstead of type-based loopRemove any imports of deleted files and replace with
libs/refsimports.Phase 3: Update CLI Commands
Each command in
cli/cmd/refs/needs review:add.go:--branchflag (git-specific)--pathflag (repurposed for OCI selective extraction globs)update.go:libs/refs.Installerfor digest comparison and re-pullremove.go:libs/refscache structurestatus.go:init.go:Phase 4: Clean Up Dependencies
Check if
github.com/jmgilman/go/gitis still needed:Note:
go-git/go-git/v5is different fromjmgilman/go/git. The former is used for worktree commands and should remain.Phase 5: Update Documentation
Review and update any documentation referencing git/file refs:
git+https://URLsfile://URLsTesting Requirements
Build Verification
After all deletions and updates:
Must succeed with no errors.
Verify no orphaned imports:
All should return empty.
Test Verification
Run all tests:
Must pass with no failures.
Run specific refs tests:
Functional Verification
sow refs add ghcr.io/org/ref:v1.0.0 --link myref --description "Test"sow refs list(should show only OCI refs)sow refs update myrefsow refs remove myrefsow refs initRegression Verification
Ensure that attempting to add non-OCI URLs fails gracefully:
sow refs add git+https://github.com/org/repo→ Error: "OCI URL required"sow refs add /local/path→ Error: "OCI URL required"Implementation Notes
Dependency Order
This work unit MUST be executed AFTER Work Units 003, 006, and 007 are complete:
libs/refsmodule with OCI clientlibs/refs.Installerfor installationOCITypeadapterOnly after these are complete and functioning can the legacy code be safely removed.
Clean Break Strategy
Per the task description, this is a "clean break":
This simplifies implementation significantly - we delete code without providing alternatives for legacy formats.
Cache Cleanup
The old cache directories (
~/.cache/sow/refs/git/and~/.cache/sow/refs/file/) are NOT automatically deleted. Users can manually clean these up. The new OCI cache uses~/.cache/sow/refs/oci/(or flat~/.cache/sow/refs/{id}-{digest}/per design).Consider adding a note to release notes: "Run
rm -rf ~/.cache/sow/refs/git ~/.cache/sow/refs/fileto clean up legacy cache."Error Messages
Update error messages to reflect OCI-only support:
Out of Scope
Implementation Standards
All code produced in this work unit MUST adhere to the following standards:
Code Quality Standards
.standards/STYLE.md.standards/TESTING.mdgolangci-lint runwith zero errors after removalVerification Checklist
Before marking this work unit complete, verify:
golangci-lint run ./cli/...passes with zero errorsgo build ./...succeeds with no errorsgo test ./...passes with no failuresAcceptance Criteria
cli/internal/refs/git.godeletedcli/internal/refs/git_test.godeletedcli/internal/refs/file.godeletedcli/internal/refs/file_test.godeletedcli/internal/refs/types.godeletedcli/internal/refs/registry.godeletedcli/internal/refs/registry_test.godeletedcli/internal/refs/url.godeletedcli/internal/refs/url_test.godeletedcli/internal/refs/manager.goupdated to uselibs/refscli/internal/refs/index_manager.goupdated to uselibs/refscli/cmd/refs/*.gocommands updated for OCI-onlygithub.com/jmgilman/go/gitremoved fromcli/go.mod(if unused elsewhere)go build ./...succeedsgo test ./...passesgrepverification shows no orphaned references