//! Regression pin: the canonical docs must stay present-tense-honest. //! //! `docs/DESIGN.md` (and `docs/PROSE_ROUNDTRIP.md`) must not assert //! something exists/works/changed that does not. This pin fails if any //! swept-and-corrected Wunschdenken / post-mortem string reappears, or //! if any present-tense corrected anchor (incl. the protected //! honest-reserved exceptions) is dropped. Matching is //! whitespace-normalised so the assertions are independent of the //! docs' hard line-wrap. Companion to `effect_doc_honesty_pin.rs` and //! to Sweep 5 of `bench/architect_sweeps.sh`. use std::fs; fn read(rel: &str) -> String { let p = concat!(env!("CARGO_MANIFEST_DIR"), "/../../"); fs::read_to_string(format!("{p}{rel}")) .unwrap_or_else(|e| panic!("read {rel}: {e}")) } /// Collapse every whitespace run (incl. newline + indent) to a single /// space, so a phrase split across the docs' hard line-wrap still /// matches a single-line assertion substring. fn norm(s: &str) -> String { s.split_whitespace().collect::>().join(" ") } #[test] fn design_md_has_no_wunschdenken() { let d = norm(&read("docs/DESIGN.md")); assert!(!d.contains("is on the path to retirement"), "DESIGN.md: Boehm retirement is forward intent — it lives in docs/roadmap.md, not DESIGN.md"); assert!(!d.contains("Will back `Show Float`"), "DESIGN.md: 'Will back Show Float' asserts a future capability as fact"); assert!(!d.contains("codegen ships in a future iter"), "DESIGN.md: float_to_str codegen is reserved/not-yet-shipped, not a promised future ship"); assert!(!d.contains("may land in a future iteration"), "DESIGN.md: auto-derivation 'may land in a future iteration' is Wunschdenken"); assert!(!d.contains("If/when concurrency arrives"), "DESIGN.md: 'if/when concurrency arrives … will be' is forward conditional"); assert!(!d.contains("was deferred — all three layer additively"), "DESIGN.md: deferred future integration paths are roadmap intent, not DESIGN.md"); assert!(!d.contains("was deferred from milestone 22 entirely"), "DESIGN.md: 'was deferred from milestone 22 entirely … A future iter ships' is history+Wunschdenken (Task 4 Step 14 catch-all)"); assert!(!d.contains("A future iter ships the full prose projection"), "DESIGN.md: Form-B class/instance prose 'a future iter ships' is forward intent → roadmap"); } #[test] fn design_md_has_no_doc_archaeology() { let d = norm(&read("docs/DESIGN.md")); assert!(!d.contains("An earlier draft of this Decision said"), "DESIGN.md: doc-archaeology ('an earlier draft said … a follow-up replaced it') lives in docs/journals/"); assert!(!d.contains("previously all diagnostics were `Error`"), "DESIGN.md: 'previously all diagnostics were Error' is project history → docs/journals/"); assert!(!d.contains("What did change in 2026-05-13 (this milestone) is"), "DESIGN.md: 'what did change in (this milestone)' is post-mortem narrative"); assert!(!d.contains("primitives were retired 2026-05-14 in iter rpe.1"), "DESIGN.md: 'X were retired in iter Y' is history → docs/journals/"); assert!(!d.contains("were retired in iter rpe.1 (2026-05-14)"), "DESIGN.md: the second per-type-print-op retirement-narrative sentence is history"); assert!(!d.contains("originally listed here as the eighth fixture, was retired"), "DESIGN.md: 'originally listed … was retired by milestone X' is doc-archaeology"); } #[test] fn design_md_present_tense_anchors_present() { let d = norm(&read("docs/DESIGN.md")); // the discriminator meta-subsection (Task 3) assert!(d.contains("the honesty rule it holds itself to"), "DESIGN.md must carry the discriminator meta-subsection heading"); assert!(d.contains("whether the document asserts something exists, works, or changed that does not"), "DESIGN.md discriminator must state the operational test"); // protected honest-reserved exceptions — over-correction guard assert!(d.contains("`Diverge` is a reserved effect name with no op and no codegen"), "the gold-form honest-reserved anchor must remain (do not over-strip)"); assert!(d.contains("Regions were considered and rejected"), "the present-tense design-rationale exclusion must remain (do not over-strip)"); assert!(d.contains("a tiebreaker, not a rationale"), "the self-labelled tiebreaker is honest and stays (do not over-strip)"); // corrected present-tense anchors (Task 4) assert!(d.contains("`--alloc=gc` selects the transitional Boehm backend"), "DESIGN.md must describe Boehm present-tense, not as 'on the path to retirement'"); assert!(d.contains("type-installed; codegen is reserved and not yet shipped"), "float_to_str must be present-tense honest-reserved"); assert!(d.contains("AILang demands annotations *because* the LLM author can produce them effortlessly"), "the 'does not infer everything' bullet must be present-tense (no doc-archaeology)"); assert!(d.contains("`io/print_str` is the only built-in direct-output effect-op"), "the print-op set must be stated present-tense, not as a retirement narrative"); assert!(d.contains("the render in `crates/ailang-prose/src/lib.rs` is a placeholder and informational only"), "the Form-B class/instance prose-projection state must be present-tense (Task 4 Step 14 catch-all)"); } #[test] fn prose_roundtrip_md_has_no_wunschdenken() { let p = norm(&read("docs/PROSE_ROUNDTRIP.md")); assert!(!p.contains("A future iter may layer a tool-use schema"), "PROSE_ROUNDTRIP.md: tool-use/MCP forward intent lives in docs/roadmap.md"); assert!(p.contains("the lowest-common-denominator cycle and always works with any client"), "PROSE_ROUNDTRIP.md must close present-tense on the static-prompt path"); }