fix(review 005 Unit 2): op/register serving-registry collision gate (G-03)
- op_register_handler takes the serving registry alongside the connection and rejects announced names that collide with the serving side's own registrations (ALREADY_EXISTS regardless of replace). Peer-announced ops may collide with peer-announced ops (replace governs, the reconnect path) but never shadow the deployment's own ops: the connection overlay resolves before base in PeerCompositeEnv, so an unscreened same-name announce would silently rewrite what a wire-dispatched handler's ctx.env.invoke resolves. Composition authority (ADR-018) stays with the deployer. - ADR-022 amendment (2026-09-04): collision policy recorded in the 2026-09-03 amendment's op/register section (rationale + visibility irrelevance); status line notes the sub-amendment. - Gates: base-External collision rejected even with replace (overlay stays clean, serving registration untouched); Internal base op equally protected; overlay/overlay collisions still follow replace; nested composition of a base op resolves the serving side's own op after an unrelated announce (real compose_root_env env shape). - PeerCompositeEnv resolution order deliberately unchanged. Verification: cargo test 587 / --all-features 604, clippy (all-targets, all-features, wasm32) clean, fmt clean, doc clean. Refs docs/reviews/005-...md (G-03; Unit 3 open).
This commit is contained in:
1 parent
1cbb7c6536
commit
23c9b28c6b
4 files changed
+330
-11
No files matched your search
@@ -2,8 +2,8 @@
|
||||
|
||||
## Status
|
||||
|
||||
Unit 1 (G-01, G-02) remediated and verified; Units 2–3 open for
|
||||
remediation. See Remediation log.
|
||||
Units 1 (G-01, G-02) and 2 (G-03) remediated and verified; Unit 3
|
||||
(G-04, G-05) open for remediation. See Remediation log.
|
||||
|
||||
## Scope
|
||||
|
||||
@@ -223,6 +223,9 @@ with an interleaved-directions phase.
|
||||
|
||||
## G-03 [major] — Announced ops can shadow the serving side's own ops in nested composition; the collision gate checks the overlay only
|
||||
|
||||
**Status: REMEDIATED (Unit 2)** — see Remediation log; the ADR-022
|
||||
amendment records the collision policy.
|
||||
|
||||
**ADR drift:** ADR-018 (composition authority) and ADR-019 (the
|
||||
overlay is the *landing zone* for imported ops — a layer beneath the
|
||||
deployment's own registry, not a rival to it); ADR-022 amendment
|
||||
@@ -375,8 +378,8 @@ either way.
|
||||
Sequenced by dependency. All units are alkcall work; Unit 4 (alkhttp
|
||||
wiring) stays downstream and should **not** start before Unit 1 —
|
||||
alkhttp's serving consumers would compose over the same connection
|
||||
and hit G-01 immediately. (Unit 1 landed — see Remediation log;
|
||||
Units 2–3 remain.)
|
||||
and hit G-01 immediately. (Units 1–2 landed — see Remediation log;
|
||||
Unit 3 remains.)
|
||||
|
||||
## Unit 1 — Concurrent serving loop + a stub-exercising gate (G-01, G-02)
|
||||
|
||||
@@ -417,6 +420,73 @@ Units 2–3 remain.)
|
||||
|
||||
# Remediation log
|
||||
|
||||
## Unit 2 — `op/register` collision policy (G-03) — LANDED
|
||||
|
||||
**Fix shape.** `op_register_handler` now takes the serving registry
|
||||
alongside the connection (`op_register_handler(connection,
|
||||
serving_registry)` — the review's "name-set closure" recommendation,
|
||||
materialized as the `Arc<OperationRegistry>` itself, mirroring how
|
||||
`install_bootstrap_discovery` closes over its registry). The handler
|
||||
checks `serving_registry.registration(name)` **before** the overlay
|
||||
gate and rejects base collisions with `ALREADY_EXISTS` regardless of
|
||||
`replace`; overlay collisions keep the existing `replace` semantics.
|
||||
Announced ops may collide with announced ops, never with the serving
|
||||
side's own registrations.
|
||||
|
||||
**ADR-022 amendment:** the 2026-09-03 amendment's `op/register`
|
||||
section gained a "Collision policy (amended 2026-09-04, review 005
|
||||
G-03)" paragraph recording the decided policy and the rationale (the
|
||||
`PeerCompositeEnv` connections-before-base resolution would let an
|
||||
unscreened announce rewrite composition resolution; visibility is
|
||||
irrelevant to the gate). The ADR's status line notes the sub-amendment.
|
||||
|
||||
**Call sites updated:** both e2e gates pass the fork the session
|
||||
dispatches over (`Arc::clone(&accept_registry)` after `fork()`), which
|
||||
is the production shape — the collision set is exactly the registry
|
||||
the serving loop dispatches against.
|
||||
|
||||
**Gates:**
|
||||
|
||||
- `handler_rejects_base_registry_collision_even_with_replace` —
|
||||
base-registered `fs/readFile` (External) + `replace: true` →
|
||||
`ALREADY_EXISTS`; the overlay stays clean and the serving
|
||||
registration is untouched.
|
||||
- `handler_rejects_collision_with_internal_serving_op` — an
|
||||
`Internal` base op is equally protected (the review's point that
|
||||
forced `Visibility::Internal` on the *announced* spec never helped:
|
||||
`OverlayOperationEnv` gates on `AccessControl`, and the composed
|
||||
child is `internal: true` by design).
|
||||
- `handler_overlay_collision_still_governed_by_replace` — announce/
|
||||
announce collisions still follow `replace` (the base gate is
|
||||
scoped to the serving registry, not widened into the overlay).
|
||||
- `nested_composition_of_base_op_unaffected_by_unrelated_announce` —
|
||||
after a successful distinct-name announce, composing the base op
|
||||
through the real `compose_root_env` shape (`PeerCompositeEnv` +
|
||||
`attach_peer(conn.overlay_env())`) resolves the serving side's own
|
||||
op, not a peer stub. (Unit-level, using the actual env types rather
|
||||
than a new full-wire fixture — the wire shape is already covered by
|
||||
the Unit-1 gates.)
|
||||
|
||||
**Deliberate non-change:** `PeerCompositeEnv` resolution order is
|
||||
untouched (connections before base) — the review's recommendation;
|
||||
reordering would change long-decided layering semantics
|
||||
(ADR-019/ADR-024) for no gain the registration-side gate doesn't
|
||||
deliver.
|
||||
|
||||
**Verification (post-fix):**
|
||||
|
||||
```
|
||||
cargo test → 587 passed, 0 failed
|
||||
cargo test --all-features → 604 passed, 0 failed
|
||||
cargo clippy --all-targets -- -D warnings → clean
|
||||
cargo clippy --all-features --all-targets -- -D warnings → clean
|
||||
cargo fmt --check → clean
|
||||
cargo clippy --target wasm32-unknown-unknown -- -D warnings → clean
|
||||
cargo doc --no-deps → clean
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Unit 1 — Concurrent serving loop + stub-exercising gates (G-01, G-02) — LANDED
|
||||
|
||||
**Fix shape.** `dispatch()` was split into a synchronous start half and
|
||||
|
||||
Reference in new issue
Block a user