git-ents.gitmain
⌘K
foforge
commit ed67097
multi: merge branch 'docs/plan-reorder'

* docs/plan-reorder: docs: serve tracey web coverage dashboard from the Phase 0 bootstrap docs: bootstrap git.ents.cloud on stock git before any crate lands docs: pin ents-web deployment-agnosticism and retarget the honesty test docs: make the queue reconstructible; durability a performance property docs: reorder plan - headless-first, single-node-first Scopes: docs #------------------------ >8 ------------------------ # Do not modify or remove the line above. # Everything below it will be ignored. # # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # An empty message aborts the commit.

Joseph D. Carpinelli · 1 month ago

Reviews

No reviews of this commit yet — record a verdict below.

Start a review

verdict

docs/development-plan.adoc @@ -20,13 +20,32 @@ * *fable* — the two crates where a quiet bug is a security hole or a wrong design (`ents-gate`, `ents-query` core semantics), public-API review of every crate at its phase boundary, and integration. -* *haiku* — trivial glue (the honesty-test root). Every crate lands with Tracey annotations mapping its spec rules (`.config/tracey/config.styx` already covers `docs/spec/`), tests run via `cargo nextest run`, and a fable review of the public API before anything in the next phase depends on it. +== Phase 0: bootstrap + +Before any crate lands, redeploy the existing Fly app +(`.config/fly.toml`) as a headless machine serving two things behind +one host — no `gix-receive`, no gate, no CI or Sprite executor: + +* stock git's smart-HTTP backend (`git http-backend`) against a bare + repo on the `odb` volume, so `git.ents.cloud` is a real `origin` from + day one; and +* `tracey web`, reading a plain working tree a post-receive hook checks + out on every push (the same `updateInstead` trick Phase 6 formalizes + for real), so the same host shows live spec coverage on HEAD. + +Every phase number below is one higher than in any prior ordering of +this document. +Nothing here is salvaged or reusable code — the single-node hosted +root in Phase 6 (`git-ents`, the CLI-complete milestone) replaces the +git backend wholesale, at the same hostname; whether it keeps serving +the coverage dashboard is a later call. + == Crate schedule [cols="2,1,1,1,4", options="header"] @@ -34,23 +53,23 @@ | Crate | Phase | Complexity | Agent | Notes | `facet-git-tree` -| 0 +| 1 | Low | sonnet | Exists (external repo). Stays domain-blind. Land the `#[facet(transparent)]` fix upstream and drop the local `[patch]`. | `gix-ref-store` -| 0 +| 1 | Medium | sonnet | Read/CAS trait split per `arch.refstore-read-cas-split`; loose-ref impl ports the CAS discipline from `pre-redo` (`arch.loose-cas-discipline`: no shelling to `git update-ref`). Fable reviews the trait before - phase 2 consumes it. + phase 3 consumes it. | `gix-receive` -| 0 +| 1 | High | opus | Smart-HTTP wire framing + pack ingestion, zero policy. Protocol-v2 and @@ -58,7 +77,7 @@ Quarantine semantics per `receive.object-access`. | `ents-model` -| 1 +| 2 | Low | sonnet | Entity structs, namespaces, trailers, taxonomy — declarative, but it is @@ -66,7 +85,7 @@ review matter more than the code. Absorbs git-metadata's trailer work. | `ents-gate` -| 2 +| 3 | Medium | fable | Small in lines, security-critical in every line: tip signature, @@ -75,7 +94,7 @@ call sites. | `ents-query` -| 2 +| 3 | High | fable | The critical path: grammar/parser (easy), static footprint extraction, @@ -84,7 +103,7 @@ semantics against synthetic ref histories. | `ents-anchor` -| 2 +| 3 | Medium | sonnet | Mostly a port: projection (blame + fuzzy context match) survives at @@ -92,16 +111,20 @@ (embed blob + context, no gitlinks). | `ents-receive` -| 3 +| 4 | Medium | sonnet | Orchestration above traits that already exist by now: gate policy (mandatory/advisory), footprint matching, enqueue, `(effect, - oid)` dedup, redaction at ingest. Defines `EventSink`. Fable reviews the + oid)` dedup, redaction at ingest. Defines `EventSink`, reconstructible + from repository state as the work set `trigger − results(self, any)` + (`query.workset`); the in-memory impl plus a boot-time reconciliation + scan is the reference implementation, durability deferred as a + performance property (`receive.reconstructible`). Fable reviews the `receive()` signature — every frontend is downstream of it. | `ents-sync` -| 3 +| 4 | High | opus | Fetch/push plumbing is routine; the schema-aware three-way merge over @@ -109,7 +132,7 @@ Absorbs git-store's merge. | `ents-effect` -| 4 +| 5 | Medium | sonnet | `Executor` trait + Docker/Sprite backends (feature-gated), toolchain @@ -117,46 +140,65 @@ readiness probes and sprite quirks from `pre-redo`; the design is settled, the environment is the risk. -| `ents-web` -| 4 -| Medium -| sonnet -| Broad surface, low algorithmic depth. Signing identity injected by the - root. Accepts the honest `ents-receive` dependency (no write facade). - | `git-ents` (bin) -| 5 +| 6 | Medium | sonnet -| Local root wiring (~50 lines) plus the real cost: subcommand surface, - `serve` = `ents-web` + `gix-receive` on loopback, - `denyCurrentBranch=updateInstead` worktree edge. +| Local root wiring (~50 lines) plus the real cost: subcommand surface + and the `denyCurrentBranch=updateInstead` worktree edge. Headless — no + `serve` subcommand yet (arrives Phase 7 with `ents-web`). Doubles as + the single-node hosted root: loose refs and a real odb on a Fly volume + behind `gix-receive`, an in-memory `EventSink` with a boot-time + reconciliation scan, and the Sprite executor, deployed at + `git.ents.cloud`. Milestone: CLI-complete. + +| `ents-web` +| 7 +| Medium +| sonnet +| Broad surface, low algorithmic depth. Lands `serve` in `git-ents`, + turning the single-node hosted root into a hosted web UI with + sessions/CSRF (`roots.web-session`). Signing identity is injected by + the composition root; the crate assumes nothing about network + reachability, so in-process webview embedding stays a supported + deployment (`roots.web-agnostic`). | `git-ents-server` (bin) -| 5 +| 8 | High | opus | Postgres `RefStore` (multi-ref CAS in a transaction), Tigris object - store behind gitoxide traits, durable-queue `EventSink`, Sprite - executor, path validation, sessions/CSRF. Salvage from the scale-out - work at `pre-redo`; worker stays a mode until scale splits it. + store behind gitoxide traits, and a durable-queue `EventSink` — a new + composition root swapped in with zero library-crate edits. This phase + IS the honesty test (`roots.honesty-test`): entry is triggered by + measured storage/load pressure (the kiln-cache growth analysis), not a + date. Reuses the Sprite executor and sessions/CSRF from `git-ents`; + salvage the store code from the scale-out work at `pre-redo`. |=== == Phase gates -* *Phase 0 → 1*: `gix-ref-store` passes a CAS conformance suite +* *Phase 0 exit*: `git.ents.cloud` resolves over HTTPS; `git clone` and + `git push` round-trip against it using stock git; this repo's + `origin` points at it; the `tracey web` dashboard at the same host + reflects HEAD's coverage after each push. +* *Phase 1 → 2*: `gix-ref-store` passes a CAS conformance suite (concurrent writers, crash injection); `gix-receive` round-trips a push from stock git. -* *Phase 2 → 3*: gate verdicts proven identical across call sites; +* *Phase 3 → 4*: gate verdicts proven identical across call sites; query evaluator handles the staged-pipeline and fan-in idioms incrementally on a synthetic repo. -* *Phase 3 → 4*: end-to-end local write path (`receive` in-process, +* *Phase 4 → 5*: end-to-end local write path (`receive` in-process, advisory gate, null `EventSink`) green; sync merge fuzz-tested against divergent typed trees. -* *Phase 5 exit*: the honesty test — a third single-node root (SQLite, - local fs, Docker; `roots.honesty-test`) built by *haiku* from library - crates alone, no library modification. If haiku can't write it in ~50 - lines, the seams failed, not haiku. +* *Phase 6 exit*: the CLI-complete milestone — every porcelain command + green against the single-node hosted root; the boot-time + reconciliation scan regenerates obligations correctly after a + `kill -9` of the in-memory queue. +* *Phase 8 exit*: the honesty test (`roots.honesty-test`) — the + Postgres/Tigris/durable-queue root is wired as a new composition root + with zero library-crate modification; a diff of library-crate + contents between phase entry and phase exit MUST be empty. Backend conformance tests are shared suites written once against each trait (`RefStore`, `EventSink`, `Executor`) and run per implementation —
docs/spec/overview.adoc @@ -236,6 +236,7 @@ so local mutations honor the same CAS guarantee hosted storage provides. -- -The honesty test for these boundaries — a third single-node composition -root constructible from library crates alone — is a deployment -requirement and lives in `roots.adoc` as <<roots.honesty-test>>. +The honesty test for these boundaries — a new composition root +constructible from library crates alone, no library modification — is a +deployment requirement and lives in `roots.adoc` as +<<roots.honesty-test>>.
docs/spec/receive.adoc @@ -95,6 +95,20 @@ state kept outside the repository. -- +[role="requirement", id="receive.reconstructible"] +.The Queue Is Reconstructible From Repository State +-- +The set of pending obligations an `EventSink` enqueues MUST be derivable +from repository state alone, per the work set defined in +<<query.workset>>. +An `EventSink` implementation MAY lose queued events on crash, provided +the composition root reconciles obligations from repository state at +startup before serving further pushes. +A durable queue MUST be treated as a performance optimization, never a +correctness requirement; the dedup key in <<receive.dedup>> is unchanged +by reconciliation. +-- + [role="requirement", id="receive.redaction-admin-only"] .Redaction Records Are Admin-Only --
docs/spec/roots.adoc @@ -42,11 +42,14 @@ -- [role="requirement", id="roots.honesty-test"] -.Single-Node Honesty-Test Root (Deferred) +.Scale-Out Root Is the Honesty Test -- -A third composition root — SQLite, local filesystem, and Docker — MUST be -constructible without modifying library code, as the project's honesty -test for the seam design. +Wiring the Postgres `RefStore`, Tigris object store, and durable-queue +`EventSink` (<<roots.hosted>>) as a new composition root MUST require +zero modification to any library crate. +This is the project's honesty test for the seam design: the proof is an +actual production migration off the single-node hosted root, not a +synthetic root built to demonstrate the seams. -- [role="requirement", id="roots.config-isolation"] @@ -67,6 +70,15 @@ root. -- +[role="requirement", id="roots.web-agnostic"] +.Web UI Is Deployment-Agnostic +-- +The `ents-web` crate MUST receive its signing identity by injection from +its composition root and MUST NOT assume it is reached over a network. +In-process webview embedding, with no network transport at all, MUST +remain a supported deployment alongside hosted and local-loopback serving. +-- + [role="requirement", id="roots.worktree-update"] .Local Serve and the Working Tree --