~bigbes/sr-ht-spec

ref: 824788ab8269bd6c58de5848bc4545450fac7aaf sr-ht-spec/service/fixture_test.go -rw-r--r-- 11.0 KiB
5a10600a — Eugene Blikh 27 days ago
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.
e1b3c64e — Eugene Blikh 27 days ago
feat: service — wiring, space lifecycle, read paths, push validation, reconciler

Phase 1 of the implementation plan: the orchestration layer's read, validate
and repair halves. The write plane (propose/merge) is Phase 3 and is absent.

- Config/New assemble a Service from the shared config.ini, reporting every
  missing key in one message; TokenStore adapts db/ to authn.TokenStore,
  mapping db.ErrNotFound onto authn.ErrUnknownToken so an unknown credential
  is a 401 rather than a 503.
- CreateSpace writes the repository first and the row second, removing the
  repository again if the insert fails; a crash between the two leaves content
  that is merely unlisted rather than a phantom space.
- ReadDocument/ListDocuments/Policy/ResolveRev resolve the approved head or a
  pinned revision through one code path.
- ValidatePush checks the refs rule first and unconditionally, then frontmatter
  and document-id uniqueness, which --push-option=skip-validation waives. The
  rejection is a structured, terminal-shaped message naming the document.
- PlanRepairs is the repair table as a pure, table-tested function; Reconcile
  gathers the facts and applies them, listing stale-index spaces for Phase 2.

Two departures from the design's repair table, both to stop the reconciler
destroying live state, documented at their definitions: an open row with no
branch is left alone inside a grace window (every propose passes through that
state), and a branch still sitting on its recorded base is never treated as
merged (its tip is trivially an ancestor of the approved head).