can you review the current state of the branch in relation to docs/rewrite-issue-list.md and @docs/rewrite-memo.md

can you review the current state of the branch in relation to docs/rewrite-issue-list.md and @docs/rewrite-memo.md
All tests pass. Here's the branch review.
Branch Status vs. Rewrite Documents
Package Structure — Fully Realized
The memo proposed 7 packages. The branch delivers all 7 plus a small convert bridge:
| Proposed | Actual | Source LOC | Test LOC |
|---|---|---|---|
internal/gitproto | ✅ | ~1,670 | ~1,130 |
internal/planner | ✅ | ~1,478 | ~921 |
internal/auth | ✅ | ~490 | ~689 |
internal/strategy/bootstrap | ✅ | ~599 | ~340 |
internal/strategy/incremental | ✅ | ~86 | ~407 |
internal/strategy/materialized | ✅ | ~101 | ~124 |
internal/syncer (orchestrator) | ✅ | ~709 | ~2,440 |
internal/convert (bonus bridge) | ✅ | ~40 | 0 |
The syncer went from being the monolith (~3k+ LOC on main) to ~709 lines of orchestration. That's the structural win the memo was after.
Issue List Scorecard
Done (17 of 22):
| # | Issue | Status |
|---|---|---|
| 1 | Batched bootstrap false tag success | done |
| 2 | Duplicate target mappings accepted | done |
| 3 | Mapping normalization inconsistencies | done |
| 4 | Sideband preference backwards | done |
| 6 | v2 include-tag without capability gate | done |
| 7 | OAuth refresh failures swallowed | done |
| 8 | statsCollector race | done |
| 9 | Unbounded response reads | done |
| 10 | File token store no locking | done |
| 11 | syncer.go monolith | done |
| 12 | Entry points duplicate setup | done |
| 16 | FF check unbounded graph walk | done |
| 17 | Packet parsing allocation | done |
| 18 | Planning functions under-tested | done |
| 19 | Relay eligibility under-tested | done |
| 20 | Protocol v2 error handling under-tested | done |
| 22 | No benchmark coverage | done |
Partial (5 of 22):
| # | Issue | What remains |
|---|---|---|
| 5 | Pack reader leak in batch loop | Core ownership is clearer + direct error-path tests exist, but deeper batched failure paths need a fuller close-audit |
| 13 | Functions carry too much ambient state | Major extraction done; strategy deps are narrowed. Some helpers still carry broad parameter structs |
| 14 | Batch planning probes by fetching full packs | Commit-count heuristic + probe memoization + pack caching added. Still fundamentally network-probed for sizing |
| 15 | Materialized fallback doesn't scale | Safety limits added (500k objects) with explicit failure. Still in-memory, no disk-spill path |
| 21 | Missing behavioral coverage | Many cases now covered. Some harder injected pack-transfer failure paths remain |
Acceptance Criteria
All 10 acceptance criteria from the issue list:
| Criterion | Status |
|---|---|
| Mapping validation before network activity | ✅ done |
| Capability negotiation centralized | ⚠️ partial — source-side is clean, target-side relay gating still orchestration-level |
| Relay strategies in separate packages | ✅ done |
| Tag creation correct without pack transfer | ✅ done |
| Stats concurrency-safe | ✅ done |
| Structured logging | ✅ done (slog) |
| Protocol malformed-input tests | ✅ done |
go test ./... and -race pass | ✅ done |
| Benchmarks for critical paths | ✅ done |
| Comparable to current integration scenarios | ✅ done |
Remaining go-git Dependency
The memo recommended owning the HTTP protocol layer directly and keeping go-git only for packfile/object utilities. The branch still depends on go-git/v5 — the protocol layer is mostly custom now (via gitproto), but go-git transport/protocol types are still used in some paths rather than being fully replaced. This matches the "partial" note on capability centralization.
Overall Assessment
The branch is in solid shape. The structural goals from the memo are met — the monolith is decomposed, the package model matches the proposal, tests are extensive (~6,100 lines of test code), and all tests pass cleanly.
The 5 partial items are all explicitly acknowledged in the issue list and represent conscious scope boundaries rather than oversights:
- #5, #13 are about further tightening, not missing functionality
- #14, #15 are deliberate "good enough for now" engineering tradeoffs called out in the memo's performance section
- #21 is incremental test coverage work
The branch looks ready for comparison testing against main on the existing integration scenarios, which is the next logical step before merge.
There is no v6. go-git/v6 only exists as v6.0.0-alpha.1 — a single alpha pre-release, not suitable for production use.
The project is on v5.17.0, which is two patches behind the latest stable (v5.17.2), but there's no stable v6 to move to.
OK, now I have the full picture. go-git v5 is not a vestigial dependency — it's deeply embedded across the entire codebase. Here's the usage surface:
~100+ import lines across 20+ files, using these go-git v5 sub-packages:
| Sub-package | Used for | Where |
|---|---|---|
plumbing | Hash, ReferenceName, NewHash | everywhere |
plumbing/protocol/packp | AdvRefs, UploadPackRequest | gitproto, planner, syncer |
plumbing/protocol/packp/capability | Capability, List | gitproto, planner, bootstrap |
plumbing/protocol/packp/sideband | sideband demux | gitproto |
plumbing/transport | Endpoint, AuthMethod | gitproto, auth, syncer |
plumbing/transport/http | BasicAuth, HTTP transport | auth, gitproto, tests |
plumbing/format/packfile | packfile encoder/scanner | gitproto, tests |
plumbing/format/pktline | pkt-line encoder | gitproto, tests |
plumbing/object | Commit, Tag objects | planner, tests |
plumbing/storer | EncodedObjectStorer | planner, bootstrap, materialized |
storage/memory | in-memory object store | syncer, bootstrap, tests |
go-billy | virtual filesystem | tests |
top-level v5 | NoErrAlreadyUpToDate, Init, Clone | bootstrap, materialized, tests |
This is not a version bump — it's a migration across the entire type system. And we don't know what v6 alpha actually changed API-wise.
Before I start, I want to be straight with you: this is a significant amount of work against an alpha that could have breaking API changes, missing sub-packages, or bugs. The rewrite memo actually recommends the opposite direction — reducing go-git surface area and owning more of the protocol layer directly.
Do you want me to:
- Investigate v6 first — check what actually changed in the v6 API, whether the sub-packages above still exist with the same signatures, and report back before touching code?
- Just do it — mechanically switch to v6 and fix whatever breaks?
- Something else — e.g., use this as an opportunity to reduce the go-git surface area as the memo recommends, replacing go-git types with owned types where practical?
Done. Here's what the migration involved:
go-git v5 → v6 Migration Summary
Dependencies:
go-git/go-git/v5v5.17.0 →go-git/go-git/v6v6.0.0-alpha.1go-billy/v5v5.8.0 →go-billy/v6go-git/gcfg→go-git/gcfg/v2
API changes handled:
| v5 | v6 |
|---|---|
transport.Endpoint{Protocol, Host, Port, User, Path} | transport.Endpoint embeds url.URL (.Scheme, .Hostname(), .Host, .User, .Path) |
transport/client.InstallProtocol | transport.Register |
transport/client.Protocols["http"] | transport.Get("http") |
transport/server.NewServer(loader) | Removed — replaced with transport.UploadPack(), transport.ReceivePack(), transport.AdvertiseReferences() standalone functions |
transport.UploadPackSession / ReceivePackSession | Removed entirely |
transport.UploadPackServiceName | transport.UploadPackService (typed Service) |
transporthttp.NewClient(c) | transporthttp.NewTransport(&TransportOptions{Client: c}) |
transporthttp.NewErr(res) | Removed — replaced with local httpError() |
packp.ReferenceUpdateRequest | packp.UpdateRequests (no Packfile/Progress fields) |
packp.NewUploadPackRequestFromCapabilities | packp.NewUploadRequest() |
pktline.NewEncoder | pktline.Writef(), pktline.WriteFlush(), pktline.WriteDelim() |
git.Init(storage, worktree) | git.Init(storage, git.WithWorkTree(worktree)) |
Architectural improvement: The v1 fetch and push paths were rewritten to use direct HTTP protocol handling (via PostRPCStream) instead of go-git's transport session abstraction. This aligns with the rewrite memo's goal of owning the smart HTTP protocol layer directly, and eliminates the dual-stack transport problem that was called out as a structural issue.
Committed as 749b51f. Net reduction of 107 lines, mostly from eliminating the go-git transport session layer.