Skip to content

Commit 0e6452c

Browse files
authored
Merge pull request #510 from AdaWorldAPI/claude/sleepy-cori-aRK2x
test(surreal_container): additive seam falsifier — SurrealMailboxView → VersionScheduler → KanbanMove
2 parents f7734ff + 010020d commit 0e6452c

1 file changed

Lines changed: 125 additions & 0 deletions

File tree

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//! Seam falsifier: `SurrealMailboxView` → `VersionScheduler::on_version` → `KanbanMove`.
2+
//!
3+
//! ADDITIVE. Asserts the IN-direction wiring the module doc-comments *claim*
4+
//! ("a version tick, fed to `VersionScheduler::on_version`, lowers to the next
5+
//! legal Rubicon move over a `MailboxSoaView`") actually holds end-to-end —
6+
//! driven by the REAL `SurrealMailboxView` read-glove, not a hand-rolled fake,
7+
//! across the FULL Rubicon lifecycle (the in-crate unit test covers one tick).
8+
//!
9+
//! Each test states its kill-condition: the observation that would prove the
10+
//! seam WRONG. None of these pin "current behaviour" — they pin the contract
11+
//! the doc-comments assert.
12+
13+
use lance_graph_contract::kanban::{ExecTarget, KanbanColumn};
14+
use lance_graph_contract::scheduler::{DatasetVersion, NextPhaseScheduler, VersionScheduler};
15+
use lance_graph_contract::soa_view::MailboxSoaView;
16+
use surreal_container::view::SurrealMailboxView;
17+
18+
/// One empty-column view at `phase` (the scheduler reads only `phase()` +
19+
/// `mailbox_id()` + `current_cycle()`; row columns are irrelevant to lowering).
20+
fn view_at(phase: KanbanColumn) -> SurrealMailboxView<'static> {
21+
SurrealMailboxView::from_columns(7, 5, 13, phase, &[], &[], &[], &[])
22+
}
23+
24+
/// KILL-CONDITION: if any forward tick lowers to a column the Rubicon DAG does
25+
/// not sanction (`can_transition_to` == false), the scheduler is mis-wired.
26+
/// Walks the whole canonical arc through the real view.
27+
#[test]
28+
fn full_rubicon_arc_lowers_to_legal_successors() {
29+
let scheduler = NextPhaseScheduler;
30+
// The canonical forward arc the doc-comment names.
31+
let arc = [
32+
(KanbanColumn::Planning, KanbanColumn::CognitiveWork),
33+
(KanbanColumn::CognitiveWork, KanbanColumn::Evaluation),
34+
(KanbanColumn::Evaluation, KanbanColumn::Commit),
35+
(KanbanColumn::Plan, KanbanColumn::Planning), // re-deliberate
36+
];
37+
for (i, (from, want_to)) in arc.iter().enumerate() {
38+
let mv = scheduler
39+
.on_version(&view_at(*from), DatasetVersion(i as u64 + 1), ExecTarget::Native)
40+
.unwrap_or_else(|| panic!("{from:?} must schedule a forward move"));
41+
assert_eq!(mv.from, *from, "move.from must echo the observed phase");
42+
assert_eq!(mv.to, *want_to, "{from:?} must lower to {want_to:?}");
43+
// The DAG itself must sanction the emitted edge — the falsifier.
44+
assert!(
45+
from.can_transition_to(mv.to),
46+
"scheduler emitted an illegal Rubicon edge {from:?}->{:?}",
47+
mv.to
48+
);
49+
}
50+
}
51+
52+
/// KILL-CONDITION: an absorbing column (`Commit`/`Prune`) is cycle-end — it must
53+
/// schedule NOTHING. If `on_version` returns `Some` here, the lifecycle would
54+
/// never terminate (a mailbox past Commit would keep being advanced).
55+
#[test]
56+
fn absorbing_columns_schedule_no_move() {
57+
let scheduler = NextPhaseScheduler;
58+
for phase in [KanbanColumn::Commit, KanbanColumn::Prune] {
59+
assert!(phase.is_absorbing(), "{phase:?} must be absorbing (precondition)");
60+
assert!(
61+
scheduler
62+
.on_version(&view_at(phase), DatasetVersion(99), ExecTarget::Native)
63+
.is_none(),
64+
"{phase:?} is absorbing — it must schedule no advance"
65+
);
66+
}
67+
}
68+
69+
/// KILL-CONDITION: the Libet `-550_000 µs` readiness-potential anchor is stamped
70+
/// ONLY on the Planning→CognitiveWork Σ-commit crossing. If any other tick
71+
/// carries a non-zero offset (or that crossing carries zero), the Libet anchor
72+
/// is mis-placed.
73+
#[test]
74+
fn libet_anchor_only_on_sigma_commit_crossing() {
75+
let scheduler = NextPhaseScheduler;
76+
77+
let crossing = scheduler
78+
.on_version(&view_at(KanbanColumn::Planning), DatasetVersion(1), ExecTarget::Native)
79+
.expect("Planning advances");
80+
assert_eq!(crossing.to, KanbanColumn::CognitiveWork);
81+
assert_eq!(
82+
crossing.libet_offset_us, -550_000,
83+
"the Σ-commit crossing must carry the -550ms Libet anchor"
84+
);
85+
86+
for from in [KanbanColumn::CognitiveWork, KanbanColumn::Evaluation, KanbanColumn::Plan] {
87+
let mv = scheduler
88+
.on_version(&view_at(from), DatasetVersion(2), ExecTarget::Native)
89+
.expect("non-absorbing column advances");
90+
assert_eq!(
91+
mv.libet_offset_us, 0,
92+
"{from:?} is not the Σ-commit crossing — Libet offset must be 0"
93+
);
94+
}
95+
}
96+
97+
/// KILL-CONDITION: the scheduler is a pure function of (view, version, exec).
98+
/// Same inputs MUST yield the same move — the determinism the whole
99+
/// version-tick → lifecycle mechanism stands on. A difference proves hidden
100+
/// state leaked in.
101+
#[test]
102+
fn lowering_is_deterministic() {
103+
let scheduler = NextPhaseScheduler;
104+
let a = scheduler
105+
.on_version(&view_at(KanbanColumn::CognitiveWork), DatasetVersion(7), ExecTarget::Jit)
106+
.expect("advances");
107+
let b = scheduler
108+
.on_version(&view_at(KanbanColumn::CognitiveWork), DatasetVersion(7), ExecTarget::Jit)
109+
.expect("advances");
110+
assert_eq!(a, b, "same (view, version, exec) must lower to the same move");
111+
}
112+
113+
/// KILL-CONDITION: the `exec` backend selector must ride through the lowering
114+
/// onto the emitted move unchanged (it names where the precipitated plan runs).
115+
/// If it is dropped or rewritten, the planner's execution-target choice is lost.
116+
#[test]
117+
fn exec_target_rides_onto_the_move() {
118+
let scheduler = NextPhaseScheduler;
119+
for exec in [ExecTarget::Native, ExecTarget::Jit, ExecTarget::SurrealQl, ExecTarget::Elixir] {
120+
let mv = scheduler
121+
.on_version(&view_at(KanbanColumn::Planning), DatasetVersion(3), exec)
122+
.expect("advances");
123+
assert_eq!(mv.exec, exec, "exec target must survive the lowering");
124+
}
125+
}

0 commit comments

Comments
 (0)