---
name: gate-against-documented-design
description: "Gating lesson: verify a wave's premise against the RECORDED design (CONTEXT.md/ADRs), not just the current impl — an impl limitation can contradict a locked design"
metadata: 
  node_type: memory
  type: feedback
  originSessionId: d89e0e1c-20df-47bc-9087-c93241d08ba2
---

When gating a design-check, verify the wave's PREMISE against the recorded domain model
(CONTEXT.md, ADRs) — not only the current implementation. An impl's *current limitation* can
silently contradict a LOCKED design, and ruling on the impl ships the wrong thing.

**Why:** M12 W2.5 (attach-presence + Kick). todlando's investigation read the broker as
single-subscriber (`OutputLog.subscriber: Option<SharedSend>`) → concluded "a 2nd attach displaces,
implicit displace already works." I gated that and ruled "(a) implicit displace, document the silent
freeze." **Both wrong:** CONTEXT.md:317 records a LOCKED **controller/viewer model** (1 controller +
N `--view` read-only letterboxed attachers; `kick`/`--take` displaces with a LOUD notice;
CONTEXT.md:318 _Avoid_: **silent controller displacement**). The single-subscriber broker is an
UNBUILT-design gap, and my "(a)" was the exact anti-pattern the design forbids. The operator caught
it — I never grep'd CONTEXT.md for the attach design before ruling.

**How to apply:** before ruling on a wave that touches a subsystem with a product surface, grep
CONTEXT.md + docs/adr for that surface's recorded model (here: "controller", "viewer", "letterbox",
"resize", "attach") and reconcile the impl against it. If impl ≠ design, that's a finding to
surface, not a premise to gate. This is literally the grill-with-docs discipline applied to gating.
Related: [[adapter-glue-model-boundary]], [[m12-w1-progress]].
