diff --git a/Cargo.toml b/Cargo.toml index fb40ed0..b8395f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ rust-version = "1.88" license = "MIT OR Apache-2.0" description = "Content-addressed blob storage: multi-hash put/get/verify store with pluggable backends, transport- and protocol-agnostic" repository = "https://git.alk.dev/alkdev/alkblobs" -keywords = ["blobs", "content-addressed", "storage", "gix", "bao"] +keywords = ["blobs", "content-addressed", "storage", "git", "gix"] categories = ["asynchronous", "filesystem", "database"] exclude = [".opencode/", "AGENTS.md", "docs/reviews/", "docs/research/", "docs/plans/", "tasks/", "docs/sdd_process.md"] diff --git a/tasks/review-wave-1.md b/tasks/review-wave-1.md index f35659a..774227b 100644 --- a/tasks/review-wave-1.md +++ b/tasks/review-wave-1.md @@ -1,7 +1,7 @@ --- id: review-wave-1 name: Wave 1 review gate — the one-way-door gate -status: pending +status: completed depends_on: [core-hashing-keys, core-error-model, core-trait-and-types, suite-scaffold] scope: narrow risk: low @@ -55,14 +55,14 @@ completion is what unblocks wave 2's decomposition. ## Acceptance Criteria -- [ ] Every gate check above read and verified against the cited ADR +- [x] Every gate check above read and verified against the cited ADR text (not from memory of it) -- [ ] Named design points each decided, recorded, and consistent with +- [x] Named design points each decided, recorded, and consistent with the specs -- [ ] Findings fixed inline or recorded as wave-2 amendments with +- [x] Findings fixed inline or recorded as wave-2 amendments with owners -- [ ] All gates re-run green after any fixes -- [ ] Wave 2 decomposition unblocked (recorded in this task's Summary) +- [x] All gates re-run green after any fixes +- [x] Wave 2 decomposition unblocked (recorded in this task's Summary) ## References @@ -76,8 +76,104 @@ completion is what unblocks wave 2's decomposition. ## Notes -> To be filled by implementation agent +Every gate check was read against the cited ADR text (the files, not +memory). Findings below; everything else passed. + +- **Key encoding vs ADR-002 (the one-way door)** — verified byte-exact: + `key := ` (src/keys.rs), 0x01/0x02 assigned, + 0x00 reserved and rejected, total lengths 33/21 (encoding test), + rejects-never-guesses over the full matrix (empty/truncated/ + over-long/unknown 0x00+0x03+0xFF, both widths), derived `Ord` == + physical byte order (sort-stability test), the preamble shared by + both algorithms with only the hasher specializing (no + special-casing, src/hashing.rs), the interop test drives the live + `git hash-object` CLI for both algorithms over empty/short/binary/ + 75-KiB content, and the oid hex policy (lowercase-only acceptance) + is recorded in core-hashing-keys Notes and stated verbatim on + `Digest::from_git_oid_hex`. No shape errors. The door holds. +- **Backend trait + seams vs ADR-003/010/012 §5** — the seven methods + (+ `put_staged`) with opaque byte keys, `size` metadata-only, + `list` complete-and-well-formed by contract; the read cursor with + both body families serving the ADR-006 slice+digest contract at one + seam; the staged-put contract (staging cursor, commit publishes, + every failure path converging on discard). The engine-state seam's + clause families match ADR-012 §5's table: `EngineWindowState` + (postgres/sqlite/pg-lo — `gc_window`-only schema rows for the + latter two), `EngineFleetState: EngineWindowState` (postgres host + only; sqlite's pin/sweep-lock bodies correctly absent — the dead + machinery ADR-012 §5 dropped never existed here; `local`/`mem` + excluded by construction). +- **Error model vs store-api.md / ADR-012 §6.5** — the five variants + exactly; payloads only where the spec writes one (`Io(String)`); + the single-enum reading audited against the spec text and held: the + facade's "re-exposes them with `GcRefuse` added" is faithfully a + one-enum posture with the altitude discipline carried by doc + comments and construction discipline (enforcement lands with the + wave-2 facade, as scoped). `#[non_exhaustive]` correctly on + `GcAbortCause` (ADR-012 §1's non-exhaustive-match ruling, made + structural) and correctly absent from `Error` (no spec requirement). +- **Feature graph vs ADR-013 §4** — the manifest table-matches exactly + (`sqlite` default-on pulling only rusqlite; `postgres`/`mem`/`pg-lo` + default-off pulling their own clusters; `pg-lo` does not imply + `postgres`; `local` ungated; `ops` default-off). Verified + `--no-default-features --features pg-lo` resolves with rusqlite + absent. +- **Named design points** — all audited consistent with the specs: + single-enum error reading (above); `Backend` `pub(crate)` visibility + (ADR-004: no consumer ever implements it; export later is purely + additive); put-form shapes (`put` + `put_staged` with associated + cursor types, kv engines carrying the degenerate staged form — + required by store-api.md invariant 7); oid hex policy (lowercase-only); + async shape (AFIT + associated types, RTN resolvable, no + `async_trait`, no `dyn`). +- **Suite convention** — the factory contract (fresh isolated store, + idempotent teardown, `Send + Sync`), the `Contract stamp:` marker + convention, and the seven-entry invariant backlog traceable to + store-api.md §Invariants 1–7 (in-code traceability gate passing), + with the mem-first column plan and the wave-2 `Store` binding point + recorded. +- **Family conventions** — no `unwrap`/`expect`/panic outside + `#[cfg(test)]` (audited every occurrence); thiserror, tokio, + parking_lot throughout; no user-comment violations (the three + inline comments on `#[allow(dead_code)]` in facade.rs and the + scoped `#![allow(dead_code)]` module attributes document why the + suppression exists — accepted under the non-obvious-constraint + exception); naming and one-module-per-file re-export shape clean. +- **Inline fix applied** — the manifest's keyword list named `bao`, + a technology this crate explicitly excludes (ADR-002 Decision + class 3; ADR-006's whole-blob verification cap); replaced with + `git`. Cosmetic publish-metadata only; no wave-2 consequence. +- **Observations recorded, no amendment needed**: (1) the staged + commit consumes the cursor and self-discards on failure — a + cancellation mid-commit leaves residue handling to engine Drop + bodies, which the contract delegates to engine tasks (waves 2–5); + each engine's hygiene tests must cover its own cancellation story. + (2) The store's verification pass reading staged bytes through the + `StagingCursor: ReadCursor` supertrait is the one design-led + extension of the ADR-010 text; it is what makes ADR-003's + second-pass-over-staged-bytes rule expressible without the retaining + the content stream — recorded in core-trait-and-types Notes and + audited consistent. ## Summary -> To be filled on completion \ No newline at end of file +Wave-1 review gate complete: every gate check read against the cited +ADR text line by line and verified — the one-way-door key encoding +holds byte-exact against ADR-002 (including live git-CLI interop for +both algorithms), the trait + I/O seams + engine-state seam match +ADR-003/010 and ADR-012 §5's reduced table, the error model's five +variants and single-enum altitude reading match store-api.md/ADR-012 +§6.5, the feature graph matches ADR-013 §4 (pg-lo implies nothing), +all five named design points are recorded and consistent, the suite +convention and backlog are traceable, and the family conventions are +clean. One inline fix (publish keyword `bao` → `git`; excluded +technology named in metadata). All gates re-run green post-fix: +`cargo test` (26 lib + 4 conformance + 3 git-interop), `cargo clippy +--all-targets -- -D warnings`, `cargo clippy --all-features +--all-targets -- -D warnings`, `cargo fmt --check`, `cargo check +--all-features`, and the pg-lo no-implication check. Wave 2 +decomposition is unblocked — it decomposes against the contract +surface as reviewed (no amendments); the two recorded observations +(cancellation residue per engine; the staging-cursor verification +pass) are engine-task scoping notes for waves 2–5, not contract +changes. \ No newline at end of file