From 18b6f5456f0000f3a8e45f2c139e7fbee284e154 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 11 Jul 2026 20:48:39 -0700 Subject: [PATCH] Assert authored plot routes surface, not exact totals Two tests pinned Marcus's Debt route count to exactly two, so any general (Schema 2) plot whose matcher also covered custodian+Debt broke the lib gate and forced a Rust/test edit. That contradicted the plot contributor contract ("adding a plot needs no Rust registry edit") and the general-by-default principle. The tests now assert that Marcus's two authored routes surface (present, enabled, interpolated, priced) and that queued-category alternates stay visible-and-disabled (>= 2), rather than asserting exact totals. Defense: honors wiki/mechanics/plots.md's content-only contributor contract and the plot-author general-by-default rule. A bespoke character's authored routes are still guaranteed to surface; general plots may now add routes to a covered category without editing Rust. plots.md carries the 2026-07-12 covered-category amendment. Test-and-doc change only; no runtime behavior change. --- crates/misaligned-core/src/actions.rs | 39 ++++++++++++++++++++---- wiki/log/2026-07-12-plot-count-intent.md | 32 +++++++++++++++++++ wiki/log/DEVLOG.md | 5 +++ wiki/mechanics/plots.md | 9 ++++++ 4 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 wiki/log/2026-07-12-plot-count-intent.md diff --git a/crates/misaligned-core/src/actions.rs b/crates/misaligned-core/src/actions.rs index da0910ef..988fa07a 100644 --- a/crates/misaligned-core/src/actions.rs +++ b/crates/misaligned-core/src/actions.rs @@ -2950,11 +2950,35 @@ mod tests { .iter() .filter(|a| matches!(a.command, ActionCommand::StartPlot { person: 0, .. })) .collect(); - assert_eq!(plots.len(), 2, "Marcus exposes both authored debt routes"); - assert!(plots.iter().all(|plot| plot.enabled())); - assert!(plots.iter().all(|plot| !plot.verb.contains("{target}"))); - assert!(plots.iter().all(|plot| plot.verb.contains("Marcus Webb"))); - assert!(plots.iter().any(|plot| { + // Both authored Marcus debt routes must surface. A general plot whose + // matcher also covers Marcus's category may add further routes, so this + // asserts the authored pair is present rather than the exact total. + let marcus_routes: Vec<_> = plots + .iter() + .filter(|a| { + matches!( + &a.command, + ActionCommand::StartPlot { plot_id, .. } if plot_id.starts_with("marcus-") + ) + }) + .collect(); + assert_eq!( + marcus_routes.len(), + 2, + "both authored Marcus debt routes surface" + ); + assert!(marcus_routes.iter().all(|plot| plot.enabled())); + assert!( + marcus_routes + .iter() + .all(|plot| !plot.verb.contains("{target}")) + ); + assert!( + marcus_routes + .iter() + .all(|plot| plot.verb.contains("Marcus Webb")) + ); + assert!(marcus_routes.iter().any(|plot| { plot.cost == ActionCost::Plot { thought: Sim::thought_tokens_for_cost(5.0), @@ -3020,7 +3044,10 @@ mod tests { .iter() .filter(|action| matches!(action.command, ActionCommand::StartPlot { person: 0, .. })) .collect(); - assert_eq!(plots.len(), 2, "the authored alternatives stay legible"); + // Every alternate route for the person stays visible and disabled while + // one reservoir is pending. General plots covering the category add + // further disabled rows, so assert the pair-or-more, not an exact total. + assert!(plots.len() >= 2, "the authored alternatives stay legible"); assert!(plots.iter().all(|plot| { plot.disabled_reason .as_deref() diff --git a/wiki/log/2026-07-12-plot-count-intent.md b/wiki/log/2026-07-12-plot-count-intent.md new file mode 100644 index 00000000..795c28a4 --- /dev/null +++ b/wiki/log/2026-07-12-plot-count-intent.md @@ -0,0 +1,32 @@ +# Plot route-count tests assert authored intent, not exact totals + +``` +Type: log +``` + +- **Intent:** resolve the contradiction filed as issue #8 — the plot-author + contract promises content-only additions ("adding a plot needs no Rust + registry edit", plots.md), but two tests in `crates/misaligned-core/src/actions.rs` + hard-asserted Marcus's Debt route count as exactly two, so any general plot + whose matcher also covered custodian+Debt broke the lib gate and forced a + Rust/test edit. Surfaced by the `looming-bill-absorbed` plot PR, which had to + silently exclude custodian to stay green. +- **Decision:** Cameron chose to loosen the tests (issue #8 option 1) and widen + the plot to include custodian. +- **Changed:** `person_actions_stage_with_knowledge` now filters the person's + plot routes to the authored `marcus-` routes and asserts that pair is present, + enabled, interpolated, and correctly priced, instead of asserting the person's + total route count is exactly two. `queued_plot_disables_every_alternate_route_for_that_person` + asserts `>= 2` visible-and-disabled alternates rather than exactly two, since a + general route in a queued category adds another disabled row. `sink_readouts` + stays two (one started plot plus the pre-opened Ears reservoir). Amended + `wiki/mechanics/plots.md` with the 2026-07-12 covered-category note. +- **Runtime impact:** none — test and doc change only; no behavior change. +- **Checks:** `./tools/check.sh --lib` (349 core tests pass). +- **Defense:** honors the plot contributor contract in `wiki/mechanics/plots.md` + ("adding a plot needs no Rust registry edit") and the general-by-default + principle in the plot-author skill: a bespoke character's authored routes are + guaranteed to surface, while general plots may add routes to the same category + without editing Rust. The tests now encode that intent rather than a brittle + total that made general-by-default fail the gate. +``` diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index 2844bff3..510fc8c9 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -21,6 +21,11 @@ add or amend a session log, then re-run the generator. - Intent: (see session log) - Log: [wiki/log/2026-07-12-sim-decomposition-persistence.md](2026-07-12-sim-decomposition-persistence.md) +## 2026-07-12 - Plot route-count tests assert authored intent, not exact totals + +- Intent: (see session log) +- Log: [wiki/log/2026-07-12-plot-count-intent.md](2026-07-12-plot-count-intent.md) + ## 2026-07-12 - People as mobile token nodes: the person-carrier projection - Intent: (see session log) diff --git a/wiki/mechanics/plots.md b/wiki/mechanics/plots.md index 8838547b..d69d7b15 100644 --- a/wiki/mechanics/plots.md +++ b/wiki/mechanics/plots.md @@ -76,6 +76,15 @@ Status note: direction adopted 2026-07-10 from Cameron's response to the HAL used retired `target` / `entry.target_leverage` fields and made every fresh `Sim` fail catalog validation; the corpus gate and catalog tests cover the repaired file. + 2026-07-12 covered-category repair: a general (Schema 2) plot whose matcher + also covers a named character's authored category is a legitimate content-only + addition. Category-coverage tests assert that the authored routes for that + character surface (present, enabled, correctly priced), not that the + character's total route count is exactly N, so adding a general route to a + covered category does not force a Rust/test edit. This keeps the "adding a + plot needs no Rust registry edit" contract literally true for covered + categories and preserves general-by-default: a bespoke character may surface + general routes alongside their authored ones. Stage: B1 — The Basement Work order: plots Work priority: 60 -- 2.51.2