~bigbes/sr-ht-spec

ref: 824788ab8269bd6c58de5848bc4545450fac7aaf sr-ht-spec/service/merge_test.go -rw-r--r-- 6.5 KiB
65eac3cf — Eugene Blikh 26 days ago
feat(service): write plane — Propose, Merge, ListProposals (Phase 3)

The service-layer orchestration for spec-zqb: the plane where the merge
model and the proposal state machine first run under real proposals
rather than on paper. Primitives (db proposal CRUD/merge, gitx
branch/commit/merge, authn provenance, core policy matcher) already
existed and were unit-tested; this composes them.

- Propose: the write plane, identical for REST and MCP. Row-first open
  (branch name derives from the serial id), branch cut, and a
  provenance-stamped commit — the agent authors, the owner commits, and
  the X-Agent-Session / X-Agent-Base trailers carry the rest into a
  plain git log. Adds to an existing proposal via ProposalID against its
  fixed base. Frontmatter/schema/id validation at propose time, mirroring
  the update hook the in-process agent write bypasses. Returns
  {proposal, url}.
- Auto-merge policy: a proposal whose every changed path matches the
  space's .spec.yml auto_merge lands immediately with ApprovalPolicy,
  best-effort — a stale or mixed-path proposal falls back to human review
  rather than failing the write.
- Merge / Reject: the state machine. Merge does the already-merged
  ancestry check before gitx's If-Match staleness (design: the two need
  different tests), the owner-signed merge commit, and the atomic row +
  document-registry flip. ErrStale / ErrAlreadyMerged / ErrForbidden map
  the 409/403 boundary.
- ListProposals / GetProposal / ProposalURL: the space-scoped read the
  graph Proposals port declared and left nil, plus the stable
  <origin>/~owner/space/p/<id> link.
- db.ListProposalsBySpace: the per-space, per-state listing.

Tested end to end against Postgres: open, auto-merge, mixed-path
fallback, stale-base 409, human merge, reject, add-to-existing, drifted
base. Surfaces (graph wiring, spec_propose, REST api/) fan out next.