~bigbes/sr-ht-spec: 5a10600a

feat: service.Archive — one accessor, one tree walk, one link graph

web/ and mcpsrv/ both needed a *doc.Archive and each invented its own way
to get one. web/ handed sp.Repo to doc.Scan — reaching past service/ into
gitx, which the layering rule forbids — and then listed the documents a
second time for their bodies, two tree walks per page view. mcpsrv/
converted []service.Document back into []gitx.Document, rebuilding hashes
service/ had already stringified. Two workarounds around one missing
accessor is how three agent-facing surfaces stop being identical.

Service.Archive resolves the revision, walks the tree once, and returns
the archive with the bodies. ArchiveFrom is the same construction over a
Document set a caller already holds — the one place a hex object name is
converted back to a hash, malformed ids refused rather than zeroed.

doc.Page.Links and Page.WordCount were documented as "filled in by a
render pass" and nothing filled them, so Archive.Backlinks always
returned empty; web/ worked around that by re-rendering every document of
the space on each page view. doc.Archive.LinkPass now owns the pass and
the accessor runs it, so the link graph exists wherever the archive does.

web/ and mcpsrv/ no longer import gitx or go-git, in tests either.
doc.DirOf replaces the three copies of the same fromDir helper.

Eugene Blikh <bigbes@gmail.com> — 2026-07-22 14:57:22 UTC

Commit 5a10600a93d35781d59b978d6b1c0f850ff43292view raw patch

Parent(s): 29370c57

17 changed file(s)

FileStatus+
doc/archive.go M +53
doc/archive_test.go M +54
doc/doc.go M +3 -2
mcpsrv/backend.go M +16 -54
mcpsrv/mcpsrv_test.go M +18 -13
search/extract.go M +1 -6
service/archive.go A +97
service/archive_test.go A +108
service/doc.go M +5 -3
service/fixture_test.go M +2 -2
service/integration_test.go M +3 -3
service/push_test.go M +12 -12
service/read_test.go M +7 -7
service/reconcile_test.go M +1 -1
web/handlers.go M +4 -41
web/reader.go M +9 -22
web/web_test.go M +27 -15