Prune the docs of work already done: 18,252 -> 7,567 lines

Iris: "the documentation is also pretty crazy too. Can you go through it
and remove everything that's already done and decided? There's entire md
files iirc for projects already complete. And many with checkboxes already
ticked off that just fill up context."

  docs/RUST.md        8503 -> 905    the framework bake-off (options,
                                     recommendation, twelve closed
                                     experiment boxes) and two superseded
                                     "where things stand" sections, out;
                                     what the experiments settled kept as
                                     one line each
  docs/IRIS_TODO.md   1383 -> 229    fifty closed items and six
                                     phone-report sections whose defects
                                     are all fixed
  docs/LAYOUT.md      1116 -> 829    the pre-implementation framing: the
                                     old trait, the checklist, the
                                     migration list, the pass conditions
  docs/TEXTURES.md     496 -> 240    the prior-art survey, the proposal
                                     and its review, all implemented
  docs/REVIEW-*.md     673 -> 0      two completed review passes; the two
                                     findings left open on purpose (mask
                                     hit-testing, the phone's font set)
                                     moved into RUST.md

What survives a prune is what cannot be cheaply re-derived: measurements
(the APK-size table, the phone bench reports), dead ends, invariants and
their reasons, and the design of what exists now rather than the route to
it. AGENTS.md now says that, so the next session prunes as it goes rather
than appending; docs/IRIS_TODO.md's header says items are deleted when
they land rather than ticked.

Deleting the two review files left eighteen citations dangling in code
comments that state their reason inline and cited the file for provenance
only — those now read "(review, 2026-09-06)" and carry no dead pointer.
The emulator's measured GPU capabilities moved to the this-machine-android
skill, where machine facts belong. IRIS.md and DECISIONS.md are dated
records and were not rewritten; each gained one note that paths in older
entries predate the 2026-09-08 crate merge, pointing at the mapping.

Not touched, deliberately: docs/DECISIONS.md's entries (that file *is* the
queue of things for Iris to review, so deleting decided items would remove
what it exists for) and iris/readme.md and iris/TODO, which are hers.

