Skip to main content

max / makenotwork

Read the crossover as two whole counts, and retire the last supplier `crossover_meter` was the last workable shape in the declaration transition. Its own doc comment gave two reasons for existing and both were dead. `meter` cannot be a member because `Row::meter` and `Cell::meter` are settings, but `proportion` is that rename and has been live since wave 14. The two numbers being a rounding and two casts away from the outcome is the ordinary read rule: arithmetic belongs in the read, and `Outcome` is already the read. So `Outcome` loses `sales_per_month: f64` and `crossover_sales: Option<f64>` and gains `crossover: Option<Crossover>`, carrying `sales` and `at` as `u32`. A fold rather than an addition, because both raw fields named the panel as their only reason to exist and outside it their only readers were the three assertions about them. It is lossless: `sanitize` already rounds `sales_per_month` to a whole count and clamps it to `MAX_SALES`, so `sales as f64` is the volume the reader set, exactly, and the property test still says so. The tone stays out of the calculator. `verdict_tone` is a match on `Verdict`, not arithmetic, and this declaration already calls it inline two lines up for the banner; resolving it in `compute` would put a `makeover_layout::Tone` in the fee model to save a spelling the file already uses. No production earned. Loss list empty: the meter's two arguments are the same two expressions moved, and the label, the tone and the condition under which the node appears are unchanged. MNW `remaining` goes 10 to 9 and every remaining MNW shape is parked. `declared` stays 154 rather than reaching the 155 the task predicted: a supplier absorbed into a declaration that already existed moves the denominator, not the numerator.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session
https://claude.ai/code/session_01P8ostB2UmZJGj5WjSHRSot
Author: Max Johnson <me@maxj.phd> · 2026-09-05 13:29 UTC
Signed with PGP, not checked
Commit: 067984e0bd8b53185bb8d69f6551630d6f5a3f5f
Parent: b3d5df8
2 files changed, +53 insertions, -51 deletions
@@ -245,8 +245,10 @@
245 245 headline,
246 246 verdict,
247 247 crossover_note,
248 - sales_per_month: i.sales_per_month,
249 - crossover_sales: crossover,
248 + crossover: crossover.map(|at| Crossover {
249 + sales: i.sales_per_month.round().max(0.0) as u32,
250 + at: at.ceil().max(1.0) as u32,
251 + }),
250 252 }
251 253 }
252 254 }
@@ -282,15 +284,30 @@
282 284 pub verdict: Verdict,
283 285 /// Where the crossover sits, or why there isn't one.
284 286 pub crossover_note: Option<String>,
285 - /// The volume the dials were set to, so the panel can say where that sits
286 - /// against the crossover. Carried rather than recomputed: the reader typed
287 - /// it, `sanitize` rounded it, and a second rounding downstream is a second
288 - /// answer.
289 - pub sales_per_month: f64,
290 - /// Sales a month at which we become the cheaper place, exactly. `None` when
291 - /// our per-sale advantage is zero or negative, which is the case no volume
292 - /// closes.
293 - pub crossover_sales: Option<f64>,
287 + /// Where the entered volume sits against the crossover. `None` when our
288 + /// per-sale advantage is zero or negative, which is the case no volume
289 + /// closes: there is then no set for the volume to be a proportion of, and
290 + /// [`Outcome::crossover_note`] says so in words instead.
291 + pub crossover: Option<Crossover>,
292 + }
293 +
294 + /// The entered volume against the crossover, as the two whole counts a meter
295 + /// is drawn from.
296 + ///
297 + /// Whole counts because a proportion is read by a person and a meter takes two
298 + /// `u32`s. They are resolved here rather than where the panel is described,
299 + /// because a description admits no arithmetic and this is a rounding and two
300 + /// casts.
301 + #[derive(Debug, Clone, Copy)]
302 + pub struct Crossover {
303 + /// The volume the dials were set to. Exact, not a second rounding:
304 + /// `sanitize` already rounded it to a whole count and clamped it to
305 + /// `MAX_SALES`.
306 + pub sales: u32,
307 + /// Sales a month at which we become the cheaper place, rounded up. At least
308 + /// one, because a meter drawn against a zero total says nothing a reader
309 + /// can act on.
310 + pub at: u32,
294 311 }
295 312
296 313 /// Format dollars as `$1,234.56`, with the sign ahead of the `$`.
@@ -434,7 +451,7 @@
434 451 let note = out.crossover_note.expect("no-crossover note");
435 452 assert!(note.contains("no amount of volume"), "note was: {note}");
436 453 // No volume closes the gap, so there is no crossover to point at.
437 - assert!(out.crossover_sales.is_none());
454 + assert!(out.crossover.is_none());
438 455 }
439 456
440 457 /// A free tier has nothing to repay, so MNW leads from the first sale and
@@ -450,7 +467,7 @@
450 467 });
451 468 assert_eq!(out.verdict, Verdict::MnwAhead);
452 469 assert!(out.crossover_note.is_none());
453 - assert!(out.crossover_sales.is_none());
470 + assert!(out.crossover.is_none());
454 471 }
455 472
456 473 /// Zero sales is a real answer, not a placeholder: the subscription still
@@ -531,14 +548,14 @@
531 548 approx(inf.other_pct, c.defaults.other_pct, "NaN cut");
532 549 }
533 550
534 - /// A crossover is a count of sales, so it is positive and finite wherever
535 - /// there is one, at every dial position the inputs allow.
551 + /// A crossover is a count of sales, so it is positive wherever there is
552 + /// one, and the volume it is read against is the one the reader set.
536 553 ///
537 554 /// This replaces `scale_segments_tile_the_axis`, which checked that two
538 555 /// hand-computed bar widths summed to 100. The widths went with the
539 556 /// template that positioned them; the property worth holding is the one the
540 - /// panel now states, since a meter drawn against a zero or negative total
541 - /// says nothing a reader can act on.
557 + /// panel now states, since a meter drawn against a zero total says nothing
558 + /// a reader can act on.
542 559 #[test]
543 560 fn a_crossover_is_a_positive_count_of_sales_wherever_there_is_one() {
544 561 let c = loaded();
@@ -552,17 +569,18 @@
552 569 other_pct: pct,
553 570 other_per_sale: 0.30,
554 571 });
555 - if let Some(crossover) = out.crossover_sales {
572 + if let Some(crossover) = out.crossover {
556 573 assert!(
557 - crossover.is_finite() && crossover > 0.0,
558 - "crossover {crossover} at price {price}, {sales} sales, pct {pct}"
574 + crossover.at >= 1,
575 + "crossover at {} at price {price}, {sales} sales, pct {pct}",
576 + crossover.at
577 + );
578 + approx(
579 + f64::from(crossover.sales),
580 + sales,
581 + "the panel is told a volume the reader did not set",
559 582 );
560 583 }
561 - approx(
562 - out.sales_per_month,
563 - sales,
564 - "the panel is told a volume the reader did not set",
565 - );
566 584 }
567 585 }
568 586 }
@@ -45,10 +45,11 @@
45 45 //! axis and a legend, and `fee_calculator::Scale` existed to compute the four
46 46 //! percentages it positioned them with. All of it said one thing: where the
47 47 //! reader's volume sits against the crossover. That is a proportion of a set,
48 - //! which is [`Meter`] -- with the reader's sales as `done` and the crossover as
49 - //! `total`, so passing it overflows the bar, which
48 + //! which is [`quasi_router::Meter`] -- with the reader's sales as `done` and
49 + //! the crossover as `total`, so passing it overflows the bar, which
50 50 //! [`layout::Meter::done`] names as the case worth drawing. `Scale` goes with
51 - //! the partial.
51 + //! the partial, and [`crate::fee_calculator::Crossover`] carries the two counts
52 + //! the meter is drawn from, already whole.
52 53 //!
53 54 //! # Two deliberate parity differences
54 55 //!
@@ -69,7 +70,7 @@
69 70
70 71 use makeover_layout as layout;
71 72 use quasi_declare::declare;
72 - use quasi_router::{Action, Choice, Consult, Document, Meter, Node, Request, Response, RouteError};
73 + use quasi_router::{Action, Choice, Consult, Document, Node, Request, Response, RouteError};
73 74 use quasi_webview::Webview;
74 75
75 76 use crate::Billing;
@@ -525,26 +526,6 @@
525 526 }
526 527 }
527 528
528 - /// Where the reader's volume sits against the crossover, as a proportion.
529 - ///
530 - /// A supplier for two reasons and both are recorded rather than worked around.
531 - /// `meter` is a **setting** on `Row` (`quasi_router::Row::meter`) and an ident
532 - /// in a declaration body is a member if it is in the member list and a setting
533 - /// if it is not, so the name cannot mean both -- the fourth instance of the
534 - /// ruling `token` produced, and quasicoherent `e2030032` is where it is being
535 - /// decided. And the two numbers are a rounding and a cast away from the
536 - /// outcome, which is arithmetic the form admits none of.
537 - fn crossover_meter(outcome: &Outcome, at: f64) -> Node {
538 - Node::Meter(
539 - Meter::new(
540 - outcome.sales_per_month.round().max(0.0) as u32,
541 - at.ceil().max(1.0) as u32,
542 - )
543 - .tone(verdict_tone(outcome.verdict))
544 - .label("sales a month to the crossover"),
545 - )
546 - }
547 -
548 529 declare! {
549 530 /// The panel the recompute replaces.
550 531 ///
@@ -597,9 +578,12 @@
597 578 // is no crossover, because there is then no set to be a proportion of,
598 579 // and the note below says why in words. An `Option` is an iterator of
599 580 // at most one.
600 - for at in outcome.crossover_sales.into_iter() {
581 + for crossover in outcome.crossover.iter() {
601 582 section "Where each one wins";
602 - include crossover_meter(outcome, at);
583 + proportion crossover.sales crossover.at {
584 + label "sales a month to the crossover";
585 + tone verdict_tone(outcome.verdict);
586 + }
603 587 }
604 588
605 589 for note in outcome.crossover_note.iter() {