~bigbes/sr-ht-spec

ref: 824788ab8269bd6c58de5848bc4545450fac7aaf sr-ht-spec/service/reconcile.go -rw-r--r-- 18.3 KiB
b217c7a7 — Eugene Blikh 27 days ago
refactor: move the reconciler's two deletes down to the layers that own them

The reconciler reached past its layer twice, because the primitives it
needed did not exist: a raw DELETE FROM proposal — the only SQL written
outside db/ — and a go-git RemoveReference under gitx's write lock. Both
move down, with no change in behaviour.

db.Store.DeleteOpenProposal keeps the guard in the statement, as
resolveProposal does, and distinguishes the two ways it can bite: a row
that is gone is ErrNotFound, a row that has been resolved is the new
ErrProposalNotOpen, which tells the reconciler "nothing to repair" apart
from "the repair no longer applies".

gitx.Repo.DeleteProposalBranch refuses anything outside proposals/* —
the only thing between a caller bug and a deleted approved branch — takes
the per-space write lock like every other write, and treats an
already-absent branch as success: the repair is a postcondition, and the
ref may legitimately vanish between the listing that found it and the
delete.
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).