diff --git a/workplans/CB-WP-0017-legible-interaction.md b/workplans/CB-WP-0017-legible-interaction.md new file mode 100644 index 0000000..a8991dd --- /dev/null +++ b/workplans/CB-WP-0017-legible-interaction.md @@ -0,0 +1,186 @@ +--- +id: CB-WP-0017 +kind: product +title: "Legible interaction: what can be picked up, what is being dragged, where it can go" +status: todo +--- + +# Purpose + +``` +structural tier S (presentation work inside an existing capability — + no new port, no canonical interface, no new + dependency, no change to the loop's own constraints) +chaos d4 = 4 → OVERRIDE, tier drawn: M +declared tier M (structural S, chaos 4 → M) +``` + +**Declaration 12 of 12 — the chaos calibration window closes here**, and +owes its evaluation (T04). + +This is the **second override in twelve declarations**, and it rolls the +opposite way from the first: CB-WP-0011 was structural L rolled *down* to +S, this is structural S rolled *up* to M. The window therefore has one of +each to evaluate, which is the minimum that makes an evaluation possible +at all. + +Tier M means survey and decision merge into one document and the +adversarial review is optional. + +## The report this pass exists for + +The maintainer ran stage 1's human check again after CB-WP-0016 and could +drag — but: + +> *"it is not possible to get what moves are possible and how they affect +> the state of the game"* … *"Can i have better visualization of which +> Elements in the ui can be manipulated"* … *"If the element isnt shown as +> picked up, there is no way to understand that i am actually dragging it +> or where i am dragging it"* … *"visual clues about where something can be +> dropped when it is picked up"* + +Four requests, and one prior finding that makes them one pass: **the page +already hides which moves are legal.** + +Measured, seat P1 at round 1 step Select — **9 legal commands**, rendered +as 5 cards each claiming all three target kinds: + +| the card says | actually legal | +|---|---| +| Investigate → *"a seat, a problem, or the table"* | **problem-2, problem-3** | +| Solve → *"a seat, a problem, or the table"* | **problem-1** | +| Attack → *"a seat, a problem, or the table"* | **seat-1, seat-2** | +| Support → *"a seat, a problem, or the table"* | **seat-1, seat-2** | +| Ground → *"a seat, a problem, or the table"* | **table** | + +Investigate is legal on problems 2 and 3 but not 1; Solve on 1 but not 2 +or 3. The card text is a **constant** — `"drag {a:?} onto a seat, a +problem, or the table"` — emitted whenever *any* legal command uses that +action, then naming all three kinds regardless. `legal` carries the exact +targets and the renderer discards them. + +So highlighting drop targets is not decoration on top of a working table. +It is the first time the page will tell the truth about what is legal. + +## Task: decide how far the JavaScript may grow + +```task +id: CB-WP-0017-T01 +status: todo +priority: high +``` + +Write `decisions/ADR-0010-*.md` (tier M: survey and decision in one). + +**This is a real decision, not a formality.** ADR-0007 Decision 5 says the +page *"reports raw pointer facts and nothing else, and Rust decides what +command they mean"*, and `doc.rs` says of `SCRIPT`: *"it does one thing"*. +Everything asked for here needs the script to do **more** than one thing — +track a drag in flight, move a ghost with the pointer, add and remove +classes on other elements. + +Decide, explicitly: + +- **Does class-toggling violate control 5?** The honest argument is that + legality still comes from Rust as data and the script only renders it — + but that argument must be *made*, because "the page renders what Rust + said" is exactly what a page constructing commands would also claim. +- **What is the invariant that replaces "it does one thing"?** If the + script may grow, say what it may never do, in a form a test can check. + The existing no-game-vocabulary test is the candidate and it is weak. +- **The cost.** Marginal AM-4a is zero either way, so the budget does not + decide this. Say what does. + +## Task: tell the truth about which moves are legal + +```task +id: CB-WP-0017-T02 +status: todo +priority: high +``` + +Emit the legal targets **derived from `legal`**, per action, and render +them so the table is legible without dragging anything. + +The generic sentence goes. A card that says *"onto a seat, a problem, or +the table"* when only `problem-1` is legal is not a simplification, it is +wrong. + +**Controls:** +- The emitted target set must equal the affordance targets of the legal + list exactly — pure Rust, no browser, and it must go red when the sets + diverge. +- A drop that the page marked legal must **resolve**. If the page can + advertise a target `resolve` then refuses, the two have drifted and the + highlighting is worse than none. + +## Task: make picking up, dragging, and dropping visible + +```task +id: CB-WP-0017-T03 +status: todo +priority: high +``` + +The four requests, in order of how badly they are needed: + +1. **What can be manipulated at all** — a resting affordance on every + pickable element. The maintainer asked for a slight shadow; the point + is that interactive and inert must not look identical. +2. **What is picked up** — the grabbed element must visibly change while + the pointer is down. +3. **Where it can go** — every legal drop target for *the thing currently + held* highlights, and nothing else does. +4. **Where it is going** — the drag must be followable, not invisible. + +**Be honest about what is testable.** Whether a shadow reads as "you can +pick this up" is not something any test here can settle, and claiming +otherwise would be this project's characteristic error in its newest +costume. What *is* testable, and must be: + +- pointerdown marks the grabbed element and **exactly** the legal targets + for it, and nothing else; +- pointerup and cancellation clear every mark — a drag that ends leaves no + residue, or the next drag highlights a stale set; +- the highlighted set is the same set T02 emitted. + +The JS DOM stub cannot express any of this today. It will have to model +`classList` and element lookup, which is a real deepening of the harness — +and CB-WP-0016 showed that a stub too thin to express a failure is how the +failure survives. + +## Task: evidence, and close the chaos calibration window + +```task +id: CB-WP-0017-T04 +status: todo +priority: high +``` + +`evidence/CB-EV-0015-*.md`, and then **the evaluation the window has owed +since 2026-07-31**. + +`gates.toml` states the retirement condition in its own words: + +> *retire_if = "the window closes with no overridden tier producing a +> different outcome than the argued one — the evaluation this window +> exists to make possible"* + +So answer it, on the two overrides actually observed: + +- **CB-WP-0011**, structural L → S. What did the deleted survey cost or + save? CB-EV-0009 §1 and CB-EV-0010 §5 already priced part of this + (0.123 $/response at L against 0.099 at S on the same subject). +- **CB-WP-0017**, structural S → M. What did the *extra* ADR buy that a + tier-S provenance paragraph would not have? If the answer is nothing, + say so — that is the finding the window was opened to produce, and a + mechanism that survives its own evaluation by being graded generously is + worse than one that is retired. + +Then: keep, retire, or change the rate, with the argument. + +Also due: + +- **Whether stage 1 closes.** It needs a human to drag again. Say so. +- **Quote CB-WP-0016's cost**, and apply CB-EV-0013 §5's correction — + quote a boundary that has actually settled, or say it has not.