feat(ops): the JSON control plane — stat, have (+ the renewal form), and the internal delete (wave 7)

- stat_pair/have_pair/delete_pair exported as spec/handler pairs the
  embedder assembles (OpsContext-bound); input/output + typed error
  schemas per alkcall ADR-016 with namespace-as-resource ACL, the read
  action on stat/have, closed-by-default (OQ-09) verified by test
- stat rides Store::stat (the miss answering the typed BLOB_MISSING,
  never {len: null}); the non-token have is the pure has probe with
  index-corresponded present[]; delete is Visibility::Internal —
  external discovery NOT_FOUND, the operator authority context carried
  as the registration-time composition authority (not namespace-gated),
  GC_REFUSED/BLOB_MISSING typed, fail-fast
- the have renewal form rides the foundation's OpsContext::renew: the
  one-digest arity enforced at the schema (if/then) and as the typed
  INVALID_RENEWAL_FORM; digests wire-form hex via the key layer's
  ingress (INVALID_DIGEST); the fleet arms tested against the harness
  server (env-driven, skipping cleanly server-less): the live row
  renews with the expiry observed moving, the expired row answers
  present: false with the expiry frozen (no renewal), the foreign
  token is the validity-domain refusal, and mint_custodial refuses
  under fleet

Gates: cargo test (default 73/19/3), cargo test --features ops
(92/19/3), cargo test --all-features against the harness server
(246/125/4), clippy -D warnings across default/ops/all-features plus
the pg-pure checks, cargo fmt --check, cargo doc --no-deps clean.
This commit is contained in:
glm-5.3-flash committed 2026-10-13 00:31:25 +00:00
1 parent bc6da37e35
commit 5144b6a733
3 files changed
+1374 -23

No files matched your search