Verified: ./run-tests.sh and `cd iris && cargo test` green, clippy and fmt
clean in every workspace, and every remaining docs/*.md cross-reference
resolves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-08 23:50:53 -04:00
1 parent a9312e9431
commit 8841959470
7 files changed
+21 -21

No files matched your search

+1 -1
View File
@@ -371,7 +371,7 @@ impl<State: DefaultAppState> AppState for DefaultApp<State> {
// the matching `Resized` separately. Before 2026-09-07 this
// event was unhandled, so every `dp` and every rasterised
// glyph stayed at the density the window opened on
// (docs/REVIEW-2026-09-07.md's R5) -- invisible on this
// (review, 2026-09-07) -- invisible on this
// machine, where every display is 1.0.
WindowEvent::ScaleFactorChanged { .. } => {
let scale = content_scale(ui_state.window.as_ref());
+9 -9
View File
@@ -832,7 +832,7 @@ pub fn log_input_event(action: &str, x: f32, y: f32, t_ms: u64, historical: &[(u
/// samples sharing a timestamp make the Lsq2 fit degenerate, so the flick
/// that produced them reads 0 px/s -- reachable whenever the first event a
/// view sees is a `Move` (the `Down` went to another view, or the view was
/// attached mid-gesture). Found by review, 2026-09-07 (docs/REVIEW-2026-09-07.md's D4).
/// attached mid-gesture). Found by review, 2026-09-07.
#[derive(Clone, Copy)]
pub struct PointerClock {
anchor_at: Instant,
@@ -1557,7 +1557,7 @@ impl VelocityTracker {
// gesture, a test) would make `velocity`'s reverse walk compute
// negative ages and fit a curve through a shuffled x-axis --
// masking the bug that produced it rather than surfacing it
// (docs/REVIEW-2026-09-06.md finding 4).
// (review, 2026-09-06 finding 4).
debug_assert!(self.samples.back().is_none_or(|&(last, _)| at >= last));
self.samples.push_back((at, position));
while self.samples.len() > HISTORY_SIZE {
@@ -1670,7 +1670,7 @@ impl VelocityTracker {
/// points than coefficients; [`MIN_SAMPLE_SIZE`] makes that unreachable
/// from the only caller, so the truncation is an assert instead of a
/// branch that could never be exercised.
// Both guards stay `debug_assert!` under docs/REVIEW-2026-09-07.md's R1:
// Both guards stay `debug_assert!` under the 2026-09-07 review's rule:
// they are preconditions of a fit run on every velocity query, and the two
// callers between them already answer 0 below `MIN_SAMPLE_SIZE` and check
// the result with `is_finite`, so a release build has a defined outcome
@@ -1712,7 +1712,7 @@ fn poly_fit_least_squares(x: &[f32], y: &[f32]) -> Option<[f32; FIT_COEFFICIENTS
// treats a norm this small as "the vectors are linearly dependent,
// so there is no solution" and returns nothing; clamping instead
// -- which this did until 2026-09-07
// (docs/REVIEW-2026-09-07.md's R7) -- produces a `q` row of zeros,
// (review, 2026-09-07's R7) -- produces a `q` row of zeros,
// a zero on `r`'s diagonal and a 0/0 that only the caller's
// `is_finite` check happened to catch. Working by accident, and
// not what the source it is transcribed from does.
@@ -1921,7 +1921,7 @@ impl FlingCalculator {
pub fn distance(&self, velocity: f32) -> f32 {
// See `ScrollController::fling`'s matching assertion -- a non-finite velocity
// here silently produces a NaN distance rather than surfacing the
// bug that produced it (docs/REVIEW-2026-09-06.md finding 3).
// bug that produced it (review, 2026-09-06 finding 3).
debug_assert!(velocity.is_finite());
if velocity == 0.0 {
return 0.0;
@@ -2056,11 +2056,11 @@ impl Flinger {
// straight through) would propagate silently into
// `deceleration_for`'s `.ln()` -- the fling either never settles
// or jumps to NaN positions with nothing on screen saying why
// (docs/REVIEW-2026-09-06.md finding 3). A plain `assert!` rather
// (review, 2026-09-06 finding 3). A plain `assert!` rather
// than a `debug_assert!`: it is one comparison per *gesture*, and
// every build anybody runs -- the emulator's and Iris's phone's --
// is release, where a debug-only guard against silently wrong
// output is no guard at all (docs/REVIEW-2026-09-07.md's R1).
// output is no guard at all (review, 2026-09-07's R1).
assert!(velocity_px_per_s.is_finite());
assert!(density.is_finite() && density > 0.0);
let max = MAX_FLING_VELOCITY_DP_S * density;
@@ -2216,7 +2216,7 @@ mod velocity_tracker_tests {
/// -- this one, the flick recording, the horizon, the stopped finger,
/// the minimum sample count and both `drag_gesture` flick tests, plus
/// `phone_screen.rs`'s flick -- and leaves everything else green. Rerun
/// 2026-09-07 (docs/REVIEW-2026-09-07.md): this comment used to say
/// 2026-09-07: this comment used to say
/// "exactly this one, the flick recording, and `phone_screen.rs`",
/// which disagreed with docs/RUST.md's count of the same experiment.
/// Seven is what the run prints; RUST.md was right.
@@ -2293,7 +2293,7 @@ mod velocity_tracker_tests {
);
}
/// docs/REVIEW-2026-09-07.md's R7. Three samples at one instant --
/// Found in review, 2026-09-07. Three samples at one instant --
/// which the input clock produced on its own before 2ec0fee -- leave
/// the second basis vector all zeros, and Compose calls that "linearly
/// dependent, no solution" and returns nothing. Clamping the norm to
+2 -2
View File
@@ -326,8 +326,8 @@ fn a_finger_drag_over_a_scroll_area_pans_it() {
assert_eq!(pointer_input(&mut rsc).holder(), Some(scroll.id()));
}
/// docs/REVIEW-2026-09-07.md's D4. The first `MotionEvent` a view sees can
/// be a `Move` -- the `Down` went to another view, or the view was attached
/// A defect found in review, 2026-09-07. The first `MotionEvent` a view
/// sees can be a `Move` -- the `Down` went to another view, or the view was attached
/// mid-gesture -- and its batched samples are older than its own
/// timestamp. Anchoring on that timestamp clamped every one of them onto
/// the anchor, so the tracker saw three samples at one instant, the Lsq2
+5 -5
View File
@@ -1053,8 +1053,8 @@ impl LazySpan {
// `prev_slot`/`next_slot`, which already check existence -- but
// that invariant is enforced by convention across three call
// sites, not by this function, which would otherwise fail with a
// bare "index out of bounds" and no context (docs/
// REVIEW-2026-09-06.md finding 2). `slot_widget`, called from
// bare "index out of bounds" and no context (review,
// 2026-09-06). `slot_widget`, called from
// here, is what actually indexes/`.expect`s on it. Stays a
// `debug_assert!` under R1's rule: this runs once per row placed
// per frame, and its release failure is the `.expect` below rather
@@ -1995,9 +1995,9 @@ mod tests {
/// its sibling below ever asserts the *evicted* key's own bookkeeping
/// is actually gone -- both replace row 4 with another row also keyed
/// `4`, so `heights.remove(&old.key)` removing and re-inserting the
/// same key would pass either test even if it did nothing (docs/
/// REVIEW-2026-09-06.md finding 10; this is `Selection`'s finding 1
/// class of bug -- a stale handle outliving what it points to --
/// same key would pass either test even if it did nothing (review,
/// 2026-09-06; the same class of bug -- a stale handle outliving what
/// it points to --
/// production-tested from `LazySpan`'s own side). Replacing with a
/// **different** key is what actually exercises the removal.
#[test]