core/tests/test_workbench_tour.py
Shay 7cf78d97e0 feat(workbench): Wave M D1+D2 — guided determinism tour (provider-agnostic)
The "they'd want to use it" first-run surface: a curated narrative that makes
the engine's discipline legible to a newcomer — bring a claim from any model and
watch it get decided, refused, or replayed. Proposer authority ignored.

Honest by construction (the risk with a narrative surface is theater):
  - workbench/tour.py determinism_tour() is a curated ordered narrative BOUND to
    the real demo registry. Intro (provider-agnostic thesis) → three demo steps
    (deductive entailment decides only on engine+oracle agreement; epistemic
    truth-state refuses a wrong proposer; proof-carrying promotion ignores
    proposer authority) → payoff (replay-to-same-hash + the citable evidence
    bundle).
  - Each demo step's what_this_proves / what_this_does_not_prove cards and the
    demo title are PULLED FROM THE REAL DEMO SPEC — never re-authored — so the
    tour can never claim more than the demo it points at.
  - A step referencing a missing demo FAILS CLOSED (KeyError), not a dead link.
    Tests assert both (cards == spec; phantom demo raises).

Backend: schemas.py DeterminismTour/TourStep; GET /tour. schema-snapshot regen.
Frontend: /tour route registered in the registry (Determinism section, 14
routes; nav/palette/guide counts updated); TourRoute — thesis hero + ordered
step cards with the honesty cards + links to the real demos / replay.

Validation: 140 workbench Python tests incl. tour drift guards; 472/472 frontend
incl. routes/routeConformance/routes.docs (guide↔registry), Shell+palette counts
(14), schemaDrift, and the tour UI test; pnpm build clean; git diff --check
clean. No serving-path imports.
2026-06-13 19:39:41 -07:00

56 lines
2.1 KiB
Python

"""D1/D2 guided determinism tour — honesty + drift guards.
The tour is authored narrative, so the load-bearing guarantee is that it cannot
drift from the real demos: every demo step binds to a registered demo, the
honesty cards come from the demo spec (never re-authored), and a phantom demo id
fails closed rather than becoming a dead link.
"""
from __future__ import annotations
import pytest
from workbench.readers import DEMO_SPECS
from workbench.tour import _build_tour, determinism_tour
def test_every_demo_step_binds_to_a_registered_demo() -> None:
tour = determinism_tour()
demo_ids = [step.demo_id for step in tour.steps if step.demo_id is not None]
assert demo_ids, "tour should reference at least one real demo"
for demo_id in demo_ids:
assert demo_id in DEMO_SPECS
def test_honesty_cards_come_from_the_spec_not_re_authored() -> None:
# If a tour step re-worded what a demo proves, this fails — the tour can
# never claim more (or less) than the demo it points at.
for step in determinism_tour().steps:
if step.demo_id is None:
continue
spec = DEMO_SPECS[step.demo_id]
assert step.what_this_proves == spec.what_this_proves
assert step.what_this_does_not_prove == spec.what_this_does_not_prove
assert step.demo_title == spec.title
def test_non_demo_steps_carry_no_demo_claims() -> None:
for step in determinism_tour().steps:
if step.kind == "demo":
continue
assert step.demo_id is None
assert step.what_this_proves is None
assert step.what_this_does_not_prove is None
def test_phantom_demo_fails_closed() -> None:
with pytest.raises(KeyError, match="unknown demo"):
_build_tour((("x", "demo", "h", "n", "no_such_demo", "/x"),))
def test_steps_are_ordered_and_thesis_is_present() -> None:
tour = determinism_tour()
assert tour.schema_version == "determinism_tour_v1"
assert [step.order for step in tour.steps] == list(range(len(tour.steps)))
# D2 provider-agnostic framing is present and explicit.
assert "proposing model" in tour.thesis.lower() or "any model" in tour.thesis.lower()