+4 -2
View File
@@ -32,8 +32,10 @@ pub mod ops;
#[cfg(feature = "ops")] #[cfg(feature = "ops")]
pub use ops::{ pub use ops::{
FanoutChunk, FanoutPublisher, FanoutReceiver, FanoutRegistry, OpsConfig, OpsContext, delete_pair, have_pair, stat_pair, FanoutChunk, FanoutPublisher, FanoutReceiver,
PinConverter, PinToken, RenewalOutcome, SlowSubscriberPolicy, TokenRegistry, FanoutRegistry, OpsConfig, OpsContext, PinConverter, PinToken, RenewalOutcome,
SlowSubscriberPolicy, TokenRegistry, BLOB_MISSING, GC_REFUSED, INVALID_DIGEST,
INVALID_RENEWAL_FORM,
}; };
#[cfg(any(feature = "postgres", feature = "pg-lo"))] #[cfg(any(feature = "postgres", feature = "pg-lo"))]
+1271 -12
View File
File diff suppressed because it is too large. Load diff
+99 -9
View File
@@ -1,7 +1,7 @@
--- ---
id: ops-json-ops id: ops-json-ops
name: the JSON control plane — blobs/stat, blobs/have (+ the token-renewal form), blobs/delete name: the JSON control plane — blobs/stat, blobs/have (+ the token-renewal form), blobs/delete
status: pending status: completed
depends_on: [ops-foundation, ops-call-harness] depends_on: [ops-foundation, ops-call-harness]
scope: moderate scope: moderate
risk: medium risk: medium
@@ -73,20 +73,20 @@ an authorization check):
## Acceptance Criteria ## Acceptance Criteria
- [ ] Three spec/handler pairs exported (stat, have, delete); input/ - [x] Three spec/handler pairs exported (stat, have, delete); input/
output schemas + typed error schemas per alkcall ADR-016 output schemas + typed error schemas per alkcall ADR-016
- [ ] The ACL mapping: namespace-as-resource with the - [x] The ACL mapping: namespace-as-resource with the
resource_id_path; the read action on stat/have; resource_id_path; the read action on stat/have;
closed-by-default verified by test (unlisted namespace denies) closed-by-default verified by test (unlisted namespace denies)
- [ ] delete: `Visibility::Internal`, the internal-authority-context - [x] delete: `Visibility::Internal`, the internal-authority-context
requirement (not namespace-gated), external discovery NOT_FOUND requirement (not namespace-gated), external discovery NOT_FOUND
- [ ] have's renewal form: one digest + token; verify-mapping → - [x] have's renewal form: one digest + token; verify-mapping →
`pin_renew`; expired/foreign → `present: false` with no `pin_renew`; expired/foreign → `present: false` with no
renewal; the non-fleet form answers from the held custody renewal; the non-fleet form answers from the held custody
- [ ] The handlers touch only the store facade + the foundation's - [x] The handlers touch only the store facade + the foundation's
crate-internal renewal access (no backend side-door — the crate-internal renewal access (no backend side-door — the
ADR-001 §4 rule) ADR-001 §4 rule)
- [ ] Harness tests green; `cargo test` (default) green; - [x] Harness tests green; `cargo test` (default) green;
`cargo test --features ops` green; clippy/fmt green on both `cargo test --features ops` green; clippy/fmt green on both
shapes; `cargo doc --no-deps` clean shapes; `cargo doc --no-deps` clean
@@ -112,8 +112,98 @@ an authorization check):
## Notes ## Notes
> To be filled by implementation agent > Landed in `src/ops.rs` (the ops module's "JSON control plane"
> section, appended to the foundation's substrate) + `src/lib.rs`
> re-exports (`stat_pair`/`have_pair`/`delete_pair` and the four
> domain codes `BLOB_MISSING`/`INVALID_DIGEST`/`INVALID_RENEWAL_FORM`/
> `GC_REFUSED`). Each export is `pub fn X_pair(ctx: Arc<OpsContext>) ->
> (OperationSpec, Handler)` — the embedder assembles; the harness's
> assembly (extended: `assemble_registrations` now carries the
> registration-side composition authority and scoped composition env,
> ADR-017/019 — the pair-level `assemble` shape is unchanged).
>
> **Schemas (alkcall ADR-016):** input/output JSON Schema per op — the
> namespace field's syntax enforced at the schema (`minLength: 1`, the
> non-empty-UTF-8 rule); the digest wire form hex with the canonical
> pattern (`^[0-9a-f]{40}$|^[0-9a-f]{64}$`, the key layer's
> lowercase-only ingress also enforced at the handlers —
> rejects-never-guesses). The have schema carries the renewal form's
> arity as `if`/`then` (token ⇒ digests minItems/maxItems 1) — verified
> live at the wire (`INVALID_INPUT` on the two-digest+token shape) —
> and re-enforced at the handler (`INVALID_RENEWAL_FORM`, the
> typed error for non-registry dispatch paths, exercised by direct
> handler invocation). Typed error schemas: `BLOB_MISSING`
> (stat's miss — details `{digest}`; a `{len: null}` was never an
> option), `INVALID_DIGEST` (the ingress), `INVALID_RENEWAL_FORM`
> (have's arity), `GC_REFUSED` (delete's `Error::GcRefuse`).
>
> **The ACL mapping (OQ-09's resolution, verified by test):**
> namespace-as-resource — `resource_type: "blob-namespace"`,
> `resource_id_path: "$.namespace"`, the read action on stat/have;
> closed-by-default proven on the wire (an unlisted namespace denies
> the granted identity's probe; a granted namespace reads; the
> anonymous call answers the authentication required gate). delete:
> `Visibility::Internal`, `AccessControl` left un-gated (not
> namespace-gated — the field is audit/triage scoping), the
> operator-admin authority context realized as the **composition
> authority the embedder declares at registration** (the pair exports
> it authority-agnostic); external discovery is the registry's
> NOT_FOUND (tested); the internal path proven through a composant op
> (`blobs/compose-delete` test stub, scoped env → delete) whose
> grantless caller composes — the check ran against the declared
> operator authority, the namespace grant not the gate. GcRefuse and
> Missing surface as the typed errors (fail-fast; no atomic multi-
> delete was specced — the preceding digests' deletions stand, and the
> doc says so).
>
> **The renewal form** (ADR-012 §2's three-step duty, riding the
> foundation's `OpsContext::renew` — no new store access, no backend
> side-door): the non-fleet arms answer from custody (renew →
> present: true; unknown/foreign/mismatched → present: false, never an
> error; the malformed-token ingress maps to the unknown-token answer);
> the fleet arms ran against the harness server (env-driven
> `ALKBLOBS_PG_HOST/...`, skipping cleanly server-less — the fleet
> column's SKIP posture adapted in-crate): the live row renews with
> the row's expiry observed moving (the independent `gc_pins`
> instrument), the expired row answers `present: false` with the
> expiry frozen at the last renewal (no renewal occurred — the
> never-resurrect discipline), and the peer mint's foreign token
> answers `present: false` the same way (the validity domain = the
> minting node). The foundation's noted `mint_custodial`-refused-under-
> fleet arm is asserted in the same test. The put-side arms (mint the
> token from a wire-carried put) ride the put's handler (ops-put).
## Summary ## Summary
> To be filled on completion > Completed 2026-10-13 (wave 7). The JSON control plane's three
> spec/handler pairs landed in `src/ops.rs` under feature `ops`:
> `blobs/stat` (Query/read — `Store::stat`, the miss as the typed
> `BLOB_MISSING`), `blobs/have` (Query/read — the pure existence probe
> over `Store::has` with index-corresponded `present[]`, engine
> failures folding to present: false, and the token-renewal form
> riding `OpsContext::renew` with the one-digest arity enforced at the
> schema (`if`/`then`) and the handler), and `blobs/delete`
> (Mutation/`Visibility::Internal` — external discovery NOT_FOUND; the
> operator authority context via the registration-time composition
> authority; not namespace-gated; `Store::delete` with `GC_REFUSED`/
> `BLOB_MISSING` as the typed errors, fail-fast). ACL: namespace-as-
> resource, the read action, closed-by-default (verified by test);
> digests wire-form hex parsed via the key layer's ingress
> (rejects-never-guesses); domain error codes `BLOB_MISSING`/
> `INVALID_DIGEST`/`INVALID_RENEWAL_FORM`/`GC_REFUSED` declared per op
> with their details schemas. Five harness tests added (stat
> round-trip/miss/ingress, have's index correspondence + closed-by-
> default matrix, the renewal form's arms incl. the arity gate at both
> the wire and the handler, delete's NOT_FOUND + internal composition
> + refusal arms) plus one fleet harness-server test (the three
> renewal answers with the row-expiry instrument; the foreign token;
> the custodial-mint refusal under fleet) — env-driven, skipping
> cleanly server-less (SKIP posture). Gates green: `cargo test`
> (default 73/19/3), `cargo test --features ops` (92/19/3),
> `cargo test --all-features` against the harness server (246/125/4 —
> one pre-existing fleet-timing row flaked once under full-suite load
> and passed on the isolated + full reruns, untouched by this task's
> diff: the fleet column reads no ops code), clippy
> `--all-targets -- -D warnings` on the default/ops/all-features
> shapes plus the pg-pure checks, `cargo fmt --check`,
> `cargo doc --no-deps` clean on the default and ops builds.