1use crate::semantic_work::{ExecutionWork, ModelWorkEvent, ModelWorkKind, ModelWorkRecording};
8mod learning_phase;
9#[cfg(feature = "semantic-policy")]
10mod model_evaluation;
11mod prepared_replay;
12pub use learning_phase::{
13 SemanticLearningCopyReset, SemanticLearningPhase, SemanticLearningPhaseRecord,
14 SemanticLearningPhaseTransition,
15};
16#[cfg(feature = "semantic-policy")]
17pub use model_evaluation::{
18 SemanticCompletedModelEvaluation, SemanticEvaluationCohort, SemanticModelEvaluation,
19 SemanticModelEvaluationResult,
20};
21#[cfg(feature = "semantic-policy")]
22pub use prepared_replay::SemanticCompletedReplayMaterials;
23use prepared_replay::{PreparedReplayCustody, PreparedReplayDescriptor};
24use sha2::{Digest, Sha256};
25use std::{
26 collections::{BTreeMap, BTreeSet},
27 fmt,
28 mem::size_of,
29 sync::Arc,
30};
31
32use cudarc::driver::sys;
33use xlog_core::{Result as XlogResult, XlogError};
34
35use crate::cuda_graph::CapturedCudaGraph;
36use crate::dlpack::DlpackManagedTensor;
37use crate::launch::{CudaEnqueue, LaunchEnqueueError, LaunchRecorder};
38use crate::memory::TrackedCudaSlice;
39use crate::memory::{
40 CudaColumn, DeviceAllocationProvenance, DeviceMemoryView, DeviceRead, GpuMemoryReservation,
41};
42use crate::provider::resident_schedule::{validate_execution_domain, ResidentExecutionDomain};
43use crate::semantic_hypergraph::{
44 material_bytes, material_u32, material_u64, SemanticMaterialReader, SemanticRootMaterial,
45};
46#[cfg(feature = "semantic-policy")]
47use crate::semantic_hypergraph::{
48 material_statement_key, SemanticStatementIdentity, SemanticSupportIdentity,
49};
50#[cfg(feature = "semantic-policy")]
51use crate::semantic_training_view::SemanticTrainingCanaryRefusalReason;
52use crate::semantic_training_view::{
53 frozen_training_coefficients, SemanticSelectedTrainingView,
54 SemanticTrainingCanaryRefusalRecord, SemanticTrainingCanaryResultRecord,
55 SemanticTrainingDomain, SemanticTrainingObjective, SemanticTrainingViewArena,
56 SemanticTrainingViewOrigin, SemanticTrainingViewOriginRecord, SemanticTrainingViewPort,
57 SemanticTrainingViewRow, SemanticTrainingViewSelection,
58};
59use crate::{
60 CudaFunction, CudaKernelProvider, CudaStream, DeviceRepr, LaunchAsync, LaunchConfig,
61 SemanticAdmission, SemanticAdmissionLimits, SemanticAdmissionRecords, SemanticHypergraph,
62 SemanticHypergraphCapacities, SemanticHypergraphError, SemanticInsertOutcome,
63 SemanticRecordRole, SemanticRootHandle, SemanticRootSnapshot,
64};
65
66#[cfg(feature = "semantic-policy")]
67type PreparedPolicyStorage = (
68 PolicyBuffers,
69 TrackedCudaSlice<u8>,
70 TrackedCudaSlice<SemanticTransitionReceipt>,
71 TrackedCudaSlice<DeviceState>,
72);
73
74#[repr(transparent)]
76#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
77pub struct Identity256([u8; 32]);
78
79impl Identity256 {
80 pub const fn from_bytes(bytes: [u8; 32]) -> Self {
81 Self(bytes)
82 }
83 pub const fn as_bytes(&self) -> &[u8; 32] {
84 &self.0
85 }
86}
87
88pub trait SemanticTaskProgram: fmt::Debug + Send + Sync {
95 fn editable_program(&self) -> Option<&crate::SemanticProgramAdmission> {
98 None
99 }
100
101 fn observe(
102 &self,
103 provider: Arc<CudaKernelProvider>,
104 ) -> Result<SemanticTaskObservation, SemanticTransitionError>;
105}
106
107pub struct SemanticTaskObservation {
110 pub program_source: Vec<u8>,
111 pub input_bytes: Vec<u8>,
112 pub result_bytes: Vec<u8>,
113 pub expected_truth: [crate::SemanticTruth; 3],
114}
115
116#[derive(Clone, Copy, Debug, PartialEq, Eq)]
122pub struct SemanticTaskContentIdentity {
123 pub query: Identity256,
124 pub theory_program: Identity256,
125 pub result: Identity256,
126}
127
128#[derive(Clone, Copy, Debug, PartialEq, Eq)]
132pub struct SemanticTaskScoring {
133 pub correct_weight: u32,
134 pub all_correct_weight: u32,
135 pub work_weight: u32,
136 pub improvement_weight: u32,
137 pub refusal_weight: u32,
138 pub spent_weight: u32,
139}
140
141#[derive(Clone, Copy, Debug, PartialEq, Eq)]
145pub struct SemanticStructuralCostDescriptor {
146 pub unit: Identity256,
147 pub cap: u64,
148}
149
150#[derive(Clone, Copy, Debug, PartialEq)]
153pub struct SemanticTaskObjectiveLaw {
154 pub return_bound: i64,
155 pub evaluator_min: f64,
156 pub evaluator_max: f64,
157 pub coefficients: [f32; 9],
158 pub structural_cost: SemanticStructuralCostDescriptor,
159}
160
161impl SemanticTaskObjectiveLaw {
162 fn require_objective(
163 self,
164 objective: &SemanticTrainingObjective,
165 ) -> Result<(), SemanticTransitionError> {
166 if objective.evaluator_min.to_bits() != self.evaluator_min.to_bits()
167 || objective.evaluator_max.to_bits() != self.evaluator_max.to_bits()
168 || objective.coefficients.map(f32::to_bits) != self.coefficients.map(f32::to_bits)
169 || objective.cost_unit != self.structural_cost.unit
170 || objective.cost_cap != self.structural_cost.cap
171 {
172 return Err(publication_input_error(
173 "training objective differs from the evaluator, coefficients or cost law frozen before actions",
174 ));
175 }
176 Ok(())
177 }
178}
179
180pub fn semantic_structural_cost_descriptor(
182 editable_program: bool,
183) -> SemanticStructuralCostDescriptor {
184 let (support_cap, truth_change_cap) = if editable_program {
185 (
186 crate::semantic_program::RESIDENT_PROGRAM_FACT_CAPACITY as u64,
187 3u64,
188 )
189 } else {
190 (2u64, 2u64)
191 };
192 let cap = 2 + support_cap + truth_change_cap;
193 let mut hash = Sha256::new();
194 hash.update(b"xlog.semantic.structural-cost.v1\0");
195 for word in [
196 u64::from(editable_program),
197 2,
198 support_cap,
199 truth_change_cap,
200 cap,
201 ] {
202 hash.update(word.to_le_bytes());
203 }
204 SemanticStructuralCostDescriptor {
205 unit: Identity256::from_bytes(hash.finalize().into()),
206 cap,
207 }
208}
209
210#[derive(Clone, Copy, Debug, PartialEq, Eq)]
214pub struct SemanticTaskPriorityGoal {
215 pub query: u8,
216 pub target_truth: u8,
217 pub weight: u32,
218}
219
220#[derive(Clone, Debug, PartialEq, Eq)]
221pub struct SemanticTaskPriorityLevel {
222 pub goals: Vec<SemanticTaskPriorityGoal>,
223}
224
225impl SemanticTaskScoring {
226 fn words(self) -> [u64; 6] {
227 [
228 self.correct_weight,
229 self.all_correct_weight,
230 self.work_weight,
231 self.improvement_weight,
232 self.refusal_weight,
233 self.spent_weight,
234 ]
235 .map(u64::from)
236 }
237
238 fn return_bound(self, editable_program: bool) -> Result<i64, SemanticTransitionError> {
239 let max_cost = u128::from(semantic_structural_cost_descriptor(editable_program).cap);
245 let max_spent = if editable_program { 19 } else { 17 };
246 let value_span = 3 * u128::from(self.correct_weight)
247 + u128::from(self.all_correct_weight)
248 + max_cost * u128::from(self.work_weight);
249 i64::try_from(value_span)
250 .map_err(|_| publication_input_error("task value can overflow signed arithmetic"))?;
251 let return_bound = value_span * u128::from(self.improvement_weight)
252 + 2 * u128::from(self.refusal_weight)
253 + max_spent * u128::from(self.spent_weight);
254 i64::try_from(return_bound)
255 .map_err(|_| publication_input_error("task scoring can overflow the signed return"))
256 }
257
258 fn validate(self, editable_program: bool) -> Result<(), SemanticTransitionError> {
259 self.return_bound(editable_program).map(|_| ())
260 }
261
262 fn objective_law(
263 self,
264 editable_program: bool,
265 ) -> Result<SemanticTaskObjectiveLaw, SemanticTransitionError> {
266 let return_bound = self.return_bound(editable_program)?;
267 let mut evaluator_max = return_bound as f64;
268 if (evaluator_max as u128) < return_bound as u128 {
271 evaluator_max = f64::from_bits(evaluator_max.to_bits() + 1);
272 }
273 let evaluator_min = -evaluator_max;
274 Ok(SemanticTaskObjectiveLaw {
275 return_bound,
276 evaluator_min,
277 evaluator_max,
278 coefficients: frozen_training_coefficients(evaluator_min, evaluator_max),
279 structural_cost: semantic_structural_cost_descriptor(editable_program),
280 })
281 }
282
283 #[cfg(feature = "semantic-policy")]
284 fn completed_law_bytes(
285 self,
286 task_identity: Identity256,
287 editable_program: bool,
288 ) -> Result<Vec<u8>, SemanticTransitionError> {
289 let mut bytes = b"XLOG-TASK-SCORING-LAW\0".to_vec();
290 material_u64(&mut bytes, 2);
291 bytes.extend_from_slice(task_identity.as_bytes());
292 let structural_cost = semantic_structural_cost_descriptor(editable_program);
293 bytes.extend_from_slice(structural_cost.unit.as_bytes());
294 material_u64(&mut bytes, structural_cost.cap);
295 for weight in self.words() {
296 material_u64(&mut bytes, weight);
297 }
298 bytes.extend_from_slice(&self.return_bound(editable_program)?.to_le_bytes());
299 Ok(bytes)
300 }
301}
302
303fn checkpoint_scoring_law_identity(
304 scoring: SemanticTaskScoring,
305 task_content: SemanticTaskContentIdentity,
306 objective_law: SemanticTaskObjectiveLaw,
307 training_domain: Option<&SemanticTrainingDomain>,
308) -> Identity256 {
309 let mut hash = Sha256::new();
310 hash.update(b"xlog.semantic.checkpoint.scoring-law.v4\0");
311 for identity in [
314 task_content.query,
315 task_content.theory_program,
316 task_content.result,
317 ] {
318 hash.update(identity.as_bytes());
319 }
320 for weight in scoring.words() {
321 hash.update(weight.to_le_bytes());
322 }
323 hash.update(objective_law.return_bound.to_le_bytes());
324 hash.update(objective_law.structural_cost.unit.as_bytes());
325 hash.update(objective_law.structural_cost.cap.to_le_bytes());
326 hash.update(objective_law.evaluator_min.to_bits().to_le_bytes());
327 hash.update(objective_law.evaluator_max.to_bits().to_le_bytes());
328 for coefficient in objective_law.coefficients {
329 hash.update(coefficient.to_bits().to_le_bytes());
330 }
331 hash.update([u8::from(training_domain.is_some())]);
332 if let Some(domain) = training_domain {
333 hash.update(domain.identity().as_bytes());
334 }
335 Identity256::from_bytes(hash.finalize().into())
336}
337
338#[cfg(feature = "semantic-policy")]
339#[expect(
340 clippy::too_many_arguments,
341 reason = "completed scoring checks independent task, work, refusal, and result fields"
342)]
343fn validate_completed_task_scoring(
344 scoring: SemanticTaskScoring,
345 editable_program: bool,
346 priority_levels: &[SemanticTaskPriorityLevel],
347 facts: &[SemanticTaskFacts; 3],
348 work: &[SemanticTransitionWork; 2],
349 lane_refusal: [u64; 2],
350 query_count: u64,
351 winner: u64,
352 return_value: i64,
353) -> bool {
354 if scoring.validate(editable_program).is_err()
355 || query_count > 9
356 || winner > 2
357 || lane_refusal.iter().any(|&refusal| refusal > 4)
358 || (!editable_program && lane_refusal.iter().any(|&refusal| refusal >= 3))
359 || work.iter().any(|work| !work.is_valid(editable_program))
360 || facts
361 .iter()
362 .any(|facts| facts.g > 3 || facts.p > 1 || facts.eligible > 1)
363 {
364 return false;
365 }
366 for (slot, facts) in facts.iter().enumerate() {
367 let measured = if slot == 0 {
368 0
369 } else {
370 let work = work[slot - 1];
371 work.raw_structural_cost()
372 };
373 let value = i128::from(scoring.correct_weight) * i128::from(facts.g)
374 + i128::from(scoring.all_correct_weight) * i128::from(facts.p)
375 - i128::from(scoring.work_weight) * i128::from(measured);
376 if facts.c != measured || i128::from(facts.v) != value {
377 return false;
378 }
379 }
380 let mut selected = 0;
381 for slot in 1..3 {
382 if facts[slot].eligible == 1
383 && (facts[selected].eligible == 0
384 || task_candidate_better(priority_levels, facts, slot, selected))
385 {
386 selected = slot;
387 }
388 }
389 if winner as usize != selected || facts[selected].eligible != 1 {
390 return false;
391 }
392 let refusals = lane_refusal.iter().filter(|&&refusal| refusal != 0).count() as i128;
393 let spent = i128::from(query_count)
394 + work
395 .iter()
396 .enumerate()
397 .filter(|(lane, _)| lane + 1 != selected)
398 .map(|(_, work)| i128::from(work.edit_commands + work.defined_truth_changes))
399 .sum::<i128>();
400 let expected_return = i128::from(scoring.improvement_weight)
401 * (i128::from(facts[selected].v) - i128::from(facts[0].v))
402 - i128::from(scoring.refusal_weight) * refusals
403 - i128::from(scoring.spent_weight) * spent;
404 i128::from(return_value) == expected_return
405}
406
407#[cfg(feature = "semantic-policy")]
408fn task_candidate_better(
409 priority_levels: &[SemanticTaskPriorityLevel],
410 facts: &[SemanticTaskFacts; 3],
411 candidate: usize,
412 incumbent: usize,
413) -> bool {
414 for level in priority_levels {
415 let score = |slot: usize| -> i64 {
416 level
417 .goals
418 .iter()
419 .map(|goal| {
420 let query = usize::from(goal.query);
421 let target = u64::from(goal.target_truth);
422 let achieved = i64::from(facts[slot].truth[query] == target);
423 let base = i64::from(facts[0].truth[query] == target);
424 i64::from(goal.weight) * (achieved - base)
425 })
426 .sum()
427 };
428 let candidate_score = score(candidate);
429 let incumbent_score = score(incumbent);
430 if candidate_score != incumbent_score {
431 return candidate_score > incumbent_score;
432 }
433 }
434 facts[candidate].g > facts[incumbent].g
435 || (facts[candidate].g == facts[incumbent].g && facts[candidate].c < facts[incumbent].c)
436}
437
438#[derive(Clone, Debug)]
443pub struct SemanticTaskEvaluationSpec {
444 pub statement_records: [u32; 3],
446 pub allowed_support_records: Vec<u32>,
448 pub program: Arc<dyn SemanticTaskProgram>,
449 pub scoring: SemanticTaskScoring,
450 pub priority_levels: Vec<SemanticTaskPriorityLevel>,
453 pub admissible_truth_masks: [u8; 3],
455 pub actor_eligible: bool,
458 pub training_domain: Option<SemanticTrainingDomain>,
462}
463
464#[derive(Clone, Debug, PartialEq, Eq)]
468pub struct SemanticTaskObservationRoots {
469 pub root_digest: Identity256,
471 pub root_extents: [u32; 3],
472 pub query_records: [u32; 3],
474 pub contributors: Vec<(u32, Option<u32>, u32)>,
478}
479
480#[derive(Clone, Copy, Debug, PartialEq, Eq)]
486pub struct SemanticTaskGoalWitness {
487 pub semantic_root: Identity256,
488 pub authority_root: Identity256,
489 pub mandatory_links_root: Identity256,
490 pub constraints_root: Identity256,
491 pub mandatory_link_count: u64,
492 pub constraint_count: u64,
493}
494
495impl SemanticTaskEvaluationSpec {
496 fn validate_records(
497 &self,
498 records: &SemanticAdmissionRecords,
499 ) -> Result<(), SemanticTransitionError> {
500 let invalid = |detail: &str| SemanticTransitionError::InvalidInput {
501 detail: format!("task binding: {detail}"),
502 };
503 self.scoring
504 .validate(self.program.editable_program().is_some())?;
505 if let Some(domain) = &self.training_domain {
506 domain.validate()?;
507 }
508 if self.priority_levels.len() > 3 {
509 return Err(invalid("task priorities exceed the three-query bank"));
510 }
511 let mut seen_queries = [false; 3];
512 let mut goal_count = 0usize;
513 for level in &self.priority_levels {
514 if level.goals.is_empty() {
515 return Err(invalid("task priority level must contain a goal"));
516 }
517 goal_count += level.goals.len();
518 if goal_count > 3 {
519 return Err(invalid("task priorities exceed the three-query bank"));
520 }
521 for goal in &level.goals {
522 let query = usize::from(goal.query);
523 if query >= 3 || goal.target_truth > 3 || goal.weight == 0 {
524 return Err(invalid(
525 "task priority goal has invalid query, truth or weight",
526 ));
527 }
528 if std::mem::replace(&mut seen_queries[query], true) {
529 return Err(invalid("task priority query appears more than once"));
530 }
531 if self.admissible_truth_masks[query] & (1 << goal.target_truth) == 0 {
532 return Err(invalid(
533 "task priority target is forbidden by hard truth mask",
534 ));
535 }
536 }
537 }
538 if self
539 .admissible_truth_masks
540 .iter()
541 .any(|mask| *mask == 0 || *mask & !15 != 0)
542 {
543 return Err(invalid(
544 "truth eligibility requires a nonempty four-valued mask",
545 ));
546 }
547 for index in self.statement_records {
548 let record = records
549 .records
550 .get(index as usize)
551 .ok_or_else(|| invalid("query statement is outside the admission"))?;
552 let predicate = records
553 .predicates
554 .iter()
555 .find(|predicate| predicate.predicate == record.predicate)
556 .ok_or_else(|| invalid("query predicate is outside the admission"))?;
557 if predicate.role != SemanticRecordRole::Statement {
558 return Err(invalid("query selection is not a statement"));
559 }
560 }
561 if self.allowed_support_records.len() > records.supports.len() {
562 return Err(invalid(
563 "support selections exceed the admitted support bank",
564 ));
565 }
566 for &index in &self.allowed_support_records {
567 let support = records
568 .supports
569 .get(index as usize)
570 .ok_or_else(|| invalid("support selection is outside the admission"))?;
571 if !self.statement_records.contains(&support.statement) {
572 return Err(invalid(
573 "support belongs to a statement outside the task scope",
574 ));
575 }
576 }
577 Ok(())
578 }
579}
580
581fn feedback_statement_payload(
582 records: &SemanticAdmissionRecords,
583 encoded: &[crate::semantic_hypergraph::SemanticRecordEncoding],
584 record: u32,
585) -> Result<Vec<u8>, SemanticTransitionError> {
586 let statement = records
587 .records
588 .get(record as usize)
589 .ok_or(SemanticTransitionError::InvalidTaskBank)?;
590 let mut payload = Vec::new();
591 let append = |payload: &mut Vec<u8>, index: u32| -> Result<(), SemanticTransitionError> {
592 let atom = encoded
593 .get(index as usize)
594 .ok_or(SemanticTransitionError::InvalidTaskBank)?;
595 let argument_begin = atom
600 .arguments
601 .first()
602 .map_or(atom.bytes.len(), |range| range.start);
603 let value_begin = argument_begin
604 .checked_sub(8)
605 .ok_or(SemanticTransitionError::InvalidTaskBank)?;
606 let values = atom
607 .bytes
608 .get(value_begin..)
609 .ok_or(SemanticTransitionError::InvalidTaskBank)?;
610 payload.extend_from_slice(&(values.len() as u64).to_le_bytes());
611 payload.extend_from_slice(values);
612 Ok(())
613 };
614 append(&mut payload, record)?;
615 let qualifier_count = u32::try_from(statement.qualifiers.len())
616 .map_err(|_| SemanticTransitionError::InvalidTaskBank)?;
617 payload.extend_from_slice(&qualifier_count.to_le_bytes());
618 for &qualifier in &statement.qualifiers {
619 append(&mut payload, qualifier)?;
620 }
621 Ok(payload)
622}
623
624pub(crate) struct TaskEvaluationBinding {
627 admission_identity: Identity256,
628 schema_generation: Identity256,
629 spec: SemanticTaskEvaluationSpec,
630 statements: [crate::SemanticStatementKey; 3],
631 statement_bytes: BTreeMap<u32, Vec<u8>>,
632 allowed_supports: Vec<(u32, [u8; 32])>,
633 observation: SemanticTaskObservation,
634 goal_witness: Option<SemanticTaskGoalWitness>,
635 objective_law: SemanticTaskObjectiveLaw,
636}
637
638type TaskContentSelection = (
639 [crate::SemanticStatementKey; 3],
640 BTreeMap<u32, Vec<u8>>,
641 Vec<(u32, [u8; 32])>,
642);
643
644fn task_content_selection(
645 admission: &SemanticAdmission,
646 statement_records: [u32; 3],
647 allowed_support_records: &[u32],
648) -> Result<TaskContentSelection, SemanticTransitionError> {
649 let statements = statement_records.map(|record| {
650 admission
651 .statement_key(record)
652 .map_err(SemanticTransitionError::Semantic)
653 });
654 let statements = statements.into_iter().collect::<Result<Vec<_>, _>>()?;
655 let statements: [_; 3] = statements
656 .try_into()
657 .expect("three selected task statements");
658 let mut statement_bytes = BTreeMap::new();
659 for record in statement_records {
660 statement_bytes.insert(
661 record,
662 feedback_statement_payload(admission.records(), &admission.encoded_records, record)?,
663 );
664 }
665 let mut allowed_supports = BTreeSet::new();
666 for &index in allowed_support_records {
667 let record = admission
668 .records()
669 .supports
670 .get(index as usize)
671 .ok_or(SemanticTransitionError::InvalidTaskBank)?;
672 if !statement_records.contains(&record.statement) {
673 return Err(SemanticTransitionError::InvalidTaskBank);
674 }
675 let statement = admission
676 .statement_key(record.statement)
677 .map_err(SemanticTransitionError::Semantic)?;
678 let event = admission
679 .support_event(index)
680 .map_err(SemanticTransitionError::Semantic)?;
681 allowed_supports.insert((index, *event.identity(statement.identity()).as_bytes()));
682 }
683 Ok((
684 statements,
685 statement_bytes,
686 allowed_supports.into_iter().collect(),
687 ))
688}
689
690#[expect(
691 clippy::too_many_arguments,
692 reason = "task content identity binds independent admitted and observed materials"
693)]
694fn task_content_identity(
695 admission_identity: Identity256,
696 schema_generation: Identity256,
697 statement_records: [u32; 3],
698 statements: [crate::SemanticStatementKey; 3],
699 statement_bytes: &BTreeMap<u32, Vec<u8>>,
700 allowed_supports: &[(u32, [u8; 32])],
701 observation: &SemanticTaskObservation,
702 editable: Option<&crate::SemanticProgramAdmission>,
703) -> SemanticTaskContentIdentity {
704 let append_bytes = |hash: &mut Sha256, bytes: &[u8]| {
705 hash.update((bytes.len() as u64).to_le_bytes());
706 hash.update(bytes);
707 };
708
709 let mut query = Sha256::new();
710 query.update(b"xlog.semantic.task-query.v1\0");
711 query.update((statement_records.len() as u64).to_le_bytes());
712 for (record, statement) in statement_records.into_iter().zip(statements) {
713 query.update(record.to_le_bytes());
714 query.update(statement.identity().as_bytes());
715 append_bytes(
716 &mut query,
717 statement_bytes
718 .get(&record)
719 .expect("bound query statement retains canonical bytes"),
720 );
721 }
722 append_bytes(&mut query, &observation.input_bytes);
723 let query = Identity256::from_bytes(query.finalize().into());
724
725 let mut theory_program = Sha256::new();
726 theory_program.update(b"xlog.semantic.task-theory-program.v1\0");
727 theory_program.update(admission_identity.as_bytes());
728 theory_program.update(schema_generation.as_bytes());
729 theory_program.update((allowed_supports.len() as u64).to_le_bytes());
730 for (record, support) in allowed_supports {
731 theory_program.update(record.to_le_bytes());
732 theory_program.update(support);
733 }
734 append_bytes(&mut theory_program, &observation.program_source);
735 if let Some(editable) = editable {
736 theory_program.update(b"xlog.semantic.editable-program.v1\0");
737 for word in editable.words() {
738 theory_program.update(word.to_le_bytes());
739 }
740 }
741 let theory_program = Identity256::from_bytes(theory_program.finalize().into());
742
743 let mut result = Sha256::new();
744 result.update(b"xlog.semantic.task-four-valued-result.v1\0");
745 result.update(query.as_bytes());
746 result.update(theory_program.as_bytes());
747 append_bytes(&mut result, &observation.result_bytes);
748 for truth in observation.expected_truth {
749 result.update((truth as u64).to_le_bytes());
750 }
751
752 SemanticTaskContentIdentity {
753 query,
754 theory_program,
755 result: Identity256::from_bytes(result.finalize().into()),
756 }
757}
758
759impl TaskEvaluationBinding {
760 pub(crate) fn bind(
761 admission: &SemanticAdmission,
762 spec: SemanticTaskEvaluationSpec,
763 observation: SemanticTaskObservation,
764 ) -> Result<Self, SemanticTransitionError> {
765 spec.validate_records(admission.records())?;
766 if let Some(program) = spec.program.editable_program() {
767 program
768 .validate()
769 .map_err(|detail| SemanticTransitionError::InvalidInput {
770 detail: format!("task binding: {detail}"),
771 })?;
772 }
773 let (statements, statement_bytes, allowed_supports) = task_content_selection(
774 admission,
775 spec.statement_records,
776 &spec.allowed_support_records,
777 )?;
778 if observation.program_source.is_empty() || observation.result_bytes.is_empty() {
779 return Err(publication_input_error(
780 "native task observer omitted source or result custody",
781 ));
782 }
783 let objective_law = spec
784 .scoring
785 .objective_law(spec.program.editable_program().is_some())?;
786 Ok(Self {
787 admission_identity: admission.identity(),
788 schema_generation: admission.schema_generation(),
789 spec,
790 statements,
791 statement_bytes,
792 allowed_supports,
793 observation,
794 goal_witness: None,
795 objective_law,
796 })
797 }
798
799 pub(crate) fn identity(&self) -> Identity256 {
800 let mut hash = Sha256::new();
801 hash.update(if self.spec.program.editable_program().is_some() {
802 b"xlog.semantic.task-evaluation.v12\0".as_slice()
803 } else {
804 b"xlog.semantic.task-evaluation.v11\0".as_slice()
805 });
806 hash.update(self.admission_identity.as_bytes());
807 hash.update(self.schema_generation.as_bytes());
808 hash.update((self.spec.statement_records.len() as u64).to_le_bytes());
811 for index in self.spec.statement_records {
812 hash.update(index.to_le_bytes());
813 }
814 hash.update((self.spec.allowed_support_records.len() as u64).to_le_bytes());
815 for index in &self.spec.allowed_support_records {
816 hash.update(index.to_le_bytes());
817 }
818 hash.update((self.observation.program_source.len() as u64).to_le_bytes());
819 hash.update(&self.observation.program_source);
820 hash.update((self.observation.input_bytes.len() as u64).to_le_bytes());
821 hash.update(&self.observation.input_bytes);
822 hash.update((self.observation.result_bytes.len() as u64).to_le_bytes());
823 hash.update(&self.observation.result_bytes);
824 for truth in self.observation.expected_truth {
825 hash.update((truth as u64).to_le_bytes());
826 }
827 hash.update(self.spec.admissible_truth_masks);
828 hash.update([u8::from(self.spec.actor_eligible)]);
829 for weight in self.spec.scoring.words() {
830 hash.update(weight.to_le_bytes());
831 }
832 hash.update(self.objective_law.evaluator_min.to_bits().to_le_bytes());
835 hash.update(self.objective_law.evaluator_max.to_bits().to_le_bytes());
836 for coefficient in self.objective_law.coefficients {
837 hash.update(coefficient.to_bits().to_le_bytes());
838 }
839 hash.update(self.objective_law.structural_cost.unit.as_bytes());
840 hash.update(self.objective_law.structural_cost.cap.to_le_bytes());
841 hash.update([u8::from(self.spec.training_domain.is_some())]);
842 if let Some(domain) = &self.spec.training_domain {
843 hash.update(domain.identity().as_bytes());
844 }
845 hash.update(b"xlog.semantic.task-priorities.v1\0");
846 hash.update((self.spec.priority_levels.len() as u64).to_le_bytes());
847 for level in &self.spec.priority_levels {
848 hash.update((level.goals.len() as u64).to_le_bytes());
849 for goal in &level.goals {
850 hash.update([goal.query, goal.target_truth]);
851 hash.update(goal.weight.to_le_bytes());
852 }
853 }
854 if let Some(editable) = self.spec.program.editable_program() {
855 hash.update(b"xlog.semantic.editable-program.v1\0");
856 for word in editable.words() {
857 hash.update(word.to_le_bytes());
858 }
859 }
860 for statement in self.statements {
861 hash.update(statement.identity().as_bytes());
862 }
863 hash.update((self.allowed_supports.len() as u64).to_le_bytes());
864 for (record, support) in &self.allowed_supports {
865 hash.update(record.to_le_bytes());
866 hash.update(support);
867 }
868 if let Some(witness) = self.goal_witness {
869 hash.update(b"xlog.semantic.goal-witness.v1\0");
870 hash.update(witness.semantic_root.as_bytes());
871 hash.update(witness.authority_root.as_bytes());
872 hash.update(witness.mandatory_links_root.as_bytes());
873 hash.update(witness.constraints_root.as_bytes());
874 hash.update(witness.mandatory_link_count.to_le_bytes());
875 hash.update(witness.constraint_count.to_le_bytes());
876 }
877 Identity256::from_bytes(hash.finalize().into())
878 }
879
880 pub(crate) fn content_identity(&self) -> SemanticTaskContentIdentity {
881 task_content_identity(
882 self.admission_identity,
883 self.schema_generation,
884 self.spec.statement_records,
885 self.statements,
886 &self.statement_bytes,
887 &self.allowed_supports,
888 &self.observation,
889 self.spec.program.editable_program(),
890 )
891 }
892
893 pub(crate) fn cold_content(
894 admission: &SemanticAdmission,
895 statement_records: [u32; 3],
896 allowed_support_records: &[u32],
897 editable: Option<&crate::SemanticProgramAdmission>,
898 observation: SemanticTaskObservation,
899 ) -> Result<(SemanticTaskContentIdentity, [crate::SemanticTruth; 3]), SemanticTransitionError>
900 {
901 if observation.program_source.is_empty() || observation.result_bytes.is_empty() {
902 return Err(publication_input_error(
903 "native task observer omitted source or result custody",
904 ));
905 }
906 if let Some(program) = editable {
907 program
908 .validate()
909 .map_err(|detail| SemanticTransitionError::InvalidInput {
910 detail: format!("task binding: {detail}"),
911 })?;
912 }
913 let (statements, statement_bytes, allowed_supports) =
914 task_content_selection(admission, statement_records, allowed_support_records)?;
915 let content = task_content_identity(
916 admission.identity(),
917 admission.schema_generation(),
918 statement_records,
919 statements,
920 &statement_bytes,
921 &allowed_supports,
922 &observation,
923 editable,
924 );
925 Ok((content, observation.expected_truth))
926 }
927
928 pub(crate) fn expected_truth(&self) -> [crate::SemanticTruth; 3] {
929 self.observation.expected_truth
930 }
931
932 #[cfg(feature = "semantic-policy")]
933 fn goal_witness(&self) -> Option<SemanticTaskGoalWitness> {
934 self.goal_witness
935 }
936
937 pub(crate) fn content(&self) -> (SemanticTaskContentIdentity, [crate::SemanticTruth; 3]) {
938 (self.content_identity(), self.expected_truth())
939 }
940
941 #[cfg(feature = "semantic-policy")]
942 fn completed_result_material(&self) -> SemanticCompletedStepWitnessMaterial {
943 let identities = self.content_identity();
944 let mut bytes = Vec::new();
945 bytes.extend_from_slice(b"xlog.semantic.task-four-valued-result.v1\0");
946 bytes.extend_from_slice(identities.query.as_bytes());
947 bytes.extend_from_slice(identities.theory_program.as_bytes());
948 material_u64(&mut bytes, self.observation.result_bytes.len() as u64);
949 bytes.extend_from_slice(&self.observation.result_bytes);
950 for truth in self.observation.expected_truth {
951 material_u64(&mut bytes, truth as u64);
952 }
953 SemanticCompletedStepWitnessMaterial {
954 identity: identities.result,
955 bytes,
956 }
957 }
958
959 pub(crate) fn spec(&self) -> &SemanticTaskEvaluationSpec {
960 &self.spec
961 }
962
963 pub(crate) fn priority_levels(&self) -> &[SemanticTaskPriorityLevel] {
964 &self.spec.priority_levels
965 }
966
967 pub(crate) fn words(&self, owner: u64) -> Vec<u64> {
968 let mut words = vec![6, owner];
969 words.extend(identity_words(*self.identity().as_bytes()));
970 for statement in self.statements {
971 words.extend(identity_words(*statement.identity().as_bytes()));
972 }
973 words.extend(self.observation.expected_truth.map(|truth| truth as u64));
974 words.push(self.allowed_supports.len() as u64);
975 words.extend(self.spec.statement_records.map(u64::from));
976 words.extend(self.spec.scoring.words());
977 words.extend(self.spec.admissible_truth_masks.map(u64::from));
978 for (record, support) in &self.allowed_supports {
979 words.push(u64::from(*record));
980 words.extend(identity_words(*support));
981 }
982 if let Some(witness) = self.goal_witness {
983 words.extend(identity_words(*witness.semantic_root.as_bytes()));
984 words.extend(identity_words(*witness.authority_root.as_bytes()));
985 words.extend(identity_words(*witness.mandatory_links_root.as_bytes()));
986 words.extend(identity_words(*witness.constraints_root.as_bytes()));
987 words.push(witness.mandatory_link_count);
988 words.push(witness.constraint_count);
989 } else {
990 words.extend([0; 18]);
991 }
992 words.push(u64::from(self.spec.actor_eligible));
993 words.push(self.spec.priority_levels.len() as u64);
994 for level in self.spec.priority_levels.iter().take(3) {
995 words.push(level.goals.len() as u64);
996 }
997 words.resize(words.len() + 3 - self.spec.priority_levels.len(), 0);
998 let mut goals = 0;
999 for level in &self.spec.priority_levels {
1000 for goal in &level.goals {
1001 words.extend([
1002 u64::from(goal.query),
1003 u64::from(goal.target_truth),
1004 u64::from(goal.weight),
1005 ]);
1006 goals += 1;
1007 }
1008 }
1009 words.resize(words.len() + (3 - goals) * 3, 0);
1010 if let Some(editable) = self.spec.program.editable_program() {
1011 let bank = editable.words();
1012 words.extend([1, bank.len() as u64]);
1013 words.extend(bank);
1014 }
1015 words
1016 }
1017}
1018
1019#[repr(C)]
1022#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1023pub struct SemanticComponent {
1024 pub offset: u64,
1025 pub ordinal: u32,
1026 pub lane: u32,
1027 pub slot: u32,
1028 pub field: u32,
1029 pub kind: u32,
1030 pub cardinality: u32,
1031}
1032
1033impl SemanticComponent {
1034 pub const fn is_text(&self) -> bool {
1035 self.kind == COMPONENT_KIND_TEXT as u32
1036 }
1037}
1038
1039pub struct SemanticCatalogueField {
1041 pub ordinal: u32,
1042 pub cardinality: u32,
1043 pub name: &'static str,
1044 pub role: &'static str,
1045}
1046
1047pub struct SemanticCatalogueSignature {
1049 pub value: u32,
1050 pub kind: &'static str,
1051 pub name: &'static str,
1052 pub signature: &'static str,
1053}
1054
1055include!(concat!(
1056 env!("OUT_DIR"),
1057 "/semantic_transition_catalogue.rs"
1058));
1059
1060pub const SEMANTIC_TRANSITION_GENERATION: u64 = CATALOGUE_GENERATION;
1061pub const SEMANTIC_TRANSITION_COMPONENT_COUNT: usize = COMPONENT_COUNT;
1062
1063#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1064pub struct SemanticCatalogueBinding {
1065 pub generation: u64,
1066 pub digest: Identity256,
1067}
1068
1069pub struct SemanticActionCatalogue;
1071
1072impl SemanticActionCatalogue {
1073 pub const fn current() -> Self {
1074 Self
1075 }
1076 pub const fn binding(&self) -> SemanticCatalogueBinding {
1077 SemanticCatalogueBinding {
1078 generation: CATALOGUE_GENERATION,
1079 digest: Identity256::from_bytes(CATALOGUE_DIGEST),
1080 }
1081 }
1082 pub const fn canonical_bytes(&self) -> &'static [u8] {
1083 CATALOGUE_ENCODING
1084 }
1085 #[cfg(feature = "semantic-policy")]
1086 fn completed_material(&self) -> SemanticCompletedStepWitnessMaterial {
1087 SemanticCompletedStepWitnessMaterial {
1088 identity: self.binding().digest,
1089 bytes: self.canonical_bytes().to_vec(),
1090 }
1091 }
1092 pub const fn components(&self) -> &'static [SemanticComponent] {
1093 COMPONENTS
1094 }
1095 pub const fn fields(&self) -> &'static [SemanticCatalogueField] {
1096 CATALOGUE_FIELDS
1097 }
1098 pub const fn signatures(&self) -> &'static [SemanticCatalogueSignature] {
1099 CATALOGUE_SIGNATURES
1100 }
1101 pub const fn text_cardinality(&self) -> usize {
1102 TEXT_CARDINALITY
1103 }
1104 pub const fn scratch_bytes(&self) -> usize {
1105 SCRATCH_BYTES
1106 }
1107 pub const fn field_masks(&self) -> [(u32, u32); 3] {
1109 [
1110 (NO_EDIT_ACTIVE_MASK as u32, NO_EDIT_NULL_MASK as u32),
1111 (
1112 INSERT_SUPPORT_ACTIVE_MASK as u32,
1113 INSERT_SUPPORT_NULL_MASK as u32,
1114 ),
1115 (INSERT_RULE_ACTIVE_MASK as u32, INSERT_RULE_NULL_MASK as u32),
1116 ]
1117 }
1118}
1119
1120pub struct SemanticComponentInput {
1122 pub logits: Vec<f32>,
1123 pub product_support: Vec<u8>,
1124}
1125
1126#[derive(Clone, Debug, PartialEq, Eq)]
1130pub struct SemanticPolicyFieldLayout {
1131 pub embeddings: std::ops::Range<usize>,
1132 pub biases: std::ops::Range<usize>,
1133 pub cardinality: usize,
1134 pub null_category: Option<usize>,
1135}
1136
1137#[derive(Clone, Debug, PartialEq, Eq)]
1141pub struct SemanticPolicyLayout {
1142 pub z: std::ops::Range<usize>,
1143 pub recurrence: std::ops::Range<usize>,
1144 pub positions: std::ops::Range<usize>,
1145 pub fields: Vec<SemanticPolicyFieldLayout>,
1146 pub parameter_cells: usize,
1147}
1148
1149impl SemanticPolicyLayout {
1150 fn from_components(components: &[SemanticComponent]) -> Result<Self, SemanticTransitionError> {
1151 let invalid = || SemanticTransitionError::InvalidInput {
1152 detail: "policy layout requires the complete native component roster".into(),
1153 };
1154 if components.len() != COMPONENT_COUNT {
1155 return Err(invalid());
1156 }
1157 let z = 0usize..4 * 128;
1158 let recurrence = z.end..z.end + 128 * 128;
1159 let positions = recurrence.end..recurrence.end + 18 * 128;
1160 let mut cursor = positions.end;
1161 let mut fields = Vec::with_capacity(18);
1162 for field in 0..18 {
1163 let cardinality = components[32 + field].cardinality as usize;
1164 if cardinality == 0 {
1165 return Err(invalid());
1166 }
1167 for lane in 0..2 {
1168 for slot in 0..2 {
1169 let component = components[lane * 68 + 32 + slot * 18 + field];
1170 if component.kind != COMPONENT_KIND_EDIT as u32
1171 || component.field as usize != field
1172 || component.lane as usize != lane + 1
1173 || component.slot as usize != slot
1174 || component.cardinality as usize != cardinality
1175 {
1176 return Err(invalid());
1177 }
1178 }
1179 }
1180 let null_category = (field != 0).then_some(0);
1181 let embedding_cells = (cardinality - usize::from(null_category.is_some()))
1182 .checked_mul(128)
1183 .ok_or_else(invalid)?;
1184 let end = cursor.checked_add(embedding_cells).ok_or_else(invalid)?;
1185 let embeddings = cursor..end;
1186 cursor = end;
1187 let bias_cells = if null_category.is_some() && cardinality == 1 {
1188 0
1189 } else {
1190 cardinality
1191 };
1192 let end = cursor.checked_add(bias_cells).ok_or_else(invalid)?;
1193 let biases = cursor..end;
1194 cursor = end;
1195 fields.push(SemanticPolicyFieldLayout {
1196 embeddings,
1197 biases,
1198 cardinality,
1199 null_category,
1200 });
1201 }
1202 Ok(Self {
1203 z,
1204 recurrence,
1205 positions,
1206 fields,
1207 parameter_cells: cursor,
1208 })
1209 }
1210
1211 pub const fn recurrent_cells(&self) -> usize {
1213 2 * 37 * 128
1214 }
1215
1216 pub fn score_cells(&self) -> usize {
1218 self.fields
1219 .iter()
1220 .map(|field| field.cardinality)
1221 .max()
1222 .unwrap_or(0)
1223 }
1224
1225 #[cfg(feature = "semantic-policy")]
1226 fn retained_score_stride(&self) -> usize {
1227 self.fields.iter().map(|field| field.cardinality).sum()
1228 }
1229
1230 #[cfg(feature = "semantic-policy")]
1231 fn retained_score_cells(&self) -> usize {
1232 4 * self.retained_score_stride()
1233 }
1234}
1235
1236#[derive(Clone, Debug, PartialEq, Eq)]
1241pub enum SemanticActionDescriptor {
1242 Target {
1243 predicate: xlog_core::RelId,
1244 },
1245 Operand {
1246 scalar_type: xlog_core::ScalarType,
1247 sort_label: String,
1248 encoded_value: Vec<u8>,
1249 },
1250 QualifierBundle {
1251 records: Vec<u32>,
1252 },
1253 SupportEvent {
1254 source_record: u32,
1255 },
1256 RulePredicate {
1257 predicate: u32,
1258 },
1259 RuleVariable {
1260 index: u32,
1261 },
1262}
1263
1264#[cfg(feature = "semantic-policy")]
1265struct SemanticDecodedSupportInsertion {
1266 statement: SemanticStatementIdentity,
1267 support: SemanticSupportIdentity,
1268 source_event: u32,
1269 reconstruction: [u32; 10],
1270 bytes: Vec<u8>,
1271}
1272
1273struct SemanticDecodedRuleInsertion {
1274 rule: crate::SemanticProgramRule,
1275 #[cfg(any(feature = "semantic-policy", test))]
1276 bytes: Vec<u8>,
1277}
1278
1279fn semantic_program_rule_words(rule: crate::SemanticProgramRule) -> [u64; 10] {
1280 [
1281 rule.head_predicate,
1282 rule.left_predicate,
1283 rule.right_predicate,
1284 rule.body_count,
1285 rule.head_variables[0],
1286 rule.head_variables[1],
1287 rule.left_variables[0],
1288 rule.left_variables[1],
1289 rule.right_variables[0],
1290 rule.right_variables[1],
1291 ]
1292 .map(u64::from)
1293}
1294
1295struct ActionCodebooks {
1296 words: Vec<u64>,
1297 targets: Vec<SemanticActionDescriptor>,
1298 operands: Vec<SemanticActionDescriptor>,
1299 qualifiers: Vec<SemanticActionDescriptor>,
1300 leaves: Vec<SemanticActionDescriptor>,
1301 components: Vec<SemanticComponent>,
1302 binding: SemanticCatalogueBinding,
1303 program_binding: Option<Identity256>,
1304 input_cells: usize,
1305}
1306
1307impl ActionCodebooks {
1308 fn program_binding(program: &crate::SemanticProgramAdmission) -> Identity256 {
1309 let mut hash = Sha256::new();
1310 hash.update(b"xlog.semantic.rule-codebook.program.v1\0");
1311 for word in program.words() {
1312 hash.update(word.to_le_bytes());
1313 }
1314 Identity256::from_bytes(hash.finalize().into())
1315 }
1316
1317 fn decoded_rule_insertion(
1318 &self,
1319 program: &crate::SemanticProgramAdmission,
1320 choices: &[u32; 18],
1321 ) -> Result<SemanticDecodedRuleInsertion, SemanticTransitionError> {
1322 if self.program_binding != Some(Self::program_binding(program))
1323 || choices[0] != 1
1324 || choices[1] != 2
1325 || choices[11..].iter().any(|&choice| choice != 0)
1326 {
1327 return Err(SemanticTransitionError::ObservationMismatch);
1328 }
1329 fn chosen(
1330 entries: &[SemanticActionDescriptor],
1331 choice: u32,
1332 ) -> Result<&SemanticActionDescriptor, SemanticTransitionError> {
1333 choice
1334 .checked_sub(1)
1335 .and_then(|index| entries.get(index as usize))
1336 .ok_or(SemanticTransitionError::ObservationMismatch)
1337 }
1338 let predicate = |entry: &SemanticActionDescriptor| match entry {
1339 SemanticActionDescriptor::RulePredicate { predicate }
1340 if *predicate < program.predicate_count =>
1341 {
1342 Ok(*predicate)
1343 }
1344 _ => Err(SemanticTransitionError::ObservationMismatch),
1345 };
1346 let variable = |entry: &SemanticActionDescriptor| match entry {
1347 SemanticActionDescriptor::RuleVariable { index } if *index < 4 => Ok(*index),
1348 _ => Err(SemanticTransitionError::ObservationMismatch),
1349 };
1350 let rule = crate::SemanticProgramRule {
1351 head_predicate: predicate(chosen(&self.targets, choices[2])?)?,
1352 left_predicate: predicate(chosen(&self.operands, choices[3])?)?,
1353 right_predicate: predicate(chosen(&self.operands, choices[4])?)?,
1354 body_count: 2,
1355 head_variables: [
1356 variable(chosen(&self.operands, choices[5])?)?,
1357 variable(chosen(&self.operands, choices[6])?)?,
1358 ],
1359 left_variables: [
1360 variable(chosen(&self.operands, choices[7])?)?,
1361 variable(chosen(&self.operands, choices[8])?)?,
1362 ],
1363 right_variables: [
1364 variable(chosen(&self.operands, choices[9])?)?,
1365 variable(chosen(&self.operands, choices[10])?)?,
1366 ],
1367 };
1368 let bound = rule
1369 .left_variables
1370 .into_iter()
1371 .chain(rule.right_variables)
1372 .fold(0u8, |set, index| set | (1 << index));
1373 if rule
1374 .head_variables
1375 .iter()
1376 .any(|index| bound & (1 << index) == 0)
1377 {
1378 return Err(SemanticTransitionError::ObservationMismatch);
1379 }
1380 #[cfg(any(feature = "semantic-policy", test))]
1381 let bytes = {
1382 let mut bytes = Vec::new();
1383 bytes.extend_from_slice(b"XLOG-DECODED-RULE-INSERTION\0");
1384 material_u64(&mut bytes, 1);
1385 bytes.extend_from_slice(self.binding.digest.as_bytes());
1386 bytes.extend_from_slice(Self::program_binding(program).as_bytes());
1387 for &choice in choices {
1388 material_u32(&mut bytes, choice);
1389 }
1390 for field in semantic_program_rule_words(rule) {
1391 material_u32(&mut bytes, field as u32);
1392 }
1393 bytes
1394 };
1395 Ok(SemanticDecodedRuleInsertion {
1396 rule,
1397 #[cfg(any(feature = "semantic-policy", test))]
1398 bytes,
1399 })
1400 }
1401
1402 #[cfg(feature = "semantic-policy")]
1403 fn decoded_support_insertion(
1404 &self,
1405 admission: &SemanticAdmission,
1406 choices: &[u32; 18],
1407 ) -> Result<Option<SemanticDecodedSupportInsertion>, SemanticTransitionError> {
1408 if choices[0] == 0 {
1409 return Ok(None);
1410 }
1411 if choices[0] != 1 || choices[1] != 1 {
1412 return Err(SemanticTransitionError::ObservationMismatch);
1413 }
1414 let chosen = |count: usize, choice: u32| {
1415 usize::try_from(choice)
1416 .ok()
1417 .and_then(|choice| choice.checked_sub(1))
1418 .filter(|&index| index < count)
1419 .ok_or(SemanticTransitionError::ObservationMismatch)
1420 };
1421 let target = chosen(self.targets.len(), choices[2])?;
1422 let predicate = match self.targets[target] {
1423 SemanticActionDescriptor::Target { predicate } => predicate,
1424 _ => return Err(SemanticTransitionError::ObservationMismatch),
1425 };
1426 let arity = admission
1427 .records()
1428 .predicates
1429 .iter()
1430 .find(|entry| entry.predicate == predicate)
1431 .ok_or(SemanticTransitionError::ObservationMismatch)?
1432 .schema
1433 .arity();
1434 let mut reconstruction = [0u32; 10];
1435 reconstruction[0] = predicate.0;
1436 for argument in 0..arity {
1437 let choice = choices[3 + argument];
1438 chosen(self.operands.len(), choice)?;
1439 let offset = self.words[2] as usize + 6 * choice as usize;
1440 reconstruction[1 + 2 * argument] = self.words[offset + 4] as u32;
1441 reconstruction[2 + 2 * argument] = self.words[offset + 5] as u32;
1442 }
1443 let qualifier = choices[11];
1444 chosen(self.qualifiers.len(), qualifier)?;
1445 reconstruction[9] = self.words[self.words[4] as usize + 3 * qualifier as usize + 2] as u32;
1446 let leaf = chosen(self.leaves.len(), choices[17])?;
1447 let source_event = match self.leaves[leaf] {
1448 SemanticActionDescriptor::SupportEvent { source_record } => source_record,
1449 _ => return Err(SemanticTransitionError::ObservationMismatch),
1450 };
1451 let statement = material_statement_key(admission, None, &reconstruction)
1452 .map_err(SemanticTransitionError::Semantic)?
1453 .identity();
1454 let support = admission
1455 .support_event(source_event)
1456 .map_err(SemanticTransitionError::Semantic)?
1457 .identity(statement);
1458 let mut bytes = Vec::new();
1459 bytes.extend_from_slice(b"XLOG-DECODED-SUPPORT-INSERTION\0");
1460 material_u64(&mut bytes, 1);
1461 bytes.extend_from_slice(self.binding.digest.as_bytes());
1462 for &choice in choices {
1463 material_u32(&mut bytes, choice);
1464 }
1465 bytes.extend_from_slice(statement.as_bytes());
1466 bytes.extend_from_slice(support.as_bytes());
1467 material_u32(&mut bytes, source_event);
1468 for reference in reconstruction {
1469 material_u32(&mut bytes, reference);
1470 }
1471 Ok(Some(SemanticDecodedSupportInsertion {
1472 statement,
1473 support,
1474 source_event,
1475 reconstruction,
1476 bytes,
1477 }))
1478 }
1479
1480 #[cfg(feature = "semantic-policy")]
1481 fn completed_material(&self) -> SemanticCompletedStepWitnessMaterial {
1482 SemanticCompletedStepWitnessMaterial {
1483 identity: self.binding.digest,
1484 bytes: publication_abi_bytes(&self.words),
1485 }
1486 }
1487
1488 #[cfg(feature = "semantic-policy")]
1489 fn completed_roster_material(&self) -> SemanticCompletedStepWitnessMaterial {
1490 let mut bytes = Vec::with_capacity(
1491 b"xlog.semantic-action-roster.v1\0".len() + 32 + 8 + self.components.len() * 7 * 8,
1492 );
1493 bytes.extend_from_slice(b"xlog.semantic-action-roster.v1\0");
1494 bytes.extend_from_slice(self.binding.digest.as_bytes());
1495 material_u64(&mut bytes, self.components.len() as u64);
1496 for component in &self.components {
1497 for value in [
1498 component.offset,
1499 component.ordinal as u64,
1500 component.lane as u64,
1501 component.slot as u64,
1502 component.field as u64,
1503 component.kind as u64,
1504 component.cardinality as u64,
1505 ] {
1506 material_u64(&mut bytes, value);
1507 }
1508 }
1509 SemanticCompletedStepWitnessMaterial {
1510 identity: Identity256::from_bytes(Sha256::digest(&bytes).into()),
1511 bytes,
1512 }
1513 }
1514
1515 fn support_layout(&self) -> (Vec<std::ops::Range<usize>>, usize) {
1516 (
1517 self.components
1518 .iter()
1519 .map(|component| {
1520 component.offset as usize
1521 ..component.offset as usize + component.cardinality as usize
1522 })
1523 .collect(),
1524 self.input_cells,
1525 )
1526 }
1527
1528 fn derive(
1529 admission: &SemanticAdmission,
1530 owner: u64,
1531 program: Option<&crate::SemanticProgramAdmission>,
1532 ) -> Result<Self, SemanticTransitionError> {
1533 if let Some(program) = program {
1534 program
1535 .validate()
1536 .map_err(|detail| SemanticTransitionError::InvalidInput {
1537 detail: detail.into(),
1538 })?;
1539 }
1540 let records = admission.records();
1541 let predicates: BTreeMap<_, _> = records
1542 .predicates
1543 .iter()
1544 .map(|p| (p.predicate.0, p))
1545 .collect();
1546 let sorts: BTreeSet<_> = records
1547 .predicates
1548 .iter()
1549 .flat_map(|p| p.schema.sort_labels().iter().cloned())
1550 .collect();
1551 let sorts: BTreeMap<_, _> = sorts
1552 .into_iter()
1553 .enumerate()
1554 .map(|(i, s)| (s, i as u64 + 1))
1555 .collect();
1556 let mut targets = BTreeMap::new();
1557 for p in predicates
1558 .values()
1559 .filter(|p| p.role == SemanticRecordRole::Statement && p.schema.arity() <= 4)
1560 {
1561 let mut row = vec![p.predicate.0 as u64, p.schema.arity() as u64];
1562 row.extend((0..4).map(|i| {
1563 p.schema
1564 .columns
1565 .get(i)
1566 .map_or(0, |(_, t)| t.to_code() as u64 + 1)
1567 }));
1568 row.extend((0..4).map(|i| p.schema.sort_labels().get(i).map_or(0, |s| sorts[s])));
1569 targets.insert(
1570 p.predicate.0.to_le_bytes(),
1571 (
1572 row,
1573 SemanticActionDescriptor::Target {
1574 predicate: p.predicate,
1575 },
1576 ),
1577 );
1578 }
1579 let mut operands = BTreeMap::new();
1580 for (record_index, (record, encoded)) in records
1581 .records
1582 .iter()
1583 .zip(&admission.encoded_records)
1584 .enumerate()
1585 {
1586 let schema = &predicates[&record.predicate.0].schema;
1587 for (i, range) in encoded.arguments.iter().enumerate() {
1588 let value = encoded.bytes[range.clone()].to_vec();
1589 let label = &schema.sort_labels()[i];
1590 let mut key = value.clone();
1591 key.extend_from_slice(&(label.len() as u64).to_le_bytes());
1592 key.extend_from_slice(label.as_bytes());
1593 operands.entry(key).or_insert_with(|| {
1594 (
1595 value.clone(),
1596 schema.columns[i].1.to_code() as u64 + 1,
1597 sorts[label],
1598 record_index as u64,
1599 i as u64,
1600 SemanticActionDescriptor::Operand {
1601 scalar_type: schema.columns[i].1,
1602 sort_label: label.clone(),
1603 encoded_value: value,
1604 },
1605 )
1606 });
1607 }
1608 }
1609 let logical = |indices: &[u32]| {
1610 let mut bytes = (indices.len() as u32).to_le_bytes().to_vec();
1611 for &index in indices {
1612 let atom = &admission.encoded_records[index as usize].bytes;
1613 bytes.extend_from_slice(&(atom.len() as u64).to_le_bytes());
1614 bytes.extend_from_slice(atom);
1615 }
1616 bytes
1617 };
1618 let mut qualifiers = BTreeMap::new();
1619 qualifiers.insert(logical(&[]), (Vec::new(), u32::MAX));
1620 for (index, record) in records.records.iter().enumerate() {
1621 if predicates[&record.predicate.0].role == SemanticRecordRole::Statement {
1622 qualifiers
1623 .entry(logical(&record.qualifiers))
1624 .or_insert_with(|| (record.qualifiers.clone(), index as u32));
1625 }
1626 }
1627 let mut leaves = BTreeMap::new();
1628 for (index, support) in records.supports.iter().enumerate() {
1629 let polarity = match support.polarity {
1630 crate::SemanticPolarity::Pro => 1u64,
1631 crate::SemanticPolarity::Contra => 2,
1632 };
1633 let refs = [
1634 support.provenance,
1635 support.source,
1636 support.context,
1637 support.scope,
1638 ];
1639 let mut key = polarity.to_le_bytes().to_vec();
1640 key.extend(logical(&refs));
1641 let mut words = vec![polarity];
1642 for record in refs {
1643 words.extend(identity_words(
1644 Sha256::digest(&admission.encoded_records[record as usize].bytes).into(),
1645 ));
1646 }
1647 words.push(index as u64);
1648 leaves.insert(
1649 (key, index),
1650 (
1651 words,
1652 SemanticActionDescriptor::SupportEvent {
1653 source_record: index as u32,
1654 },
1655 ),
1656 );
1657 }
1658 let additional_targets = program
1659 .map(|program| program.predicate_count as usize)
1660 .unwrap_or(0);
1661 let additional_operands = program
1662 .map(|program| program.predicate_count as usize + 4)
1663 .unwrap_or(0);
1664 if [
1665 targets.len().saturating_add(additional_targets),
1666 operands.len().saturating_add(additional_operands),
1667 qualifiers.len(),
1668 leaves.len(),
1669 ]
1670 .into_iter()
1671 .any(|n| n >= 65536)
1672 {
1673 return Err(SemanticTransitionError::InvalidInput {
1674 detail: "descriptor codebook exceeds 65535 non-NULL entries".into(),
1675 });
1676 }
1677 let mut words = vec![0; 25];
1678 let mut bytes = Vec::new();
1679 words[0] = words.len() as u64;
1680 words[1] = (targets.len() + additional_targets) as u64 + 1;
1681 words.extend([0; 10]);
1682 let mut target_views: Vec<SemanticActionDescriptor> = targets
1683 .into_values()
1684 .map(|(row, view)| {
1685 words.extend(row);
1686 view
1687 })
1688 .collect();
1689 if let Some(program) = program {
1690 for predicate in 0..program.predicate_count {
1691 words.extend([u64::from(predicate), u64::MAX, 0, 0, 0, 0, 0, 0, 0, 0]);
1692 target_views.push(SemanticActionDescriptor::RulePredicate { predicate });
1693 }
1694 }
1695 words[2] = words.len() as u64;
1696 words[3] = (operands.len() + additional_operands) as u64 + 1;
1697 words.extend([0; 6]);
1698 let mut operand_views: Vec<SemanticActionDescriptor> = operands
1699 .into_values()
1700 .map(|(value, ty, sort, record, argument, view)| {
1701 words.extend([
1702 bytes.len() as u64,
1703 value.len() as u64,
1704 ty,
1705 sort,
1706 record,
1707 argument,
1708 ]);
1709 bytes.extend(value);
1710 view
1711 })
1712 .collect();
1713 if let Some(program) = program {
1714 for predicate in 0..program.predicate_count {
1715 words.extend([0, 0, 0, 1, u64::from(predicate), 0]);
1716 operand_views.push(SemanticActionDescriptor::RulePredicate { predicate });
1717 }
1718 for index in 0..4 {
1719 words.extend([0, 0, 0, 2, u64::from(index), 0]);
1720 operand_views.push(SemanticActionDescriptor::RuleVariable { index });
1721 }
1722 }
1723 words[4] = words.len() as u64;
1724 words[5] = qualifiers.len() as u64 + 1;
1725 words.extend([0; 3]);
1726 let qualifier_views = qualifiers
1727 .into_values()
1728 .map(|(refs, source)| {
1729 let offset = bytes.len();
1730 bytes.extend_from_slice(&(refs.len() as u32).to_le_bytes());
1731 for &index in &refs {
1732 bytes.extend_from_slice(&Sha256::digest(
1733 &admission.encoded_records[index as usize].bytes,
1734 ));
1735 }
1736 words.extend([
1737 offset as u64,
1738 (bytes.len() - offset) as u64,
1739 u64::from(source),
1740 ]);
1741 SemanticActionDescriptor::QualifierBundle { records: refs }
1742 })
1743 .collect();
1744 words[6] = words.len() as u64;
1745 words[7] = leaves.len() as u64 + 1;
1746 words.extend([0; 18]);
1747 let leaf_views = leaves
1748 .into_values()
1749 .map(|(row, view)| {
1750 words.extend(row);
1751 view
1752 })
1753 .collect();
1754 words[8] = words.len() as u64 * 8;
1755 words[9] = bytes.len() as u64;
1756 words[10..14].copy_from_slice(&identity_words(*admission.schema_generation().as_bytes()));
1757 words[14] = owner;
1758 words[15] = admission.base().slot() as u64;
1759 words[16] = admission.base().generation();
1760 words[17..21].copy_from_slice(&identity_words(
1761 *admission.base_snapshot().digest().as_bytes(),
1762 ));
1763 bytes.resize(bytes.len().div_ceil(8) * 8, 0);
1764 words.extend(
1765 bytes
1766 .as_chunks::<8>()
1767 .0
1768 .iter()
1769 .map(|v| u64::from_le_bytes(*v)),
1770 );
1771 let mut hash = Sha256::new();
1772 hash.update(b"xlog.semantic.action-binding.v4\0");
1773 hash.update(CATALOGUE_DIGEST);
1774 hash.update(admission.identity().as_bytes());
1775 let program_binding = program.map(Self::program_binding);
1776 if let Some(identity) = program_binding {
1777 hash.update(identity.as_bytes());
1778 }
1779 for &word in &words {
1780 hash.update(word.to_le_bytes());
1781 }
1782 let digest = Identity256::from_bytes(hash.finalize().into());
1783 words[21..25].copy_from_slice(&identity_words(*digest.as_bytes()));
1784 let mut offset = 0u64;
1785 let components = COMPONENTS
1786 .iter()
1787 .map(|&c| {
1788 let cardinality = if c.is_text() {
1789 c.cardinality
1790 } else {
1791 match c.field {
1792 2 => words[1] as u32,
1793 3..=6 => words[3] as u32,
1794 7..=10 if program.is_some() => words[3] as u32,
1795 1 if program.is_none() => 2,
1796 11 => words[5] as u32,
1797 17 => words[7] as u32,
1798 _ => c.cardinality,
1799 }
1800 };
1801 let result = SemanticComponent {
1802 offset,
1803 cardinality,
1804 ..c
1805 };
1806 offset += cardinality as u64;
1807 result
1808 })
1809 .collect();
1810 Ok(Self {
1811 words,
1812 targets: target_views,
1813 operands: operand_views,
1814 qualifiers: qualifier_views,
1815 leaves: leaf_views,
1816 components,
1817 binding: SemanticCatalogueBinding {
1818 generation: CATALOGUE_GENERATION,
1819 digest,
1820 },
1821 program_binding,
1822 input_cells: offset as usize,
1823 })
1824 }
1825}
1826
1827fn identity_words(bytes: [u8; 32]) -> [u64; 4] {
1828 std::array::from_fn(|i| u64::from_le_bytes(bytes[8 * i..8 * i + 8].try_into().unwrap()))
1829}
1830
1831unsafe impl DeviceRepr for SemanticComponent {}
1833
1834#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1835pub struct SemanticRngBinding {
1836 pub model_generation: u32,
1837 pub stream_serial: u64,
1838 pub family_id: u8,
1839 pub proposal: u32,
1840}
1841
1842#[repr(C)]
1846#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
1847pub struct SemanticTransitionReceipt {
1848 pub proposal: u64,
1849 pub catalogue_generation: u64,
1850 pub catalogue_digest: Identity256,
1851 pub admission_binding: Identity256,
1853 pub ordinal: u32,
1854 pub lane: u32,
1855 pub slot: u32,
1856 pub field: u32,
1857 pub kind: u32,
1858 pub choice: u32,
1859 pub legal_count: u32,
1860 pub active_count: u32,
1861 pub selected_rank: u32,
1862 pub reserved: u32,
1863 pub key: [u32; 2],
1864 pub counter: [u32; 4],
1865 pub random_words: [u32; 4],
1866 pub draw: u64,
1867 pub cdf_start: u64,
1868 pub cdf_end: u64,
1869 pub mass: u64,
1870 pub p: [u64; 3],
1871 pub q: [u64; 3],
1872 pub factor_denominator: [u64; 3],
1873 pub cumulative_mass_below: [u64; 3],
1874 pub active_fields: u32,
1875 pub null_fields: u32,
1876}
1877
1878unsafe impl DeviceRepr for SemanticTransitionReceipt {}
1880
1881fn canonical_text_null(receipt: &SemanticTransitionReceipt) -> bool {
1882 receipt.kind == COMPONENT_KIND_TEXT as u32
1883 && receipt.choice == TEXT_NULL as u32
1884 && receipt.legal_count == 1
1885 && receipt.active_count == 1
1886 && receipt.selected_rank == 0
1887 && receipt.cumulative_mass_below == [0, 0, 0]
1888 && receipt.active_fields == 0
1889 && receipt.null_fields == 0
1890 && receipt.p == [1, 0, 0]
1891 && receipt.q == [1, 0, 0]
1892 && receipt.factor_denominator == [1, 0, 0]
1893 && receipt.cdf_start == 0
1894 && receipt.cdf_end == 1 << 63
1895 && receipt.mass == 1 << 63
1896}
1897
1898#[repr(C)]
1900#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
1901pub struct SemanticTaskFacts {
1902 pub truth: [u64; 3],
1905 pub correct: [u64; 3],
1907 pub g: u64,
1909 pub p: u64,
1911 pub c: u64,
1913 pub v: i64,
1915 pub eligible: u64,
1917}
1918
1919#[repr(C)]
1920#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1921struct DeviceTaskEvaluation {
1922 lane_refusal: [u64; 2],
1923 query_receipts: [[[u64; 42]; 3]; 3],
1924 query_count: u64,
1925 winner: u64,
1926 return_value: i64,
1927 facts: [SemanticTaskFacts; 3],
1928}
1929
1930#[repr(C)]
1933#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
1934struct SemanticPolicyPwlCell {
1935 abi: u64,
1936 ordinal: u64,
1937 cardinality: u64,
1938 legal_count: u64,
1939 active_count: u64,
1940 selected_rank: u64,
1941 maximum_bits: u64,
1942 singleton: u64,
1943 g: [u64; 3],
1944 active_sum: [u64; 3],
1945 selected_probability: [u64; 3],
1946 probability_denominator: [u64; 3],
1947}
1948
1949#[repr(C)]
1952#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
1953struct SemanticPolicySelectedScoreVjp {
1954 abi: u64,
1955 ordinal: u64,
1956 choice: u64,
1957 active_count: u64,
1958 selected_active: u64,
1959 singleton: u64,
1960 probability_numerator: [u64; 3],
1961 probability_denominator: [u64; 3],
1962}
1963
1964#[repr(C)]
1968#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
1969struct SemanticActionBatchReceipt {
1970 abi: u64,
1971 proposal: u64,
1972 stream_serial: u64,
1973 family_id: u64,
1974 action_law_generation: u64,
1975 model_generation: u64,
1976 actor_eligible: u64,
1977 component_count: u64,
1978 candidate_count: u64,
1979 winner: u64,
1980 total_return_bits: u64,
1981 base_word: u64,
1982 next_word: u64,
1983 rng_base: u64,
1984 rng_span: u64,
1985 rng_successor: u64,
1986 catalogue_digest: Identity256,
1987 component_receipts_digest: Identity256,
1988 semantic_receipts_digest: Identity256,
1989 candidate_roots: [Identity256; 3],
1990 base_logical_digest: Identity256,
1991 execution_work: ExecutionWork,
1992}
1993
1994#[repr(C)]
1995#[derive(Clone, Copy)]
1996struct DeviceState {
1997 model_generation: u32,
1998 family_id: u32,
1999 stream_serial: u64,
2000 proposal: u64,
2001 next_proposal: u64,
2002 blocks: u64,
2003 status: u64,
2004 catalogue_generation: u64,
2005 catalogue_digest: Identity256,
2006 binding_digest: Identity256,
2007 semantic_receipts: [[u64; 42]; 7],
2008 work: [SemanticTransitionWork; 2],
2009 importance_weight: f64,
2010 retired_roots_mask: u64,
2011 cleanup_receipts: [[u64; 42]; 3],
2012 task_evaluation: DeviceTaskEvaluation,
2013 actor_eligible: u64,
2014 execution_work: ExecutionWork,
2015 action_batch: SemanticActionBatchReceipt,
2016 action_batch_root: Identity256,
2017}
2018
2019impl Default for DeviceState {
2020 fn default() -> Self {
2021 unsafe { std::mem::zeroed() }
2024 }
2025}
2026
2027unsafe impl DeviceRepr for DeviceState {}
2029unsafe impl DeviceRepr for SemanticPolicyPwlCell {}
2030unsafe impl DeviceRepr for SemanticPolicySelectedScoreVjp {}
2031unsafe impl DeviceRepr for SemanticActionBatchReceipt {}
2032
2033const _: () = assert!(size_of::<SemanticPolicyPwlCell>() == 160);
2034const _: () = assert!(size_of::<SemanticPolicySelectedScoreVjp>() == 96);
2035const _: () = assert!(size_of::<SemanticActionBatchReceipt>() == 504);
2036
2037#[repr(C)]
2040#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
2041pub struct SemanticTextSlot {
2042 pub token: u64,
2043 pub logical_position: u64,
2044 pub kind: u64,
2046 pub provenance: u64,
2048 pub valid: u64,
2049 pub committed: u64,
2050 pub recomputed: u64,
2051 pub provenance_record: u64,
2053}
2054
2055type SourceSlot = SemanticTextSlot;
2056
2057unsafe impl DeviceRepr for SourceSlot {}
2059
2060#[repr(u64)]
2063#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
2064pub enum SemanticStateRole {
2065 PrefixSource = 1,
2066 TokenProvenanceRecords = 2,
2067 PrefixIdentity = 3,
2068 AttentionKeys = 4,
2069 AttentionValues = 5,
2070 ConvolutionState = 6,
2071 RecurrentState = 7,
2072 ValueRunningMax = 8,
2073 ValueDenominator = 9,
2074 ValueNumerator = 10,
2075 EditRunningMax = 11,
2076 EditDenominator = 12,
2077 EditNumerator = 13,
2078 CompletionCoverage = 14,
2079 RawFeedback = 15,
2080 FeedbackStatements = 16,
2081 FeedbackSupportProvenance = 17,
2082 SlowWeights = 18,
2083 FastAdapters = 19,
2084 SymbolicHeads = 20,
2085 OptimizerState = 21,
2086 LossScaler = 22,
2087 TrainingSchedule = 23,
2088 Gradients = 24,
2089 GradientAccumulation = 25,
2090 OtherRng = 26,
2091 ReplayEntries = 27,
2092 ReplayPayload = 28,
2093 TrainingView = 29,
2094 IntentEntries = 30,
2095 IntentPayload = 31,
2096 Acknowledgements = 32,
2097 AttemptReceipt = 33,
2098 GoalState = 34,
2099 WorldLineage = 35,
2100 EditJournal = 36,
2101 Environment = 37,
2102 AuthorityEnvelope = 38,
2103 AuthorityDecisions = 39,
2104 CheckpointLineage = 40,
2105 SchemaContract = 41,
2106 TokenizerContract = 42,
2107 RuntimeContract = 43,
2108 ModelContract = 44,
2109 TopologyContract = 45,
2110 PositionTable = 46,
2111 ActionCatalogue = 47,
2112 ActionCodebooks = 48,
2113 ProofRecords = 49,
2114 LearningCopyReset = 50,
2115 ActiveAttentionKeys = 51,
2116 ActiveAttentionValues = 52,
2117 ActiveConvolution = 53,
2118 ActiveRecurrent = 54,
2119 TensorLayout = 55,
2120}
2121
2122impl SemanticStateRole {
2123 pub fn from_code(code: u64) -> Option<Self> {
2124 const ROLES: [SemanticStateRole; 55] = [
2125 SemanticStateRole::PrefixSource,
2126 SemanticStateRole::TokenProvenanceRecords,
2127 SemanticStateRole::PrefixIdentity,
2128 SemanticStateRole::AttentionKeys,
2129 SemanticStateRole::AttentionValues,
2130 SemanticStateRole::ConvolutionState,
2131 SemanticStateRole::RecurrentState,
2132 SemanticStateRole::ValueRunningMax,
2133 SemanticStateRole::ValueDenominator,
2134 SemanticStateRole::ValueNumerator,
2135 SemanticStateRole::EditRunningMax,
2136 SemanticStateRole::EditDenominator,
2137 SemanticStateRole::EditNumerator,
2138 SemanticStateRole::CompletionCoverage,
2139 SemanticStateRole::RawFeedback,
2140 SemanticStateRole::FeedbackStatements,
2141 SemanticStateRole::FeedbackSupportProvenance,
2142 SemanticStateRole::SlowWeights,
2143 SemanticStateRole::FastAdapters,
2144 SemanticStateRole::SymbolicHeads,
2145 SemanticStateRole::OptimizerState,
2146 SemanticStateRole::LossScaler,
2147 SemanticStateRole::TrainingSchedule,
2148 SemanticStateRole::Gradients,
2149 SemanticStateRole::GradientAccumulation,
2150 SemanticStateRole::OtherRng,
2151 SemanticStateRole::ReplayEntries,
2152 SemanticStateRole::ReplayPayload,
2153 SemanticStateRole::TrainingView,
2154 SemanticStateRole::IntentEntries,
2155 SemanticStateRole::IntentPayload,
2156 SemanticStateRole::Acknowledgements,
2157 SemanticStateRole::AttemptReceipt,
2158 SemanticStateRole::GoalState,
2159 SemanticStateRole::WorldLineage,
2160 SemanticStateRole::EditJournal,
2161 SemanticStateRole::Environment,
2162 SemanticStateRole::AuthorityEnvelope,
2163 SemanticStateRole::AuthorityDecisions,
2164 SemanticStateRole::CheckpointLineage,
2165 SemanticStateRole::SchemaContract,
2166 SemanticStateRole::TokenizerContract,
2167 SemanticStateRole::RuntimeContract,
2168 SemanticStateRole::ModelContract,
2169 SemanticStateRole::TopologyContract,
2170 SemanticStateRole::PositionTable,
2171 SemanticStateRole::ActionCatalogue,
2172 SemanticStateRole::ActionCodebooks,
2173 SemanticStateRole::ProofRecords,
2174 SemanticStateRole::LearningCopyReset,
2175 SemanticStateRole::ActiveAttentionKeys,
2176 SemanticStateRole::ActiveAttentionValues,
2177 SemanticStateRole::ActiveConvolution,
2178 SemanticStateRole::ActiveRecurrent,
2179 SemanticStateRole::TensorLayout,
2180 ];
2181 let index = usize::try_from(code.checked_sub(1)?).ok()?;
2182 ROLES.get(index).copied()
2183 }
2184}
2185
2186pub struct SemanticStateRecord {
2190 pub role: SemanticStateRole,
2191 pub index: u64,
2192 pub bytes: Vec<u8>,
2193 pub capacity_bytes: usize,
2194}
2195
2196#[repr(C)]
2201#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
2202pub struct SemanticModelContractLayout {
2203 pub schema_begin: u64,
2204 pub schema_bytes: u64,
2205 pub schema_digest_offset: u64,
2206 pub generation_offset: u64,
2207 pub numerical_digest_offset: u64,
2208 pub identity_offset: u64,
2209}
2210
2211impl SemanticModelContractLayout {
2212 fn validate(self, record_bytes: u64) -> Result<(), SemanticTransitionError> {
2213 let spans = [
2214 (self.schema_begin, self.schema_bytes),
2215 (self.schema_digest_offset, 32),
2216 (self.generation_offset, 8),
2217 (self.numerical_digest_offset, 32),
2218 (self.identity_offset, 32),
2219 ];
2220 for (index, &(begin, bytes)) in spans.iter().enumerate() {
2221 if bytes == 0
2222 || begin > record_bytes
2223 || bytes > record_bytes - begin
2224 || spans[..index]
2225 .iter()
2226 .any(|&(other, length)| begin < other + length && other < begin + bytes)
2227 {
2228 return Err(publication_input_error(
2229 "model contract spans must be nonempty, disjoint and within its actual bytes",
2230 ));
2231 }
2232 }
2233 Ok(())
2234 }
2235}
2236
2237pub struct SemanticTensorInput {
2241 pub layout: SemanticTensorLayout,
2242 pub logical_begin: u64,
2243 pub logical_end: u64,
2244 pub tensor: DlpackManagedTensor,
2245 pub native_allocation: Option<DeviceAllocationProvenance>,
2248}
2249
2250pub struct SemanticGradientDeliveryBinding {
2254 _tensors: Vec<PreparedSemanticTensor>,
2255}
2256
2257#[derive(Clone, Debug, PartialEq, Eq)]
2260pub struct SemanticModelStorage {
2261 pub allocation: u64,
2262 pub byte_offset: u64,
2263 pub span_bytes: u64,
2264}
2265
2266#[derive(Clone, Debug, PartialEq, Eq)]
2268pub struct SemanticModelView {
2269 pub role: u64,
2270 pub index: u64,
2271 pub storage: u64,
2272 pub byte_offset: u64,
2273}
2274
2275pub struct SemanticModelMemory {
2279 pub allocations: Vec<SemanticTensorInput>,
2280 pub storages: Vec<SemanticModelStorage>,
2281 pub views: Vec<SemanticModelView>,
2282}
2283
2284#[derive(Clone, Debug, Default, PartialEq, Eq)]
2285struct ModelMemoryGeometry {
2286 allocation_bytes: Vec<u64>,
2287 storages: Vec<SemanticModelStorage>,
2288 views: Vec<SemanticModelView>,
2289}
2290
2291impl ModelMemoryGeometry {
2292 fn location(&self, role: u64, index: u64) -> Result<(usize, usize), SemanticTransitionError> {
2293 let view = self
2294 .views
2295 .iter()
2296 .find(|view| (view.role, view.index) == (role, index))
2297 .ok_or_else(|| {
2298 publication_input_error("model tensor lacks its producer storage view")
2299 })?;
2300 let storage = usize::try_from(view.storage)
2301 .ok()
2302 .and_then(|index| self.storages.get(index))
2303 .ok_or_else(|| publication_input_error("model view names an absent storage object"))?;
2304 let allocation = usize::try_from(storage.allocation)
2305 .ok()
2306 .filter(|&index| index < self.allocation_bytes.len())
2307 .ok_or_else(|| {
2308 publication_input_error("model storage names an absent backing allocation")
2309 })?;
2310 let offset = storage
2311 .byte_offset
2312 .checked_add(view.byte_offset)
2313 .and_then(|offset| usize::try_from(offset).ok())
2314 .ok_or_else(|| publication_input_error("model storage view offset overflows"))?;
2315 Ok((allocation, offset))
2316 }
2317
2318 fn validate(
2319 &self,
2320 layouts: &BTreeMap<(u64, u64), SemanticTensorLayout>,
2321 ) -> Result<(), SemanticTransitionError> {
2322 let mut allocations = BTreeSet::new();
2323 for storage in &self.storages {
2324 let capacity = usize::try_from(storage.allocation)
2325 .ok()
2326 .and_then(|index| self.allocation_bytes.get(index))
2327 .ok_or_else(|| publication_input_error("model storage allocation is absent"))?;
2328 if usize::try_from(*capacity).is_err()
2329 || storage
2330 .byte_offset
2331 .checked_add(storage.span_bytes)
2332 .is_none_or(|end| end > *capacity)
2333 {
2334 return Err(publication_input_error(
2335 "model storage exceeds its complete backing allocation",
2336 ));
2337 }
2338 allocations.insert(storage.allocation);
2339 }
2340 let mut storages = BTreeSet::new();
2341 let mut previous = None;
2342 for view in &self.views {
2343 let key = (view.role, view.index);
2344 if !matches!(view.role, 18..=25) || previous.is_some_and(|previous| previous >= key) {
2345 return Err(publication_input_error(
2346 "model views must enumerate unique model tensor coordinates in order",
2347 ));
2348 }
2349 previous = Some(key);
2350 let layout = layouts.get(&key).ok_or_else(|| {
2351 publication_input_error("model storage view lacks its original tensor layout")
2352 })?;
2353 let (_, offset) = self.location(view.role, view.index)?;
2354 let storage = &self.storages[view.storage as usize];
2355 let span = tensor_layout_bytes(layout)? as u64;
2356 if layout.logical_axis != u64::MAX
2357 || !(offset as u64).is_multiple_of(layout.element_bytes)
2358 || view
2359 .byte_offset
2360 .checked_add(span)
2361 .is_none_or(|end| end > storage.span_bytes)
2362 {
2363 return Err(publication_input_error(
2364 "typed model view exceeds or misaligns its declared storage",
2365 ));
2366 }
2367 storages.insert(view.storage);
2368 }
2369 if allocations.len() != self.allocation_bytes.len()
2370 || storages.len() != self.storages.len()
2371 || self.views.len()
2372 != layouts
2373 .values()
2374 .filter(|layout| matches!(layout.role, 18..=25))
2375 .count()
2376 {
2377 return Err(publication_input_error(
2378 "model memory map omits a tensor or contains unreachable storage",
2379 ));
2380 }
2381 Ok(())
2382 }
2383
2384 fn encode_into(&self, bytes: &mut Vec<u8>) -> Result<(), SemanticTransitionError> {
2385 for count in [
2386 self.allocation_bytes.len(),
2387 self.storages.len(),
2388 self.views.len(),
2389 ] {
2390 material_u32(
2391 bytes,
2392 u32::try_from(count).map_err(|_| SemanticTransitionError::GenerationExhausted)?,
2393 );
2394 }
2395 for &extent in &self.allocation_bytes {
2396 material_u64(bytes, extent);
2397 }
2398 for storage in &self.storages {
2399 for field in [storage.allocation, storage.byte_offset, storage.span_bytes] {
2400 material_u64(bytes, field);
2401 }
2402 }
2403 for view in &self.views {
2404 for field in [view.role, view.index, view.storage, view.byte_offset] {
2405 material_u64(bytes, field);
2406 }
2407 }
2408 Ok(())
2409 }
2410
2411 fn digest(
2412 &self,
2413 layouts: &BTreeMap<(u64, u64), SemanticTensorLayout>,
2414 ) -> Result<Identity256, SemanticTransitionError> {
2415 self.validate(layouts)?;
2416 let mut bytes = b"xlog.semantic.model-memory.v1\0".to_vec();
2417 self.encode_into(&mut bytes)?;
2418 let model = layouts
2419 .values()
2420 .filter(|layout| matches!(layout.role, 18..=25));
2421 material_u64(&mut bytes, model.clone().count() as u64);
2422 for layout in model {
2423 for field in [
2424 layout.role,
2425 layout.index,
2426 layout.element_bytes,
2427 layout.scalar_type,
2428 layout.rank,
2429 layout.logical_axis,
2430 ]
2431 .into_iter()
2432 .chain(layout.dimensions)
2433 .chain(layout.strides_bytes)
2434 {
2435 material_u64(&mut bytes, field);
2436 }
2437 }
2438 Ok(Identity256::from_bytes(Sha256::digest(&bytes).into()))
2439 }
2440
2441 fn decode_from(
2442 reader: &mut SemanticMaterialReader<'_>,
2443 ) -> Result<Self, SemanticTransitionError> {
2444 let allocations = reader.count(8).map_err(SemanticTransitionError::Semantic)?;
2445 let storages = reader
2446 .count(24)
2447 .map_err(SemanticTransitionError::Semantic)?;
2448 let views = reader
2449 .count(32)
2450 .map_err(SemanticTransitionError::Semantic)?;
2451 let mut geometry = Self::default();
2452 for _ in 0..allocations {
2453 geometry
2454 .allocation_bytes
2455 .push(reader.u64().map_err(SemanticTransitionError::Semantic)?);
2456 }
2457 for _ in 0..storages {
2458 geometry.storages.push(SemanticModelStorage {
2459 allocation: reader.u64().map_err(SemanticTransitionError::Semantic)?,
2460 byte_offset: reader.u64().map_err(SemanticTransitionError::Semantic)?,
2461 span_bytes: reader.u64().map_err(SemanticTransitionError::Semantic)?,
2462 });
2463 }
2464 for _ in 0..views {
2465 geometry.views.push(SemanticModelView {
2466 role: reader.u64().map_err(SemanticTransitionError::Semantic)?,
2467 index: reader.u64().map_err(SemanticTransitionError::Semantic)?,
2468 storage: reader.u64().map_err(SemanticTransitionError::Semantic)?,
2469 byte_offset: reader.u64().map_err(SemanticTransitionError::Semantic)?,
2470 });
2471 }
2472 Ok(geometry)
2473 }
2474}
2475
2476fn prepare_model_memory(
2477 allocations: &[PreparedSemanticTensor],
2478 storages: Vec<SemanticModelStorage>,
2479 views: Vec<SemanticModelView>,
2480 tensors: &[PreparedSemanticTensor],
2481) -> Result<ModelMemoryGeometry, SemanticTransitionError> {
2482 let mut geometry = ModelMemoryGeometry {
2483 allocation_bytes: Vec::new(),
2484 storages,
2485 views,
2486 };
2487 for (index, allocation) in allocations.iter().enumerate() {
2488 let layout = allocation.layout;
2489 if layout.role != 0
2490 || layout.index != index as u64
2491 || layout.rank != 1
2492 || layout.scalar_type != 1
2493 || layout.element_bytes != 1
2494 || layout.logical_axis != u64::MAX
2495 || layout.strides_bytes != [1, 0, 0, 0]
2496 || allocation.logical_begin != 0
2497 || allocation.logical_end != 0
2498 {
2499 return Err(publication_input_error(
2500 "model backing producer must be its complete ordinal U8 vector",
2501 ));
2502 }
2503 let bytes = tensor_layout_bytes(&layout)? as u64;
2504 let end = allocation
2505 .data
2506 .checked_add(bytes)
2507 .ok_or(SemanticTransitionError::GenerationExhausted)?;
2508 for (prior, &prior_bytes) in allocations[..index].iter().zip(&geometry.allocation_bytes) {
2510 if bytes != 0
2511 && prior_bytes != 0
2512 && allocation.data < prior.data + prior_bytes
2513 && prior.data < end
2514 {
2515 return Err(publication_input_error(
2516 "declared model backing allocations overlap",
2517 ));
2518 }
2519 }
2520 geometry.allocation_bytes.push(bytes);
2521 }
2522 let layouts = tensors
2523 .iter()
2524 .map(|tensor| ((tensor.layout.role, tensor.layout.index), tensor.layout))
2525 .collect();
2526 geometry.validate(&layouts)?;
2527 for tensor in tensors
2528 .iter()
2529 .filter(|tensor| matches!(tensor.layout.role, 18..=25))
2530 {
2531 let (allocation, offset) = geometry.location(tensor.layout.role, tensor.layout.index)?;
2532 if allocations[allocation].data.checked_add(offset as u64) != Some(tensor.data) {
2533 return Err(publication_input_error(
2534 "original tensor does not occupy its producer-declared backing view",
2535 ));
2536 }
2537 }
2538 Ok(geometry)
2539}
2540
2541pub struct SemanticParentBinding {
2546 pub recovered_instance: Option<Identity256>,
2547 pub source: [SemanticTextSlot; 32],
2548 pub prefix: Vec<SemanticTextSlot>,
2549 pub ring_head: u64,
2550 pub provenance_records: u64,
2551 pub prefix_capacity: u64,
2552 pub feedback_capacity: u64,
2553 pub max_position: u64,
2554 pub pad_token: u64,
2555 pub terminal_tokens: Vec<u64>,
2556 pub final_intent_payload_bytes: u64,
2557 pub intent_effect: Vec<u8>,
2560 pub intent_entry_capacity: u64,
2561 pub intent_payload_capacity_bytes: usize,
2562 pub acknowledgement_payload_capacity_bytes: usize,
2563 pub model_generation: u64,
2564 pub model_numerical_mode: Vec<u8>,
2568 pub model_contract_layout: SemanticModelContractLayout,
2569 pub policy_generation: u64,
2570 pub neural_generation: u64,
2571 pub cache_generation: u64,
2572 pub authority_generation: u64,
2573 pub training_cursor: u64,
2574 pub training_rng: [u64; 4],
2575 pub fuel: u64,
2576 pub rng: SemanticRngBinding,
2577 pub topology_identity: Identity256,
2578 pub table_identity: Identity256,
2579 pub role_counts: [u64; 55],
2581 pub records: Vec<SemanticStateRecord>,
2582 pub tensors: Vec<SemanticTensorInput>,
2583 pub model_memory: SemanticModelMemory,
2584 pub active_layouts: Vec<SemanticTensorLayout>,
2587}
2588
2589#[derive(Clone, Debug)]
2593pub struct SemanticObservedSource {
2594 pub identity: String,
2595 pub tokens: Vec<u64>,
2596 pub origin: Vec<u8>,
2597}
2598
2599#[derive(Clone, Debug)]
2601pub struct SemanticSourceMapping {
2602 pub source: String,
2603 pub offset: u64,
2604 pub logical_position: u64,
2605}
2606
2607#[derive(Clone)]
2611pub struct SemanticInitialSourceLayout {
2612 pub source: [SemanticTextSlot; 32],
2613 pub prefix: Vec<SemanticTextSlot>,
2614 pub prefill_tokens: Vec<u64>,
2615 pub ring_head: u64,
2616 #[cfg(feature = "semantic-policy")]
2617 prefill_mapping: Vec<SemanticSourceMapping>,
2618 provenance_bytes: Vec<u8>,
2619 provenance_capacity_bytes: usize,
2620 provenance_records: u64,
2621}
2622
2623struct InitialPrefillStage {
2626 scope: Arc<()>,
2627 task_identity: Identity256,
2628 task_epoch: u64,
2629 model_generation: u64,
2630 layout: SemanticInitialSourceLayout,
2631 expected_tokens: TrackedCudaSlice<u64>,
2632 input: Option<PreparedSemanticTensor>,
2633 model_content: Option<TensorContentBuffers>,
2634 output_content: Option<TensorContentBuffers>,
2635 captured_content: Vec<TensorContentBuffers>,
2636 consumer_stream: Option<u64>,
2637}
2638
2639struct RetainedInitialPrefillContent {
2642 scope: Arc<()>,
2643 task_identity: Identity256,
2644 task_epoch: u64,
2645 model_generation: u64,
2646 model: TensorContentBuffers,
2647 #[cfg(feature = "semantic-policy")]
2648 output: TensorContentBuffers,
2649 #[cfg(feature = "semantic-policy")]
2650 record: InitialPrefillRecord,
2651 captured: Vec<TensorContentBuffers>,
2652}
2653
2654#[cfg(feature = "semantic-policy")]
2655#[derive(Clone)]
2656struct InitialPrefillRecord {
2657 predecessor: SemanticPublishedIdentity,
2658 semantic_root: Identity256,
2659 task_identity: Identity256,
2660 task_epoch: u64,
2661 task_content: SemanticTaskContentIdentity,
2662 model_generation: u64,
2663 tokens: Vec<u64>,
2664 mapping: Vec<SemanticSourceMapping>,
2665}
2666
2667struct CheckpointInitialPrefill {
2668 original: SemanticPublishedIdentity,
2669 content: Vec<u8>,
2670 recovery_referent: Option<Vec<u8>>,
2671}
2672
2673impl CheckpointInitialPrefill {
2674 const MAGIC: &'static [u8] = b"XLOG-CHECKPOINT-INITIAL-PREFILL\0";
2675
2676 fn encode_section(value: Option<&Self>) -> Result<Vec<u8>, SemanticTransitionError> {
2677 let mut bytes = Self::MAGIC.to_vec();
2678 material_u64(&mut bytes, 1);
2679 if let Some(value) = value {
2680 bytes.push(1);
2681 encode_publication_identity(&mut bytes, value.original);
2682 material_u64(
2683 &mut bytes,
2684 u64::try_from(value.content.len())
2685 .map_err(|_| publication_input_error("initial prefill exceeds u64"))?,
2686 );
2687 bytes.extend_from_slice(&value.content);
2688 } else {
2689 bytes.push(0);
2690 }
2691 Ok(bytes)
2692 }
2693
2694 fn decode_section(bytes: &[u8]) -> Result<Option<Self>, SemanticTransitionError> {
2695 let mut reader = SemanticMaterialReader::new(bytes);
2696 if reader
2697 .take(Self::MAGIC.len())
2698 .map_err(SemanticTransitionError::Semantic)?
2699 != Self::MAGIC
2700 || reader.u64().map_err(SemanticTransitionError::Semantic)? != 1
2701 {
2702 return Err(publication_input_error(
2703 "checkpoint initial prefill has another domain or version",
2704 ));
2705 }
2706 let result = match reader.u8().map_err(SemanticTransitionError::Semantic)? {
2707 0 => None,
2708 1 => {
2709 let original = decode_publication_identity(&mut reader)?;
2710 let length =
2711 usize::try_from(reader.u64().map_err(SemanticTransitionError::Semantic)?)
2712 .map_err(|_| {
2713 publication_input_error("checkpoint initial prefill exceeds this host")
2714 })?;
2715 let content = reader
2716 .take(length)
2717 .map_err(SemanticTransitionError::Semantic)?
2718 .to_vec();
2719 if content.is_empty() {
2720 return Err(publication_input_error(
2721 "checkpoint initial prefill is empty",
2722 ));
2723 }
2724 Some(Self {
2725 original,
2726 content,
2727 recovery_referent: None,
2728 })
2729 }
2730 _ => {
2731 return Err(publication_input_error(
2732 "checkpoint initial prefill presence is invalid",
2733 ))
2734 }
2735 };
2736 reader.finish().map_err(SemanticTransitionError::Semantic)?;
2737 Ok(result)
2738 }
2739
2740 fn verify_content(
2741 &self,
2742 semantic_root: Identity256,
2743 model_generation: u64,
2744 task_identity: Identity256,
2745 task_epoch: u64,
2746 task_content: SemanticTaskContentIdentity,
2747 prefix_extent: u64,
2748 ) -> Result<(), SemanticTransitionError> {
2749 let mut reader = SemanticMaterialReader::new(&self.content);
2750 let read_identity = |reader: &mut SemanticMaterialReader<'_>| {
2751 reader
2752 .take(32)
2753 .map(|value| Identity256::from_bytes(value.try_into().unwrap()))
2754 .map_err(SemanticTransitionError::Semantic)
2755 };
2756 if read_identity(&mut reader)? != semantic_root
2757 || reader.u64().map_err(SemanticTransitionError::Semantic)? != model_generation
2758 || read_identity(&mut reader)? != task_identity
2759 || reader.u64().map_err(SemanticTransitionError::Semantic)? != task_epoch
2760 || [
2761 read_identity(&mut reader)?,
2762 read_identity(&mut reader)?,
2763 read_identity(&mut reader)?,
2764 ] != [
2765 task_content.query,
2766 task_content.theory_program,
2767 task_content.result,
2768 ]
2769 {
2770 return Err(publication_input_error(
2771 "checkpoint initial prefill differs from its native task or parent",
2772 ));
2773 }
2774 let count = reader.u64().map_err(SemanticTransitionError::Semantic)?;
2775 if count == 0 || count != prefix_extent {
2776 return Err(publication_input_error(
2777 "checkpoint initial prefill token extent differs",
2778 ));
2779 }
2780 for _ in 0..count {
2781 reader.u64().map_err(SemanticTransitionError::Semantic)?;
2782 }
2783 if reader.u64().map_err(SemanticTransitionError::Semantic)? != count {
2784 return Err(publication_input_error(
2785 "checkpoint initial prefill mapping extent differs",
2786 ));
2787 }
2788 for position in 0..count {
2789 let length = usize::try_from(reader.u64().map_err(SemanticTransitionError::Semantic)?)
2790 .map_err(|_| {
2791 publication_input_error("initial prefill source name exceeds this host")
2792 })?;
2793 let source = reader
2794 .take(length)
2795 .map_err(SemanticTransitionError::Semantic)?;
2796 if source.is_empty() || std::str::from_utf8(source).is_err() {
2797 return Err(publication_input_error(
2798 "checkpoint initial prefill source name is invalid",
2799 ));
2800 }
2801 reader.u64().map_err(SemanticTransitionError::Semantic)?;
2802 if reader.u64().map_err(SemanticTransitionError::Semantic)? != position {
2803 return Err(publication_input_error(
2804 "checkpoint initial prefill logical positions differ",
2805 ));
2806 }
2807 }
2808 for model in [true, false] {
2809 let count = reader.u64().map_err(SemanticTransitionError::Semantic)?;
2810 if count == 0 {
2811 return Err(publication_input_error(
2812 "checkpoint initial prefill has an empty seal group",
2813 ));
2814 }
2815 for _ in 0..count {
2816 let role = reader.u64().map_err(SemanticTransitionError::Semantic)?;
2817 if if model {
2818 !matches!(role, 0 | 18..=25)
2819 } else {
2820 !matches!(role, 4..=13)
2821 } {
2822 return Err(publication_input_error(
2823 "checkpoint initial prefill seal role is invalid",
2824 ));
2825 }
2826 reader.u64().map_err(SemanticTransitionError::Semantic)?;
2827 reader.take(32).map_err(SemanticTransitionError::Semantic)?;
2828 }
2829 }
2830 reader.finish().map_err(SemanticTransitionError::Semantic)?;
2831 Ok(())
2832 }
2833
2834 fn verify_recorded_content(
2835 &self,
2836 task_identity: Identity256,
2837 task_epoch: u64,
2838 task_content: SemanticTaskContentIdentity,
2839 ) -> Result<(), SemanticTransitionError> {
2840 let mut reader = SemanticMaterialReader::new(&self.content);
2841 let semantic_root = Identity256::from_bytes(
2842 reader
2843 .take(32)
2844 .map_err(SemanticTransitionError::Semantic)?
2845 .try_into()
2846 .unwrap(),
2847 );
2848 let model_generation = reader.u64().map_err(SemanticTransitionError::Semantic)?;
2849 reader
2850 .take(32 + 8 + 3 * 32)
2851 .map_err(SemanticTransitionError::Semantic)?;
2852 let prefix_extent = reader.u64().map_err(SemanticTransitionError::Semantic)?;
2853 self.verify_content(
2854 semantic_root,
2855 model_generation,
2856 task_identity,
2857 task_epoch,
2858 task_content,
2859 prefix_extent,
2860 )
2861 }
2862}
2863
2864#[derive(Clone)]
2868pub struct SemanticInitialPrefillLease {
2869 issuer: Arc<()>,
2870 scope: Arc<()>,
2871}
2872
2873#[derive(Clone, Copy)]
2874enum InitialPrefillContentSlot {
2875 Model,
2876 Captured(usize),
2877}
2878
2879#[derive(Clone, Copy)]
2880enum InitialPrefillCaptureKind {
2881 Model,
2882 Outputs,
2883 Captured,
2884}
2885
2886#[derive(Clone)]
2889pub struct SemanticInitialPrefillContentWitness {
2890 issuer: Arc<()>,
2891 scope: Arc<()>,
2892 task_identity: Identity256,
2893 task_epoch: u64,
2894 model_generation: u64,
2895 slot: InitialPrefillContentSlot,
2896}
2897
2898impl SemanticInitialPrefillContentWitness {
2899 fn matches(
2900 &self,
2901 issuer: &Arc<()>,
2902 scope: &Arc<()>,
2903 task_identity: Identity256,
2904 task_epoch: u64,
2905 model_generation: u64,
2906 captured_count: usize,
2907 ) -> bool {
2908 Arc::ptr_eq(&self.issuer, issuer)
2909 && Arc::ptr_eq(&self.scope, scope)
2910 && self.task_identity == task_identity
2911 && self.task_epoch == task_epoch
2912 && self.model_generation == model_generation
2913 && match self.slot {
2914 InitialPrefillContentSlot::Model => true,
2915 InitialPrefillContentSlot::Captured(index) => index < captured_count,
2916 }
2917 }
2918}
2919
2920fn validate_initial_prefill_input_layout(
2921 layout: &SemanticTensorLayout,
2922 token_count: u64,
2923) -> Result<(), SemanticTransitionError> {
2924 let row_bytes = token_count
2925 .checked_mul(size_of::<i64>() as u64)
2926 .filter(|_| token_count != 0)
2927 .ok_or_else(|| {
2928 publication_input_error("initial prefill requires nonempty admitted prefix tokens")
2929 })?;
2930 if *layout
2931 != (SemanticTensorLayout {
2932 role: 0,
2933 index: 0,
2934 element_bytes: size_of::<i64>() as u64,
2935 scalar_type: 7,
2936 rank: 2,
2937 logical_axis: 1,
2938 dimensions: [1, token_count, 0, 0],
2939 strides_bytes: [row_bytes, size_of::<i64>() as u64, 0, 0],
2940 })
2941 {
2942 return Err(publication_input_error(
2943 "initial prefill input must be the exact contiguous I64 model token tensor [1,prefix]",
2944 ));
2945 }
2946 Ok(())
2947}
2948
2949fn same_initial_source_rows(expected: &[SemanticTextSlot], actual: &[SemanticTextSlot]) -> bool {
2950 expected.len() == actual.len()
2951 && expected.iter().zip(actual).all(|(expected, actual)| {
2952 SemanticTextSlot {
2953 provenance_record: 0,
2954 ..*expected
2955 } == SemanticTextSlot {
2956 provenance_record: 0,
2957 ..*actual
2958 }
2959 })
2960}
2961
2962#[expect(
2966 clippy::too_many_arguments,
2967 reason = "cold planning checks the admitted source and complete parent text geometry together"
2968)]
2969pub fn initial_source_layout(
2970 sources: &[SemanticObservedSource],
2971 mapping: &[SemanticSourceMapping],
2972 authority: &[u8],
2973 generation: u64,
2974 provenance_capacity_records: u64,
2975 prefix_capacity: u64,
2976 feedback_capacity: u64,
2977 max_position: u64,
2978 pad_token: u64,
2979) -> Result<SemanticInitialSourceLayout, SemanticTransitionError> {
2980 let invalid = publication_input_error;
2981 if pad_token >= TEXT_CARDINALITY as u64 {
2982 return Err(invalid(
2983 "initial source padding token is outside the text vocabulary",
2984 ));
2985 }
2986 let last_position = mapping.iter().map(|entry| entry.logical_position).max();
2987 let source_extent = last_position
2988 .map(|last| {
2989 last.checked_add(1)
2990 .ok_or_else(|| invalid("initial source position overflows"))
2991 })
2992 .transpose()?
2993 .unwrap_or(0);
2994 let prefix_extent = source_extent.saturating_sub(32);
2995 if prefix_extent > prefix_capacity || prefix_extent > mapping.len() as u64 {
2996 return Err(invalid(
2997 "admitted source exceeds its complete prefix capacity",
2998 ));
2999 }
3000 let admitted = sources
3001 .iter()
3002 .map(|source| (source.identity.as_str(), source))
3003 .collect::<BTreeMap<_, _>>();
3004 let mut tokens = BTreeMap::new();
3005 for entry in mapping {
3006 let source = admitted
3007 .get(entry.source.as_str())
3008 .ok_or_else(|| invalid("source mapping names an unadmitted payload"))?;
3009 let offset =
3010 usize::try_from(entry.offset).map_err(|_| invalid("source token offset overflows"))?;
3011 let token = *source
3012 .tokens
3013 .get(offset)
3014 .ok_or_else(|| invalid("source mapping token offset is out of range"))?;
3015 if tokens.insert(entry.logical_position, token).is_some() {
3016 return Err(invalid("source mapping repeats a logical position"));
3017 }
3018 }
3019 let mut source = [SemanticTextSlot {
3020 token: pad_token,
3021 ..SemanticTextSlot::default()
3022 }; 32];
3023 let mut prefix = Vec::with_capacity(prefix_extent as usize);
3024 let mut prefill_tokens = Vec::with_capacity(prefix_extent as usize);
3025 for position in 0..prefix_extent {
3026 let token = *tokens
3027 .get(&position)
3028 .ok_or_else(|| invalid("computed prefix lacks an admitted source token"))?;
3029 prefix.push(SemanticTextSlot {
3030 token,
3031 logical_position: position,
3032 kind: 1,
3033 provenance: 1,
3034 valid: 1,
3035 committed: 1,
3036 ..SemanticTextSlot::default()
3037 });
3038 prefill_tokens.push(token);
3039 }
3040 for (&position, &token) in tokens.range(prefix_extent..) {
3041 let index = usize::try_from(position - prefix_extent)
3042 .map_err(|_| invalid("initial source ring offset overflows"))?;
3043 if index >= source.len() {
3044 return Err(invalid("admitted source exceeds its 32-row active ring"));
3045 }
3046 source[index] = SemanticTextSlot {
3047 token,
3048 logical_position: position,
3049 kind: 1,
3050 provenance: 1,
3051 valid: 1,
3052 ..SemanticTextSlot::default()
3053 };
3054 }
3055 let (_, _, provenance) = initial_source_ledger(
3056 source,
3057 prefix.clone(),
3058 sources,
3059 mapping,
3060 authority,
3061 generation,
3062 provenance_capacity_records,
3063 )?;
3064 #[cfg(feature = "semantic-policy")]
3065 let mut prefill_mapping = mapping
3066 .iter()
3067 .filter(|entry| entry.logical_position < prefix_extent)
3068 .cloned()
3069 .collect::<Vec<_>>();
3070 #[cfg(feature = "semantic-policy")]
3071 prefill_mapping.sort_by_key(|entry| entry.logical_position);
3072 let ring_head = (source_extent - prefix_extent) % 32;
3073 validate_text_parent(
3074 &source,
3075 prefix_extent,
3076 prefix_capacity,
3077 feedback_capacity,
3078 max_position,
3079 ring_head,
3080 mapping.len() as u64,
3081 )?;
3082 Ok(SemanticInitialSourceLayout {
3083 source,
3084 prefix,
3085 prefill_tokens,
3086 ring_head,
3087 #[cfg(feature = "semantic-policy")]
3088 prefill_mapping,
3089 provenance_bytes: provenance.bytes,
3090 provenance_capacity_bytes: provenance.capacity_bytes,
3091 provenance_records: mapping.len() as u64,
3092 })
3093}
3094
3095impl SemanticParentBinding {
3096 pub fn bind_initial_sources(
3100 &mut self,
3101 sources: &[SemanticObservedSource],
3102 mapping: &[SemanticSourceMapping],
3103 authority: &[u8],
3104 capacity_records: u64,
3105 ) -> Result<(), SemanticTransitionError> {
3106 if self.recovered_instance.is_some()
3107 || self.provenance_records != 0
3108 || self
3109 .records
3110 .iter()
3111 .any(|record| record.role == SemanticStateRole::TokenProvenanceRecords)
3112 || self.role_counts[SemanticStateRole::TokenProvenanceRecords as usize - 1] != 1
3113 {
3114 return Err(publication_input_error(
3115 "fresh source provenance must be constructed by the controller",
3116 ));
3117 }
3118 let (source, prefix, record) = initial_source_ledger(
3119 self.source,
3120 self.prefix.clone(),
3121 sources,
3122 mapping,
3123 authority,
3124 self.authority_generation,
3125 capacity_records,
3126 )?;
3127 self.source = source;
3128 self.prefix = prefix;
3129 self.provenance_records = mapping.len() as u64;
3130 self.records.push(record);
3131 Ok(())
3132 }
3133}
3134
3135fn initial_source_ledger(
3136 mut ring: [SemanticTextSlot; 32],
3137 mut prefix: Vec<SemanticTextSlot>,
3138 sources: &[SemanticObservedSource],
3139 mapping: &[SemanticSourceMapping],
3140 authority: &[u8],
3141 generation: u64,
3142 capacity: u64,
3143) -> Result<
3144 (
3145 [SemanticTextSlot; 32],
3146 Vec<SemanticTextSlot>,
3147 SemanticStateRecord,
3148 ),
3149 SemanticTransitionError,
3150> {
3151 let invalid = publication_input_error;
3152 let source_count = sources.len();
3153 let sources = sources
3154 .iter()
3155 .map(|source| (source.identity.as_str(), source))
3156 .collect::<BTreeMap<_, _>>();
3157 if sources.len() != source_count
3158 || sources.values().any(|source| {
3159 source.identity.is_empty()
3160 || source.origin.is_empty()
3161 || source.tokens.is_empty()
3162 || source
3163 .tokens
3164 .iter()
3165 .any(|&token| token >= TEXT_CARDINALITY as u64 || token == MASK_TOKEN as u64)
3166 })
3167 {
3168 return Err(invalid(
3169 "observed sources require unique identities and complete valid token payloads",
3170 ));
3171 }
3172 if authority.is_empty()
3173 || generation == 0
3174 || capacity
3175 < (mapping.len() as u64)
3176 .checked_add(32)
3177 .ok_or_else(|| invalid("source ledger capacity overflows"))?
3178 {
3179 return Err(invalid(
3180 "source ledger requires complete authority and append capacity",
3181 ));
3182 }
3183 let mut positions = BTreeMap::new();
3184 for entry in mapping {
3185 let source = sources
3186 .get(entry.source.as_str())
3187 .ok_or_else(|| invalid("source mapping names an unadmitted payload"))?;
3188 let offset =
3189 usize::try_from(entry.offset).map_err(|_| invalid("source token offset overflows"))?;
3190 if offset >= source.tokens.len()
3191 || positions.insert(entry.logical_position, entry).is_some()
3192 {
3193 return Err(invalid(
3194 "source mapping has invalid payload, offset, or duplicate logical position",
3195 ));
3196 }
3197 }
3198 let authority_digest = Identity256::from_bytes(Sha256::digest(authority).into());
3199 let mut bytes = Vec::with_capacity(
3200 mapping
3201 .len()
3202 .checked_mul(size_of::<TokenProvenance>())
3203 .ok_or_else(|| invalid("source ledger extent overflows"))?,
3204 );
3205 let mut seen = BTreeSet::new();
3206 for (physical_slot, slot) in prefix.iter_mut().map(|slot| (u64::MAX, slot)).chain(
3207 ring.iter_mut()
3208 .enumerate()
3209 .map(|(index, slot)| (index as u64, slot)),
3210 ) {
3211 if slot.kind != 1 {
3212 if slot.kind > 2 || slot.provenance != 0 || slot.provenance_record != 0 {
3213 return Err(invalid(
3214 "MASK or PAD cannot carry initial SOURCE provenance",
3215 ));
3216 }
3217 continue;
3218 }
3219 let entry = positions.get(&slot.logical_position).ok_or_else(|| {
3220 invalid("every initial FILLED position requires its exact source mapping")
3221 })?;
3222 let source = sources[entry.source.as_str()];
3223 let token = source.tokens[entry.offset as usize];
3224 if slot.provenance != 1
3225 || slot.provenance_record != 0
3226 || slot.token != token
3227 || !seen.insert(slot.logical_position)
3228 {
3229 return Err(invalid(
3230 "initial FILLED token differs from its admitted SOURCE payload or position",
3231 ));
3232 }
3233 slot.provenance_record = (bytes.len() / size_of::<TokenProvenance>()) as u64;
3234 let mut record = TokenProvenance {
3235 source_slot: physical_slot,
3236 logical_position: entry.logical_position,
3237 token,
3238 ordinal: entry.offset,
3241 authority_generation: generation,
3242 origin_logical_digest: Identity256::from_bytes(Sha256::digest(&source.origin).into()),
3243 authority_closure_digest: authority_digest,
3244 ..TokenProvenance::default()
3245 };
3246 let logical = unsafe {
3249 std::slice::from_raw_parts(
3250 (&record as *const TokenProvenance).cast::<u8>(),
3251 size_of::<TokenProvenance>(),
3252 )
3253 };
3254 record.record_digest = Identity256::from_bytes(Sha256::digest(logical).into());
3255 bytes.extend_from_slice(unsafe {
3257 std::slice::from_raw_parts(
3258 (&record as *const TokenProvenance).cast::<u8>(),
3259 size_of::<TokenProvenance>(),
3260 )
3261 });
3262 }
3263 if seen.len() != mapping.len() {
3264 return Err(invalid(
3265 "source mapping includes a MASK, PAD, or absent logical position",
3266 ));
3267 }
3268 let capacity_bytes = usize::try_from(capacity)
3269 .ok()
3270 .and_then(|count| count.checked_mul(size_of::<TokenProvenance>()))
3271 .ok_or_else(|| invalid("source ledger capacity overflows"))?;
3272 Ok((
3273 ring,
3274 prefix,
3275 SemanticStateRecord {
3276 role: SemanticStateRole::TokenProvenanceRecords,
3277 index: 0,
3278 bytes,
3279 capacity_bytes,
3280 },
3281 ))
3282}
3283
3284pub struct SemanticContinuationInput {
3287 pub tensors: Vec<SemanticTensorInput>,
3288 pub authority_decisions: Vec<u8>,
3291 pub text_rows: DlpackManagedTensor,
3293 pub text_row_count: DlpackManagedTensor,
3294 pub selected_text: DlpackManagedTensor,
3296 pub active_rows: DlpackManagedTensor,
3298 pub active_row_count: DlpackManagedTensor,
3299 pub numerical_admissibility: DlpackManagedTensor,
3301 pub numerical_blocks: Option<DlpackManagedTensor>,
3303 pub model_schema_digest: Option<Identity256>,
3305 pub model_identity: Option<Identity256>,
3307}
3308
3309fn continuation_service_layouts(
3310 first_index: usize,
3311 capacity: u64,
3312 physical_blocks: Option<usize>,
3313) -> Result<Vec<SemanticTensorLayout>, SemanticTransitionError> {
3314 let first_index = u64::try_from(first_index)
3315 .ok()
3316 .filter(|index| {
3317 index
3318 .checked_add(if physical_blocks.is_some() { 6 } else { 5 })
3319 .is_some()
3320 })
3321 .ok_or_else(|| publication_input_error("continuation service roster overflow"))?;
3322 if capacity < 34 {
3323 return Err(publication_input_error(
3324 "continuation active capacity lacks its source and feedback slots",
3325 ));
3326 }
3327 let layout = |offset, scalar_type, element_bytes, rank, dimensions| {
3328 canonical_tensor_layout(SemanticTensorLayout {
3329 role: 0,
3330 index: first_index + offset,
3331 scalar_type,
3332 element_bytes,
3333 rank,
3334 dimensions,
3335 logical_axis: u64::MAX,
3336 strides_bytes: [0; 4],
3337 })
3338 };
3339 let mut layouts = vec![
3340 layout(0, 3, 8, 2, [32, 2, 0, 0])?,
3341 layout(1, 3, 8, 1, [1, 0, 0, 0])?,
3342 layout(2, 8, 1, 1, [32, 0, 0, 0])?,
3343 layout(3, 3, 8, 2, [capacity, 4, 0, 0])?,
3344 layout(4, 3, 8, 1, [1, 0, 0, 0])?,
3345 layout(5, 8, 1, 1, [1, 0, 0, 0])?,
3346 ];
3347 if let Some(blocks) = physical_blocks {
3348 layouts.push(layout(6, 9, 8, 3, [blocks as u64, 2, 3, 0])?);
3349 }
3350 Ok(layouts)
3351}
3352
3353fn retained_model_schema(
3355 record: &[u8],
3356 layout: SemanticModelContractLayout,
3357) -> Result<Option<serde_json::Value>, SemanticTransitionError> {
3358 layout.validate(record.len() as u64)?;
3359 let begin = layout.schema_begin as usize;
3360 let end = begin + layout.schema_bytes as usize;
3361 let Ok(schema) = serde_json::from_slice::<serde_json::Value>(&record[begin..end]) else {
3362 return Ok(None);
3363 };
3364 if schema
3365 .get("counter_encoding")
3366 .and_then(serde_json::Value::as_str)
3367 != Some("u32-hex8")
3368 {
3369 return Ok(None);
3370 }
3371 Ok(Some(schema))
3372}
3373
3374fn model_physical_parameter_roster(
3377 record: &[u8],
3378 layout: SemanticModelContractLayout,
3379) -> Result<Option<Vec<String>>, SemanticTransitionError> {
3380 let Some(schema) = retained_model_schema(record, layout)? else {
3381 return Ok(None);
3382 };
3383 let model = schema
3384 .get("model")
3385 .ok_or_else(|| publication_input_error("versioned model schema lacks its model owner"))?;
3386 let physical = model
3387 .get("physical")
3388 .and_then(serde_json::Value::as_object)
3389 .ok_or_else(|| publication_input_error("model schema lacks its physical owner roster"))?;
3390 let mut names = Vec::new();
3391 for (name, entry) in physical {
3392 match entry.get("kind").and_then(serde_json::Value::as_str) {
3393 Some("parameter") => names.push(name.clone()),
3394 Some("buffer") => {}
3395 _ => {
3396 return Err(publication_input_error(
3397 "model physical roster has an unknown owner kind",
3398 ))
3399 }
3400 }
3401 }
3402 if names.is_empty() {
3403 return Err(publication_input_error(
3404 "model physical roster has no parameter owners",
3405 ));
3406 }
3407 names.sort_unstable();
3408 Ok(Some(names))
3409}
3410
3411#[repr(C)]
3414#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
3415pub struct SemanticActiveRow {
3416 pub physical_row: u64,
3417 pub source_slot: u64,
3418 pub logical_position: u64,
3419 pub kind: u64,
3420}
3421
3422#[derive(Clone, Debug, PartialEq, Eq)]
3425pub struct SemanticActiveRows {
3426 pub computed: bool,
3427 pub rows: Vec<SemanticActiveRow>,
3428}
3429
3430#[repr(C)]
3433#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
3434pub struct SemanticTextRow {
3435 pub source_slot: u64,
3436 pub logical_position: u64,
3437}
3438unsafe impl DeviceRepr for SemanticTextRow {}
3440
3441#[repr(C)]
3442#[derive(Clone, Copy, Default)]
3443struct TextBinding {
3444 rows: u64,
3445 count: u64,
3446 selected: u64,
3447}
3448
3449struct TextBindingStorage {
3450 inputs: Vec<PreparedSemanticTensor>,
3451 numerical_block_snapshot: Option<Arc<TrackedCudaSlice<f64>>>,
3452 model_contract: Option<DeviceMemoryView<u8>>,
3453 physical_blocks: u64,
3454 model_schema_digest: Identity256,
3455 model_identity: Identity256,
3456 _witness: SemanticTensorContentWitness,
3457 _model_content_witness: Option<SemanticTensorContentWitness>,
3458 consumer_stream: u64,
3459 parent: TextBindingParent,
3460}
3461
3462#[expect(
3463 clippy::large_enum_variant,
3464 reason = "the published header stays inline on the latency-sensitive export path"
3465)]
3466enum TextBindingParent {
3467 Published {
3468 bank: usize,
3469 header: PublicationHeader,
3470 },
3471 Prepared(Arc<PreparedStepInputs>),
3472}
3473
3474impl TextBindingStorage {
3475 fn published_parent(&self) -> Result<(usize, PublicationHeader), SemanticTransitionError> {
3476 match &self.parent {
3477 TextBindingParent::Published { bank, header } => Ok((*bank, *header)),
3478 TextBindingParent::Prepared(_) => Err(publication_input_error(
3479 "a prepared invocation has no host-observed parent header",
3480 )),
3481 }
3482 }
3483 fn descriptor(&self) -> TextBinding {
3484 TextBinding {
3485 rows: self.inputs[0].data,
3486 count: self.inputs[1].data,
3487 selected: self.inputs[2].data,
3488 }
3489 }
3490
3491 fn record(&self, recorder: &mut LaunchRecorder) {
3492 for input in &self.inputs {
3493 if let Some(source) = &input.source {
3494 recorder.read(source);
3495 }
3496 }
3497 if let Some(snapshot) = &self.numerical_block_snapshot {
3498 recorder.read(snapshot.as_ref());
3499 }
3500 if let Some(contract) = &self.model_contract {
3501 recorder.read(contract);
3502 }
3503 }
3504
3505 fn continuation_inputs(
3506 &self,
3507 kind: SemanticTransitionKind,
3508 authority_bytes: u64,
3509 training_selection: u64,
3510 model_update: ModelUpdateContinuationInputs,
3511 ) -> ContinuationInputs {
3512 ContinuationInputs {
3513 text: self.descriptor(),
3514 active_rows: self.inputs[3].data,
3515 active_row_count: self.inputs[4].data,
3516 numerical_admissibility: self.inputs[5].data,
3517 numerical_blocks: self
3518 .numerical_block_snapshot
3519 .as_ref()
3520 .map_or(0, |snapshot| snapshot.device_ptr_value()),
3521 physical_blocks: self.physical_blocks,
3522 model_schema_digest: self.model_schema_digest,
3523 model_identity: self.model_identity,
3524 model_contract: self
3525 .model_contract
3526 .as_ref()
3527 .map_or(0, |contract| *contract.device_ptr()),
3528 model_contract_bytes: self
3529 .model_contract
3530 .as_ref()
3531 .map_or(0, |contract| contract.len() as u64),
3532 transition_kind: kind.code(),
3533 authority_bytes,
3534 training_selection,
3535 model_update_bindings: model_update.bindings,
3536 model_update_binding_count: model_update.binding_count,
3537 model_update_admissibility: model_update.admissibility,
3538 model_update_refusal: model_update.refusal,
3539 model_update_canary_results: model_update.canary_results,
3540 }
3541 }
3542}
3543
3544fn enqueue_numerical_block_snapshot(
3545 domain: &ResidentExecutionDomain,
3546 poisoned: &mut bool,
3547 original: &PreparedSemanticTensor,
3548 destination: &TrackedCudaSlice<f64>,
3549) -> Result<(), SemanticTransitionError> {
3550 let source = original
3551 .source
3552 .as_ref()
3553 .ok_or_else(|| publication_input_error("original block bounds have no device storage"))?;
3554 let bytes = destination
3555 .len()
3556 .checked_mul(size_of::<f64>())
3557 .ok_or(SemanticTransitionError::GenerationExhausted)?;
3558 if source.len() != bytes {
3559 return Err(publication_input_error(
3560 "original block bounds differ from the frozen native capacity",
3561 ));
3562 }
3563 let mut recorder = domain.new_strict_recorder();
3564 recorder.read(source);
3565 recorder.write(destination);
3566 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
3567 unsafe {
3570 sys::cuMemcpyDtoDAsync_v2(
3571 destination.device_ptr_value(),
3572 *source.device_ptr(),
3573 bytes,
3574 enqueue.stream().cu_stream(),
3575 )
3576 }
3577 .result()
3578 .map_err(|error| XlogError::Kernel(format!("block bound snapshot: {error}")))
3579 })
3580}
3581
3582#[derive(Clone, Copy, Debug, PartialEq, Eq)]
3585pub struct SemanticPublishedIdentity {
3586 pub instance: Identity256,
3587 pub word: u64,
3588 pub logical_digest: Identity256,
3589 pub state_digest: Identity256,
3590}
3591
3592#[derive(Clone, Copy, Debug, PartialEq, Eq)]
3594pub struct SemanticCheckpointNativeProjection {
3595 pub publication: SemanticPublishedIdentity,
3596 pub semantic_root: Identity256,
3597 pub model_generation: u64,
3598}
3599
3600#[derive(Clone, Debug, PartialEq, Eq)]
3603pub struct SemanticPublicationInputProjection {
3604 pub publication: SemanticPublishedIdentity,
3605 pub semantic_root: Identity256,
3606 pub model_generation: u64,
3607 pub model_geometry_digest: Identity256,
3608 pub model_numerical_digest: Identity256,
3609 pub neural_generation: u64,
3610 pub cache_generation: u64,
3611 pub prefix_extent: u64,
3612 pub ring_head: u64,
3613 pub prefix_identity: Identity256,
3614 pub prefix: Vec<SemanticTextSlot>,
3615 pub source: [SemanticTextSlot; 32],
3616 pub token_provenance: Vec<SemanticTokenProvenance>,
3617 pub cache: Vec<SemanticPublicationTensorProjection>,
3618}
3619
3620#[derive(Clone, Debug, PartialEq, Eq)]
3623pub struct SemanticPublicationTensorProjection {
3624 pub layout: SemanticTensorLayout,
3625 pub capacity_bytes: u64,
3626 pub logical_begin: u64,
3627 pub logical_end: u64,
3628 pub identity: Identity256,
3629 pub logical_bytes: Vec<u8>,
3630}
3631
3632#[derive(Clone, Debug, PartialEq, Eq)]
3636pub struct SemanticTokenProvenance {
3637 pub source_slot: u64,
3638 pub logical_position: u64,
3639 pub token: u64,
3640 pub base_word: u64,
3641 pub proposal: u64,
3642 pub ordinal: u64,
3643 pub action_receipt_digest: Identity256,
3644 pub authority_generation: u64,
3645 pub origin_logical_digest: Identity256,
3646 pub authority_closure_digest: Identity256,
3647 pub record_digest: Identity256,
3648}
3649
3650pub struct SemanticModelContext {
3653 pub parent: SemanticPublishedIdentity,
3654 pub descriptor_digest: Identity256,
3655 pub numerical_state: (Identity256, Identity256),
3658 pub semantic_root: (u64, u64, u64, Identity256, [u64; 3]),
3659 pub prefix: (DlpackManagedTensor, DlpackManagedTensor),
3661 pub ring_head: DlpackManagedTensor,
3663 pub source: DlpackManagedTensor,
3665 pub generations: (u64, u64, u64, u64, u64),
3667 pub topology_identity: Identity256,
3668 pub table_identity: Identity256,
3669 pub capacities: (u64, u64, u64),
3671}
3672
3673pub struct SemanticResidentModelMemory {
3678 pub parent: SemanticPublishedIdentity,
3679 pub generations: (u64, u64, u64),
3681 pub numerical_state: (Identity256, Identity256),
3683 pub allocations: Vec<(DeviceAllocationProvenance, DlpackManagedTensor)>,
3684 pub storages: Vec<SemanticModelStorage>,
3685 pub views: Vec<(SemanticModelView, SemanticTensorLayout)>,
3686}
3687
3688#[derive(Clone, Copy, Debug, PartialEq, Eq)]
3690pub enum SemanticTransitionKind {
3691 Proposal,
3692 Recompute,
3693 Drain,
3694 Update,
3695}
3696
3697impl SemanticTransitionKind {
3698 fn code(self) -> u64 {
3699 match self {
3700 Self::Proposal => 1,
3701 Self::Recompute => 2,
3702 Self::Drain => 3,
3703 Self::Update => 4,
3704 }
3705 }
3706}
3707
3708fn is_tensor_role(role: u64) -> bool {
3709 matches!(role, 4..=13 | 18..=25 | 51..=54)
3710}
3711
3712fn validate_publication_counts(counts: &[u64; 55]) -> Result<usize, SemanticTransitionError> {
3713 let mut total = 0u64;
3714 for (index, &count) in counts.iter().enumerate() {
3715 let role = index as u64 + 1;
3716 if (!is_tensor_role(role) && count != if role == 16 { 3 } else { 1 })
3717 || (matches!(role, 8..=13) && count != 1)
3718 || (role == 18 && count == 0)
3719 {
3720 return Err(publication_input_error(
3721 "publication role count omits or duplicates a required owner",
3722 ));
3723 }
3724 total = total
3725 .checked_add(count)
3726 .ok_or_else(|| publication_input_error("role count overflow"))?;
3727 }
3728 for (left, right) in [(4, 5), (6, 7), (4, 51), (5, 52), (6, 53), (7, 54)] {
3729 if counts[left - 1] != counts[right - 1] {
3730 return Err(publication_input_error(
3731 "paired cache and active tensor layer counts differ",
3732 ));
3733 }
3734 }
3735 usize::try_from(total).map_err(|_| publication_input_error("role count exceeds host extent"))
3736}
3737
3738fn tensor_layout_bytes(layout: &SemanticTensorLayout) -> Result<usize, SemanticTransitionError> {
3739 if layout.rank > 4
3740 || !matches!(
3741 (layout.scalar_type, layout.element_bytes),
3742 (1, 1) | (2, 4) | (3, 8) | (4, 2) | (5, 2) | (6, 4) | (7, 8) | (8, 1) | (9, 8)
3743 )
3744 || (layout.logical_axis != u64::MAX && layout.logical_axis >= layout.rank)
3745 || layout.dimensions[layout.rank as usize..]
3746 .iter()
3747 .any(|&n| n != 0)
3748 || layout.strides_bytes[layout.rank as usize..]
3749 .iter()
3750 .any(|&n| n != 0)
3751 {
3752 return Err(publication_input_error(
3753 "invalid tensor rank, scalar type, or unused dimensions",
3754 ));
3755 }
3756 if layout.dimensions[..layout.rank as usize].contains(&0) {
3757 return Ok(0);
3758 }
3759 let mut axes: Vec<_> = (0..layout.rank as usize)
3760 .filter(|&i| layout.dimensions[i] > 1)
3761 .collect();
3762 axes.sort_by_key(|&i| layout.strides_bytes[i]);
3763 let mut span = layout.element_bytes;
3764 for axis in axes {
3765 let stride = layout.strides_bytes[axis];
3766 if stride < span || !stride.is_multiple_of(layout.element_bytes) {
3767 return Err(publication_input_error(
3768 "overlapping or unaligned tensor layout",
3769 ));
3770 }
3771 span = stride
3772 .checked_mul(layout.dimensions[axis] - 1)
3773 .and_then(|n| span.checked_add(n))
3774 .ok_or_else(|| publication_input_error("tensor byte extent overflow"))?;
3775 }
3776 usize::try_from(span).map_err(|_| publication_input_error("tensor extent exceeds host size"))
3777}
3778
3779fn empty_model_tensor_layout(layout: &SemanticTensorLayout) -> bool {
3780 matches!(layout.role, 18..=25)
3781 && layout.logical_axis == u64::MAX
3782 && tensor_layout_bytes(layout).is_ok_and(|bytes| bytes == 0)
3783}
3784
3785fn prefix_capacity_layout(
3786 mut layout: SemanticTensorLayout,
3787 capacity: u64,
3788) -> Result<SemanticTensorLayout, SemanticTransitionError> {
3789 if !matches!(layout.role, 4 | 5)
3790 || layout.rank != 4
3791 || layout.logical_axis != 2
3792 || layout.dimensions[0] != 1
3793 || layout.dimensions[2] > capacity
3794 {
3795 return Err(publication_input_error(
3796 "prefix cache layout must be batch-one rank-four with position axis two",
3797 ));
3798 }
3799 layout.dimensions[2] = capacity;
3800 canonical_tensor_layout(layout)
3801}
3802
3803fn canonical_tensor_layout(
3804 mut layout: SemanticTensorLayout,
3805) -> Result<SemanticTensorLayout, SemanticTransitionError> {
3806 if layout.rank > 4 {
3807 return Err(publication_input_error("canonical tensor rank is invalid"));
3808 }
3809 let mut stride = layout.element_bytes;
3810 for axis in (0..layout.rank as usize).rev() {
3811 layout.strides_bytes[axis] = stride;
3812 stride = stride
3813 .checked_mul(layout.dimensions[axis].max(1))
3814 .ok_or_else(|| publication_input_error("canonical tensor stride overflow"))?;
3815 }
3816 tensor_layout_bytes(&layout)?;
3817 Ok(layout)
3818}
3819
3820fn validate_active_capacity(
3821 layout: &SemanticTensorLayout,
3822 capacity: u64,
3823) -> Result<(), SemanticTransitionError> {
3824 tensor_layout_bytes(layout)?;
3825 let axis = if matches!(layout.role, 51 | 52) {
3826 if layout.rank != 4 || layout.dimensions[0] != 1 {
3827 return Err(publication_input_error(
3828 "active attention must be batch-one rank-four",
3829 ));
3830 }
3831 2
3832 } else if matches!(layout.role, 53 | 54) {
3833 0
3834 } else {
3835 return Err(publication_input_error(
3836 "active capacity requires an active tensor role",
3837 ));
3838 };
3839 if layout.logical_axis != axis
3840 || layout.dimensions[axis as usize] != capacity
3841 || capacity == 0
3842 || layout.dimensions[..layout.rank as usize].contains(&0)
3843 || !matches!(layout.scalar_type, 4..=6)
3844 {
3845 return Err(publication_input_error(
3846 "active tensor row axis must have the exact window plus feedback capacity",
3847 ));
3848 }
3849 Ok(())
3850}
3851
3852fn continuation_capacity_layout(
3853 mut model: SemanticTensorLayout,
3854) -> Result<SemanticTensorLayout, SemanticTransitionError> {
3855 tensor_layout_bytes(&model)?;
3856 if !continuation_role(model.role) || !is_tensor_role(model.role) {
3857 return Err(publication_input_error(
3858 "continuation layout has no forward tensor owner",
3859 ));
3860 }
3861 let active = matches!(model.role, 51..=54);
3862 let suffix = matches!(model.role, 4 | 5);
3863 let axis = if active {
3864 if matches!(model.role, 51 | 52) {
3865 2
3866 } else {
3867 0
3868 }
3869 } else if suffix {
3870 2
3871 } else {
3872 u64::MAX
3873 };
3874 if model.logical_axis != axis || (axis != u64::MAX && axis >= model.rank) {
3875 return Err(publication_input_error(
3876 "continuation tensor has the wrong original row axis",
3877 ));
3878 }
3879 if suffix {
3880 model.dimensions[2] = 0;
3881 prefix_capacity_layout(model, 32)
3882 } else {
3883 canonical_tensor_layout(model)
3884 }
3885}
3886
3887fn continuation_allocation_layout(
3888 model: SemanticTensorLayout,
3889) -> Result<SemanticTensorLayout, SemanticTransitionError> {
3890 continuation_capacity_layout(model)?;
3891 if matches!(model.role, 4 | 5) {
3892 canonical_tensor_layout(model)
3893 } else {
3894 continuation_capacity_layout(model)
3895 }
3896}
3897
3898fn continuation_tensor_layout_for_kind(
3899 actual: &SemanticTensorLayout,
3900 begin: u64,
3901 end: u64,
3902 model: &SemanticTensorLayout,
3903 kind: SemanticTransitionKind,
3904) -> Result<SemanticTensorLayout, SemanticTransitionError> {
3905 if kind != SemanticTransitionKind::Update || !matches!(model.role, 4 | 5) {
3906 return continuation_tensor_layout(actual, begin, end, model);
3907 }
3908 let expected = canonical_tensor_layout(*model)?;
3909 let destination = canonical_tensor_layout(*actual)?;
3910 if destination != expected {
3911 return Err(publication_input_error(
3912 "continuation tensor differs from its transition-specific fixed-capacity layout",
3913 ));
3914 }
3915 tensor_layout_bytes(actual)?;
3916 let capacity = if expected.logical_axis == u64::MAX {
3917 0
3918 } else {
3919 expected.dimensions[expected.logical_axis as usize]
3920 };
3921 if (begin, end) != (0, capacity) {
3922 return Err(publication_input_error(
3923 "continuation transport differs from its transition-specific fixed-capacity output",
3924 ));
3925 }
3926 Ok(destination)
3927}
3928
3929fn continuation_tensor_layout(
3930 actual: &SemanticTensorLayout,
3931 begin: u64,
3932 end: u64,
3933 model: &SemanticTensorLayout,
3934) -> Result<SemanticTensorLayout, SemanticTransitionError> {
3935 let expected = continuation_capacity_layout(*model)?;
3936 let destination = canonical_tensor_layout(*actual)?;
3937 if destination != expected {
3938 return Err(publication_input_error(
3939 "continuation tensor differs from its cold fixed-capacity layout",
3940 ));
3941 }
3942 tensor_layout_bytes(actual)?;
3945 let capacity = if expected.logical_axis == u64::MAX {
3946 0
3947 } else {
3948 expected.dimensions[expected.logical_axis as usize]
3949 };
3950 if (begin, end) != (0, capacity) {
3951 return Err(publication_input_error(
3952 "continuation transport differs from its original fixed-capacity output",
3953 ));
3954 }
3955 Ok(destination)
3956}
3957
3958fn tensor_copy_plan(
3960 source: &SemanticTensorLayout,
3961 destination: &SemanticTensorLayout,
3962) -> Result<Vec<(u64, u64, usize)>, SemanticTransitionError> {
3963 tensor_layout_bytes(source)?;
3964 tensor_layout_bytes(destination)?;
3965 if source.rank != destination.rank
3966 || source.scalar_type != destination.scalar_type
3967 || source.element_bytes != destination.element_bytes
3968 || (0..source.rank as usize)
3969 .any(|axis| source.dimensions[axis] > destination.dimensions[axis])
3970 {
3971 return Err(publication_input_error(
3972 "tensor snapshot layout does not fit its owned destination",
3973 ));
3974 }
3975 if source.dimensions[..source.rank as usize].contains(&0) {
3976 return Ok(Vec::new());
3977 }
3978 let mut first_outer = source.rank as usize;
3979 let mut chunk = source.element_bytes;
3980 while first_outer > 0 {
3981 let axis = first_outer - 1;
3982 if source.strides_bytes[axis] != chunk || destination.strides_bytes[axis] != chunk {
3983 break;
3984 }
3985 chunk = chunk
3986 .checked_mul(source.dimensions[axis])
3987 .ok_or_else(|| publication_input_error("copy chunk overflow"))?;
3988 first_outer = axis;
3989 }
3990 let count = source.dimensions[..first_outer]
3991 .iter()
3992 .try_fold(1u64, |count, &dim| count.checked_mul(dim))
3993 .ok_or_else(|| publication_input_error("copy row count overflow"))?;
3994 let mut result = Vec::new();
3995 result
3996 .try_reserve(
3997 usize::try_from(count)
3998 .map_err(|_| publication_input_error("copy row count exceeds host extent"))?,
3999 )
4000 .map_err(|error| runtime_error("copy plan allocation", error))?;
4001 for mut linear in 0..count {
4002 let (mut source_offset, mut destination_offset) = (0u64, 0u64);
4003 for axis in (0..first_outer).rev() {
4004 let position = linear % source.dimensions[axis];
4005 linear /= source.dimensions[axis];
4006 source_offset += position * source.strides_bytes[axis];
4007 destination_offset += position * destination.strides_bytes[axis];
4008 }
4009 result.push((source_offset, destination_offset, chunk as usize));
4010 }
4011 Ok(result)
4012}
4013
4014#[derive(Clone, Copy)]
4015struct TensorMetadata<'a> {
4016 device_type: i32,
4017 device_id: i32,
4018 dtype: crate::dlpack::DLDataType,
4019 shape: &'a [i64],
4020 strides: Option<&'a [i64]>,
4021 data: u64,
4022 byte_offset: u64,
4023}
4024
4025unsafe fn semantic_tensor_metadata(
4029 actual: &crate::dlpack::DLTensor,
4030) -> Result<TensorMetadata<'_>, SemanticTransitionError> {
4031 if !(0..=4).contains(&actual.ndim) || (actual.ndim != 0 && actual.shape.is_null()) {
4032 return Err(publication_input_error(
4033 "semantic tensor requires an original scalar through rank-four shape",
4034 ));
4035 }
4036 let rank = actual.ndim as usize;
4037 Ok(TensorMetadata {
4038 device_type: actual.device.device_type,
4039 device_id: actual.device.device_id,
4040 dtype: actual.dtype,
4041 shape: if rank == 0 {
4043 &[]
4044 } else {
4045 unsafe { std::slice::from_raw_parts(actual.shape, rank) }
4046 },
4047 strides: if rank == 0 || actual.strides.is_null() {
4048 None
4049 } else {
4050 Some(unsafe { std::slice::from_raw_parts(actual.strides, rank) })
4052 },
4053 data: actual.data as usize as u64,
4054 byte_offset: actual.byte_offset,
4055 })
4056}
4057
4058fn publication_input_error(detail: &str) -> SemanticTransitionError {
4059 SemanticTransitionError::InvalidInput {
4060 detail: detail.into(),
4061 }
4062}
4063
4064fn validate_tensor_metadata(
4065 declared: &SemanticTensorLayout,
4066 actual: &TensorMetadata<'_>,
4067 device_id: i32,
4068) -> Result<(u64, usize), SemanticTransitionError> {
4069 let invalid = || {
4070 publication_input_error("semantic tensor metadata differs from its exact model contract")
4071 };
4072 let (dtype_code, bits) = match declared.scalar_type {
4073 1 => (crate::dlpack::K_DLUINT, 8),
4074 2 => (crate::dlpack::K_DLUINT, 32),
4075 3 => (crate::dlpack::K_DLUINT, 64),
4076 4 => (crate::dlpack::K_DLFLOAT, 16),
4077 5 => (4, 16), 6 => (crate::dlpack::K_DLFLOAT, 32),
4079 7 => (0, 64), 8 => (6, 8), 9 => (crate::dlpack::K_DLFLOAT, 64),
4082 _ => return Err(invalid()),
4083 };
4084 let rank = actual.shape.len();
4085 if actual.device_type != crate::dlpack::K_DLCUDA
4086 || actual.device_id != device_id
4087 || rank > 4
4088 || declared.rank != rank as u64
4089 || actual.dtype.code != dtype_code
4090 || actual.dtype.bits != bits
4091 || actual.dtype.lanes != 1
4092 || declared.element_bytes != u64::from(bits / 8)
4093 || (declared.role != 0 && SemanticStateRole::from_code(declared.role).is_none())
4094 || (declared.logical_axis != u64::MAX && declared.logical_axis >= declared.rank)
4095 || declared.dimensions[rank..]
4096 .iter()
4097 .any(|&dimension| dimension != 0)
4098 || declared.strides_bytes[rank..]
4099 .iter()
4100 .any(|&stride| stride != 0)
4101 {
4102 return Err(invalid());
4103 }
4104 let element_bytes = declared.element_bytes;
4105 let mut dimensions = [0u64; 4];
4106 for (index, &dimension) in actual.shape.iter().enumerate() {
4107 dimensions[index] = u64::try_from(dimension).map_err(|_| invalid())?;
4108 }
4109 if dimensions != declared.dimensions {
4110 return Err(invalid());
4111 }
4112 let mut strides = [0u64; 4];
4113 if let Some(actual_strides) = actual.strides {
4114 if actual_strides.len() != rank {
4115 return Err(invalid());
4116 }
4117 for (index, &stride) in actual_strides.iter().enumerate() {
4118 strides[index] = u64::try_from(stride)
4119 .ok()
4120 .and_then(|stride| stride.checked_mul(element_bytes))
4121 .ok_or_else(invalid)?;
4122 }
4123 } else {
4124 let mut stride = element_bytes;
4125 for index in (0..rank).rev() {
4126 strides[index] = stride;
4127 stride = stride.checked_mul(dimensions[index]).ok_or_else(invalid)?;
4128 }
4129 }
4130 if strides != declared.strides_bytes {
4131 return Err(invalid());
4132 }
4133 let empty = dimensions[..rank].contains(&0);
4134 let bytes = if empty {
4135 0
4136 } else {
4137 let mut axes = (0..rank)
4140 .filter(|&axis| dimensions[axis] > 1)
4141 .collect::<Vec<_>>();
4142 axes.sort_by_key(|&axis| strides[axis]);
4143 let mut span = element_bytes;
4144 for axis in axes {
4145 if strides[axis] < span {
4146 return Err(invalid());
4147 }
4148 span = strides[axis]
4149 .checked_mul(dimensions[axis] - 1)
4150 .and_then(|bytes| span.checked_add(bytes))
4151 .ok_or_else(invalid)?;
4152 }
4153 span
4154 };
4155 if !actual.byte_offset.is_multiple_of(element_bytes) || (bytes != 0 && actual.data == 0) {
4156 return Err(invalid());
4157 }
4158 let pointer = actual
4159 .data
4160 .checked_add(actual.byte_offset)
4161 .ok_or_else(invalid)?;
4162 if !pointer.is_multiple_of(element_bytes) || pointer.checked_add(bytes).is_none() {
4163 return Err(invalid());
4164 }
4165 let bytes = usize::try_from(bytes).map_err(|_| invalid())?;
4166 usize::try_from(pointer).map_err(|_| invalid())?;
4167 Ok((pointer, bytes))
4168}
4169
4170#[derive(Clone)]
4171struct PreparedSemanticTensor {
4172 layout: SemanticTensorLayout,
4173 logical_begin: u64,
4174 logical_end: u64,
4175 data: u64,
4176 source: Option<DeviceMemoryView<u8>>,
4177 native_allocation: Option<DeviceAllocationProvenance>,
4178 _empty_owner: Option<Arc<DlpackManagedTensor>>,
4181}
4182
4183#[cfg(feature = "semantic-policy")]
4184unsafe fn policy_score_cotangent_metadata(
4185 actual: &crate::dlpack::DLTensor,
4186 device_id: i32,
4187) -> Result<(u64, usize), SemanticTransitionError> {
4188 let (rows, scalar, data, bytes) =
4190 unsafe { crate::dlpack::dlpack_tensor_metadata(device_id, actual) }.map_err(|error| {
4191 publication_input_error(&format!("selected-score cotangent metadata: {error}"))
4192 })?;
4193 if rows != COMPONENT_COUNT as u64
4194 || scalar != xlog_core::ScalarType::F64
4195 || data.checked_add(bytes as u64).is_none()
4196 {
4197 return Err(publication_input_error(
4198 "selected-score cotangents require exact contiguous FP64 storage",
4199 ));
4200 }
4201 Ok((data, bytes))
4202}
4203
4204struct RetainedTensorAdmission<T: Send + 'static> {
4205 inputs: Option<Vec<T>>,
4206 stream: Arc<CudaStream>,
4207 ready: bool,
4208}
4209
4210impl<T: Send + 'static> Drop for RetainedTensorAdmission<T> {
4211 fn drop(&mut self) {
4212 let Some(inputs) = self.inputs.take() else {
4213 return;
4214 };
4215 if self.ready {
4216 drop(inputs);
4217 return;
4218 }
4219 crate::cuda_graph::retire_resources_after_completion(
4222 (Some(inputs), Arc::clone(&self.stream)),
4223 |owners| owners.1.synchronize(),
4224 |owners| {
4225 drop(owners.0.take());
4226 Ok(())
4227 },
4228 |_| Ok(()),
4229 |_, error| eprintln!("semantic tensor producer retirement incomplete: {error}"),
4230 );
4231 }
4232}
4233
4234fn prepare_semantic_tensors(
4238 provider: &CudaKernelProvider,
4239 inputs: Vec<SemanticTensorInput>,
4240) -> Result<Vec<PreparedSemanticTensor>, SemanticTransitionError> {
4241 let stream = Arc::clone(provider.device().inner().stream());
4242 let mut pending = RetainedTensorAdmission {
4243 inputs: Some(inputs),
4244 stream: Arc::clone(&stream),
4245 ready: false,
4246 };
4247 let mut geometry = Vec::new();
4248 for input in pending
4249 .inputs
4250 .as_ref()
4251 .expect("retained original producer roster")
4252 {
4253 let pointer = input.tensor.as_ptr();
4254 if pointer.is_null() {
4255 return Err(publication_input_error(
4256 "semantic tensor managed owner is null",
4257 ));
4258 }
4259 let actual = unsafe { &(*pointer).dl_tensor };
4263 let metadata = unsafe { semantic_tensor_metadata(actual) }?;
4265 let (data, bytes) =
4266 validate_tensor_metadata(&input.layout, &metadata, provider.device().ordinal() as i32)?;
4267 geometry.push((data, bytes));
4268 }
4269 pending.ready = true;
4273 let inputs = pending
4274 .inputs
4275 .take()
4276 .expect("retained original producer roster");
4277 let mut imported = Vec::with_capacity(inputs.len());
4278 for (input, (data, bytes)) in inputs.into_iter().zip(geometry) {
4279 let (source, empty_owner) = if bytes == 0 {
4280 (None, Some(Arc::new(input.tensor)))
4283 } else {
4284 let column =
4288 unsafe { CudaColumn::dlpack(data, bytes, Arc::clone(&stream), input.tensor) };
4289 (Some(column.device_view()), None)
4290 };
4291 imported.push(PreparedSemanticTensor {
4292 layout: input.layout,
4293 logical_begin: input.logical_begin,
4294 logical_end: input.logical_end,
4295 data,
4296 source,
4297 native_allocation: input.native_allocation,
4298 _empty_owner: empty_owner,
4299 });
4300 }
4301 Ok(imported)
4302}
4303
4304fn complete_tensor_handoff<T: Send + 'static>(
4305 provider: &CudaKernelProvider,
4306 inputs: Vec<T>,
4307) -> Result<Vec<T>, SemanticTransitionError> {
4308 let stream = Arc::clone(provider.device().inner().stream());
4309 let mut pending = RetainedTensorAdmission {
4310 inputs: Some(inputs),
4311 stream,
4312 ready: false,
4313 };
4314 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&pending.stream)
4315 .map_err(|error| runtime_error("tensor producer stream admission", error))?;
4316 pending
4317 .stream
4318 .synchronize()
4319 .map_err(|error| runtime_error("tensor producer handoff", error))?;
4320 pending.ready = true;
4321 Ok(pending
4322 .inputs
4323 .take()
4324 .expect("retained tensor admission owns its inputs"))
4325}
4326
4327#[repr(C)]
4328#[derive(Clone, Copy, Default)]
4329struct PublicationStorageEntry {
4330 pointer: u64,
4331 bytes: u64,
4332 generation: u64,
4333}
4334
4335#[repr(C)]
4336#[derive(Clone, Copy, Default)]
4337struct PublicationRange {
4338 role: u64,
4339 index: u64,
4340 storage_slot: u64,
4341 generation: u64,
4342 offset_bytes: u64,
4343 length_bytes: u64,
4344 logical_begin: u64,
4345 logical_end: u64,
4346 digest: Identity256,
4347 backing_digest: Identity256,
4348}
4349
4350#[repr(C)]
4353#[derive(Clone, Copy, Default, PartialEq, Eq)]
4354struct PublicationHeader {
4355 abi: u64,
4356 instance: Identity256,
4357 recovered_instance: Identity256,
4358 sealed_epoch: u64,
4359 base_word: u64,
4360 publication_word: u64,
4361 ring_head: u64,
4362 prefix_extent: u64,
4363 semantic_owner: u64,
4364 semantic_slot: u64,
4365 semantic_generation: u64,
4366 semantic_digest: Identity256,
4367 semantic_extents: [u64; 3],
4368 model_generation: u64,
4369 neural_bank: u64,
4370 neural_generation: u64,
4371 cache_generation: u64,
4372 authority_generation: u64,
4373 terminal: u64,
4374 terminal_position: u64,
4375 fuel: u64,
4376 proposal: u64,
4377 stream_serial: u64,
4378 family_id: u64,
4379 training_cursor: u64,
4380 training_rng: [u64; 4],
4381 range_count: u64,
4382 model_geometry_digest: Identity256,
4383 model_numerical_digest: Identity256,
4384 logical_digest: Identity256,
4385 state_digest: Identity256,
4386 descriptor_digest: Identity256,
4387}
4388
4389impl PublicationHeader {
4390 fn rng_binding(&self) -> Result<SemanticRngBinding, SemanticTransitionError> {
4391 if self.stream_serial > u64::MAX >> 8 {
4392 return Err(SemanticTransitionError::GenerationExhausted);
4393 }
4394 Ok(SemanticRngBinding {
4395 model_generation: u32::try_from(self.model_generation)
4396 .map_err(|_| SemanticTransitionError::GenerationExhausted)?,
4397 family_id: u8::try_from(self.family_id)
4398 .map_err(|_| SemanticTransitionError::GenerationExhausted)?,
4399 stream_serial: self.stream_serial,
4400 proposal: u32::try_from(self.proposal)
4401 .map_err(|_| SemanticTransitionError::GenerationExhausted)?,
4402 })
4403 }
4404}
4405
4406#[repr(C)]
4407#[derive(Clone, Copy, Default)]
4408struct PublicationControl {
4409 abi: u64,
4410 word: u64,
4411 instance: Identity256,
4412 banks: [u64; 2],
4413 directories: [u64; 2],
4414 storage: u64,
4415 storage_count: u64,
4416 contract: u64,
4417 continuation: u64,
4418 reader_counts: [u64; 2],
4419 reader_gate: u64,
4420 refusal: u64,
4421}
4422
4423#[repr(C)]
4424#[derive(Clone, Copy)]
4425struct PublicationBank {
4426 header: PublicationHeader,
4427 source: [SourceSlot; 32],
4428 state: DeviceState,
4429 receipts: [SemanticTransitionReceipt; COMPONENT_COUNT],
4430}
4431
4432#[derive(Clone, Copy)]
4433enum PublicationBankField {
4434 Source,
4435 PrefixExtent,
4436 RingHead,
4437 Terminal,
4438}
4439
4440impl PublicationBankField {
4441 fn layout(self) -> (std::ops::Range<usize>, Vec<i64>, Vec<i64>) {
4442 let (offset, bytes, shape, strides) = match self {
4443 Self::Source => (
4444 std::mem::offset_of!(PublicationBank, source),
4445 size_of::<[SourceSlot; 32]>(),
4446 vec![32, 8],
4447 vec![8, 1],
4448 ),
4449 Self::PrefixExtent => (
4450 std::mem::offset_of!(PublicationBank, header)
4451 + std::mem::offset_of!(PublicationHeader, prefix_extent),
4452 size_of::<u64>(),
4453 vec![1],
4454 vec![1],
4455 ),
4456 Self::RingHead => (
4457 std::mem::offset_of!(PublicationBank, header)
4458 + std::mem::offset_of!(PublicationHeader, ring_head),
4459 size_of::<u64>(),
4460 vec![1],
4461 vec![1],
4462 ),
4463 Self::Terminal => (
4464 std::mem::offset_of!(PublicationBank, header)
4465 + std::mem::offset_of!(PublicationHeader, terminal),
4466 size_of::<u64>(),
4467 vec![1],
4468 vec![1],
4469 ),
4470 };
4471 (offset..offset + bytes, shape, strides)
4472 }
4473}
4474
4475#[repr(C)]
4476#[derive(Clone, Copy, Default)]
4477struct PublicationRoleCount {
4478 role: u64,
4479 count: u64,
4480}
4481
4482#[repr(C)]
4483#[derive(Clone, Copy, Default)]
4484struct PublicationContract {
4485 abi: u64,
4486 range_capacity: u64,
4487 prefix_capacity: u64,
4488 window_capacity: u64,
4489 feedback_capacity: u64,
4490 max_position: u64,
4491 pad_token: u64,
4492 terminal_tokens: u64,
4493 terminal_token_count: u64,
4494 final_intent_payload_bytes: u64,
4495 model_generation: u64,
4496 policy_generation: u64,
4497 authority_generation: u64,
4498 semantic_owner: u64,
4499 task_identity: Identity256,
4500 topology_identity: Identity256,
4501 table_identity: Identity256,
4502 role_counts: u64,
4503 role_count: u64,
4504 model_contract_layout: SemanticModelContractLayout,
4505}
4506
4507#[repr(C)]
4508#[derive(Clone, Copy, Default)]
4509struct PendingContinuation {
4510 abi: u64,
4511 instance: Identity256,
4512 base_word: u64,
4513 model_generation: u64,
4514 authority_generation: u64,
4515 topology_identity: Identity256,
4516 table_identity: Identity256,
4517 prefix_identity: Identity256,
4518 ranges: u64,
4519 range_count: u64,
4520 transition_kind: u64,
4521 text: TextBinding,
4522 numerical_admissibility: u64,
4523 training_selection: u64,
4524 model_update_bindings: u64,
4525 model_update_binding_count: u64,
4526 model_update_admissibility: u64,
4527 model_update_refusal: u64,
4528 model_update_canary_results: u64,
4529 numerical_blocks: u64,
4530 physical_blocks: u64,
4531 model_schema_digest: Identity256,
4532 model_identity: Identity256,
4533}
4534
4535#[repr(C)]
4536#[derive(Clone, Copy)]
4537struct ContinuationInputs {
4538 text: TextBinding,
4539 active_rows: u64,
4540 active_row_count: u64,
4541 numerical_admissibility: u64,
4542 transition_kind: u64,
4543 authority_bytes: u64,
4544 training_selection: u64,
4545 model_update_bindings: u64,
4546 model_update_binding_count: u64,
4547 model_update_admissibility: u64,
4548 model_update_refusal: u64,
4549 model_update_canary_results: u64,
4550 numerical_blocks: u64,
4551 physical_blocks: u64,
4552 model_schema_digest: Identity256,
4553 model_identity: Identity256,
4554 model_contract: u64,
4555 model_contract_bytes: u64,
4556}
4557
4558#[derive(Clone, Copy, Default)]
4559struct ModelUpdateContinuationInputs {
4560 bindings: u64,
4561 binding_count: u64,
4562 admissibility: u64,
4563 refusal: u64,
4564 canary_results: u64,
4565}
4566
4567#[repr(C)]
4568#[derive(Clone, Copy, Default)]
4569struct ModelUpdateBinding {
4570 source: u64,
4571 bytes: u64,
4572 slots: [u64; 2],
4573}
4574
4575#[repr(C)]
4576#[derive(Clone, Copy, Default)]
4577struct ModelUpdateEvidenceSource {
4578 lease: u64,
4579 parent_header: u64,
4580 result: u64,
4581 origin: u64,
4582 states: [u64; 2],
4583}
4584
4585#[repr(C)]
4586#[derive(Clone, Copy, Default)]
4587struct ModelForwardSealInput {
4588 role: u64,
4589 index: u64,
4590 tensor_digest: u64,
4591 backing_digest: u64,
4592}
4593
4594#[repr(C)]
4595#[derive(Clone, Copy, Default)]
4596struct ModelForwardReceipt {
4597 abi: u64,
4598 availability: u64,
4599 role: u64,
4600 generation: u64,
4601 work_sequence: u64,
4602 logits: u64,
4603 scalar_type: u64,
4604 row_count: u64,
4605 capacity: u64,
4606 vocabulary: u64,
4607 strides_bytes: [u64; 3],
4608 model_geometry_digest: Identity256,
4609 model_numerical_digest: Identity256,
4610 logits_digest: Identity256,
4611 identity: Identity256,
4612}
4613
4614#[cfg(feature = "semantic-policy")]
4615impl ModelForwardReceipt {
4616 fn canonical_bytes(&self) -> Vec<u8> {
4617 let mut bytes = Vec::with_capacity(size_of::<Self>());
4618 for word in [
4619 self.abi,
4620 self.availability,
4621 self.role,
4622 self.generation,
4623 self.work_sequence,
4624 self.logits,
4625 self.scalar_type,
4626 self.row_count,
4627 self.capacity,
4628 self.vocabulary,
4629 ]
4630 .into_iter()
4631 .chain(self.strides_bytes)
4632 {
4633 bytes.extend_from_slice(&word.to_le_bytes());
4634 }
4635 for identity in [
4636 self.model_geometry_digest,
4637 self.model_numerical_digest,
4638 self.logits_digest,
4639 self.identity,
4640 ] {
4641 bytes.extend_from_slice(identity.as_bytes());
4642 }
4643 bytes
4644 }
4645}
4646
4647#[cfg(feature = "semantic-policy")]
4649#[derive(Clone, Debug)]
4650pub struct SemanticUpdateForwardReceipt {
4651 pub availability: u64,
4652 pub material: Option<SemanticUpdateForwardReceiptMaterial>,
4654}
4655
4656#[cfg(feature = "semantic-policy")]
4657#[derive(Clone, Debug)]
4658pub struct SemanticUpdateForwardReceiptMaterial {
4659 pub role: u64,
4660 pub generation: u64,
4661 pub work_sequence: u64,
4662 pub scalar_type: u64,
4663 pub dimensions: [u64; 3],
4664 pub strides_bytes: [u64; 3],
4665 pub model_geometry_digest: Identity256,
4666 pub model_numerical_digest: Identity256,
4667 pub logits_digest: Identity256,
4668 pub identity: Identity256,
4669 pub canonical_bytes: Vec<u8>,
4672}
4673
4674#[cfg(feature = "semantic-policy")]
4676#[derive(Clone, Debug)]
4677pub struct SemanticUpdateCanaryMeasurement {
4678 pub frozen: crate::SemanticTrainingCanaryRecord,
4679 pub protected_positions: Vec<u64>,
4680 pub availability: u64,
4681 pub reason: u64,
4682 pub measurement_bits: Option<u64>,
4683 pub memory_used: u64,
4684 pub work_used: u64,
4685}
4686
4687#[cfg(feature = "semantic-policy")]
4689#[derive(Clone, Debug)]
4690pub struct SemanticUpdateMeasurements {
4691 pub predecessor: SemanticPublishedIdentity,
4692 pub successor: Option<SemanticPublishedIdentity>,
4693 pub bank: u8,
4694 pub model_generation: u64,
4695 pub model_geometry_digest: Identity256,
4696 pub model_numerical_digest: Identity256,
4697 pub transition_status: u64,
4698 pub selection: SemanticTrainingViewSelection,
4699 pub canaries: Vec<SemanticUpdateCanaryMeasurement>,
4700 pub forward_receipts: [SemanticUpdateForwardReceipt; 2],
4701 pub canary_refusal: Option<SemanticTrainingCanaryRefusalRecord>,
4702}
4703
4704#[repr(C)]
4705#[derive(Clone, Copy, Default)]
4706struct ModelForwardReceiptInputs {
4707 control: u64,
4708 lease: u64,
4709 candidate_seals: u64,
4710 candidate_seal_count: u64,
4711 role: u64,
4712 work_sequence: u64,
4713 logits: u64,
4714 scalar_type: u64,
4715 row_count: u64,
4716 capacity: u64,
4717 vocabulary: u64,
4718 row_stride_bytes: u64,
4719 position_stride_bytes: u64,
4720 vocabulary_stride_bytes: u64,
4721 logits_digest: u64,
4722 receipt: u64,
4723}
4724
4725#[repr(C)]
4726#[derive(Clone, Copy, Default)]
4727struct PublicationCommand {
4728 control: u64,
4729 lease: u64,
4730 operation: u64,
4731}
4732
4733#[repr(C)]
4734#[derive(Clone, Copy, Default)]
4735struct PublicationDeliveryInput {
4736 lease: u64,
4737 receipt: u64,
4738 receipt_len: u64,
4739 recipient_id: Identity256,
4740 receipt_digest: Identity256,
4741}
4742
4743#[repr(C)]
4744#[derive(Clone, Copy, Default)]
4745struct PublicationLease {
4746 abi: u64,
4747 status: u64,
4748 instance: Identity256,
4749 word: u64,
4750 bank: u64,
4751 epoch: u64,
4752 active: u64,
4753 transition_kind: u64,
4754}
4755
4756#[repr(C)]
4757#[derive(Clone, Copy, Default)]
4758struct CompletionCoverage {
4759 abi: u64,
4760 instance: Identity256,
4761 base_word: u64,
4762 model_generation: u64,
4763 topology_identity: Identity256,
4764 table_identity: Identity256,
4765 prefix_identity: Identity256,
4766 prefix_begin: u64,
4767 prefix_end: u64,
4768 source_digest: Identity256,
4769 attention_digest: Identity256,
4770 linear_digest: Identity256,
4771 value_digest: Identity256,
4772 edit_digest: Identity256,
4773 receipt_digest: Identity256,
4774}
4775
4776#[repr(C)]
4777#[derive(Clone, Copy)]
4778struct RawFeedbackRecord {
4779 valid: u64,
4780 statement_index: u64,
4781 statement_offset_bytes: u64,
4782 statement_length_bytes: u64,
4783 pro: u64,
4784 contra: u64,
4785 query_receipt: [u64; 42],
4786}
4787
4788#[repr(C)]
4789#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
4790struct AttemptReceipt {
4791 abi: u64,
4792 transition_kind: u64,
4793 instance: Identity256,
4794 base_word: u64,
4795 next_word: u64,
4796 logical_digest: Identity256,
4797 action_receipts_digest: Identity256,
4798 semantic_receipts_digest: Identity256,
4799 coverage_digest: Identity256,
4800 replay_head_digest: Identity256,
4801 intent_head_digest: Identity256,
4802 acknowledgement_head_digest: Identity256,
4803 previous_attempt_digest: Identity256,
4804 receipt_digest: Identity256,
4805}
4806
4807#[repr(C)]
4808#[derive(Clone, Copy, Default)]
4809struct IntentQueueHeader {
4810 abi: u64,
4811 count: u64,
4812 capacity: u64,
4813 payload_used_bytes: u64,
4814 payload_capacity_bytes: u64,
4815 effect_offset_bytes: u64,
4816 effect_length_bytes: u64,
4817 chain_head: Identity256,
4818}
4819
4820#[repr(C)]
4821#[derive(Clone, Copy, Default)]
4822struct IntentEntry {
4823 stable_identity: Identity256,
4824 checkpoint_lineage: Identity256,
4825 base_logical: Identity256,
4826 effective_delta: Identity256,
4827 result_logical: Identity256,
4828 effect_digest: Identity256,
4829 payload_digest: Identity256,
4830 payload_offset: u64,
4831 payload_len: u64,
4832 audit_instance: Identity256,
4833 audit_epoch: u64,
4834 previous_chain: Identity256,
4835 chain: Identity256,
4836}
4837
4838#[repr(C)]
4839#[derive(Clone, Copy, Default)]
4840struct AcknowledgementQueueHeader {
4841 abi: u64,
4842 count: u64,
4843 capacity: u64,
4844 payload_used_bytes: u64,
4845 payload_capacity_bytes: u64,
4846 chain_head: Identity256,
4847}
4848
4849#[repr(C)]
4850#[derive(Clone, Copy, Default)]
4851struct AcknowledgementEntry {
4852 stable_identity: Identity256,
4853 receipt_digest: Identity256,
4854 receipt_len: u64,
4855 previous_chain: Identity256,
4856 chain: Identity256,
4857}
4858
4859#[repr(C)]
4860#[derive(Clone, Copy, Default)]
4861struct TokenProvenance {
4862 source_slot: u64,
4863 logical_position: u64,
4864 token: u64,
4865 base_word: u64,
4866 proposal: u64,
4867 ordinal: u64,
4868 action_receipt_digest: Identity256,
4869 authority_generation: u64,
4870 origin_logical_digest: Identity256,
4871 authority_closure_digest: Identity256,
4872 record_digest: Identity256,
4873}
4874
4875#[repr(C)]
4876#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
4877pub struct SemanticTensorLayout {
4878 pub role: u64,
4879 pub index: u64,
4880 pub element_bytes: u64,
4881 pub scalar_type: u64,
4884 pub rank: u64,
4885 pub logical_axis: u64,
4886 pub dimensions: [u64; 4],
4887 pub strides_bytes: [u64; 4],
4888}
4889
4890#[repr(C)]
4891#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
4892struct TensorLayoutTableHeader {
4893 abi: u64,
4894 layout_count: u64,
4895 active_computed: u64,
4896 active_row_count: u64,
4897}
4898
4899fn tensor_table_capacity(
4900 layout_count: usize,
4901 row_count: u64,
4902) -> Result<usize, SemanticTransitionError> {
4903 layout_count
4904 .checked_mul(size_of::<SemanticTensorLayout>())
4905 .and_then(|n| n.checked_add(size_of::<TensorLayoutTableHeader>()))
4906 .and_then(|n| {
4907 usize::try_from(row_count)
4908 .ok()?
4909 .checked_mul(size_of::<SemanticActiveRow>())?
4910 .checked_add(n)
4911 })
4912 .ok_or_else(|| publication_input_error("tensor layout table extent overflow"))
4913}
4914
4915fn tensor_table_bytes(
4916 layouts: &[SemanticTensorLayout],
4917 computed: bool,
4918 rows: &[SemanticActiveRow],
4919) -> Result<Vec<u8>, SemanticTransitionError> {
4920 if !computed && !rows.is_empty() {
4921 return Err(publication_input_error(
4922 "uncomputed active cache cannot contain rows",
4923 ));
4924 }
4925 let length = tensor_table_capacity(layouts.len(), rows.len() as u64)?;
4926 let mut bytes = Vec::new();
4927 bytes
4928 .try_reserve_exact(length)
4929 .map_err(|error| runtime_error("tensor layout table allocation", error))?;
4930 bytes.extend(publication_abi_bytes(&[TensorLayoutTableHeader {
4931 abi: 1,
4932 layout_count: layouts.len() as u64,
4933 active_computed: u64::from(computed),
4934 active_row_count: rows.len() as u64,
4935 }]));
4936 bytes.extend(publication_abi_bytes(layouts));
4937 bytes.extend(publication_abi_bytes(rows));
4938 Ok(bytes)
4939}
4940
4941fn decode_tensor_table(
4942 bytes: &[u8],
4943) -> Result<
4944 (
4945 TensorLayoutTableHeader,
4946 Vec<SemanticTensorLayout>,
4947 SemanticActiveRows,
4948 ),
4949 SemanticTransitionError,
4950> {
4951 if bytes.len() < size_of::<TensorLayoutTableHeader>() {
4952 return Err(SemanticTransitionError::ObservationMismatch);
4953 }
4954 let header = unsafe {
4956 bytes
4957 .as_ptr()
4958 .cast::<TensorLayoutTableHeader>()
4959 .read_unaligned()
4960 };
4961 let count = usize::try_from(header.layout_count)
4962 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
4963 if header.abi != 1
4964 || header.active_computed > 1
4965 || (header.active_computed == 0 && header.active_row_count != 0)
4966 || tensor_table_capacity(count, header.active_row_count)? != bytes.len()
4967 {
4968 return Err(SemanticTransitionError::ObservationMismatch);
4969 }
4970 let layouts_end =
4971 size_of::<TensorLayoutTableHeader>() + count * size_of::<SemanticTensorLayout>();
4972 let layouts = bytes[size_of::<TensorLayoutTableHeader>()..layouts_end]
4973 .as_chunks::<{ size_of::<SemanticTensorLayout>() }>()
4974 .0
4975 .iter()
4976 .map(|chunk| unsafe {
4978 chunk
4979 .as_ptr()
4980 .cast::<SemanticTensorLayout>()
4981 .read_unaligned()
4982 })
4983 .collect();
4984 let rows = bytes[layouts_end..]
4985 .as_chunks::<{ size_of::<SemanticActiveRow>() }>()
4986 .0
4987 .iter()
4988 .map(|chunk| unsafe { chunk.as_ptr().cast::<SemanticActiveRow>().read_unaligned() })
4990 .collect();
4991 Ok((
4992 header,
4993 layouts,
4994 SemanticActiveRows {
4995 computed: header.active_computed == 1,
4996 rows,
4997 },
4998 ))
4999}
5000
5001unsafe impl DeviceRepr for PublicationStorageEntry {}
5004unsafe impl DeviceRepr for PublicationRange {}
5005unsafe impl DeviceRepr for PublicationHeader {}
5006unsafe impl DeviceRepr for PublicationControl {}
5007unsafe impl DeviceRepr for PublicationBank {}
5008unsafe impl DeviceRepr for PublicationRoleCount {}
5009unsafe impl DeviceRepr for PublicationContract {}
5010unsafe impl DeviceRepr for PendingContinuation {}
5011unsafe impl DeviceRepr for ModelUpdateBinding {}
5012unsafe impl DeviceRepr for ModelUpdateEvidenceSource {}
5013unsafe impl DeviceRepr for ModelForwardSealInput {}
5014unsafe impl DeviceRepr for ModelForwardReceipt {}
5015unsafe impl DeviceRepr for PublicationCommand {}
5016unsafe impl DeviceRepr for PublicationDeliveryInput {}
5017unsafe impl DeviceRepr for AcknowledgementQueueHeader {}
5018unsafe impl DeviceRepr for AcknowledgementEntry {}
5019unsafe impl DeviceRepr for PublicationLease {}
5020unsafe impl DeviceRepr for SemanticTensorLayout {}
5021unsafe impl DeviceRepr for TensorLayoutTableHeader {}
5023unsafe impl DeviceRepr for SemanticActiveRow {}
5024unsafe impl DeviceRepr for CompletionCoverage {}
5025unsafe impl DeviceRepr for RawFeedbackRecord {}
5026unsafe impl DeviceRepr for AttemptReceipt {}
5027unsafe impl DeviceRepr for IntentQueueHeader {}
5028unsafe impl DeviceRepr for IntentEntry {}
5029unsafe impl DeviceRepr for TokenProvenance {}
5030
5031const _: () = assert!(size_of::<SourceSlot>() == 64);
5032const _: () = assert!(size_of::<PublicationStorageEntry>() == 24);
5033const _: () = assert!(size_of::<PublicationRange>() == 128);
5034const _: () = assert!(size_of::<PublicationHeader>() == 488);
5035const _: () = assert!(size_of::<PublicationControl>() == 144);
5036const _: () = assert!(size_of::<PublicationBank>() == 50360);
5037const _: () = assert!(size_of::<PublicationRoleCount>() == 16);
5038const _: () = assert!(size_of::<SemanticModelContractLayout>() == 48);
5039const _: () = assert!(size_of::<PublicationContract>() == 272);
5040const _: () = assert!(size_of::<SemanticTextRow>() == 16);
5041const _: () = assert!(size_of::<TextBinding>() == 24);
5042const _: () = assert!(size_of::<ModelUpdateBinding>() == 32);
5043const _: () = assert!(size_of::<ModelUpdateEvidenceSource>() == 48);
5044const _: () = assert!(size_of::<ModelForwardSealInput>() == 32);
5045const _: () = assert!(size_of::<ModelForwardReceipt>() == 232);
5046const _: () = assert!(size_of::<ModelForwardReceiptInputs>() == 128);
5047const _: () = assert!(size_of::<PublicationCommand>() == 24);
5048const _: () = assert!(size_of::<PublicationDeliveryInput>() == 88);
5049const _: () = assert!(size_of::<PublicationLease>() == 88);
5050const _: () = assert!(size_of::<SemanticTensorLayout>() == 112);
5051const _: () = assert!(size_of::<TensorLayoutTableHeader>() == 32);
5052const _: () = assert!(size_of::<SemanticActiveRow>() == 32);
5053const _: () = assert!(size_of::<CompletionCoverage>() == 360);
5054const _: () = assert!(size_of::<RawFeedbackRecord>() == 384);
5055const _: () = assert!(size_of::<AttemptReceipt>() == 352);
5056const _: () = assert!(size_of::<IntentQueueHeader>() == 88);
5057const _: () = assert!(size_of::<AcknowledgementQueueHeader>() == 72);
5058const _: () = assert!(size_of::<AcknowledgementEntry>() == 136);
5059const _: () = assert!(size_of::<IntentEntry>() == 344);
5060const _: () = assert!(size_of::<TokenProvenance>() == 184);
5061
5062#[derive(Clone)]
5063enum PublicationPayload {
5064 Metadata(Vec<u8>),
5065 Tensor(PreparedSemanticTensor),
5066 Uncomputed,
5067}
5068
5069struct PublicationAllocationPlan {
5070 role: u64,
5071 index: u64,
5072 capacity: usize,
5073 length: usize,
5074 logical_begin: u64,
5075 logical_end: u64,
5076 payload: PublicationPayload,
5077}
5078
5079#[derive(Clone)]
5082struct PublicationMaterialRange {
5083 range: PublicationRange,
5084 capacity: usize,
5085 bytes: Vec<u8>,
5086}
5087
5088pub struct SemanticFeedbackRecordMaterial {
5093 pub role: SemanticStateRole,
5094 pub index: u64,
5095 pub generation: u64,
5096 pub capacity_bytes: u64,
5097 pub logical_begin: u64,
5098 pub logical_end: u64,
5099 pub identity: Identity256,
5100 pub bytes: Vec<u8>,
5101}
5102
5103#[cfg(feature = "semantic-policy")]
5107#[derive(Clone)]
5108pub struct SemanticCompletedStepWitnessMaterial {
5109 pub identity: Identity256,
5110 pub bytes: Vec<u8>,
5111}
5112
5113#[cfg(feature = "semantic-policy")]
5114pub struct SemanticCompletedModelCarrierMaterial {
5115 pub numerical_realization: SemanticCompletedStepWitnessMaterial,
5116 pub logits: SemanticCompletedStepWitnessMaterial,
5117 pub random_state: SemanticCompletedStepWitnessMaterial,
5118}
5119
5120#[cfg(feature = "semantic-policy")]
5124#[derive(Clone)]
5125pub struct SemanticCompletedActionComponentMaterial {
5126 pub ordinal: u32,
5127 pub null: bool,
5128 pub choice: u32,
5129 pub legal_count: u32,
5130 pub active_count: u32,
5131 pub probability_numerator: [u64; 3],
5132 pub probability_denominator: [u64; 3],
5133 pub importance_denominator: [u64; 3],
5134 pub cumulative_mass_below: [u64; 3],
5135 pub cdf_start: u64,
5136 pub cdf_end: u64,
5137 pub mass: u64,
5138 pub selected_rank: u32,
5139 pub draw: u64,
5140 pub key: [u32; 2],
5141 pub counter: [u32; 4],
5142 pub final_mask: SemanticCompletedStepWitnessMaterial,
5143 pub pwl_cell: SemanticCompletedStepWitnessMaterial,
5144 pub active_set: SemanticCompletedStepWitnessMaterial,
5145 pub vjp: SemanticCompletedStepWitnessMaterial,
5146 pub component_receipt: SemanticCompletedStepWitnessMaterial,
5147 pub hard_decode_receipt: Option<SemanticCompletedStepWitnessMaterial>,
5148}
5149
5150#[cfg(feature = "semantic-policy")]
5152#[derive(Clone)]
5153pub struct SemanticCompletedActionLaneMaterial {
5154 pub text_actions: Vec<(u32, u32)>,
5156 pub edit_actions: [[u32; 18]; 2],
5157 pub admitted: bool,
5158 pub refusal_reason: Option<&'static str>,
5159 pub admission: SemanticCompletedStepWitnessMaterial,
5160 pub hard_decode_receipts: [SemanticCompletedStepWitnessMaterial; 2],
5161}
5162
5163#[cfg(feature = "semantic-policy")]
5166#[derive(Clone)]
5167pub struct SemanticCompletedTheoryDeltaMaterial {
5168 pub kind: &'static str,
5169 pub delta: SemanticCompletedStepWitnessMaterial,
5170 pub theory_generation: Identity256,
5171 pub verdict: &'static str,
5172 pub evidence: SemanticCompletedStepWitnessMaterial,
5173 pub lane: u32,
5174 pub slot: u32,
5175}
5176
5177#[cfg(feature = "semantic-policy")]
5180#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5181pub enum SemanticCompletedLaneOutcomeMaterial {
5182 Executed([crate::SemanticTruth; 3]),
5183 Refused(SemanticTaskRefusal),
5184}
5185
5186#[cfg(feature = "semantic-policy")]
5190#[derive(Clone)]
5191pub struct SemanticCompletedTaskGroundMaterial {
5192 pub witness: SemanticCompletedStepWitnessMaterial,
5193 pub scoring_law: SemanticCompletedStepWitnessMaterial,
5195 pub scoring: SemanticTaskScoring,
5196 pub return_bound: i64,
5197 pub structural_cost: SemanticStructuralCostDescriptor,
5198 pub task_identity: Identity256,
5199 pub content: SemanticTaskContentIdentity,
5200 pub goal: SemanticTaskGoalWitness,
5201 pub priority_levels: Vec<SemanticTaskPriorityLevel>,
5202 pub base: SemanticPublishedIdentity,
5203 pub expected_truth: [crate::SemanticTruth; 3],
5204 pub facts: [SemanticTaskFacts; 3],
5205 pub base_truth: [crate::SemanticTruth; 3],
5206 pub lane_outcomes: [SemanticCompletedLaneOutcomeMaterial; 2],
5207}
5208
5209#[cfg(feature = "semantic-policy")]
5213#[derive(Clone)]
5214pub struct SemanticCompletedEditSolutionMaterial {
5215 pub witness: SemanticCompletedStepWitnessMaterial,
5216 pub lane: u64,
5217 pub component_begin: u64,
5218 pub component_end: u64,
5219 pub structural_delta: SemanticTransitionWork,
5220 pub resulting_state_receipt: SemanticCompletedStepWitnessMaterial,
5221}
5222
5223#[cfg(feature = "semantic-policy")]
5226pub struct SemanticCompletedActionProjectionMaterial {
5227 pub owner: SemanticCompletedStepWitnessMaterial,
5228 pub initial_prefill: Option<SemanticCompletedStepWitnessMaterial>,
5231 pub pre_action_checkpoint: Option<SemanticCompletedStepWitnessMaterial>,
5234 pub world_root: Option<SemanticCompletedStepWitnessMaterial>,
5237 pub schema_generation: SemanticCompletedStepWitnessMaterial,
5238 pub action_law: SemanticCompletedStepWitnessMaterial,
5239 pub edit_codebook: SemanticCompletedStepWitnessMaterial,
5240 pub roster: SemanticCompletedStepWitnessMaterial,
5241 pub estimator_bound: Option<SemanticCompletedStepWitnessMaterial>,
5244 pub predecessor_semantic_root_digest: Identity256,
5246 pub predecessor: SemanticPublishedIdentity,
5247 pub successor: SemanticPublishedIdentity,
5248 pub proposal: u64,
5249 pub stream_serial: u64,
5250 pub family_id: u64,
5251 pub action_law_generation: u64,
5252 pub model_generation: u64,
5253 pub winner: u64,
5254 pub actor_eligible: bool,
5255 pub total_return_bits: u64,
5256 pub batch_root: Identity256,
5257 pub batch_receipt: SemanticCompletedStepWitnessMaterial,
5258 pub result: SemanticCompletedStepWitnessMaterial,
5259 pub action_rng_base: SemanticCompletedStepWitnessMaterial,
5260 pub action_rng_successor: SemanticCompletedStepWitnessMaterial,
5261 pub base_logical_state: SemanticCompletedStepWitnessMaterial,
5262 pub successor_logical_state: SemanticCompletedStepWitnessMaterial,
5263 pub slot_zero_admission: SemanticCompletedStepWitnessMaterial,
5264 pub lanes: [SemanticCompletedActionLaneMaterial; 2],
5265 pub theory_deltas: Vec<SemanticCompletedTheoryDeltaMaterial>,
5266 pub components: Vec<SemanticCompletedActionComponentMaterial>,
5267 pub task_ground: SemanticCompletedTaskGroundMaterial,
5268 pub edit_solution: Option<SemanticCompletedEditSolutionMaterial>,
5269 pub attempt_receipt: SemanticCompletedStepWitnessMaterial,
5270}
5271
5272#[cfg(feature = "semantic-policy")]
5275#[derive(Default)]
5276pub struct SemanticCompletedMaterialCapacity {
5277 pub material_count: usize,
5278 pub largest_material_bytes: usize,
5279 pub total_material_bytes: usize,
5280 pub carrier_bytes: [usize; 3],
5282 pub attempt_receipt_bytes: usize,
5283 pub publication_evidence_bytes: usize,
5284}
5285
5286#[cfg(feature = "semantic-policy")]
5287fn completed_material_extent(parts: &[usize]) -> Result<usize, SemanticTransitionError> {
5288 parts.iter().try_fold(0usize, |total, &bytes| {
5289 total.checked_add(bytes).ok_or_else(|| {
5290 publication_input_error("completed material capacity exceeds host extent")
5291 })
5292 })
5293}
5294
5295#[cfg(feature = "semantic-policy")]
5296fn repeated_material_extent(count: usize, bytes: usize) -> Result<usize, SemanticTransitionError> {
5297 count
5298 .checked_mul(bytes)
5299 .ok_or_else(|| publication_input_error("completed material capacity exceeds host extent"))
5300}
5301
5302#[cfg(feature = "semantic-policy")]
5303impl SemanticCompletedMaterialCapacity {
5304 fn add(&mut self, bytes: usize) -> Result<(), SemanticTransitionError> {
5305 self.material_count = completed_material_extent(&[self.material_count, 1])?;
5306 self.total_material_bytes = completed_material_extent(&[self.total_material_bytes, bytes])?;
5307 self.largest_material_bytes = self.largest_material_bytes.max(bytes);
5308 Ok(())
5309 }
5310
5311 fn child(&mut self, kind: &[u8], payload: usize) -> Result<usize, SemanticTransitionError> {
5312 let bytes = completed_material_extent(&[
5313 b"XLOG-COMPLETED-ACTION-CHILD\0".len(),
5314 32 + 4 * size_of::<u64>(),
5315 kind.len(),
5316 payload,
5317 ])?;
5318 self.add(bytes)?;
5319 Ok(bytes)
5320 }
5321}
5322
5323impl PublicationMaterialRange {
5324 fn into_feedback_record(
5325 self,
5326 ) -> Result<SemanticFeedbackRecordMaterial, SemanticTransitionError> {
5327 if !matches!(self.range.role, 15..=17)
5328 || self.range.generation != 1
5329 || self.range.length_bytes != self.bytes.len() as u64
5330 || self.bytes.is_empty()
5331 || self.bytes.len() > self.capacity
5332 || self.range.logical_begin != 0
5333 || (self.range.role != 15 && self.range.logical_end != 0)
5334 || (self.range.role == 15
5335 && (!self
5336 .bytes
5337 .len()
5338 .is_multiple_of(size_of::<RawFeedbackRecord>())
5339 || self.range.logical_end
5340 > (self.bytes.len() / size_of::<RawFeedbackRecord>()) as u64))
5341 || self.original_record_digest() != self.range.digest
5342 {
5343 return Err(SemanticTransitionError::ObservationMismatch);
5344 }
5345 Ok(SemanticFeedbackRecordMaterial {
5346 role: SemanticStateRole::from_code(self.range.role).expect("checked feedback role"),
5347 index: self.range.index,
5348 generation: self.range.generation,
5349 capacity_bytes: self.capacity as u64,
5350 logical_begin: self.range.logical_begin,
5351 logical_end: self.range.logical_end,
5352 identity: self.range.digest,
5353 bytes: self.bytes,
5354 })
5355 }
5356
5357 fn original_record_digest(&self) -> Identity256 {
5360 debug_assert!(!is_tensor_role(self.range.role));
5361 self.record_digest(&self.bytes)
5362 }
5363
5364 fn digest_prefix(&self) -> [u64; 16] {
5365 let mut prefix = [0u64; 16];
5366 prefix[..5].copy_from_slice(&[
5367 0x786c6f6772616e31,
5368 self.range.role,
5369 self.range.index,
5370 self.range.logical_begin,
5371 self.range.logical_end,
5372 ]);
5373 prefix
5374 }
5375
5376 fn record_digest(&self, bytes: &[u8]) -> Identity256 {
5377 let mut hash = Sha256::new();
5378 for word in self.digest_prefix() {
5379 hash.update(word.to_le_bytes());
5380 }
5381 hash.update(bytes);
5382 Identity256::from_bytes(hash.finalize().into())
5383 }
5384
5385 fn cache_projection(
5388 &self,
5389 layout: SemanticTensorLayout,
5390 ) -> Result<SemanticPublicationTensorProjection, SemanticTransitionError> {
5391 tensor_layout_bytes(&layout)?;
5392 if !matches!(layout.role, 4..=13)
5393 || (layout.role, layout.index) != (self.range.role, self.range.index)
5394 || layout.strides_bytes[..layout.rank as usize]
5395 .iter()
5396 .any(|stride| !stride.is_multiple_of(layout.element_bytes))
5397 {
5398 return Err(publication_input_error(
5399 "cache material has another tensor layout",
5400 ));
5401 }
5402 let mut dimensions = layout.dimensions;
5403 if layout.logical_axis != u64::MAX {
5404 let axis = layout.logical_axis as usize;
5405 dimensions[axis] = self.range.logical_end - self.range.logical_begin;
5406 if dimensions[axis] > layout.dimensions[axis] {
5407 return Err(publication_input_error(
5408 "cache interval exceeds its original layout",
5409 ));
5410 }
5411 }
5412 let cells =
5413 dimensions[..layout.rank as usize]
5414 .iter()
5415 .try_fold(1u64, |cells, &dimension| {
5416 cells
5417 .checked_mul(dimension)
5418 .ok_or(SemanticTransitionError::GenerationExhausted)
5419 })?;
5420 let length = cells
5421 .checked_mul(layout.element_bytes)
5422 .and_then(|bytes| usize::try_from(bytes).ok())
5423 .filter(|&bytes| bytes <= self.bytes.len())
5424 .ok_or(SemanticTransitionError::ObservationMismatch)?;
5425 let mut logical_bytes = Vec::with_capacity(length);
5426 for cell in 0..cells {
5427 let mut coordinate = cell;
5428 let mut offset = 0u64;
5429 for axis in (0..layout.rank as usize).rev() {
5430 let at = coordinate % dimensions[axis];
5431 coordinate /= dimensions[axis];
5432 offset = at
5433 .checked_mul(layout.strides_bytes[axis])
5434 .and_then(|bytes| offset.checked_add(bytes))
5435 .ok_or(SemanticTransitionError::GenerationExhausted)?;
5436 }
5437 let start = usize::try_from(offset)
5438 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
5439 let end = offset
5440 .checked_add(layout.element_bytes)
5441 .and_then(|bytes| usize::try_from(bytes).ok())
5442 .ok_or(SemanticTransitionError::ObservationMismatch)?;
5443 logical_bytes.extend_from_slice(
5444 self.bytes
5445 .get(start..end)
5446 .ok_or(SemanticTransitionError::ObservationMismatch)?,
5447 );
5448 }
5449 let mut prefix = self.digest_prefix();
5450 prefix[5..9].copy_from_slice(&[
5451 layout.element_bytes,
5452 layout.scalar_type,
5453 layout.rank,
5454 layout.logical_axis,
5455 ]);
5456 prefix[9..13].copy_from_slice(&dimensions);
5457 let mut hash = Sha256::new();
5458 for word in prefix {
5459 hash.update(word.to_le_bytes());
5460 }
5461 hash.update(&logical_bytes);
5462 if Identity256::from_bytes(hash.finalize().into()) != self.range.digest {
5463 return Err(publication_input_error(
5464 "cache bytes differ from their original native seal",
5465 ));
5466 }
5467 Ok(SemanticPublicationTensorProjection {
5468 layout,
5469 capacity_bytes: self.capacity as u64,
5470 logical_begin: self.range.logical_begin,
5471 logical_end: self.range.logical_end,
5472 identity: self.range.digest,
5473 logical_bytes,
5474 })
5475 }
5476
5477 fn attempt(&self) -> Result<AttemptReceipt, SemanticTransitionError> {
5478 if self.range.role != 33 || self.bytes.len() != size_of::<AttemptReceipt>() {
5479 return Err(publication_input_error(
5480 "replay evidence requires the whole native attempt receipt",
5481 ));
5482 }
5483 Ok(unsafe { std::ptr::read_unaligned(self.bytes.as_ptr().cast::<AttemptReceipt>()) })
5485 }
5486
5487 fn logical_record_digest(&self) -> Result<Identity256, SemanticTransitionError> {
5491 let mut bytes = self.bytes.clone();
5492 match self.range.role {
5493 14 | 33 => {
5494 let (extent, first, last, tail) = if self.range.role == 14 {
5495 (size_of::<CompletionCoverage>(), 1, 5, 41)
5496 } else {
5497 (size_of::<AttemptReceipt>(), 1, 6, 39)
5498 };
5499 if bytes.len() != extent {
5500 return Err(publication_input_error(
5501 "replay record has another native ABI extent",
5502 ));
5503 }
5504 bytes[first * 8..(last + 1) * 8].fill(0);
5505 bytes[tail * 8..].fill(0);
5506 }
5507 30 => {
5508 if bytes.len() < size_of::<IntentQueueHeader>() {
5509 return Err(publication_input_error(
5510 "replay intent queue omits its native header",
5511 ));
5512 }
5513 let header =
5515 unsafe { std::ptr::read_unaligned(bytes.as_ptr().cast::<IntentQueueHeader>()) };
5516 if header.abi != 1
5517 || header.count > header.capacity
5518 || header
5519 .count
5520 .checked_mul(size_of::<IntentEntry>() as u64)
5521 .and_then(|n| n.checked_add(size_of::<IntentQueueHeader>() as u64))
5522 != Some(bytes.len() as u64)
5523 {
5524 return Err(publication_input_error(
5525 "replay intent queue differs from its exact native extent",
5526 ));
5527 }
5528 for entry in bytes[size_of::<IntentQueueHeader>()..]
5529 .as_chunks_mut::<{ size_of::<IntentEntry>() }>()
5530 .0
5531 {
5532 entry[30 * 8..35 * 8].fill(0);
5533 }
5534 }
5535 27 | 28 | 31 | 32 => {}
5536 _ => {
5537 return Err(publication_input_error(
5538 "record is not a native replay comparison record",
5539 ))
5540 }
5541 }
5542 Ok(self.record_digest(&bytes))
5543 }
5544
5545 fn encode_into(&self, bytes: &mut Vec<u8>) -> Result<(), SemanticTransitionError> {
5546 material_bytes(bytes, &publication_abi_bytes(&[self.range]))
5547 .map_err(SemanticTransitionError::Semantic)?;
5548 material_u64(bytes, self.capacity as u64);
5549 material_bytes(bytes, &self.bytes).map_err(SemanticTransitionError::Semantic)
5550 }
5551
5552 fn decode_from(
5553 reader: &mut SemanticMaterialReader<'_>,
5554 ) -> Result<Self, SemanticTransitionError> {
5555 let range = unsafe { publication_material_record::<PublicationRange>(reader)? };
5557 let capacity = usize::try_from(reader.u64().map_err(SemanticTransitionError::Semantic)?)
5558 .map_err(|_| {
5559 publication_input_error("publication material capacity exceeds host extent")
5560 })?;
5561 let bytes = reader
5562 .bytes()
5563 .map_err(SemanticTransitionError::Semantic)?
5564 .to_vec();
5565 Ok(Self {
5566 range,
5567 capacity,
5568 bytes,
5569 })
5570 }
5571}
5572
5573fn publication_fold_digest(
5576 digest: Identity256,
5577 role: u64,
5578 index: u64,
5579 content: Identity256,
5580) -> Identity256 {
5581 let mut hash = Sha256::new();
5582 hash.update(digest.as_bytes());
5583 hash.update(role.to_le_bytes());
5584 hash.update(index.to_le_bytes());
5585 hash.update(content.as_bytes());
5586 Identity256::from_bytes(hash.finalize().into())
5587}
5588
5589fn publication_action_receipts_digest(
5590 codebook: &PublicationMaterialRange,
5591 receipts: &[SemanticTransitionReceipt],
5592) -> Result<Identity256, SemanticTransitionError> {
5593 if codebook.range.role != 48 {
5596 return Err(publication_input_error(
5597 "replay action codebook has another native extent",
5598 ));
5599 }
5600 publication_action_receipts_digest_bytes(&codebook.bytes, receipts)
5601}
5602
5603fn publication_action_receipts_digest_bytes(
5604 bytes: &[u8],
5605 receipts: &[SemanticTransitionReceipt],
5606) -> Result<Identity256, SemanticTransitionError> {
5607 if bytes.len() < 25 * 8 || !bytes.len().is_multiple_of(8) {
5608 return Err(publication_input_error(
5609 "replay action codebook has another native extent",
5610 ));
5611 }
5612 let word =
5613 |index: usize| u64::from_le_bytes(bytes[index * 8..(index + 1) * 8].try_into().unwrap());
5614 let (offset, length) = (word(8), word(9));
5615 if offset % 8 != 0
5616 || offset > bytes.len() as u64
5617 || length > bytes.len() as u64 - offset
5618 || (offset + length).div_ceil(8) != (bytes.len() / 8) as u64
5619 {
5620 return Err(publication_input_error(
5621 "replay action codebook omits its exact statement payload",
5622 ));
5623 }
5624 let mut hash = Sha256::new();
5625 hash.update(b"xlog.semantic.logical-codebooks.v1\0");
5626 hash.update(CATALOGUE_DIGEST);
5627 hash.update(((bytes.len() / 8) as u64).to_le_bytes());
5628 for (index, bytes) in bytes.as_chunks::<8>().0.iter().enumerate() {
5629 hash.update(if matches!(index, 14..=16 | 21..=24) {
5630 &[0; 8]
5631 } else {
5632 bytes
5633 });
5634 }
5635 let binding = Identity256::from_bytes(hash.finalize().into());
5636 let mut hash = Sha256::new();
5637 for receipt in receipts {
5638 let mut normalized = *receipt;
5639 if normalized.catalogue_generation == CATALOGUE_GENERATION {
5640 normalized.admission_binding = binding;
5641 }
5642 hash.update(publication_abi_bytes(&[normalized]));
5643 }
5644 Ok(Identity256::from_bytes(hash.finalize().into()))
5645}
5646
5647fn publication_semantic_receipts_digest(receipts: &[[u64; 42]; 7]) -> Identity256 {
5648 let mut hash = Sha256::new();
5649 for receipt in receipts {
5650 for (index, &word) in receipt.iter().enumerate() {
5651 hash.update(
5652 if matches!(index, 3..=12 | 34..=41) {
5653 0
5654 } else {
5655 word
5656 }
5657 .to_le_bytes(),
5658 );
5659 }
5660 }
5661 Identity256::from_bytes(hash.finalize().into())
5662}
5663
5664fn publication_action_batch_root(batch: &SemanticActionBatchReceipt) -> Identity256 {
5665 Identity256::from_bytes(Sha256::digest(publication_abi_bytes(&[*batch])).into())
5666}
5667
5668const REPLAY_EVIDENCE_ROLES: [u64; 6] = [27, 28, 30, 31, 32, 33];
5669const REPLAY_EVIDENCE_MAGIC: &[u8] = b"XLOG-REPLAY-EVIDENCE\0";
5670const REPLAY_PROVENANCE_MAGIC: &[u8] = b"XLOG-REPLAY-PROVENANCE\0";
5671
5672fn encode_publication_identity(bytes: &mut Vec<u8>, identity: SemanticPublishedIdentity) {
5673 bytes.extend_from_slice(identity.instance.as_bytes());
5674 material_u64(bytes, identity.word);
5675 bytes.extend_from_slice(identity.logical_digest.as_bytes());
5676 bytes.extend_from_slice(identity.state_digest.as_bytes());
5677}
5678
5679#[cfg(feature = "semantic-policy")]
5680fn completed_action_child_material(
5681 owner: Identity256,
5682 kind: &[u8],
5683 ordinal: u64,
5684 payload: &[u8],
5685) -> SemanticCompletedStepWitnessMaterial {
5686 let mut owner_binding = Vec::new();
5687 owner_binding.extend_from_slice(b"xlog.completed-action-child.v1\0");
5688 owner_binding.extend_from_slice(owner.as_bytes());
5689 material_u64(&mut owner_binding, kind.len() as u64);
5690 owner_binding.extend_from_slice(kind);
5691 material_u64(&mut owner_binding, ordinal);
5692 let identity = Identity256::from_bytes(Sha256::digest(&owner_binding).into());
5693
5694 let mut bytes = Vec::new();
5695 bytes.extend_from_slice(b"XLOG-COMPLETED-ACTION-CHILD\0");
5696 material_u64(&mut bytes, 1);
5697 bytes.extend_from_slice(owner.as_bytes());
5698 material_u64(&mut bytes, kind.len() as u64);
5699 bytes.extend_from_slice(kind);
5700 material_u64(&mut bytes, ordinal);
5701 material_u64(&mut bytes, payload.len() as u64);
5702 bytes.extend_from_slice(payload);
5703 SemanticCompletedStepWitnessMaterial { identity, bytes }
5704}
5705
5706#[cfg(feature = "semantic-policy")]
5707fn encode_completed_component_receipt(bytes: &mut Vec<u8>, receipt: SemanticTransitionReceipt) {
5708 material_u64(bytes, receipt.proposal);
5709 material_u64(bytes, receipt.catalogue_generation);
5710 bytes.extend_from_slice(receipt.catalogue_digest.as_bytes());
5711 bytes.extend_from_slice(receipt.admission_binding.as_bytes());
5712 for value in [
5713 receipt.ordinal,
5714 receipt.lane,
5715 receipt.slot,
5716 receipt.field,
5717 receipt.kind,
5718 receipt.choice,
5719 receipt.legal_count,
5720 receipt.active_count,
5721 receipt.selected_rank,
5722 ] {
5723 material_u64(bytes, value as u64);
5724 }
5725 for value in receipt.key {
5726 material_u64(bytes, value as u64);
5727 }
5728 for value in receipt.counter {
5729 material_u64(bytes, value as u64);
5730 }
5731 for value in receipt.random_words {
5732 material_u64(bytes, value as u64);
5733 }
5734 for value in [
5735 receipt.draw,
5736 receipt.cdf_start,
5737 receipt.cdf_end,
5738 receipt.mass,
5739 ] {
5740 material_u64(bytes, value);
5741 }
5742 for limbs in [
5743 receipt.p,
5744 receipt.q,
5745 receipt.factor_denominator,
5746 receipt.cumulative_mass_below,
5747 ] {
5748 for value in limbs {
5749 material_u64(bytes, value);
5750 }
5751 }
5752 material_u64(bytes, receipt.active_fields as u64);
5753 material_u64(bytes, receipt.null_fields as u64);
5754}
5755
5756#[cfg(feature = "semantic-policy")]
5757fn completed_receipt_material(
5758 owner: Identity256,
5759 kind: &[u8],
5760 ordinal: u64,
5761 receipt: &[u64; 42],
5762) -> SemanticCompletedStepWitnessMaterial {
5763 let mut payload = Vec::new();
5764 for value in receipt {
5765 material_u64(&mut payload, *value);
5766 }
5767 completed_action_child_material(owner, kind, ordinal, &payload)
5768}
5769
5770#[expect(
5771 clippy::too_many_arguments,
5772 reason = "the native rule receipt binds task, lane, slot, current edit, and prior edit independently"
5773)]
5774fn validated_rule_receipt(
5775 codebooks: &ActionCodebooks,
5776 program: &crate::SemanticProgramAdmission,
5777 task_identity: Identity256,
5778 lane: usize,
5779 slot: usize,
5780 choices: &[u32; 18],
5781 previous_choices: Option<&[u32; 18]>,
5782 receipt: &[u64; 42],
5783) -> Result<
5784 (
5785 SemanticDecodedRuleInsertion,
5786 Option<crate::SemanticProgramRule>,
5787 ),
5788 SemanticTransitionError,
5789> {
5790 let mismatch = || SemanticTransitionError::ObservationMismatch;
5791 if lane >= 2 || slot >= 2 {
5792 return Err(mismatch());
5793 }
5794 let decoded = codebooks.decoded_rule_insertion(program, choices)?;
5795 let previous = match previous_choices {
5796 Some(prior) if prior[0] == 1 && prior[1] == 2 => {
5797 Some(codebooks.decoded_rule_insertion(program, prior)?.rule)
5798 }
5799 Some(prior) if prior.iter().all(|&choice| choice == 0) => None,
5800 None => None,
5801 _ => return Err(mismatch()),
5802 };
5803 let previous_fields = previous.map(semantic_program_rule_words).unwrap_or([0; 10]);
5804 if receipt[0] != 0
5805 || receipt[1] != 3
5806 || receipt[2] != lane as u64 + 1
5807 || receipt[3] != slot as u64
5808 || receipt[4..8] != identity_words(*task_identity.as_bytes())
5809 || receipt[8..12] != identity_words(*codebooks.binding.digest.as_bytes())
5810 || receipt[12..22] != semantic_program_rule_words(decoded.rule)
5811 || receipt[22] != program.initial_facts.len() as u64
5812 || receipt[23] != program.initial_rules.len() as u64
5813 || receipt[24] != u64::from(previous.is_some())
5814 || receipt[25..35] != previous_fields
5815 || receipt[35..].iter().any(|&word| word != 0)
5816 {
5817 return Err(mismatch());
5818 }
5819 Ok((decoded, previous))
5820}
5821
5822#[cfg(feature = "semantic-policy")]
5823#[expect(
5824 clippy::too_many_arguments,
5825 reason = "one delta binds independent native owner, source, decode, and admission receipts"
5826)]
5827fn completed_theory_delta_for_slot(
5828 codebooks: &ActionCodebooks,
5829 admission: &SemanticAdmission,
5830 program: Option<&crate::SemanticProgramAdmission>,
5831 task_identity: Identity256,
5832 owner: Identity256,
5833 predecessor_semantic_root_digest: Identity256,
5834 lane: usize,
5835 slot: usize,
5836 choices: &[u32; 18],
5837 previous_choices: Option<&[u32; 18]>,
5838 hard_decode: &[u64; 42],
5839 lane_admission: &[u64; 42],
5840 component_receipts: &[SemanticTransitionReceipt],
5841 lane_refusal: u64,
5842) -> Result<Option<SemanticCompletedTheoryDeltaMaterial>, SemanticTransitionError> {
5843 if lane >= 2
5844 || slot >= 2
5845 || component_receipts.len() != 18
5846 || hard_decode[0] != 0
5847 || hard_decode[1] > 3
5848 || lane_refusal > 4
5849 {
5850 return Err(SemanticTransitionError::ObservationMismatch);
5851 }
5852 if hard_decode[1] == 0 {
5853 if choices[0] == 1 && choices[1] == 2 {
5854 return Err(SemanticTransitionError::ObservationMismatch);
5855 }
5856 return Ok(None);
5857 }
5858 if hard_decode[1] == 3 {
5859 let program = program.ok_or(SemanticTransitionError::ObservationMismatch)?;
5860 let (decoded, previous) = validated_rule_receipt(
5861 codebooks,
5862 program,
5863 task_identity,
5864 lane,
5865 slot,
5866 choices,
5867 previous_choices,
5868 hard_decode,
5869 )?;
5870 let previous_fields = previous.map(semantic_program_rule_words).unwrap_or([0; 10]);
5871 let program_binding = ActionCodebooks::program_binding(program);
5872 let theory_generation = if previous.is_some() {
5873 let mut hash = Sha256::new();
5874 hash.update(b"xlog.semantic.program-theory.v1\0");
5875 hash.update(program_binding.as_bytes());
5876 for word in previous_fields {
5877 hash.update(word.to_le_bytes());
5878 }
5879 Identity256::from_bytes(hash.finalize().into())
5880 } else {
5881 program_binding
5882 };
5883 let ordinal = (lane * 2 + slot) as u64;
5884 let delta =
5885 completed_action_child_material(owner, b"theory-rule-delta", ordinal, &decoded.bytes);
5886 let mut payload = Vec::new();
5887 payload.extend_from_slice(theory_generation.as_bytes());
5888 payload.extend_from_slice(task_identity.as_bytes());
5889 material_u64(&mut payload, lane as u64 + 1);
5890 material_u64(&mut payload, slot as u64);
5891 material_u64(&mut payload, lane_refusal);
5892 for receipt in [hard_decode, lane_admission] {
5893 for &word in receipt {
5894 material_u64(&mut payload, word);
5895 }
5896 }
5897 for receipt in component_receipts {
5898 encode_completed_component_receipt(&mut payload, *receipt);
5899 }
5900 let evidence = completed_action_child_material(
5901 owner,
5902 b"theory-rule-delta-evidence",
5903 ordinal,
5904 &payload,
5905 );
5906 return Ok(Some(SemanticCompletedTheoryDeltaMaterial {
5907 kind: "rule",
5908 delta,
5909 theory_generation,
5910 verdict: if lane_refusal == 0 {
5911 "accepted"
5912 } else {
5913 "rejected"
5914 },
5915 evidence,
5916 lane: lane as u32 + 1,
5917 slot: slot as u32,
5918 }));
5919 }
5920 if program.is_some() {
5921 return Err(SemanticTransitionError::ObservationMismatch);
5922 }
5923 let decoded = codebooks
5924 .decoded_support_insertion(admission, choices)?
5925 .ok_or(SemanticTransitionError::ObservationMismatch)?;
5926 if hard_decode[20..24] != identity_words(*decoded.statement.as_bytes())
5927 || hard_decode[24..28] != identity_words(*decoded.support.as_bytes())
5928 {
5929 return Err(SemanticTransitionError::ObservationMismatch);
5930 }
5931 let ordinal = (lane * 2 + slot) as u64;
5932 let delta = completed_action_child_material(owner, b"theory-delta", ordinal, &decoded.bytes);
5933 let mut payload = Vec::new();
5934 payload.extend_from_slice(predecessor_semantic_root_digest.as_bytes());
5935 material_u64(&mut payload, lane as u64 + 1);
5936 material_u64(&mut payload, slot as u64);
5937 material_u64(&mut payload, lane_refusal);
5938 material_u32(&mut payload, decoded.source_event);
5939 for reference in decoded.reconstruction {
5940 material_u32(&mut payload, reference);
5941 }
5942 for receipt in [hard_decode, lane_admission] {
5943 for &word in receipt {
5944 material_u64(&mut payload, word);
5945 }
5946 }
5947 for receipt in component_receipts {
5948 encode_completed_component_receipt(&mut payload, *receipt);
5949 }
5950 let evidence =
5951 completed_action_child_material(owner, b"theory-delta-evidence", ordinal, &payload);
5952 Ok(Some(SemanticCompletedTheoryDeltaMaterial {
5953 kind: "fact",
5954 delta,
5955 theory_generation: predecessor_semantic_root_digest,
5956 verdict: if lane_refusal == 0 {
5957 "accepted"
5958 } else {
5959 "rejected"
5960 },
5961 evidence,
5962 lane: lane as u32 + 1,
5963 slot: slot as u32,
5964 }))
5965}
5966
5967fn validate_program_query_receipts(
5968 program: &crate::SemanticProgramAdmission,
5969 task_identity: Identity256,
5970 codebooks: &ActionCodebooks,
5971 state: &DeviceState,
5972 edits: &[[[u32; 18]; 2]; 2],
5973) -> Result<(), SemanticTransitionError> {
5974 let mismatch = || SemanticTransitionError::ObservationMismatch;
5975 let expected_queries = 3 + state
5976 .task_evaluation
5977 .lane_refusal
5978 .iter()
5979 .filter(|&&refusal| refusal != 3 && refusal != 4)
5980 .count() as u64
5981 * 3;
5982 if state.binding_digest != codebooks.binding.digest
5983 || state.task_evaluation.query_count != expected_queries
5984 || state.task_evaluation.lane_refusal.contains(&1)
5985 {
5986 return Err(mismatch());
5987 }
5988 let mut inserted: [Vec<crate::SemanticProgramRule>; 2] = std::array::from_fn(|_| Vec::new());
5989 for (lane, actions) in edits.iter().enumerate() {
5990 for choices in actions {
5991 match (choices[0], choices[1]) {
5992 (0, 0) if choices[2..].iter().all(|&value| value == 0) => {}
5993 (1, 2) => {
5994 inserted[lane].push(codebooks.decoded_rule_insertion(program, choices)?.rule)
5995 }
5996 _ => return Err(mismatch()),
5997 }
5998 }
5999 }
6000 let task_words = identity_words(*task_identity.as_bytes());
6001 let binding_words = identity_words(*codebooks.binding.digest.as_bytes());
6002 for slot in 0..3 {
6003 let rules: &[crate::SemanticProgramRule] =
6004 if slot == 0 { &[] } else { &inserted[slot - 1] };
6005 let receipts = &state.task_evaluation.query_receipts[slot];
6006 let facts = &state.task_evaluation.facts[slot];
6007 if slot != 0 && matches!(state.task_evaluation.lane_refusal[slot - 1], 3 | 4) {
6008 let work = state.work[slot - 1];
6009 if rules.is_empty()
6010 || receipts
6011 .iter()
6012 .any(|receipt| receipt.iter().any(|&word| word != 0))
6013 || facts.truth != [0; 3]
6014 || facts.correct != [0; 3]
6015 || facts.g != 0
6016 || facts.p != 0
6017 || facts.eligible != 0
6018 || work.edit_commands != rules.len() as u64
6019 || work.added_supports != 0
6020 || work.defined_truth_changes != 0
6021 {
6022 return Err(mismatch());
6023 }
6024 continue;
6025 }
6026 let metrics = &receipts[0][37..40];
6027 if metrics[1] > crate::semantic_program::RESIDENT_PROGRAM_FACT_CAPACITY as u64
6028 || metrics[2] > metrics[1]
6029 || facts.truth.iter().any(|&truth| truth > 1)
6030 {
6031 return Err(mismatch());
6032 }
6033 for (query, receipt) in receipts.iter().enumerate() {
6034 let mut expected = [0u64; 42];
6035 expected[1] = 0x5850524f47515545;
6036 expected[2] = facts.truth[query];
6037 expected[3] = slot as u64;
6038 expected[4] = query as u64;
6039 expected[5..9].copy_from_slice(&task_words);
6040 expected[9..13].copy_from_slice(&binding_words);
6041 expected[13] = rules.len() as u64;
6042 for (edit, rule) in rules.iter().enumerate() {
6043 expected[14 + edit * 10..24 + edit * 10]
6044 .copy_from_slice(&semantic_program_rule_words(*rule));
6045 }
6046 let query_fact = program.queries[query];
6047 expected[34..37].copy_from_slice(&[
6048 u64::from(query_fact.predicate),
6049 u64::from(query_fact.first),
6050 u64::from(query_fact.second),
6051 ]);
6052 expected[37..40].copy_from_slice(metrics);
6053 expected[40] = program.initial_rules.len() as u64;
6054 expected[41] = program.initial_facts.len() as u64;
6055 if receipt != &expected {
6056 return Err(mismatch());
6057 }
6058 }
6059 if slot != 0 {
6060 let baseline = &state.task_evaluation.facts[0];
6061 let derived = metrics[2]
6062 .checked_sub(state.task_evaluation.query_receipts[0][0][39])
6063 .ok_or_else(mismatch)?;
6064 let truth_changes = facts
6065 .truth
6066 .iter()
6067 .zip(baseline.truth)
6068 .filter(|(current, original)| **current != *original)
6069 .count() as u64;
6070 let work = state.work[slot - 1];
6071 if work.edit_commands != rules.len() as u64
6072 || work.added_supports != derived
6073 || work.defined_truth_changes != truth_changes
6074 {
6075 return Err(mismatch());
6076 }
6077 }
6078 }
6079 Ok(())
6080}
6081
6082#[cfg(feature = "semantic-policy")]
6083fn completed_task_truths(
6084 facts: SemanticTaskFacts,
6085) -> Result<[crate::SemanticTruth; 3], SemanticTransitionError> {
6086 Ok([
6087 crate::SemanticTruth::from_bits(facts.truth[0])
6088 .map_err(SemanticTransitionError::Semantic)?,
6089 crate::SemanticTruth::from_bits(facts.truth[1])
6090 .map_err(SemanticTransitionError::Semantic)?,
6091 crate::SemanticTruth::from_bits(facts.truth[2])
6092 .map_err(SemanticTransitionError::Semantic)?,
6093 ])
6094}
6095
6096#[cfg(feature = "semantic-policy")]
6097fn encode_completed_task_facts(bytes: &mut Vec<u8>, facts: SemanticTaskFacts) {
6098 for value in facts.truth {
6099 material_u64(bytes, value);
6100 }
6101 for value in facts.correct {
6102 material_u64(bytes, value);
6103 }
6104 for value in [facts.g, facts.p, facts.c, facts.v as u64, facts.eligible] {
6105 material_u64(bytes, value);
6106 }
6107}
6108
6109#[cfg(feature = "semantic-policy")]
6110fn bind_completed_material(bytes: &mut Vec<u8>, material: &SemanticCompletedStepWitnessMaterial) {
6111 bytes.extend_from_slice(material.identity.as_bytes());
6112 bytes.extend_from_slice(&Sha256::digest(&material.bytes));
6113}
6114
6115#[cfg(feature = "semantic-policy")]
6116fn completed_logical_state_material(
6117 owner: Identity256,
6118 ordinal: u64,
6119 identity: SemanticPublishedIdentity,
6120) -> SemanticCompletedStepWitnessMaterial {
6121 let mut payload = Vec::new();
6122 encode_publication_identity(&mut payload, identity);
6123 let mut material = completed_action_child_material(owner, b"logical-state", ordinal, &payload);
6124 material.identity = identity.logical_digest;
6125 material
6126}
6127
6128#[cfg(feature = "semantic-policy")]
6129fn completed_rng_material(
6130 owner: Identity256,
6131 ordinal: u64,
6132 model_generation: u64,
6133 stream_serial: u64,
6134 family_id: u64,
6135 proposal: u64,
6136) -> SemanticCompletedStepWitnessMaterial {
6137 let mut payload = Vec::new();
6138 for value in [model_generation, stream_serial, family_id, proposal] {
6139 material_u64(&mut payload, value);
6140 }
6141 completed_action_child_material(owner, b"action-rng", ordinal, &payload)
6142}
6143
6144fn decode_publication_identity(
6145 reader: &mut SemanticMaterialReader<'_>,
6146) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
6147 let instance = Identity256::from_bytes(
6148 reader
6149 .take(32)
6150 .map_err(SemanticTransitionError::Semantic)?
6151 .try_into()
6152 .unwrap(),
6153 );
6154 let word = reader.u64().map_err(SemanticTransitionError::Semantic)?;
6155 let logical_digest = Identity256::from_bytes(
6156 reader
6157 .take(32)
6158 .map_err(SemanticTransitionError::Semantic)?
6159 .try_into()
6160 .unwrap(),
6161 );
6162 let state_digest = Identity256::from_bytes(
6163 reader
6164 .take(32)
6165 .map_err(SemanticTransitionError::Semantic)?
6166 .try_into()
6167 .unwrap(),
6168 );
6169 Ok(SemanticPublishedIdentity {
6170 instance,
6171 word,
6172 logical_digest,
6173 state_digest,
6174 })
6175}
6176
6177struct PublicationReplayProvenance {
6180 predecessor: SemanticPublishedIdentity,
6181 authority: PublicationMaterialRange,
6182 decision: PublicationMaterialRange,
6183}
6184
6185impl PublicationReplayProvenance {
6186 fn encode(&self) -> Result<Vec<u8>, SemanticTransitionError> {
6187 let mut bytes = REPLAY_PROVENANCE_MAGIC.to_vec();
6188 material_u32(&mut bytes, 1);
6189 bytes.extend_from_slice(&publication_material_runtime());
6190 encode_publication_identity(&mut bytes, self.predecessor);
6191 self.authority.encode_into(&mut bytes)?;
6192 self.decision.encode_into(&mut bytes)?;
6193 Ok(bytes)
6194 }
6195
6196 fn decode(bytes: &[u8]) -> Result<Self, SemanticTransitionError> {
6197 let mut reader = SemanticMaterialReader::new(bytes);
6198 if reader
6199 .take(REPLAY_PROVENANCE_MAGIC.len())
6200 .map_err(SemanticTransitionError::Semantic)?
6201 != REPLAY_PROVENANCE_MAGIC
6202 || reader.u32().map_err(SemanticTransitionError::Semantic)? != 1
6203 || reader.take(32).map_err(SemanticTransitionError::Semantic)?
6204 != publication_material_runtime()
6205 {
6206 return Err(publication_input_error(
6207 "replay provenance requires its exact pinned native runtime",
6208 ));
6209 }
6210 let predecessor = decode_publication_identity(&mut reader)?;
6211 let authority = PublicationMaterialRange::decode_from(&mut reader)?;
6212 let decision = PublicationMaterialRange::decode_from(&mut reader)?;
6213 reader.finish().map_err(SemanticTransitionError::Semantic)?;
6214 Ok(Self {
6215 predecessor,
6216 authority,
6217 decision,
6218 })
6219 }
6220
6221 fn validate(&self, predecessor: &PublicationMaterial) -> Result<(), SemanticTransitionError> {
6222 let header = predecessor.bank.header;
6223 let original = SemanticPublishedIdentity {
6224 instance: header.instance,
6225 word: header.publication_word,
6226 logical_digest: header.logical_digest,
6227 state_digest: header.state_digest,
6228 };
6229 if self.predecessor != original {
6230 return Err(publication_input_error(
6231 "replay provenance names another original native predecessor",
6232 ));
6233 }
6234 for (item, role) in [(&self.authority, 38), (&self.decision, 39)] {
6235 let saved = predecessor
6236 .ranges
6237 .iter()
6238 .find(|item| item.range.role == role && item.range.index == 0)
6239 .ok_or(SemanticTransitionError::ObservationMismatch)?;
6240 if (item.range.role, item.range.index) != (role, 0)
6241 || item.range.generation != 1
6242 || item.range.length_bytes != item.bytes.len() as u64
6243 || item.capacity != saved.capacity
6244 || item.capacity == 0
6245 || item.bytes.is_empty()
6246 || item.bytes.len() > item.capacity
6247 || item.range.logical_begin > item.range.logical_end
6248 || item.original_record_digest() != item.range.digest
6249 {
6250 return Err(publication_input_error(
6251 "replay provenance changes an originally sealed authority record",
6252 ));
6253 }
6254 if role == 38
6255 && (item.bytes != saved.bytes
6256 || publication_abi_bytes(&[item.range])
6257 != publication_abi_bytes(&[saved.range]))
6258 {
6259 return Err(publication_input_error("replay provenance differs from the predecessor's whole original authority envelope"));
6260 }
6261 }
6262 Ok(())
6263 }
6264}
6265
6266struct PublicationReplayEvidence {
6267 successor: SemanticPublishedIdentity,
6268 ranges: Vec<PublicationMaterialRange>,
6269}
6270
6271impl PublicationReplayEvidence {
6272 fn range(&self, role: u64) -> Result<&PublicationMaterialRange, SemanticTransitionError> {
6273 self.ranges
6274 .iter()
6275 .find(|item| item.range.role == role && item.range.index == 0)
6276 .ok_or_else(|| publication_input_error("replay evidence omits a publication record"))
6277 }
6278
6279 fn state_digest(&self) -> Result<Identity256, SemanticTransitionError> {
6280 let mut digest = self.successor.logical_digest;
6281 for item in &self.ranges {
6282 digest = publication_fold_digest(
6283 digest,
6284 item.range.role,
6285 item.range.index,
6286 item.logical_record_digest()?,
6287 );
6288 }
6289 Ok(digest)
6290 }
6291
6292 fn encode(&self) -> Result<Vec<u8>, SemanticTransitionError> {
6293 let mut bytes = REPLAY_EVIDENCE_MAGIC.to_vec();
6294 material_u32(&mut bytes, 1);
6295 bytes.extend_from_slice(&publication_material_runtime());
6296 encode_publication_identity(&mut bytes, self.successor);
6297 material_u32(
6298 &mut bytes,
6299 u32::try_from(self.ranges.len())
6300 .map_err(|_| SemanticTransitionError::GenerationExhausted)?,
6301 );
6302 for item in &self.ranges {
6303 item.encode_into(&mut bytes)?;
6304 }
6305 Ok(bytes)
6306 }
6307
6308 fn decode(bytes: &[u8]) -> Result<Self, SemanticTransitionError> {
6309 let mut reader = SemanticMaterialReader::new(bytes);
6310 if reader
6311 .take(REPLAY_EVIDENCE_MAGIC.len())
6312 .map_err(SemanticTransitionError::Semantic)?
6313 != REPLAY_EVIDENCE_MAGIC
6314 || reader.u32().map_err(SemanticTransitionError::Semantic)? != 1
6315 || reader.take(32).map_err(SemanticTransitionError::Semantic)?
6316 != publication_material_runtime()
6317 {
6318 return Err(publication_input_error(
6319 "replay evidence requires its exact pinned native runtime",
6320 ));
6321 }
6322 let successor = decode_publication_identity(&mut reader)?;
6323 if reader.u32().map_err(SemanticTransitionError::Semantic)?
6324 != REPLAY_EVIDENCE_ROLES.len() as u32
6325 {
6326 return Err(publication_input_error(
6327 "replay evidence requires all six native publication records",
6328 ));
6329 }
6330 let mut ranges = Vec::with_capacity(REPLAY_EVIDENCE_ROLES.len());
6331 for _ in REPLAY_EVIDENCE_ROLES {
6332 ranges.push(PublicationMaterialRange::decode_from(&mut reader)?);
6333 }
6334 reader.finish().map_err(SemanticTransitionError::Semantic)?;
6335 Ok(Self { successor, ranges })
6336 }
6337
6338 fn validate(
6339 &self,
6340 predecessor: &PublicationMaterial,
6341 ) -> Result<SemanticTransitionKind, SemanticTransitionError> {
6342 let base = predecessor.bank.header;
6343 let successor_word = (base.publication_word >> 1)
6344 .checked_add(1)
6345 .filter(|&epoch| epoch <= u64::MAX >> 1)
6346 .map(|epoch| (epoch << 1) | ((base.publication_word & 1) ^ 1))
6347 .ok_or(SemanticTransitionError::GenerationExhausted)?;
6348 if self.successor.instance != base.instance
6349 || self.successor.word != successor_word
6350 || self.ranges.len() != REPLAY_EVIDENCE_ROLES.len()
6351 {
6352 return Err(publication_input_error(
6353 "replay evidence is not the original predecessor's immediate successor",
6354 ));
6355 }
6356 for (item, role) in self.ranges.iter().zip(REPLAY_EVIDENCE_ROLES) {
6357 let previous = predecessor
6358 .ranges
6359 .iter()
6360 .find(|item| item.range.role == role && item.range.index == 0)
6361 .ok_or(SemanticTransitionError::ObservationMismatch)?;
6362 if (item.range.role, item.range.index) != (role, 0)
6363 || item.range.generation != 1
6364 || item.range.length_bytes != item.bytes.len() as u64
6365 || item.capacity != previous.capacity
6366 || item.capacity == 0
6367 || item.bytes.len() > item.capacity
6368 || item.range.logical_begin > item.range.logical_end
6369 || item.original_record_digest() != item.range.digest
6370 {
6371 return Err(publication_input_error(
6372 "replay evidence changes or omits an originally sealed publication record",
6373 ));
6374 }
6375 }
6376 let attempt_range = self.range(33)?;
6377 let attempt = attempt_range.attempt()?;
6378 let previous_attempt = predecessor
6379 .ranges
6380 .iter()
6381 .find(|item| item.range.role == 33 && item.range.index == 0)
6382 .ok_or(SemanticTransitionError::ObservationMismatch)?;
6383 if attempt.abi != 2
6384 || attempt.instance != self.successor.instance
6385 || attempt.base_word != base.publication_word
6386 || attempt.next_word != self.successor.word
6387 || attempt.logical_digest != self.successor.logical_digest
6388 || attempt.receipt_digest != attempt_range.logical_record_digest()?
6389 || attempt.previous_attempt_digest != previous_attempt.logical_record_digest()?
6390 || attempt.replay_head_digest != self.range(27)?.logical_record_digest()?
6391 || attempt.intent_head_digest != self.range(30)?.logical_record_digest()?
6392 || attempt.acknowledgement_head_digest != self.range(32)?.logical_record_digest()?
6393 || self.successor.state_digest != self.state_digest()?
6394 {
6395 return Err(publication_input_error(
6396 "replay evidence differs from its whole native attempt and state links",
6397 ));
6398 }
6399 let no_draw =
6400 attempt.action_receipts_digest == Identity256::from_bytes(Sha256::digest([]).into());
6401 match (attempt.transition_kind, base.terminal, no_draw) {
6402 (1, 0, false) => Ok(SemanticTransitionKind::Proposal),
6403 (2, 0, true) => Ok(SemanticTransitionKind::Recompute),
6404 (3, 1, true) => Ok(SemanticTransitionKind::Drain),
6405 (4, 0, true) => Ok(SemanticTransitionKind::Update),
6406 _ => Err(publication_input_error(
6407 "replay attempt cannot follow this predecessor's native terminal state",
6408 )),
6409 }
6410 }
6411
6412 fn validate_observed(
6413 &self,
6414 predecessor: &PublicationMaterial,
6415 bank: &PublicationBank,
6416 coverage: &PublicationMaterialRange,
6417 codebook: &PublicationMaterialRange,
6418 ) -> Result<(), SemanticTransitionError> {
6419 let kind = self.validate(predecessor)?;
6420 let base = predecessor.bank.header;
6421 let header = bank.header;
6422 let draws = if kind == SemanticTransitionKind::Proposal {
6423 COMPONENT_COUNT
6424 } else {
6425 0
6426 };
6427 let proposal = base
6428 .proposal
6429 .checked_add(u64::from(draws != 0))
6430 .ok_or(SemanticTransitionError::GenerationExhausted)?;
6431 if header.abi != 1
6432 || header.instance != self.successor.instance
6433 || header.publication_word != self.successor.word
6434 || header.base_word != base.publication_word
6435 || header.sealed_epoch != self.successor.word >> 1
6436 || header.logical_digest != self.successor.logical_digest
6437 || header.state_digest != self.successor.state_digest
6438 || header.proposal != proposal
6439 || bank.state.proposal != base.proposal
6440 || bank.state.next_proposal != proposal
6441 || bank.state.blocks != draws as u64
6442 || bank.state.status != 0
6443 || (kind == SemanticTransitionKind::Drain && header.terminal != 2)
6444 || (kind == SemanticTransitionKind::Recompute && header.terminal != 0)
6445 || (kind == SemanticTransitionKind::Proposal && header.terminal > 1)
6446 {
6447 return Err(publication_input_error(
6448 "replay evidence does not describe the actual acquired native transition",
6449 ));
6450 }
6451 let attempt = self.range(33)?.attempt()?;
6452 if coverage.range.role != 14
6453 || coverage.bytes.len() != size_of::<CompletionCoverage>()
6454 || coverage.original_record_digest() != coverage.range.digest
6455 || codebook.original_record_digest() != codebook.range.digest
6456 {
6457 return Err(publication_input_error(
6458 "replay evidence sources differ from their actual native seals",
6459 ));
6460 }
6461 let completion = unsafe {
6463 std::ptr::read_unaligned(coverage.bytes.as_ptr().cast::<CompletionCoverage>())
6464 };
6465 let coverage_digest = coverage.logical_record_digest()?;
6466 let component_receipts_digest =
6467 publication_action_receipts_digest(codebook, &bank.receipts[..draws])?;
6468 let semantic_receipts_digest =
6469 publication_semantic_receipts_digest(&bank.state.semantic_receipts);
6470 let action_batch_valid = if kind == SemanticTransitionKind::Proposal {
6471 let batch = &bank.state.action_batch;
6472 let root = publication_action_batch_root(batch);
6473 batch.abi == 1
6474 && batch.proposal == bank.state.proposal
6475 && batch.stream_serial == bank.state.stream_serial
6476 && batch.family_id == u64::from(bank.state.family_id)
6477 && batch.action_law_generation == bank.state.catalogue_generation
6478 && batch.model_generation == u64::from(bank.state.model_generation)
6479 && batch.actor_eligible == bank.state.actor_eligible
6480 && batch.actor_eligible <= 1
6481 && batch.component_count == COMPONENT_COUNT as u64
6482 && batch.candidate_count == 3
6483 && batch.winner == bank.state.task_evaluation.winner
6484 && batch.total_return_bits == bank.state.task_evaluation.return_value as u64
6485 && batch.base_word == base.publication_word
6486 && batch.next_word == header.publication_word
6487 && batch.rng_base == bank.state.proposal * COMPONENT_COUNT as u64
6488 && batch.rng_span == COMPONENT_COUNT as u64
6489 && batch.rng_successor == bank.state.next_proposal * COMPONENT_COUNT as u64
6490 && batch.catalogue_digest == bank.state.catalogue_digest
6491 && batch.component_receipts_digest == component_receipts_digest
6492 && batch.semantic_receipts_digest == semantic_receipts_digest
6493 && batch.base_logical_digest == base.logical_digest
6494 && batch.execution_work == bank.state.execution_work
6495 && [0usize, 3, 6]
6496 .into_iter()
6497 .enumerate()
6498 .all(|(candidate, receipt)| {
6499 identity_words(*batch.candidate_roots[candidate].as_bytes())
6500 == bank.state.semantic_receipts[receipt][16..20]
6501 })
6502 && root == bank.state.action_batch_root
6503 && root == attempt.action_receipts_digest
6504 } else {
6505 bank.state.action_batch == SemanticActionBatchReceipt::default()
6506 && bank.state.action_batch_root == Identity256::default()
6507 && attempt.action_receipts_digest == component_receipts_digest
6508 };
6509 if completion.abi != 1
6510 || completion.instance != header.instance
6511 || completion.base_word != base.publication_word
6512 || completion.receipt_digest != coverage_digest
6513 || attempt.coverage_digest != coverage_digest
6514 || !action_batch_valid
6515 || attempt.semantic_receipts_digest != semantic_receipts_digest
6516 {
6517 return Err(publication_input_error(
6518 "whole native attempt differs from actual action, semantic or completion receipts",
6519 ));
6520 }
6521 Ok(())
6522 }
6523}
6524
6525pub struct SemanticReplayMaterial {
6529 predecessor: PublicationMaterial,
6530 evidence: PublicationReplayEvidence,
6531 kind: SemanticTransitionKind,
6532}
6533
6534struct ReplayInitialPrefill {
6535 original: SemanticPublishedIdentity,
6536 content: Vec<u8>,
6537 recovery_referent: Option<Vec<u8>>,
6538}
6539
6540impl SemanticReplayMaterial {
6541 fn completed_child_payload<'a>(
6542 &self,
6543 bytes: &'a [u8],
6544 kind: &[u8],
6545 expected_identity: Identity256,
6546 expected_owner: Identity256,
6547 ) -> Result<&'a [u8], SemanticTransitionError> {
6548 let mut reader = SemanticMaterialReader::new(bytes);
6549 let magic = b"XLOG-COMPLETED-ACTION-CHILD\0";
6550 if reader
6551 .take(magic.len())
6552 .map_err(SemanticTransitionError::Semantic)?
6553 != magic
6554 || reader.u64().map_err(SemanticTransitionError::Semantic)? != 1
6555 {
6556 return Err(publication_input_error(
6557 "completed action child has another envelope",
6558 ));
6559 }
6560 let owner = reader.take(32).map_err(SemanticTransitionError::Semantic)?;
6561 if owner != expected_owner.as_bytes() {
6562 return Err(publication_input_error(
6563 "completed action child belongs to another action",
6564 ));
6565 }
6566 if reader.u64().map_err(SemanticTransitionError::Semantic)? != kind.len() as u64
6567 || reader
6568 .take(kind.len())
6569 .map_err(SemanticTransitionError::Semantic)?
6570 != kind
6571 || reader.u64().map_err(SemanticTransitionError::Semantic)? != 0
6572 {
6573 return Err(publication_input_error(
6574 "completed action child has another kind or ordinal",
6575 ));
6576 }
6577 let mut binding = b"xlog.completed-action-child.v1\0".to_vec();
6578 binding.extend_from_slice(owner);
6579 material_u64(&mut binding, kind.len() as u64);
6580 binding.extend_from_slice(kind);
6581 material_u64(&mut binding, 0);
6582 if Identity256::from_bytes(Sha256::digest(binding).into()) != expected_identity {
6583 return Err(publication_input_error(
6584 "completed action child identity differs from its owner",
6585 ));
6586 }
6587 let length = usize::try_from(reader.u64().map_err(SemanticTransitionError::Semantic)?)
6588 .map_err(|_| publication_input_error("completed action child exceeds this host"))?;
6589 let payload = reader
6590 .take(length)
6591 .map_err(SemanticTransitionError::Semantic)?;
6592 reader.finish().map_err(SemanticTransitionError::Semantic)?;
6593 Ok(payload)
6594 }
6595
6596 fn read_initial_prefill_child(
6597 &self,
6598 bytes: &[u8],
6599 expected_identity: Identity256,
6600 expected_owner: Identity256,
6601 ) -> Result<ReplayInitialPrefill, SemanticTransitionError> {
6602 let payload = self.completed_child_payload(
6603 bytes,
6604 b"initial-prefill",
6605 expected_identity,
6606 expected_owner,
6607 )?;
6608 let mut payload = SemanticMaterialReader::new(payload);
6609 let magic = b"XLOG-INITIAL-PREFILL\0";
6610 if payload
6611 .take(magic.len())
6612 .map_err(SemanticTransitionError::Semantic)?
6613 != magic
6614 || payload.u64().map_err(SemanticTransitionError::Semantic)? != 2
6615 {
6616 return Err(publication_input_error(
6617 "initial prefill child has another body version",
6618 ));
6619 }
6620 let original = decode_publication_identity(&mut payload)?;
6621 let actual = decode_publication_identity(&mut payload)?;
6622 let header = self.predecessor.bank.header;
6623 if actual != self.predecessor_identity() {
6624 return Err(publication_input_error(
6625 "initial prefill child names another actual predecessor",
6626 ));
6627 }
6628 let recovery_referent = match payload.u8().map_err(SemanticTransitionError::Semantic)? {
6629 1 if original == actual => None,
6630 2 if original != actual
6631 && original.word == 0
6632 && actual.word == 0
6633 && original.instance != actual.instance
6634 && header.recovered_instance == original.instance
6635 && original.logical_digest == actual.logical_digest
6636 && original.state_digest == actual.state_digest =>
6637 {
6638 let length =
6639 usize::try_from(payload.u64().map_err(SemanticTransitionError::Semantic)?)
6640 .map_err(|_| {
6641 publication_input_error("initial prefill referent exceeds this host")
6642 })?;
6643 let referent = payload
6644 .take(length)
6645 .map_err(SemanticTransitionError::Semantic)?
6646 .to_vec();
6647 if referent.is_empty() {
6648 return Err(publication_input_error(
6649 "recovered initial prefill has no source referent",
6650 ));
6651 }
6652 Some(referent)
6653 }
6654 _ => {
6655 return Err(publication_input_error(
6656 "initial prefill recovery chain is invalid",
6657 ))
6658 }
6659 };
6660 let content = payload.take_rest().to_vec();
6661 if content.is_empty() {
6662 return Err(publication_input_error(
6663 "initial prefill child has no original content",
6664 ));
6665 }
6666 let mut tail = SemanticMaterialReader::new(&content);
6667 tail.take(32 + 8 + 32)
6668 .map_err(SemanticTransitionError::Semantic)?;
6669 let task_epoch = tail.u64().map_err(SemanticTransitionError::Semantic)?;
6670 let mut read_identity = || -> Result<Identity256, SemanticTransitionError> {
6671 Ok(Identity256::from_bytes(
6672 tail.take(32)
6673 .map_err(SemanticTransitionError::Semantic)?
6674 .try_into()
6675 .unwrap(),
6676 ))
6677 };
6678 let task_content = SemanticTaskContentIdentity {
6679 query: read_identity()?,
6680 theory_program: read_identity()?,
6681 result: read_identity()?,
6682 };
6683 CheckpointInitialPrefill {
6684 original,
6685 content: content.clone(),
6686 recovery_referent: None,
6687 }
6688 .verify_content(
6689 header.semantic_digest,
6690 header.model_generation,
6691 self.predecessor.contract.task_identity,
6692 task_epoch,
6693 task_content,
6694 header.prefix_extent,
6695 )?;
6696 Ok(ReplayInitialPrefill {
6697 original,
6698 content,
6699 recovery_referent,
6700 })
6701 }
6702
6703 pub fn initial_prefill_recovery_referent(
6706 &self,
6707 child: &[u8],
6708 child_identity: Identity256,
6709 action_identity: Identity256,
6710 ) -> Result<Option<Vec<u8>>, SemanticTransitionError> {
6711 Ok(self
6712 .read_initial_prefill_child(child, child_identity, action_identity)?
6713 .recovery_referent)
6714 }
6715
6716 pub fn pre_action_checkpoint_referent(
6720 &self,
6721 child: &[u8],
6722 child_identity: Identity256,
6723 action_identity: Identity256,
6724 ) -> Result<Vec<u8>, SemanticTransitionError> {
6725 let payload = self.completed_child_payload(
6726 child,
6727 b"pre-action-checkpoint",
6728 child_identity,
6729 action_identity,
6730 )?;
6731 if payload.len() != SemanticTransitionSession::CHECKPOINT_REFERENT_BYTES
6732 || payload.last() != Some(&3)
6733 {
6734 return Err(publication_input_error(
6735 "late checkpoint child has another pre-action phase or extent",
6736 ));
6737 }
6738 Ok(payload.to_vec())
6739 }
6740
6741 pub fn verify_pre_action_checkpoint_source(
6744 &self,
6745 native: &[u8],
6746 task_identity: Identity256,
6747 task_epoch: u64,
6748 ) -> Result<(), SemanticTransitionError> {
6749 if self.predecessor.contract.task_identity != task_identity
6750 || self.predecessor.bank.header.authority_generation != task_epoch
6751 || native != self.predecessor.encode()?
6752 {
6753 return Err(publication_input_error(
6754 "late checkpoint differs from this action's complete predecessor custody",
6755 ));
6756 }
6757 Ok(())
6758 }
6759
6760 pub fn verify_initial_prefill_checkpoint_source(
6765 &self,
6766 (child, child_identity): (&[u8], Identity256),
6767 action_identity: Identity256,
6768 (original_native, original_prefill_section): (&[u8], &[u8]),
6769 task_identity: Identity256,
6770 task_epoch: u64,
6771 task_content: SemanticTaskContentIdentity,
6772 ) -> Result<(), SemanticTransitionError> {
6773 let replay = self.read_initial_prefill_child(child, child_identity, action_identity)?;
6774 if replay.recovery_referent.is_none()
6775 || !SemanticTransitionSession::verify_checkpoint_initial_prefill_source(
6776 original_prefill_section,
6777 original_native,
6778 task_identity,
6779 task_epoch,
6780 task_content,
6781 true,
6782 )?
6783 {
6784 return Err(publication_input_error(
6785 "initial prefill recovery has no original checkpoint source",
6786 ));
6787 }
6788 let original = CheckpointInitialPrefill::decode_section(original_prefill_section)?
6789 .ok_or_else(|| publication_input_error("original checkpoint has no initial prefill"))?;
6790 if replay.original != original.original || replay.content != original.content {
6791 return Err(publication_input_error(
6792 "recovered prefill differs from original checkpoint content",
6793 ));
6794 }
6795 Ok(())
6796 }
6797
6798 pub fn decode(
6800 predecessor_bytes: &[u8],
6801 evidence_bytes: &[u8],
6802 expected_predecessor_logical: Identity256,
6803 expected_successor_logical: Identity256,
6804 ) -> Result<Self, SemanticTransitionError> {
6805 let predecessor = PublicationMaterial::decode(predecessor_bytes)?;
6806 let evidence = PublicationReplayEvidence::decode(evidence_bytes)?;
6807 if predecessor.bank.header.logical_digest != expected_predecessor_logical
6808 || evidence.successor.logical_digest != expected_successor_logical
6809 {
6810 return Err(publication_input_error(
6811 "replay native materials differ from the execution's logical identities",
6812 ));
6813 }
6814 let kind = evidence.validate(&predecessor)?;
6815 Ok(Self {
6816 predecessor,
6817 evidence,
6818 kind,
6819 })
6820 }
6821
6822 pub fn predecessor_identity(&self) -> SemanticPublishedIdentity {
6823 let header = self.predecessor.bank.header;
6824 SemanticPublishedIdentity {
6825 instance: header.instance,
6826 word: header.publication_word,
6827 logical_digest: header.logical_digest,
6828 state_digest: header.state_digest,
6829 }
6830 }
6831
6832 pub fn successor_identity(&self) -> SemanticPublishedIdentity {
6833 self.evidence.successor
6834 }
6835
6836 pub fn transition_kind(&self) -> SemanticTransitionKind {
6837 self.kind
6838 }
6839
6840 pub fn training_view_origin(
6841 &self,
6842 ) -> Result<SemanticTrainingViewOrigin, SemanticTransitionError> {
6843 let header = self.predecessor.bank.header;
6844 Ok(SemanticTrainingViewOrigin {
6845 transition: self.kind,
6846 predecessor: self.predecessor_identity(),
6847 successor: self.successor_identity(),
6848 invocation: header.rng_binding()?,
6849 model_geometry_digest: header.model_geometry_digest,
6850 model_numerical_digest: header.model_numerical_digest,
6851 })
6852 }
6853
6854 pub fn model_numerical_mode(&self) -> Result<&[u8], SemanticTransitionError> {
6858 self.predecessor.model_numerical_mode()
6859 }
6860
6861 pub fn verify_provenance(&self, bytes: &[u8]) -> Result<Vec<u8>, SemanticTransitionError> {
6866 let provenance = PublicationReplayProvenance::decode(bytes)?;
6867 provenance.validate(&self.predecessor)?;
6868 Ok(provenance.decision.bytes)
6869 }
6870}
6871
6872struct PublicationMaterial {
6875 bank: PublicationBank,
6876 contract: PublicationContract,
6877 role_counts: [u64; 55],
6878 terminals: Vec<u64>,
6879 layouts: BTreeMap<(u64, u64), SemanticTensorLayout>,
6880 model_memory: ModelMemoryGeometry,
6881 model_allocations: Vec<Vec<u8>>,
6882 ranges: Vec<PublicationMaterialRange>,
6883 graph: SemanticRootMaterial,
6884 learning_phases: Vec<SemanticLearningPhaseRecord>,
6885}
6886
6887pub struct SemanticOutputIntent {
6891 pub stable_identity: Identity256,
6892 pub effect: Vec<u8>,
6893 pub payload: Vec<u8>,
6894}
6895
6896fn acknowledgement_receipts(
6897 bytes: &[u8],
6898 capacity_bytes: usize,
6899) -> Result<Vec<(Identity256, Vec<u8>)>, SemanticTransitionError> {
6900 if bytes.len() < size_of::<AcknowledgementQueueHeader>() {
6901 return Err(publication_input_error(
6902 "acknowledgement queue has no native header",
6903 ));
6904 }
6905 let header = unsafe {
6907 bytes
6908 .as_ptr()
6909 .cast::<AcknowledgementQueueHeader>()
6910 .read_unaligned()
6911 };
6912 let declared_capacity = usize::try_from(header.capacity)
6913 .ok()
6914 .and_then(|count| count.checked_mul(size_of::<AcknowledgementEntry>()))
6915 .and_then(|entries| {
6916 usize::try_from(header.payload_capacity_bytes)
6917 .ok()?
6918 .checked_add(entries)
6919 })
6920 .and_then(|body| body.checked_add(size_of::<AcknowledgementQueueHeader>()));
6921 if header.abi != 1
6922 || header.count > header.capacity
6923 || declared_capacity != Some(capacity_bytes)
6924 || header.payload_used_bytes
6925 != (bytes.len() - size_of::<AcknowledgementQueueHeader>()) as u64
6926 {
6927 return Err(publication_input_error(
6928 "acknowledgement queue extent is inconsistent",
6929 ));
6930 }
6931 let mut cursor = size_of::<AcknowledgementQueueHeader>();
6932 let mut receipt_bytes = 0usize;
6933 let mut chain = Identity256::default();
6934 let mut seen = BTreeSet::new();
6935 let mut result = Vec::with_capacity(header.count as usize);
6936 for ordinal in 0..header.count {
6937 let entry_end = cursor
6938 .checked_add(size_of::<AcknowledgementEntry>())
6939 .filter(|&end| end <= bytes.len())
6940 .ok_or_else(|| publication_input_error("acknowledgement entry is incomplete"))?;
6941 let entry = unsafe {
6943 bytes[cursor..]
6944 .as_ptr()
6945 .cast::<AcknowledgementEntry>()
6946 .read_unaligned()
6947 };
6948 let length = usize::try_from(entry.receipt_len)
6949 .map_err(|_| publication_input_error("acknowledgement receipt overflows this host"))?;
6950 let end = entry_end
6951 .checked_add(length)
6952 .filter(|&end| end <= bytes.len())
6953 .ok_or_else(|| publication_input_error("acknowledgement receipt is incomplete"))?;
6954 let receipt = &bytes[entry_end..end];
6955 receipt_bytes = receipt_bytes
6956 .checked_add(length)
6957 .ok_or_else(|| publication_input_error("acknowledgement receipt extent overflows"))?;
6958 let previous = chain;
6959 chain = publication_fold_digest(chain, 32, ordinal, entry.stable_identity);
6960 chain = publication_fold_digest(chain, 32, ordinal, entry.receipt_digest);
6961 if entry.stable_identity == Identity256::default()
6962 || !seen.insert(*entry.stable_identity.as_bytes())
6963 || entry.previous_chain != previous
6964 || entry.chain != chain
6965 || entry.receipt_digest != Identity256::from_bytes(Sha256::digest(receipt).into())
6966 {
6967 return Err(publication_input_error(
6968 "acknowledgement differs from its native chain",
6969 ));
6970 }
6971 result.push((entry.stable_identity, receipt.to_vec()));
6972 cursor = end;
6973 }
6974 if cursor != bytes.len()
6975 || chain != header.chain_head
6976 || receipt_bytes > header.payload_capacity_bytes as usize
6977 {
6978 return Err(publication_input_error(
6979 "acknowledgement chain does not cover its receipts",
6980 ));
6981 }
6982 Ok(result)
6983}
6984
6985pub fn output_intents_from_publication_material(
6986 native_material: &[u8],
6987) -> Result<Vec<SemanticOutputIntent>, SemanticTransitionError> {
6988 let material = PublicationMaterial::decode(native_material)?;
6989 let entries = material
6990 .ranges
6991 .iter()
6992 .find(|item| (item.range.role, item.range.index) == (30, 0))
6993 .ok_or_else(|| publication_input_error("checkpoint omits its native intent queue"))?;
6994 let payload = material
6995 .ranges
6996 .iter()
6997 .find(|item| (item.range.role, item.range.index) == (31, 0))
6998 .ok_or_else(|| publication_input_error("checkpoint omits its native intent payload"))?;
6999 output_intents_from_ranges(entries, payload)
7000}
7001
7002pub fn pending_output_intents_from_publication_material(
7006 native_material: &[u8],
7007 recipient_id: Identity256,
7008 verification_key: &[u8; 32],
7009 expected_effect: &[u8],
7010) -> Result<Vec<SemanticOutputIntent>, SemanticTransitionError> {
7011 if recipient_id == Identity256::default() || verification_key.iter().all(|&byte| byte == 0) {
7012 return Err(publication_input_error(
7013 "pending intent projection requires the trusted receiver identity and key",
7014 ));
7015 }
7016 let material = PublicationMaterial::decode(native_material)?;
7017 let entries = material
7018 .ranges
7019 .iter()
7020 .find(|item| (item.range.role, item.range.index) == (30, 0))
7021 .ok_or_else(|| publication_input_error("checkpoint omits its native intent queue"))?;
7022 let payload = material
7023 .ranges
7024 .iter()
7025 .find(|item| (item.range.role, item.range.index) == (31, 0))
7026 .ok_or_else(|| publication_input_error("checkpoint omits its native intent payload"))?;
7027 let acknowledgements = material
7028 .ranges
7029 .iter()
7030 .find(|item| (item.range.role, item.range.index) == (32, 0))
7031 .ok_or_else(|| {
7032 publication_input_error("checkpoint omits its native acknowledgement queue")
7033 })?;
7034 let intents = output_intents_from_ranges(entries, payload)?;
7035 if expected_effect.is_empty()
7036 || intents
7037 .iter()
7038 .any(|intent| intent.effect.as_slice() != expected_effect)
7039 {
7040 return Err(publication_input_error(
7041 "checkpoint intent differs from the bound receiver effect",
7042 ));
7043 }
7044 let receipts = acknowledgement_receipts(&acknowledgements.bytes, acknowledgements.capacity)?;
7045 let mut acknowledged = BTreeSet::new();
7046 for (identity, receipt) in receipts {
7047 let intent = intents
7048 .iter()
7049 .find(|intent| intent.stable_identity == identity)
7050 .ok_or_else(|| {
7051 publication_input_error("checkpoint acknowledges an absent native intent")
7052 })?;
7053 verify_delivery_receipt(&receipt, intent, recipient_id, verification_key)?;
7054 acknowledged.insert(*identity.as_bytes());
7055 }
7056 Ok(intents
7057 .into_iter()
7058 .filter(|intent| !acknowledged.contains(intent.stable_identity.as_bytes()))
7059 .collect())
7060}
7061
7062fn output_intents_from_ranges(
7063 entries: &PublicationMaterialRange,
7064 payload: &PublicationMaterialRange,
7065) -> Result<Vec<SemanticOutputIntent>, SemanticTransitionError> {
7066 if entries.bytes.len() < size_of::<IntentQueueHeader>() {
7067 return Err(publication_input_error(
7068 "checkpoint intent queue has no header",
7069 ));
7070 }
7071 let header =
7073 unsafe { std::ptr::read_unaligned(entries.bytes.as_ptr().cast::<IntentQueueHeader>()) };
7074 let entry_extent = usize::try_from(header.count)
7075 .ok()
7076 .and_then(|count| count.checked_mul(size_of::<IntentEntry>()))
7077 .and_then(|bytes| bytes.checked_add(size_of::<IntentQueueHeader>()));
7078 let capacity_extent = usize::try_from(header.capacity)
7079 .ok()
7080 .and_then(|count| count.checked_mul(size_of::<IntentEntry>()))
7081 .and_then(|bytes| bytes.checked_add(size_of::<IntentQueueHeader>()));
7082 if header.abi != 1
7083 || header.count > header.capacity
7084 || entry_extent != Some(entries.bytes.len())
7085 || capacity_extent.is_none_or(|extent| extent != entries.capacity)
7086 || header.payload_used_bytes != payload.bytes.len() as u64
7087 || header.payload_capacity_bytes != payload.capacity as u64
7088 || header.effect_offset_bytes != 0
7089 || header.effect_length_bytes == 0
7090 || header.effect_length_bytes > header.payload_used_bytes
7091 {
7092 return Err(publication_input_error(
7093 "checkpoint intent queue has inconsistent extents",
7094 ));
7095 }
7096 let effect_end = usize::try_from(header.effect_length_bytes)
7097 .map_err(|_| publication_input_error("checkpoint intent effect overflows this host"))?;
7098 let effect = &payload.bytes[..effect_end];
7099 let effect_digest = Identity256::from_bytes(Sha256::digest(effect).into());
7100 let mut cursor = effect_end;
7101 let mut chain = Identity256::default();
7102 let mut result = Vec::with_capacity(header.count as usize);
7103 for ordinal in 0..header.count {
7104 let offset = size_of::<IntentQueueHeader>() + ordinal as usize * size_of::<IntentEntry>();
7105 let entry = unsafe {
7107 std::ptr::read_unaligned(entries.bytes[offset..].as_ptr().cast::<IntentEntry>())
7108 };
7109 let length = usize::try_from(entry.payload_len).map_err(|_| {
7110 publication_input_error("checkpoint intent payload overflows this host")
7111 })?;
7112 let end = cursor
7113 .checked_add(length)
7114 .filter(|&end| end <= payload.bytes.len())
7115 .ok_or_else(|| publication_input_error("checkpoint intent payload is incomplete"))?;
7116 let content = &payload.bytes[cursor..end];
7117 let mut identity = Sha256::new();
7118 identity.update(0x786c6f67696e7431u64.to_le_bytes());
7119 for part in [
7120 entry.checkpoint_lineage,
7121 entry.base_logical,
7122 entry.effective_delta,
7123 entry.result_logical,
7124 entry.effect_digest,
7125 entry.payload_digest,
7126 ] {
7127 identity.update(part.as_bytes());
7128 }
7129 let stable_identity = Identity256::from_bytes(identity.finalize().into());
7130 let previous_chain = chain;
7131 chain = publication_fold_digest(chain, 30, ordinal, stable_identity);
7132 if entry.payload_offset != cursor as u64
7133 || entry.payload_len < 8
7134 || entry.effect_digest != effect_digest
7135 || entry.payload_digest != Identity256::from_bytes(Sha256::digest(content).into())
7136 || entry.previous_chain != previous_chain
7137 || entry.chain != chain
7138 || entry.stable_identity != stable_identity
7139 || stable_identity == Identity256::default()
7140 {
7141 return Err(publication_input_error(
7142 "checkpoint intent entry differs from its native chain",
7143 ));
7144 }
7145 result.push(SemanticOutputIntent {
7146 stable_identity,
7147 effect: effect.to_vec(),
7148 payload: content.to_vec(),
7149 });
7150 cursor = end;
7151 }
7152 if cursor != payload.bytes.len() || header.chain_head != chain {
7153 return Err(publication_input_error(
7154 "checkpoint intent chain does not cover its payload",
7155 ));
7156 }
7157 Ok(result)
7158}
7159
7160fn verify_delivery_receipt(
7161 receipt: &[u8],
7162 intent: &SemanticOutputIntent,
7163 recipient_id: Identity256,
7164 verification_key: &[u8; 32],
7165) -> Result<Identity256, SemanticTransitionError> {
7166 const RECEIPT_DOMAIN: &[u8] = b"xlog.delivery.receipt.v1\0";
7167 const RECORD_DOMAIN: &[u8] = b"xlog.delivery.record.v1\0";
7168 let body_len = RECEIPT_DOMAIN
7169 .len()
7170 .checked_add(32 + 32 + 8 + 8 + 32)
7171 .and_then(|size| size.checked_add(intent.effect.len()))
7172 .and_then(|size| size.checked_add(intent.payload.len()))
7173 .ok_or_else(|| publication_input_error("delivery receipt extent overflows"))?;
7174 if recipient_id == Identity256::default()
7175 || body_len.checked_add(32) != Some(receipt.len())
7176 || !receipt.starts_with(RECEIPT_DOMAIN)
7177 {
7178 return Err(publication_input_error(
7179 "delivery receipt has another canonical extent or recipient",
7180 ));
7181 }
7182 let mut cursor = RECEIPT_DOMAIN.len();
7183 let identity_end = cursor + 32;
7184 if receipt[cursor..identity_end] != intent.stable_identity.as_bytes()[..] {
7185 return Err(publication_input_error(
7186 "delivery receipt has another native intent identity",
7187 ));
7188 }
7189 cursor = identity_end;
7190 let recipient_end = cursor + 32;
7191 if receipt[cursor..recipient_end] != recipient_id.as_bytes()[..] {
7192 return Err(publication_input_error(
7193 "delivery receipt has another trusted recipient",
7194 ));
7195 }
7196 cursor = recipient_end;
7197 let effect_length = u64::from_le_bytes(
7198 receipt[cursor..cursor + 8]
7199 .try_into()
7200 .expect("fixed extent"),
7201 );
7202 cursor += 8;
7203 if effect_length != intent.effect.len() as u64
7204 || receipt[cursor..cursor + intent.effect.len()] != intent.effect[..]
7205 {
7206 return Err(publication_input_error(
7207 "delivery receipt has another native effect",
7208 ));
7209 }
7210 cursor += intent.effect.len();
7211 let payload_length = u64::from_le_bytes(
7212 receipt[cursor..cursor + 8]
7213 .try_into()
7214 .expect("fixed extent"),
7215 );
7216 cursor += 8;
7217 if payload_length != intent.payload.len() as u64
7218 || receipt[cursor..cursor + intent.payload.len()] != intent.payload[..]
7219 {
7220 return Err(publication_input_error(
7221 "delivery receipt has another native payload",
7222 ));
7223 }
7224 cursor += intent.payload.len();
7225 let mut record = Sha256::new();
7226 record.update(RECORD_DOMAIN);
7227 record.update(&receipt[RECEIPT_DOMAIN.len()..cursor]);
7228 let expected_record: [u8; 32] = record.finalize().into();
7229 if receipt[cursor..cursor + 32] != expected_record {
7230 return Err(publication_input_error(
7231 "delivery receipt differs from its durable record digest",
7232 ));
7233 }
7234 let mut ipad = [0x36u8; 64];
7235 let mut opad = [0x5cu8; 64];
7236 for (index, &byte) in verification_key.iter().enumerate() {
7237 ipad[index] ^= byte;
7238 opad[index] ^= byte;
7239 }
7240 let mut inner = Sha256::new();
7241 inner.update(ipad);
7242 inner.update(&receipt[..body_len]);
7243 let mut outer = Sha256::new();
7244 outer.update(opad);
7245 outer.update(inner.finalize());
7246 let expected_mac: [u8; 32] = outer.finalize().into();
7247 let mut mismatch = 0u8;
7248 for (actual, expected) in receipt[body_len..].iter().zip(expected_mac) {
7249 mismatch |= *actual ^ expected;
7250 }
7251 if mismatch != 0 {
7252 return Err(publication_input_error(
7253 "delivery receipt MAC does not match the trusted receiver",
7254 ));
7255 }
7256 Ok(Identity256::from_bytes(Sha256::digest(receipt).into()))
7257}
7258
7259#[cfg(test)]
7260mod delivery_receipt_tests {
7261 use super::*;
7262
7263 #[test]
7264 fn exact_durable_receipt_binds_the_native_intent_and_receiver() {
7265 let intent = SemanticOutputIntent {
7266 stable_identity: Identity256::from_bytes([3; 32]),
7267 effect: b"deliver".to_vec(),
7268 payload: b"result".to_vec(),
7269 };
7270 let recipient = Identity256::from_bytes([5; 32]);
7271 let key = [7; 32];
7272 let mut receipt = b"xlog.delivery.receipt.v1\0".to_vec();
7273 receipt.extend_from_slice(intent.stable_identity.as_bytes());
7274 receipt.extend_from_slice(recipient.as_bytes());
7275 receipt.extend_from_slice(&(intent.effect.len() as u64).to_le_bytes());
7276 receipt.extend_from_slice(&intent.effect);
7277 receipt.extend_from_slice(&(intent.payload.len() as u64).to_le_bytes());
7278 receipt.extend_from_slice(&intent.payload);
7279 let mut record = Sha256::new();
7280 record.update(b"xlog.delivery.record.v1\0");
7281 record.update(&receipt[b"xlog.delivery.receipt.v1\0".len()..]);
7282 receipt.extend_from_slice(&record.finalize());
7283 let mut ipad = [0x36u8; 64];
7284 let mut opad = [0x5cu8; 64];
7285 for (index, byte) in key.iter().enumerate() {
7286 ipad[index] ^= byte;
7287 opad[index] ^= byte;
7288 }
7289 let mut inner = Sha256::new();
7290 inner.update(ipad);
7291 inner.update(&receipt);
7292 let mut outer = Sha256::new();
7293 outer.update(opad);
7294 outer.update(inner.finalize());
7295 receipt.extend_from_slice(&outer.finalize());
7296 assert_eq!(
7297 receipt.len(),
7298 169 + intent.effect.len() + intent.payload.len()
7299 );
7300 assert_eq!(
7301 verify_delivery_receipt(&receipt, &intent, recipient, &key).unwrap(),
7302 Identity256::from_bytes(Sha256::digest(&receipt).into())
7303 );
7304 assert!(verify_delivery_receipt(&receipt, &intent, recipient, &[8; 32]).is_err());
7305 assert!(
7306 verify_delivery_receipt(&receipt, &intent, Identity256::from_bytes([6; 32]), &key)
7307 .is_err()
7308 );
7309 receipt[100] ^= 1;
7310 assert!(verify_delivery_receipt(&receipt, &intent, recipient, &key).is_err());
7311 }
7312
7313 #[test]
7314 fn acknowledgement_reserve_covers_every_full_receipt() {
7315 let required = 169 * 3 + 256 + 2 * 7;
7316 assert!(initial_acknowledgement_record(3, required - 1, 256, 7).is_err());
7317 let record = initial_acknowledgement_record(3, required, 256, 7).unwrap();
7318 assert_eq!(
7319 acknowledgement_receipts(&record.bytes, record.capacity_bytes)
7320 .unwrap()
7321 .len(),
7322 0
7323 );
7324 assert!(initial_acknowledgement_record(0, required, 256, 7).is_err());
7325 }
7326}
7327
7328fn relocate_publication_codebooks(
7329 saved: &[u8],
7330 actual: &[u64],
7331) -> Result<Vec<u8>, SemanticTransitionError> {
7332 if actual.len() < 25
7333 || saved.len()
7334 != actual
7335 .len()
7336 .checked_mul(8)
7337 .ok_or(SemanticTransitionError::GenerationExhausted)?
7338 {
7339 return Err(publication_input_error(
7340 "restored codebook has another actual extent",
7341 ));
7342 }
7343 for (index, (saved, &actual)) in saved.as_chunks::<8>().0.iter().zip(actual).enumerate() {
7344 if !matches!(index, 14..=16 | 21..=24) && u64::from_le_bytes(*saved) != actual {
7345 return Err(publication_input_error(
7346 "restored codebook changes its admitted logical content or original base",
7347 ));
7348 }
7349 }
7350 Ok(publication_abi_bytes(actual))
7351}
7352
7353fn publication_material_runtime() -> [u8; 32] {
7354 static IDENTITY: std::sync::OnceLock<[u8; 32]> = std::sync::OnceLock::new();
7355 *IDENTITY.get_or_init(|| {
7356 let mut hash = Sha256::new();
7357 hash.update(b"xlog.publication.material-runtime.v1\0");
7358 hash.update(include_bytes!("semantic_transition.rs"));
7359 hash.update(include_bytes!("semantic_transition/learning_phase.rs"));
7360 hash.update(include_bytes!("semantic_transition/prepared_replay.rs"));
7361 #[cfg(feature = "semantic-policy")]
7362 hash.update(include_bytes!("semantic_transition/model_evaluation.rs"));
7363 hash.update(include_bytes!("../kernels/semantic_transition.cu"));
7364 let policy_identity: [u8; 32] =
7365 include!(concat!(env!("OUT_DIR"), "/semantic_policy_identity.rs"));
7366 hash.update(policy_identity);
7367 #[cfg(feature = "semantic-policy")]
7368 hash.update(include_bytes!("../kernels/semantic_policy_binding.cuh"));
7369 hash.update(include_bytes!("../kernels/semantic_policy_domains.cuh"));
7370 hash.update(include_bytes!("semantic_hypergraph.rs"));
7371 hash.update(include_bytes!("../kernels/semantic_hypergraph.cu"));
7372 hash.finalize().into()
7373 })
7374}
7375
7376const RUNTIME_CONTRACT_MAGIC: &[u8] = b"XLOG-PUBLICATION-RUNTIME\0";
7377
7378fn runtime_contract_bytes(
7382 contract: PublicationContract,
7383 counts: &[u64; 55],
7384 terminals: &[u64],
7385 layouts: &BTreeMap<(u64, u64), SemanticTensorLayout>,
7386 capacities: &[(u64, u64, usize)],
7387 model_mode: &[u8],
7388 model_memory: &ModelMemoryGeometry,
7389) -> Result<Vec<u8>, SemanticTransitionError> {
7390 if model_mode.is_empty() || model_mode.len() > 16 * 1024 * 1024 {
7391 return Err(publication_input_error(
7392 "runtime contract requires the complete bounded model numerical mode",
7393 ));
7394 }
7395 let mut bytes = RUNTIME_CONTRACT_MAGIC.to_vec();
7396 material_u32(&mut bytes, 1);
7397 bytes.extend_from_slice(&publication_material_runtime());
7398 material_bytes(&mut bytes, model_mode).map_err(SemanticTransitionError::Semantic)?;
7399 for field in [
7400 contract.abi,
7401 contract.range_capacity,
7402 contract.prefix_capacity,
7403 contract.window_capacity,
7404 contract.feedback_capacity,
7405 contract.max_position,
7406 contract.pad_token,
7407 contract.terminal_token_count,
7408 contract.final_intent_payload_bytes,
7409 contract.model_generation,
7410 contract.policy_generation,
7411 contract.authority_generation,
7412 contract.role_count,
7413 ] {
7414 material_u64(&mut bytes, field);
7415 }
7416 let model = contract.model_contract_layout;
7417 for field in [
7418 model.schema_begin,
7419 model.schema_bytes,
7420 model.schema_digest_offset,
7421 model.generation_offset,
7422 model.numerical_digest_offset,
7423 model.identity_offset,
7424 ] {
7425 material_u64(&mut bytes, field);
7426 }
7427 for identity in [
7428 contract.task_identity,
7429 contract.topology_identity,
7430 contract.table_identity,
7431 ] {
7432 bytes.extend_from_slice(identity.as_bytes());
7433 }
7434 for &count in counts {
7435 material_u64(&mut bytes, count);
7436 }
7437 for &token in terminals {
7438 material_u64(&mut bytes, token);
7439 }
7440 material_u64(&mut bytes, layouts.len() as u64);
7441 for layout in layouts.values() {
7442 for field in [
7443 layout.role,
7444 layout.index,
7445 layout.element_bytes,
7446 layout.scalar_type,
7447 layout.rank,
7448 layout.logical_axis,
7449 ]
7450 .into_iter()
7451 .chain(layout.dimensions)
7452 .chain(layout.strides_bytes)
7453 {
7454 material_u64(&mut bytes, field);
7455 }
7456 }
7457 material_u64(&mut bytes, capacities.len() as u64);
7458 for &(role, index, capacity) in capacities {
7459 for field in [role, index, capacity as u64] {
7460 material_u64(&mut bytes, field);
7461 }
7462 }
7463 model_memory.encode_into(&mut bytes)?;
7464 Ok(bytes)
7465}
7466
7467#[expect(
7468 clippy::too_many_arguments,
7469 reason = "the authenticated model mode is defined by independent publication owners"
7470)]
7471fn verified_runtime_model_mode<'a>(
7472 bytes: &'a [u8],
7473 contract: PublicationContract,
7474 counts: &[u64; 55],
7475 terminals: &[u64],
7476 layouts: &BTreeMap<(u64, u64), SemanticTensorLayout>,
7477 capacities: &[(u64, u64, usize)],
7478 table: &PublicationMaterialRange,
7479 model_memory: &ModelMemoryGeometry,
7480) -> Result<&'a [u8], SemanticTransitionError> {
7481 if (table.range.role, table.range.index, table.range.generation) != (55, 0, 1)
7485 || table.range.length_bytes != table.bytes.len() as u64
7486 || table.bytes.len() > table.capacity
7487 || table.original_record_digest() != table.range.digest
7488 {
7489 return Err(SemanticTransitionError::ObservationMismatch);
7490 }
7491 let (_, actual_layouts, _) = decode_tensor_table(&table.bytes)?;
7492 if actual_layouts != layouts.values().copied().collect::<Vec<_>>() {
7493 return Err(publication_input_error(
7494 "publication material layout differs from its sealed table",
7495 ));
7496 }
7497 let mut reader = SemanticMaterialReader::new(bytes);
7498 if reader
7499 .take(RUNTIME_CONTRACT_MAGIC.len())
7500 .map_err(SemanticTransitionError::Semantic)?
7501 != RUNTIME_CONTRACT_MAGIC
7502 || reader.u32().map_err(SemanticTransitionError::Semantic)? != 1
7503 || reader.take(32).map_err(SemanticTransitionError::Semantic)?
7504 != publication_material_runtime()
7505 {
7506 return Err(publication_input_error(
7507 "unsupported native runtime contract format or identity",
7508 ));
7509 }
7510 let mode = reader.bytes().map_err(SemanticTransitionError::Semantic)?;
7511 if runtime_contract_bytes(
7514 contract,
7515 counts,
7516 terminals,
7517 layouts,
7518 capacities,
7519 mode,
7520 model_memory,
7521 )? != bytes
7522 {
7523 return Err(publication_input_error(
7524 "runtime contract differs from actual cold publication state",
7525 ));
7526 }
7527 Ok(mode)
7528}
7529
7530fn initial_runtime_contract_record(
7531 contract: PublicationContract,
7532 counts: &[u64; 55],
7533 terminals: &[u64],
7534 layouts: &BTreeMap<(u64, u64), SemanticTensorLayout>,
7535 mut capacities: Vec<(u64, u64, usize)>,
7536 model_mode: &[u8],
7537 model_memory: &ModelMemoryGeometry,
7538) -> Result<SemanticStateRecord, SemanticTransitionError> {
7539 if capacities.iter().any(|&(role, _, _)| role == 43) || counts[42] != 1 {
7540 return Err(publication_input_error(
7541 "runtime contract is generated exactly once by the native owner",
7542 ));
7543 }
7544 capacities.push((43, 0, 0));
7545 capacities.sort_by_key(|&(role, index, _)| (role, index));
7546 if capacities.len() != validate_publication_counts(counts)?
7547 || contract.range_capacity != capacities.len() as u64
7548 {
7549 return Err(publication_input_error(
7550 "runtime capacity roster differs from the actual publication directory",
7551 ));
7552 }
7553 let capacity = runtime_contract_bytes(
7555 contract,
7556 counts,
7557 terminals,
7558 layouts,
7559 &capacities,
7560 model_mode,
7561 model_memory,
7562 )?
7563 .len();
7564 capacities.iter_mut().find(|entry| entry.0 == 43).unwrap().2 = capacity;
7565 let bytes = runtime_contract_bytes(
7566 contract,
7567 counts,
7568 terminals,
7569 layouts,
7570 &capacities,
7571 model_mode,
7572 model_memory,
7573 )?;
7574 debug_assert_eq!(bytes.len(), capacity);
7575 Ok(SemanticStateRecord {
7576 role: SemanticStateRole::RuntimeContract,
7577 index: 0,
7578 capacity_bytes: capacity,
7579 bytes,
7580 })
7581}
7582
7583unsafe fn publication_material_record<T: Copy>(
7587 reader: &mut SemanticMaterialReader<'_>,
7588) -> Result<T, SemanticTransitionError> {
7589 let bytes = reader.bytes().map_err(SemanticTransitionError::Semantic)?;
7590 if bytes.len() != size_of::<T>() {
7591 return Err(publication_input_error(
7592 "publication material record has another ABI extent",
7593 ));
7594 }
7595 Ok(unsafe { std::ptr::read_unaligned(bytes.as_ptr().cast::<T>()) })
7596}
7597
7598impl PublicationMaterial {
7599 fn model_numerical_mode(&self) -> Result<&[u8], SemanticTransitionError> {
7600 let record = self
7601 .ranges
7602 .iter()
7603 .find(|item| item.range.role == 43 && item.range.index == 0)
7604 .ok_or(SemanticTransitionError::ObservationMismatch)?;
7605 let table = self
7606 .ranges
7607 .iter()
7608 .find(|item| item.range.role == 55 && item.range.index == 0)
7609 .ok_or(SemanticTransitionError::ObservationMismatch)?;
7610 let capacities = self
7611 .ranges
7612 .iter()
7613 .map(|item| (item.range.role, item.range.index, item.capacity))
7614 .collect::<Vec<_>>();
7615 verified_runtime_model_mode(
7616 &record.bytes,
7617 self.contract,
7618 &self.role_counts,
7619 &self.terminals,
7620 &self.layouts,
7621 &capacities,
7622 table,
7623 &self.model_memory,
7624 )
7625 }
7626
7627 fn encode(&self) -> Result<Vec<u8>, SemanticTransitionError> {
7628 self.validate()?;
7629 let mut bytes = b"XLOG-PUBLICATION-MATERIAL\0".to_vec();
7630 material_u32(&mut bytes, 3);
7631 bytes.extend_from_slice(&publication_material_runtime());
7632 material_bytes(
7633 &mut bytes,
7634 &self
7635 .graph
7636 .encode()
7637 .map_err(SemanticTransitionError::Semantic)?,
7638 )
7639 .map_err(SemanticTransitionError::Semantic)?;
7640 for record in [
7641 publication_abi_bytes(&[self.bank]),
7642 publication_abi_bytes(&[self.contract]),
7643 publication_abi_bytes(&self.role_counts),
7644 publication_abi_bytes(&self.terminals),
7645 ] {
7646 material_bytes(&mut bytes, &record).map_err(SemanticTransitionError::Semantic)?;
7647 }
7648 material_u32(
7649 &mut bytes,
7650 u32::try_from(self.layouts.len())
7651 .map_err(|_| SemanticTransitionError::GenerationExhausted)?,
7652 );
7653 for layout in self.layouts.values() {
7654 material_bytes(&mut bytes, &publication_abi_bytes(&[*layout]))
7655 .map_err(SemanticTransitionError::Semantic)?;
7656 }
7657 self.model_memory.encode_into(&mut bytes)?;
7658 for allocation in &self.model_allocations {
7659 material_bytes(&mut bytes, allocation).map_err(SemanticTransitionError::Semantic)?;
7660 }
7661 material_u32(
7662 &mut bytes,
7663 u32::try_from(self.ranges.len())
7664 .map_err(|_| SemanticTransitionError::GenerationExhausted)?,
7665 );
7666 for range in &self.ranges {
7667 if matches!(range.range.role, 18..=25) {
7668 material_bytes(&mut bytes, &publication_abi_bytes(&[range.range]))
7671 .map_err(SemanticTransitionError::Semantic)?;
7672 material_u64(&mut bytes, range.capacity as u64);
7673 } else {
7674 range.encode_into(&mut bytes)?;
7675 }
7676 }
7677 learning_phase::encode_history(&self.learning_phases, &mut bytes)?;
7678 Ok(bytes)
7679 }
7680
7681 fn decode(bytes: &[u8]) -> Result<Self, SemanticTransitionError> {
7682 let mut reader = SemanticMaterialReader::new(bytes);
7683 if reader.take(26).map_err(SemanticTransitionError::Semantic)?
7684 != b"XLOG-PUBLICATION-MATERIAL\0"
7685 || reader.u32().map_err(SemanticTransitionError::Semantic)? != 3
7686 || reader.take(32).map_err(SemanticTransitionError::Semantic)?
7687 != publication_material_runtime()
7688 {
7689 return Err(publication_input_error(
7690 "publication material requires its exact pinned native runtime",
7691 ));
7692 }
7693 let graph_bytes = reader.bytes().map_err(SemanticTransitionError::Semantic)?;
7694 let limit = u32::try_from(graph_bytes.len()).unwrap_or(u32::MAX);
7695 let graph = SemanticRootMaterial::decode(
7696 graph_bytes,
7697 SemanticAdmissionLimits {
7698 max_records: limit,
7699 max_terms: limit,
7700 max_references: limit,
7701 max_utf8_bytes: graph_bytes.len(),
7702 },
7703 )
7704 .map_err(SemanticTransitionError::Semantic)?;
7705 let bank = unsafe { publication_material_record::<PublicationBank>(&mut reader)? };
7707 let contract = unsafe { publication_material_record::<PublicationContract>(&mut reader)? };
7708 let role_counts = unsafe { publication_material_record::<[u64; 55]>(&mut reader)? };
7709 let terminal_bytes = reader.bytes().map_err(SemanticTransitionError::Semantic)?;
7710 if terminal_bytes.len() % 8 != 0 {
7711 return Err(publication_input_error(
7712 "publication terminal material is not integral",
7713 ));
7714 }
7715 let terminals = terminal_bytes
7716 .as_chunks::<8>()
7717 .0
7718 .iter()
7719 .map(|item| u64::from_le_bytes(*item))
7720 .collect();
7721 let count = reader
7722 .count(4 + size_of::<SemanticTensorLayout>())
7723 .map_err(SemanticTransitionError::Semantic)?;
7724 let mut layouts = BTreeMap::new();
7725 let mut previous = None;
7726 for _ in 0..count {
7727 let layout =
7729 unsafe { publication_material_record::<SemanticTensorLayout>(&mut reader)? };
7730 let key = (layout.role, layout.index);
7731 if previous.is_some_and(|previous| previous >= key) {
7732 return Err(publication_input_error(
7733 "publication material tensor layouts are not in canonical order",
7734 ));
7735 }
7736 previous = Some(key);
7737 layouts.insert(key, layout);
7738 }
7739 let model_memory = ModelMemoryGeometry::decode_from(&mut reader)?;
7740 model_memory.validate(&layouts)?;
7741 let mut model_allocations = Vec::new();
7742 for &extent in &model_memory.allocation_bytes {
7743 let allocation = reader.bytes().map_err(SemanticTransitionError::Semantic)?;
7744 if allocation.len() as u64 != extent {
7745 return Err(publication_input_error(
7746 "publication material truncates a complete model backing allocation",
7747 ));
7748 }
7749 model_allocations.push(allocation.to_vec());
7750 }
7751 let count = reader
7752 .count(12 + size_of::<PublicationRange>())
7753 .map_err(SemanticTransitionError::Semantic)?;
7754 let mut ranges = Vec::with_capacity(count);
7755 for _ in 0..count {
7756 let range = unsafe { publication_material_record::<PublicationRange>(&mut reader)? };
7758 let capacity =
7759 usize::try_from(reader.u64().map_err(SemanticTransitionError::Semantic)?).map_err(
7760 |_| publication_input_error("publication material range capacity overflows"),
7761 )?;
7762 let payload = if matches!(range.role, 18..=25) {
7763 let (allocation, offset) = model_memory.location(range.role, range.index)?;
7764 let end = usize::try_from(range.length_bytes)
7765 .ok()
7766 .and_then(|bytes| offset.checked_add(bytes))
7767 .ok_or(SemanticTransitionError::ObservationMismatch)?;
7768 model_allocations[allocation]
7769 .get(offset..end)
7770 .ok_or(SemanticTransitionError::ObservationMismatch)?
7771 } else {
7772 reader.bytes().map_err(SemanticTransitionError::Semantic)?
7773 };
7774 ranges.push(PublicationMaterialRange {
7775 range,
7776 capacity,
7777 bytes: payload.to_vec(),
7778 });
7779 }
7780 let learning_phases = learning_phase::decode_history(&mut reader)?;
7781 reader.finish().map_err(SemanticTransitionError::Semantic)?;
7782 let material = Self {
7783 bank,
7784 contract,
7785 role_counts,
7786 terminals,
7787 layouts,
7788 model_memory,
7789 model_allocations,
7790 ranges,
7791 graph,
7792 learning_phases,
7793 };
7794 material.validate()?;
7795 for range in &material.ranges {
7796 if !is_tensor_role(range.range.role)
7797 && range.original_record_digest() != range.range.digest
7798 {
7799 return Err(publication_input_error(
7800 "publication material changes an originally sealed native record",
7801 ));
7802 }
7803 }
7804 if material.original_descriptor_digest() != material.bank.header.descriptor_digest {
7805 return Err(publication_input_error(
7806 "publication material differs from its original descriptor seal",
7807 ));
7808 }
7809 Ok(material)
7810 }
7811
7812 fn require_current_model_caches(&self) -> Result<(), SemanticTransitionError> {
7817 let coverage = self
7818 .ranges
7819 .iter()
7820 .find(|r| (r.range.role, r.range.index) == (14, 0))
7821 .filter(|r| r.bytes.len() == size_of::<CompletionCoverage>())
7822 .ok_or(SemanticTransitionError::ObservationMismatch)?;
7823 let coverage = unsafe {
7826 std::ptr::read_unaligned(coverage.bytes.as_ptr().cast::<CompletionCoverage>())
7827 };
7828 if coverage.abi != 1 || coverage.model_generation != self.bank.header.model_generation {
7829 return Err(publication_input_error(
7830 "effective model changed; original caches require a full recompute before use",
7831 ));
7832 }
7833 Ok(())
7834 }
7835
7836 fn require_successful_recompute(&self) -> Result<(), SemanticTransitionError> {
7837 self.require_current_model_caches()?;
7838 let header = self.bank.header;
7839 let next_word = (header.base_word >> 1)
7840 .checked_add(1)
7841 .filter(|epoch| *epoch <= u64::MAX >> 1)
7842 .map(|epoch| (epoch << 1) | ((header.base_word & 1) ^ 1))
7843 .ok_or(SemanticTransitionError::GenerationExhausted)?;
7844 let successor = SemanticPublishedIdentity {
7845 instance: header.instance,
7846 word: header.publication_word,
7847 logical_digest: header.logical_digest,
7848 state_digest: header.state_digest,
7849 };
7850 let ranges = REPLAY_EVIDENCE_ROLES
7851 .iter()
7852 .map(|&role| {
7853 self.ranges
7854 .iter()
7855 .find(|item| item.range.role == role && item.range.index == 0)
7856 .cloned()
7857 .ok_or(SemanticTransitionError::ObservationMismatch)
7858 })
7859 .collect::<Result<Vec<_>, _>>()?;
7860 let evidence = PublicationReplayEvidence { successor, ranges };
7861 let attempt = evidence.range(33)?.attempt()?;
7862 let coverage = self
7863 .ranges
7864 .iter()
7865 .find(|item| item.range.role == 14 && item.range.index == 0)
7866 .ok_or(SemanticTransitionError::ObservationMismatch)?;
7867 if header.abi != 1
7868 || header.publication_word != next_word
7869 || header.terminal != 0
7870 || attempt.abi != 2
7871 || attempt.transition_kind != 2
7872 || attempt.instance != header.instance
7873 || attempt.base_word != header.base_word
7874 || attempt.next_word != header.publication_word
7875 || attempt.logical_digest != header.logical_digest
7876 || attempt.action_receipts_digest != Identity256::from_bytes(Sha256::digest([]).into())
7877 || attempt.coverage_digest != coverage.logical_record_digest()?
7878 || attempt.replay_head_digest != evidence.range(27)?.logical_record_digest()?
7879 || attempt.intent_head_digest != evidence.range(30)?.logical_record_digest()?
7880 || attempt.acknowledgement_head_digest != evidence.range(32)?.logical_record_digest()?
7881 || attempt.previous_attempt_digest == Identity256::default()
7882 || attempt.receipt_digest != evidence.range(33)?.logical_record_digest()?
7883 || evidence.state_digest()? != header.state_digest
7884 {
7885 return Err(publication_input_error(
7886 "selected publication has no sealed successful recompute completion",
7887 ));
7888 }
7889 Ok(())
7890 }
7891
7892 fn original_descriptor_digest(&self) -> Identity256 {
7897 let mut bank = self.bank;
7898 bank.header.abi = 1;
7899 bank.header.descriptor_digest = Identity256::default();
7900 let mut digest =
7901 Identity256::from_bytes(Sha256::digest(publication_abi_bytes(&[bank])).into());
7902 for material in &self.ranges {
7903 let range = material.range;
7904 let content =
7905 Identity256::from_bytes(Sha256::digest(publication_abi_bytes(&[range])).into());
7906 digest = publication_fold_digest(digest, range.role, range.index, content);
7907 }
7908 digest
7909 }
7910
7911 fn validate(&self) -> Result<(), SemanticTransitionError> {
7912 self.model_memory.validate(&self.layouts)?;
7913 let model = self
7914 .ranges
7915 .iter()
7916 .find(|item| (item.range.role, item.range.index) == (44, 0))
7917 .ok_or_else(|| {
7918 publication_input_error("publication material lacks its complete model contract")
7919 })?;
7920 self.contract
7921 .model_contract_layout
7922 .validate(model.bytes.len() as u64)?;
7923 if self.bank.header.model_geometry_digest != self.model_memory.digest(&self.layouts)? {
7924 return Err(publication_input_error(
7925 "publication model geometry differs from its original sealed map",
7926 ));
7927 }
7928 if self.model_allocations.len() != self.model_memory.allocation_bytes.len()
7929 || self
7930 .model_allocations
7931 .iter()
7932 .zip(&self.model_memory.allocation_bytes)
7933 .any(|(bytes, &extent)| bytes.len() as u64 != extent)
7934 {
7935 return Err(publication_input_error(
7936 "publication material lacks complete model backing bytes",
7937 ));
7938 }
7939 learning_phase::validate_history(self)?;
7940 let mut model_slots = BTreeMap::new();
7941 let mut slot_allocations = BTreeMap::new();
7942 let backing_digests = self
7943 .model_allocations
7944 .iter()
7945 .map(|bytes| Identity256::from_bytes(Sha256::digest(bytes).into()))
7946 .collect::<Vec<_>>();
7947 for item in self
7948 .ranges
7949 .iter()
7950 .filter(|item| matches!(item.range.role, 18..=25))
7951 {
7952 let (allocation, offset) = self
7953 .model_memory
7954 .location(item.range.role, item.range.index)?;
7955 let bytes = &self.model_allocations[allocation];
7956 let end = offset
7957 .checked_add(item.bytes.len())
7958 .ok_or(SemanticTransitionError::ObservationMismatch)?;
7959 if item.range.offset_bytes != offset as u64
7960 || item.capacity != bytes.len() - offset
7961 || bytes.get(offset..end) != Some(item.bytes.as_slice())
7962 || item.range.backing_digest != backing_digests[allocation]
7963 || model_slots
7964 .insert(allocation, item.range.storage_slot)
7965 .is_some_and(|slot| slot != item.range.storage_slot)
7966 || slot_allocations
7967 .insert(item.range.storage_slot, allocation)
7968 .is_some_and(|prior| prior != allocation)
7969 {
7970 return Err(publication_input_error(
7971 "publication material changes model backing or view relationships",
7972 ));
7973 }
7974 }
7975 if self.ranges.iter().any(|item| {
7976 !matches!(item.range.role, 18..=25)
7977 && (slot_allocations.contains_key(&item.range.storage_slot)
7978 || item.range.backing_digest != Identity256::default())
7979 }) {
7980 return Err(publication_input_error(
7981 "model backing aliases native control or cache storage",
7982 ));
7983 }
7984 let header = self.bank.header;
7985 let contract = self.contract;
7986 if !cfg!(target_endian = "little")
7987 || header.abi != 1
7988 || contract.abi != 1
7989 || header.sealed_epoch != header.publication_word >> 1
7990 || contract.terminal_tokens != 0
7991 || contract.role_counts != 0
7992 || contract.semantic_owner != 0
7993 || contract.window_capacity != 32
7994 || contract.role_count != 55
7995 || contract.terminal_token_count != self.terminals.len() as u64
7996 || contract.model_generation == 0
7997 || header.model_generation < contract.model_generation
7998 || u32::try_from(header.model_generation).is_err()
7999 || header.authority_generation != contract.authority_generation
8000 || header.semantic_digest.as_bytes() != &self.graph.digest
8001 || header.semantic_extents != self.graph.extents.map(u64::from)
8002 || validate_publication_counts(&self.role_counts)? != self.ranges.len()
8003 || header.range_count != self.ranges.len() as u64
8004 || contract.range_capacity != header.range_count
8005 {
8006 return Err(publication_input_error(
8007 "publication material header or graph differs from its complete owned state",
8008 ));
8009 }
8010 let mut ranges = self.ranges.iter();
8011 for (ordinal, &count) in self.role_counts.iter().enumerate() {
8012 let role = ordinal as u64 + 1;
8013 for index in 0..count {
8014 let item = ranges
8015 .next()
8016 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8017 if (item.range.role, item.range.index) != (role, index)
8018 || item.range.generation != 1
8019 || item.range.length_bytes != item.bytes.len() as u64
8020 || (item.capacity == 0
8021 && !self
8022 .layouts
8023 .get(&(role, index))
8024 .is_some_and(empty_model_tensor_layout))
8025 || item.bytes.len() > item.capacity
8026 || item.range.logical_begin > item.range.logical_end
8027 {
8028 return Err(publication_input_error(
8029 "publication material omits, reorders or changes a reachable range",
8030 ));
8031 }
8032 if is_tensor_role(role) {
8033 let layout = self.layouts.get(&(role, index)).ok_or_else(|| {
8034 publication_input_error("publication material omits a tensor layout")
8035 })?;
8036 if tensor_layout_bytes(layout)? > item.capacity
8037 || (empty_model_tensor_layout(layout)
8038 && (item.range.logical_begin != 0 || item.range.logical_end != 0))
8039 {
8040 return Err(publication_input_error(
8041 "publication material tensor exceeds its actual capacity",
8042 ));
8043 }
8044 } else if self.layouts.contains_key(&(role, index)) {
8045 return Err(publication_input_error(
8046 "publication material gives a tensor layout to a native record",
8047 ));
8048 }
8049 }
8050 }
8051 if self.layouts.len()
8052 != self
8053 .ranges
8054 .iter()
8055 .filter(|item| is_tensor_role(item.range.role))
8056 .count()
8057 {
8058 return Err(publication_input_error(
8059 "publication material has an undeclared tensor layout",
8060 ));
8061 }
8062 let acknowledgements = self
8063 .ranges
8064 .iter()
8065 .find(|item| (item.range.role, item.range.index) == (32, 0))
8066 .ok_or_else(|| {
8067 publication_input_error("publication material omits its acknowledgement queue")
8068 })?;
8069 let receipts =
8070 acknowledgement_receipts(&acknowledgements.bytes, acknowledgements.capacity)?;
8071 if !receipts.is_empty() {
8072 let entries = self
8073 .ranges
8074 .iter()
8075 .find(|item| (item.range.role, item.range.index) == (30, 0))
8076 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8077 let payload = self
8078 .ranges
8079 .iter()
8080 .find(|item| (item.range.role, item.range.index) == (31, 0))
8081 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8082 let intents = output_intents_from_ranges(entries, payload)?;
8083 if receipts.iter().any(|(identity, _)| {
8084 !intents
8085 .iter()
8086 .any(|intent| intent.stable_identity == *identity)
8087 }) {
8088 return Err(publication_input_error(
8089 "publication acknowledges an absent native intent",
8090 ));
8091 }
8092 }
8093 self.model_numerical_mode()?;
8094 Ok(())
8095 }
8096}
8097
8098struct PublicationStorage {
8099 control: TrackedCudaSlice<PublicationControl>,
8100 banks: [TrackedCudaSlice<PublicationBank>; 2],
8101 directories: [TrackedCudaSlice<PublicationRange>; 2],
8102 storage: TrackedCudaSlice<PublicationStorageEntry>,
8103 contract: TrackedCudaSlice<PublicationContract>,
8104 role_counts: TrackedCudaSlice<PublicationRoleCount>,
8105 terminals: TrackedCudaSlice<u64>,
8106 continuation: TrackedCudaSlice<PendingContinuation>,
8107 continuation_directory: TrackedCudaSlice<PublicationRange>,
8108 allocations: Vec<TrackedCudaSlice<u8>>,
8109 model_memory: ModelMemoryGeometry,
8110 physical_parameter_roster: Option<Vec<String>>,
8111 model_slots: Vec<[usize; 2]>,
8112 bank_templates: [Vec<PublicationRange>; 2],
8113 continuation_templates: Vec<PublicationRange>,
8114 layouts: BTreeMap<(u64, u64), SemanticTensorLayout>,
8115 contract_value: PublicationContract,
8116 instance: Identity256,
8117}
8118
8119fn allocate_publication<T: DeviceRepr>(
8120 provider: &CudaKernelProvider,
8121 count: usize,
8122) -> Result<TrackedCudaSlice<T>, SemanticTransitionError> {
8123 provider
8124 .memory()
8125 .alloc::<T>(count)
8126 .map_err(|error| runtime_error("publication allocation", error))
8127}
8128
8129fn upload_publication<T: DeviceRepr>(
8130 provider: &CudaKernelProvider,
8131 values: &[T],
8132 destination: &TrackedCudaSlice<T>,
8133) -> Result<(), SemanticTransitionError> {
8134 let mut destination = destination.view();
8135 provider
8136 .htod_launch_metadata_sync_copy_into(values, &mut destination)
8137 .map_err(|error| runtime_error("publication cold metadata upload", error))
8138}
8139
8140#[cfg(feature = "semantic-policy")]
8141fn account_tracked_allocation<T: cudarc::driver::DeviceRepr>(
8142 allocations: &mut Vec<DeviceAllocationProvenance>,
8143 slice: &TrackedCudaSlice<T>,
8144) -> Result<(), SemanticTransitionError> {
8145 let provenance = slice
8146 .view()
8147 .allocation_provenance()
8148 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8149 if !allocations
8150 .iter()
8151 .any(|known| provenance.same_allocation(known))
8152 {
8153 allocations.push(provenance);
8154 }
8155 Ok(())
8156}
8157
8158#[cfg(feature = "semantic-policy")]
8159fn accounted_tracked_bytes(
8160 allocations: Vec<DeviceAllocationProvenance>,
8161) -> Result<u64, SemanticTransitionError> {
8162 allocations.into_iter().try_fold(0u64, |total, allocation| {
8163 total
8164 .checked_add(allocation.allocation_bytes())
8165 .ok_or(SemanticTransitionError::GenerationExhausted)
8166 })
8167}
8168
8169impl PublicationStorage {
8170 fn continuation_block_contract(
8171 &self,
8172 kind: SemanticTransitionKind,
8173 input: &SemanticContinuationInput,
8174 prepared: bool,
8175 ) -> Result<(Option<usize>, Identity256, Identity256), SemanticTransitionError> {
8176 let expected = if kind == SemanticTransitionKind::Proposal {
8177 self.physical_parameter_roster.as_ref().map(Vec::len)
8178 } else {
8179 None
8180 };
8181 let host_identities = expected.is_some() && !prepared;
8182 if input.numerical_blocks.is_some() != expected.is_some()
8183 || input.model_schema_digest.is_some() != host_identities
8184 || input.model_identity.is_some() != host_identities
8185 {
8186 return Err(publication_input_error(
8187 "proposal block bounds require their original roster; only acquired replay accepts host model identities",
8188 ));
8189 }
8190 let schema = input.model_schema_digest.unwrap_or_default();
8191 let identity = input.model_identity.unwrap_or_default();
8192 if host_identities
8193 && (schema == Identity256::default() || identity == Identity256::default())
8194 {
8195 return Err(publication_input_error(
8196 "proposal block bounds require nonzero original model identities",
8197 ));
8198 }
8199 Ok((expected, schema, identity))
8200 }
8201
8202 #[cfg(feature = "semantic-policy")]
8203 fn accounted_allocation_bytes(&self) -> Result<u64, SemanticTransitionError> {
8204 let mut allocations = Vec::new();
8205 account_tracked_allocation(&mut allocations, &self.control)?;
8206 for bank in &self.banks {
8207 account_tracked_allocation(&mut allocations, bank)?;
8208 }
8209 for directory in &self.directories {
8210 account_tracked_allocation(&mut allocations, directory)?;
8211 }
8212 account_tracked_allocation(&mut allocations, &self.storage)?;
8213 account_tracked_allocation(&mut allocations, &self.contract)?;
8214 account_tracked_allocation(&mut allocations, &self.role_counts)?;
8215 account_tracked_allocation(&mut allocations, &self.terminals)?;
8216 account_tracked_allocation(&mut allocations, &self.continuation)?;
8217 account_tracked_allocation(&mut allocations, &self.continuation_directory)?;
8218 for allocation in &self.allocations {
8219 account_tracked_allocation(&mut allocations, allocation)?;
8220 }
8221 accounted_tracked_bytes(allocations)
8222 }
8223
8224 #[expect(
8225 clippy::too_many_arguments,
8226 reason = "the guard records each authenticated publication coordinate explicitly"
8227 )]
8228 fn enqueue_content_guard(
8229 &self,
8230 domain: &ResidentExecutionDomain,
8231 poisoned: &mut bool,
8232 reader: DeviceMemoryView<PublicationLease>,
8233 execute: &CudaFunction,
8234 role: u64,
8235 index: u64,
8236 layout: SemanticTensorLayout,
8237 ) -> Result<(), SemanticTransitionError> {
8238 let mut recorder = domain.new_strict_recorder();
8239 recorder.read(&reader);
8240 recorder.read(&self.control);
8241 recorder.read(&self.storage);
8242 recorder.read(&self.contract);
8243 for bank in &self.banks {
8244 recorder.read(bank);
8245 }
8246 for directory in &self.directories {
8247 recorder.read(directory);
8248 }
8249 for allocation in &self.allocations {
8250 recorder.read(allocation);
8251 }
8252 let arguments = (
8253 self.control.device_ptr_value(),
8254 role,
8255 index,
8256 layout,
8257 u64::from(is_tensor_role(role)),
8258 *reader.device_ptr(),
8259 );
8260 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
8261 unsafe {
8264 execute.clone().launch_in(
8265 enqueue,
8266 LaunchConfig {
8267 grid_dim: (1, 1, 1),
8268 block_dim: (1, 1, 1),
8269 shared_mem_bytes: 0,
8270 },
8271 arguments,
8272 )
8273 }
8274 .map_err(|error| XlogError::Kernel(error.to_string()))
8275 })
8276 }
8277
8278 #[expect(
8279 clippy::too_many_arguments,
8280 reason = "cold allocation consumes the complete independently owned publication contract"
8281 )]
8282 fn allocate(
8283 provider: &CudaKernelProvider,
8284 plans: &[PublicationAllocationPlan],
8285 layouts: BTreeMap<(u64, u64), SemanticTensorLayout>,
8286 model_memory: ModelMemoryGeometry,
8287 model_payloads: &[PublicationPayload],
8288 mut contract: PublicationContract,
8289 terminal_tokens: &[u64],
8290 instance: Identity256,
8291 ) -> Result<(Self, Vec<(usize, PublicationPayload)>), SemanticTransitionError> {
8292 let mut allocations = Vec::new();
8293 let mut bank_templates = [Vec::new(), Vec::new()];
8294 let mut uploads = Vec::new();
8295 model_memory.validate(&layouts)?;
8296 if model_payloads.len() != model_memory.allocation_bytes.len() {
8297 return Err(publication_input_error(
8298 "model backing upload roster differs from its complete memory map",
8299 ));
8300 }
8301 let physical_parameter_roster = plans
8302 .iter()
8303 .find(|plan| (plan.role, plan.index) == (44, 0))
8304 .and_then(|plan| match &plan.payload {
8305 PublicationPayload::Metadata(bytes) => Some(bytes.as_slice()),
8306 _ => None,
8307 })
8308 .map(|record| model_physical_parameter_roster(record, contract.model_contract_layout))
8309 .transpose()?
8310 .flatten();
8311 let mut model_slots = Vec::new();
8312 for (&bytes, payload) in model_memory.allocation_bytes.iter().zip(model_payloads) {
8313 let mut slots = [0; 2];
8314 for slot in &mut slots {
8315 *slot = allocations.len();
8316 allocations.push(allocate_publication::<u8>(provider, bytes as usize)?);
8317 uploads.push((*slot, payload.clone()));
8318 }
8319 model_slots.push(slots);
8320 }
8321 for plan in plans {
8322 if (plan.capacity == 0
8323 && !layouts
8324 .get(&(plan.role, plan.index))
8325 .is_some_and(empty_model_tensor_layout))
8326 || plan.length > plan.capacity
8327 || (layouts
8328 .get(&(plan.role, plan.index))
8329 .is_some_and(empty_model_tensor_layout)
8330 && (plan.logical_begin != 0 || plan.logical_end != 0))
8331 {
8332 return Err(publication_input_error(
8333 "owned publication allocation has invalid capacity",
8334 ));
8335 }
8336 let mut slot = 0;
8337 let model_view = if matches!(plan.role, 18..=25) {
8338 Some(model_memory.location(plan.role, plan.index)?)
8339 } else {
8340 None
8341 };
8342 for (bank, directory) in bank_templates.iter_mut().enumerate() {
8343 if let Some((allocation, offset)) = model_view {
8344 slot = model_slots[allocation][bank];
8345 if plan.capacity != allocations[slot].len() - offset {
8346 return Err(publication_input_error(
8347 "model range capacity differs from its actual backing view",
8348 ));
8349 }
8350 } else if bank == 0 || publication_mutable_role(plan.role) {
8351 slot = allocations.len();
8352 allocations.push(allocate_publication::<u8>(provider, plan.capacity)?);
8353 uploads.push((slot, plan.payload.clone()));
8354 }
8355 directory.push(PublicationRange {
8356 role: plan.role,
8357 index: plan.index,
8358 storage_slot: slot as u64,
8359 generation: 1,
8360 offset_bytes: model_view.map_or(0, |(_, offset)| offset as u64),
8361 length_bytes: plan.length as u64,
8362 logical_begin: plan.logical_begin,
8363 logical_end: plan.logical_end,
8364 digest: Identity256::default(),
8365 backing_digest: Identity256::default(),
8366 });
8367 }
8368 }
8369 let pending_layouts = layouts
8370 .values()
8371 .filter(|layout| continuation_role(layout.role))
8372 .map(|layout| continuation_allocation_layout(*layout))
8373 .collect::<Result<Vec<_>, _>>()?;
8374 let pending_table = tensor_table_bytes(&pending_layouts, true, &[])?;
8375 let mut continuation_templates = Vec::new();
8376 for plan in plans.iter().filter(|plan| continuation_role(plan.role)) {
8377 let capacity = if plan.role == 1 {
8378 32 * size_of::<SemanticTextSlot>()
8379 } else if plan.role == 39 {
8380 plan.capacity
8381 } else if plan.role == 55 {
8382 tensor_table_capacity(pending_layouts.len(), 32 + contract.feedback_capacity)?
8383 } else {
8384 tensor_layout_bytes(&continuation_allocation_layout(
8385 layouts[&(plan.role, plan.index)],
8386 )?)?
8387 };
8388 if capacity == 0 {
8389 return Err(publication_input_error(
8390 "continuation destination has no actual capacity",
8391 ));
8392 }
8393 let slot = allocations.len();
8394 allocations.push(allocate_publication::<u8>(provider, capacity)?);
8395 let length = if plan.role == 55 {
8396 uploads.push((slot, PublicationPayload::Metadata(pending_table.clone())));
8397 pending_table.len()
8398 } else if matches!(plan.role, 1 | 39) {
8399 0
8400 } else {
8401 capacity
8402 };
8403 continuation_templates.push(PublicationRange {
8404 role: plan.role,
8405 index: plan.index,
8406 storage_slot: slot as u64,
8407 generation: 1,
8408 length_bytes: length as u64,
8409 ..PublicationRange::default()
8410 });
8411 }
8412 let terminals = allocate_publication::<u64>(provider, terminal_tokens.len())?;
8413 let role_counts = allocate_publication::<PublicationRoleCount>(provider, 55)?;
8414 contract.terminal_tokens = terminals.device_ptr_value();
8415 contract.role_counts = role_counts.device_ptr_value();
8416 let contract_value = contract;
8417 Ok((
8418 Self {
8419 control: allocate_publication(provider, 1)?,
8420 banks: [
8421 allocate_publication(provider, 1)?,
8422 allocate_publication(provider, 1)?,
8423 ],
8424 directories: [
8425 allocate_publication(provider, plans.len())?,
8426 allocate_publication(provider, plans.len())?,
8427 ],
8428 storage: allocate_publication(provider, allocations.len())?,
8429 contract: allocate_publication(provider, 1)?,
8430 role_counts,
8431 terminals,
8432 continuation: allocate_publication(provider, 1)?,
8433 continuation_directory: allocate_publication(
8434 provider,
8435 continuation_templates.len(),
8436 )?,
8437 allocations,
8438 model_memory,
8439 physical_parameter_roster,
8440 model_slots,
8441 bank_templates,
8442 continuation_templates,
8443 layouts,
8444 contract_value,
8445 instance,
8446 },
8447 uploads,
8448 ))
8449 }
8450
8451 fn record(&self, recorder: &mut LaunchRecorder) {
8452 recorder.read_write(&self.control);
8453 for bank in &self.banks {
8454 recorder.read_write(bank);
8455 }
8456 for directory in &self.directories {
8457 recorder.read_write(directory);
8458 }
8459 recorder.read(&self.storage);
8460 recorder.read(&self.contract);
8461 recorder.read(&self.role_counts);
8462 recorder.read(&self.terminals);
8463 recorder.read_write(&self.continuation);
8464 recorder.read_write(&self.continuation_directory);
8465 for allocation in &self.allocations {
8466 recorder.read_write(allocation);
8467 }
8468 }
8469}
8470
8471struct PreparedContinuation {
8472 storage: Arc<PublicationStorage>,
8473 reader: DeviceMemoryView<PublicationLease>,
8474 text_binding: Arc<TextBindingStorage>,
8475 sources: Vec<PreparedSemanticTensor>,
8476 copies: Vec<(u64, u64, usize)>,
8477 inputs: ContinuationInputs,
8478 training_selection: Option<DeviceMemoryView<SemanticTrainingViewSelection>>,
8479 execute: CudaFunction,
8480}
8481
8482type ContinuationPayloadPlan = (
8483 Vec<(usize, PublicationPayload)>,
8484 BTreeMap<(u64, u64), SemanticTensorLayout>,
8485);
8486
8487fn prepare_continuation_payloads(
8488 storage: &PublicationStorage,
8489 original: &[PreparedSemanticTensor],
8490 authority_decisions: &[u8],
8491 kind: SemanticTransitionKind,
8492) -> Result<ContinuationPayloadPlan, SemanticTransitionError> {
8493 let mut pending_layouts = BTreeMap::new();
8494 let mut inputs = BTreeMap::new();
8495 for tensor in original {
8496 let key = (tensor.layout.role, tensor.layout.index);
8497 let model = storage.layouts.get(&key).ok_or_else(|| {
8498 publication_input_error("continuation tensor has no cold model owner")
8499 })?;
8500 if !continuation_role(key.0) || !is_tensor_role(key.0) || inputs.contains_key(&key) {
8501 return Err(publication_input_error(
8502 "continuation tensor type or role differs from the model",
8503 ));
8504 }
8505 let destination = continuation_tensor_layout_for_kind(
8506 &tensor.layout,
8507 tensor.logical_begin,
8508 tensor.logical_end,
8509 model,
8510 kind,
8511 )?;
8512 pending_layouts.insert(key, destination);
8513 inputs.insert(key, tensor.clone());
8514 }
8515 let mut uploads = Vec::new();
8516 for range in &storage.continuation_templates {
8517 let key = (range.role, range.index);
8518 if matches!(range.role, 1 | 55) {
8519 continue;
8520 }
8521 let payload = if range.role == 39 {
8522 PublicationPayload::Metadata(authority_decisions.to_vec())
8523 } else {
8524 PublicationPayload::Tensor(inputs.remove(&key).ok_or_else(|| {
8525 publication_input_error("continuation omits an actual required forward tensor")
8526 })?)
8527 };
8528 let length = match &payload {
8529 PublicationPayload::Metadata(bytes) => bytes.len(),
8530 PublicationPayload::Tensor(_) => tensor_layout_bytes(&pending_layouts[&key])?,
8531 PublicationPayload::Uncomputed => {
8532 unreachable!("continuation accepts original computed tensors only")
8533 }
8534 };
8535 if length > storage.allocations[range.storage_slot as usize].len() {
8536 return Err(publication_input_error(
8537 "actual continuation exceeds its owned fixed destination capacity",
8538 ));
8539 }
8540 uploads.push((range.storage_slot as usize, payload));
8541 }
8542 if !inputs.is_empty() {
8543 return Err(publication_input_error(
8544 "continuation contains an undeclared tensor owner",
8545 ));
8546 }
8547 Ok((uploads, pending_layouts))
8548}
8549
8550impl PreparedContinuation {
8551 #[expect(
8554 clippy::too_many_arguments,
8555 reason = "continuation preparation binds all retained producer and publication owners"
8556 )]
8557 fn prepare(
8558 provider: &CudaKernelProvider,
8559 storage: Arc<PublicationStorage>,
8560 reader: DeviceMemoryView<PublicationLease>,
8561 text_binding: Arc<TextBindingStorage>,
8562 inputs: ContinuationInputs,
8563 training_selection: Option<DeviceMemoryView<SemanticTrainingViewSelection>>,
8564 uploads: &[(usize, PublicationPayload)],
8565 layouts: &BTreeMap<(u64, u64), SemanticTensorLayout>,
8566 ) -> Result<Self, SemanticTransitionError> {
8567 let mut sources = Vec::new();
8568 let mut copies = Vec::new();
8569 for (slot, payload) in uploads {
8570 let PublicationPayload::Tensor(tensor) = payload else {
8571 continue;
8572 };
8573 let destination = storage
8574 .allocations
8575 .get(*slot)
8576 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8577 if let Some(source) = &tensor.source {
8578 let layout = layouts
8579 .get(&(tensor.layout.role, tensor.layout.index))
8580 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8581 for (source_offset, destination_offset, bytes) in
8582 tensor_copy_plan(&tensor.layout, layout)?
8583 {
8584 if source_offset
8585 .checked_add(bytes as u64)
8586 .is_none_or(|end| end > source.len() as u64)
8587 || destination_offset
8588 .checked_add(bytes as u64)
8589 .is_none_or(|end| end > destination.len() as u64)
8590 {
8591 return Err(SemanticTransitionError::ObservationMismatch);
8592 }
8593 let source = source
8594 .device_ptr()
8595 .checked_add(source_offset)
8596 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8597 let destination = destination
8598 .device_ptr_value()
8599 .checked_add(destination_offset)
8600 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8601 copies.push((source, destination, bytes));
8602 }
8603 }
8604 sources.push(tensor.clone());
8606 }
8607 let execute = provider
8608 .device()
8609 .inner()
8610 .get_func(
8611 "xlog_semantic_transition",
8612 "semantic_publication_prepare_continuation",
8613 )
8614 .ok_or_else(|| {
8615 runtime_error("kernel lookup", "continuation preparation unavailable")
8616 })?;
8617 Ok(Self {
8618 storage,
8619 reader,
8620 text_binding,
8621 sources,
8622 copies,
8623 inputs,
8624 training_selection,
8625 execute,
8626 })
8627 }
8628
8629 fn enqueue(
8632 &self,
8633 domain: &ResidentExecutionDomain,
8634 poisoned: &mut bool,
8635 ) -> Result<(), SemanticTransitionError> {
8636 let mut recorder = domain.new_strict_recorder();
8637 self.storage.record(&mut recorder);
8638 recorder.read(&self.reader);
8639 self.text_binding.record(&mut recorder);
8640 if let Some(selection) = &self.training_selection {
8641 recorder.read(selection);
8642 }
8643 for tensor in &self.sources {
8644 if let Some(source) = &tensor.source {
8645 recorder.read(source);
8646 }
8647 }
8648 let arguments = (
8649 self.storage.control.device_ptr_value(),
8650 *self.reader.device_ptr(),
8651 self.inputs,
8652 );
8653 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
8654 for &(source, destination, bytes) in &self.copies {
8655 unsafe {
8658 sys::cuMemcpyDtoDAsync_v2(
8659 destination,
8660 source,
8661 bytes,
8662 enqueue.stream().cu_stream(),
8663 )
8664 }
8665 .result()
8666 .map_err(|error| XlogError::Kernel(error.to_string()))?;
8667 }
8668 unsafe {
8671 self.execute.clone().launch_in(
8672 enqueue,
8673 LaunchConfig {
8674 grid_dim: (1, 1, 1),
8675 block_dim: (1, 1, 1),
8676 shared_mem_bytes: 0,
8677 },
8678 arguments,
8679 )
8680 }
8681 .map_err(|error| XlogError::Kernel(error.to_string()))
8682 })
8683 }
8684}
8685
8686struct PublishedReader {
8687 device: TrackedCudaSlice<PublicationLease>,
8688 aliases: Arc<()>,
8689 consumer_streams: BTreeSet<u64>,
8690}
8691
8692#[repr(C)]
8693#[derive(Clone, Copy)]
8694struct PublicationStepInput {
8695 role: u64,
8696 index: u64,
8697 destination: u64,
8698 capacity_bytes: u64,
8699 backing: u64,
8700 backing_bytes: u64,
8701 layout: SemanticTensorLayout,
8702}
8703
8704unsafe impl DeviceRepr for PublicationStepInput {}
8706const _: () = assert!(size_of::<PublicationStepInput>() == 160);
8707
8708#[derive(Clone, Debug)]
8709struct StepInputBankPlan {
8710 storage_slot: usize,
8711 span: std::ops::Range<usize>,
8712}
8713
8714#[derive(Clone)]
8715struct StepInputPlan {
8716 role: u64,
8717 index: u64,
8718 layout: SemanticTensorLayout,
8719 banks: [StepInputBankPlan; 2],
8720}
8721
8722fn step_input_overlap(
8723 data: u64,
8724 bytes: usize,
8725 base: u64,
8726 capacity: usize,
8727) -> Result<bool, SemanticTransitionError> {
8728 let end = data
8729 .checked_add(bytes as u64)
8730 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8731 let limit = base
8732 .checked_add(capacity as u64)
8733 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8734 Ok(if bytes == 0 {
8735 data >= base && data < limit
8736 } else {
8737 data < limit && base < end
8738 })
8739}
8740
8741fn plan_step_inputs(
8742 banks: &[Vec<PublicationRange>; 2],
8743 layouts: &BTreeMap<(u64, u64), SemanticTensorLayout>,
8744 prefix_capacity: u64,
8745 allocation_bytes: &[usize],
8746) -> Result<Vec<StepInputPlan>, SemanticTransitionError> {
8747 let mut expected = BTreeSet::from([(1, 0), (3, 0), (15, 0), (16, 0), (17, 0), (44, 0)]);
8748 expected.extend(
8749 banks[0]
8750 .iter()
8751 .filter(|range| matches!(range.role, 16 | 17))
8752 .map(|range| (range.role, range.index)),
8753 );
8754 for (&key, layout) in layouts
8755 .iter()
8756 .filter(|(key, _)| matches!(key.0, 4..=13 | 18..=25))
8757 {
8758 let model = matches!(key.0, 18..=25);
8759 let bytes = tensor_layout_bytes(layout)?;
8760 if key != (layout.role, layout.index)
8761 || (!model && (canonical_tensor_layout(*layout)? != *layout || bytes == 0))
8762 || (model && layout.logical_axis != u64::MAX)
8763 {
8764 return Err(publication_input_error(
8765 "step input must retain its original tensor layout",
8766 ));
8767 }
8768 expected.insert(key);
8769 }
8770 for role in (4..=13).chain(15..=25) {
8771 for (index, key) in expected.iter().filter(|key| key.0 == role).enumerate() {
8772 if key.1 != index as u64 {
8773 return Err(publication_input_error(
8774 "step input tensor indexes must be contiguous",
8775 ));
8776 }
8777 }
8778 }
8779 for bank in banks {
8780 let actual = bank
8781 .iter()
8782 .filter(|range| matches!(range.role, 1 | 3..=13 | 15..=25 | 44))
8783 .map(|range| (range.role, range.index))
8784 .collect::<Vec<_>>();
8785 if actual.len() != expected.len()
8786 || actual.iter().copied().collect::<BTreeSet<_>>() != expected
8787 {
8788 return Err(publication_input_error(
8789 "step input banks must have the exact original input roster",
8790 ));
8791 }
8792 }
8793 let mut plan = Vec::with_capacity(expected.len());
8794 let mut spans = Vec::new();
8795 for (role, index) in expected {
8796 let ranges = banks.each_ref().map(|bank| {
8797 *bank
8798 .iter()
8799 .find(|range| (range.role, range.index) == (role, index))
8800 .expect("validated input roster")
8801 });
8802 let layout = if role == 1 {
8803 committed_prefix_layout(&ranges[0], prefix_capacity)?
8804 } else if matches!(role, 3 | 15..=17 | 44) {
8805 SemanticTensorLayout {
8806 role,
8807 index,
8808 scalar_type: 1,
8809 element_bytes: 1,
8810 rank: 1,
8811 logical_axis: u64::MAX,
8812 dimensions: [ranges[0].length_bytes, 0, 0, 0],
8813 strides_bytes: [1, 0, 0, 0],
8814 }
8815 } else {
8816 layouts[&(role, index)]
8817 };
8818 let bytes = tensor_layout_bytes(&layout)?;
8819 if (bytes == 0 && !matches!(role, 18..=25))
8820 || (role == 3 && ranges.iter().any(|range| range.length_bytes != 32))
8821 {
8822 return Err(publication_input_error(
8823 "step input has no complete fixed physical capacity",
8824 ));
8825 }
8826 if matches!(role, 15..=17)
8827 && ranges.iter().any(|range| {
8828 range.logical_begin != 0
8829 || if role == 15 {
8830 range.length_bytes % size_of::<RawFeedbackRecord>() as u64 != 0
8831 || range.logical_end
8832 > range.length_bytes / size_of::<RawFeedbackRecord>() as u64
8833 } else {
8834 range.logical_end != 0
8835 }
8836 })
8837 {
8838 return Err(publication_input_error(
8839 "raw feedback input differs from its original record extent",
8840 ));
8841 }
8842 let mut resolved = Vec::with_capacity(2);
8843 for (bank, range) in ranges.iter().enumerate() {
8844 if role == 1 {
8845 committed_prefix_layout(range, prefix_capacity)?;
8846 }
8847 let slot = usize::try_from(range.storage_slot)
8848 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
8849 let capacity = *allocation_bytes
8850 .get(slot)
8851 .ok_or(SemanticTransitionError::ObservationMismatch)?;
8852 let span = publication_export_span(range, &layout, capacity)?;
8853 if span.len() != bytes {
8854 return Err(publication_input_error(
8855 "step input differs from its full typed capacity",
8856 ));
8857 }
8858 spans.push((bank, role, index, slot, span.clone()));
8859 resolved.push((slot, span, capacity));
8860 }
8861 if role == 1 && resolved[0] != resolved[1] {
8862 return Err(publication_input_error(
8863 "prefix step inputs must share their original capacity allocation",
8864 ));
8865 }
8866 if matches!(role, 4 | 5 | 15 | 18..=25 | 44)
8867 && (resolved[0].0 == resolved[1].0
8868 || resolved[0].1 != resolved[1].1
8869 || resolved[0].2 != resolved[1].2)
8870 {
8871 return Err(publication_input_error("bank-selected step inputs require disjoint banks with the same complete backing geometry"));
8872 }
8873 plan.push(StepInputPlan {
8874 role,
8875 index,
8876 layout,
8877 banks: resolved
8878 .into_iter()
8879 .map(
8880 |(storage_slot, span, _allocation_bytes)| StepInputBankPlan {
8881 storage_slot,
8882 span,
8883 },
8884 )
8885 .collect::<Vec<_>>()
8886 .try_into()
8887 .expect("two publication banks"),
8888 });
8889 }
8890 for (ordinal, (bank, role, index, slot, span)) in spans.iter().enumerate() {
8891 for (other_bank, other_role, other_index, other_slot, other_span) in &spans[..ordinal] {
8892 let same_shared = bank != other_bank
8893 && role == other_role
8894 && index == other_index
8895 && slot == other_slot
8896 && span == other_span
8897 && matches!(*role, 1 | 16 | 17);
8898 let same_model =
8899 bank == other_bank && matches!(*role, 18..=25) && matches!(*other_role, 18..=25);
8900 if slot == other_slot
8901 && span.start < other_span.end
8902 && other_span.start < span.end
8903 && !same_shared
8904 && !same_model
8905 {
8906 return Err(publication_input_error(
8907 "step input caches and distinct tensor ranges must be isolated",
8908 ));
8909 }
8910 }
8911 }
8912 Ok(plan)
8913}
8914
8915struct PreparedStepInputs {
8918 storage: Arc<PublicationStorage>,
8919 reader: DeviceMemoryView<PublicationLease>,
8920 header: TrackedCudaSlice<PublicationHeader>,
8921 source: TrackedCudaSlice<SourceSlot>,
8922 ranges: TrackedCudaSlice<PublicationRange>,
8923 metadata_digests: TrackedCudaSlice<u64>,
8924 bindings: [TrackedCudaSlice<PublicationStepInput>; 2],
8925 binding_values: [Vec<PublicationStepInput>; 2],
8926 plans: Vec<StepInputPlan>,
8927 views: [BTreeMap<(u64, u64), DeviceMemoryView<u8>>; 2],
8928 private: Vec<TrackedCudaSlice<u8>>,
8929 execute: CudaFunction,
8930 guard: CudaFunction,
8931 completed_guard: CudaFunction,
8932}
8933
8934impl PreparedStepInputs {
8935 fn plan(storage: &PublicationStorage) -> Result<Vec<StepInputPlan>, SemanticTransitionError> {
8936 plan_step_inputs(
8937 &storage.bank_templates,
8938 &storage.layouts,
8939 storage.contract_value.prefix_capacity,
8940 &storage
8941 .allocations
8942 .iter()
8943 .map(TrackedCudaSlice::len)
8944 .collect::<Vec<_>>(),
8945 )
8946 }
8947
8948 fn allocation_bytes(plans: &[StepInputPlan]) -> Result<usize, SemanticTransitionError> {
8949 let fixed =
8950 size_of::<PublicationHeader>() + 32 * size_of::<SourceSlot>() + u64::BITS as usize;
8951 let bytes = plans
8952 .len()
8953 .checked_mul(size_of::<PublicationRange>() + 2 * size_of::<PublicationStepInput>())
8954 .and_then(|n| n.checked_add(fixed))
8955 .ok_or(SemanticTransitionError::GenerationExhausted)?;
8956 plans
8957 .iter()
8958 .filter(|input| !matches!(input.role, 1 | 4 | 5 | 18..=25))
8959 .try_fold(bytes, |sum, input| {
8960 sum.checked_add(input.banks[0].span.len())
8961 .ok_or(SemanticTransitionError::GenerationExhausted)
8962 })
8963 }
8964
8965 fn allocate(
8966 provider: &CudaKernelProvider,
8967 storage: Arc<PublicationStorage>,
8968 reader: DeviceMemoryView<PublicationLease>,
8969 ) -> Result<Self, SemanticTransitionError> {
8970 let plans = Self::plan(&storage)?;
8971 let mut reservation = provider
8972 .memory()
8973 .reserve_bytes(Self::allocation_bytes(&plans)? as u64)
8974 .map_err(|error| runtime_error("step input reservation", error))?;
8975 Self::allocate_reserved(provider, storage, reader, plans, &mut reservation)
8976 }
8977
8978 fn allocate_reserved(
8979 provider: &CudaKernelProvider,
8980 storage: Arc<PublicationStorage>,
8981 reader: DeviceMemoryView<PublicationLease>,
8982 plans: Vec<StepInputPlan>,
8983 reservation: &mut GpuMemoryReservation,
8984 ) -> Result<Self, SemanticTransitionError> {
8985 let contract = storage.contract_value;
8986 if contract.abi != 1
8987 || contract.model_generation == 0
8988 || contract.window_capacity != 32
8989 || reader.len() != 1
8990 {
8991 return Err(publication_input_error(
8992 "fixed step inputs require the original admitted model contract and device reader",
8993 ));
8994 }
8995 let execute = provider
8996 .device()
8997 .inner()
8998 .get_func(
8999 "xlog_semantic_transition",
9000 "semantic_publication_step_inputs",
9001 )
9002 .ok_or_else(|| {
9003 runtime_error(
9004 "kernel lookup",
9005 "publication step input producer unavailable",
9006 )
9007 })?;
9008 let guard = provider
9009 .device()
9010 .inner()
9011 .get_func(
9012 "xlog_semantic_transition",
9013 "semantic_publication_step_input_guard",
9014 )
9015 .ok_or_else(|| {
9016 runtime_error("kernel lookup", "publication step input guard unavailable")
9017 })?;
9018 let mut private = Vec::new();
9019 let completed_guard = provider
9020 .device()
9021 .inner()
9022 .get_func(
9023 "xlog_semantic_transition",
9024 "semantic_completed_step_input_guard",
9025 )
9026 .ok_or_else(|| runtime_error("kernel lookup", "completed input guard unavailable"))?;
9027 let mut views = [BTreeMap::new(), BTreeMap::new()];
9028 let mut binding_values = [
9029 Vec::with_capacity(plans.len()),
9030 Vec::with_capacity(plans.len()),
9031 ];
9032 for input in &plans {
9033 if matches!(input.role, 1 | 4 | 5 | 18..=25) {
9034 for bank in 0..2 {
9035 let plan = &input.banks[bank];
9036 let view = storage.allocations[plan.storage_slot]
9037 .view()
9038 .slice(plan.span.clone());
9039 let backing = if matches!(input.role, 18..=25) {
9040 view.allocation_view()
9041 .ok_or(SemanticTransitionError::ObservationMismatch)?
9042 } else {
9043 view.clone()
9044 };
9045 binding_values[bank].push(PublicationStepInput {
9046 role: input.role,
9047 index: input.index,
9048 destination: *view.device_ptr(),
9049 capacity_bytes: view.len() as u64,
9050 backing: *backing.device_ptr(),
9051 backing_bytes: backing.len() as u64,
9052 layout: input.layout,
9053 });
9054 views[bank].insert((input.role, input.index), view);
9055 }
9056 } else {
9057 private.push(
9058 reservation
9059 .alloc::<u8>(input.banks[0].span.len())
9060 .map_err(|error| runtime_error("step private input allocation", error))?,
9061 );
9062 let view = private
9063 .last()
9064 .expect("retained private input allocation")
9065 .view();
9066 for bank in 0..2 {
9067 binding_values[bank].push(PublicationStepInput {
9068 role: input.role,
9069 index: input.index,
9070 destination: *view.device_ptr(),
9071 capacity_bytes: view.len() as u64,
9072 backing: *view.device_ptr(),
9073 backing_bytes: view.len() as u64,
9074 layout: if matches!(input.role, 3 | 15..=17 | 44) {
9075 SemanticTensorLayout::default()
9076 } else {
9077 input.layout
9078 },
9079 });
9080 views[bank].insert((input.role, input.index), view.clone());
9081 }
9082 }
9083 }
9084 let owner = Self {
9085 header: reservation
9086 .alloc(1)
9087 .map_err(|error| runtime_error("step header allocation", error))?,
9088 source: reservation
9089 .alloc(32)
9090 .map_err(|error| runtime_error("step source allocation", error))?,
9091 ranges: reservation
9092 .alloc(plans.len())
9093 .map_err(|error| runtime_error("step range allocation", error))?,
9094 metadata_digests: reservation
9095 .alloc(8)
9096 .map_err(|error| runtime_error("step digest allocation", error))?,
9097 bindings: [
9098 reservation
9099 .alloc(plans.len())
9100 .map_err(|error| runtime_error("step binding allocation", error))?,
9101 reservation
9102 .alloc(plans.len())
9103 .map_err(|error| runtime_error("step binding allocation", error))?,
9104 ],
9105 storage,
9106 reader,
9107 plans,
9108 views,
9109 private,
9110 binding_values,
9111 execute,
9112 guard,
9113 completed_guard,
9114 };
9115 owner.validate_output_regions()?;
9116 Ok(owner)
9117 }
9118
9119 fn validate_output_regions(&self) -> Result<(), SemanticTransitionError> {
9120 let mut output = vec![
9121 (
9122 self.header.device_ptr_value(),
9123 size_of::<PublicationHeader>(),
9124 ),
9125 (self.source.device_ptr_value(), 32 * size_of::<SourceSlot>()),
9126 (
9127 self.ranges.device_ptr_value(),
9128 self.ranges.len() * size_of::<PublicationRange>(),
9129 ),
9130 (self.metadata_digests.device_ptr_value(), u64::BITS as usize),
9131 (
9132 self.bindings[0].device_ptr_value(),
9133 self.bindings[0].len() * size_of::<PublicationStepInput>(),
9134 ),
9135 (
9136 self.bindings[1].device_ptr_value(),
9137 self.bindings[1].len() * size_of::<PublicationStepInput>(),
9138 ),
9139 ];
9140 output.extend(
9141 self.private
9142 .iter()
9143 .map(|allocation| (allocation.device_ptr_value(), allocation.len())),
9144 );
9145 let mut original = self
9146 .storage
9147 .allocations
9148 .iter()
9149 .map(|allocation| (allocation.device_ptr_value(), allocation.len()))
9150 .collect::<Vec<_>>();
9151 original.extend(
9152 self.storage
9153 .banks
9154 .iter()
9155 .map(|bank| (bank.device_ptr_value(), size_of::<PublicationBank>())),
9156 );
9157 original.extend(self.storage.directories.iter().map(|directory| {
9158 (
9159 directory.device_ptr_value(),
9160 directory.len() * size_of::<PublicationRange>(),
9161 )
9162 }));
9163 original.extend([
9164 (*self.reader.device_ptr(), size_of::<PublicationLease>()),
9165 (
9166 self.storage.control.device_ptr_value(),
9167 size_of::<PublicationControl>(),
9168 ),
9169 (
9170 self.storage.contract.device_ptr_value(),
9171 size_of::<PublicationContract>(),
9172 ),
9173 (
9174 self.storage.storage.device_ptr_value(),
9175 self.storage.storage.len() * size_of::<PublicationStorageEntry>(),
9176 ),
9177 (
9178 self.storage.role_counts.device_ptr_value(),
9179 self.storage.role_counts.len() * size_of::<PublicationRoleCount>(),
9180 ),
9181 (
9182 self.storage.terminals.device_ptr_value(),
9183 self.storage.terminals.len() * size_of::<u64>(),
9184 ),
9185 ]);
9186 for (ordinal, &(begin, bytes)) in output.iter().enumerate() {
9187 if bytes == 0 {
9188 continue;
9189 }
9190 let end = begin
9191 .checked_add(bytes as u64)
9192 .filter(|&end| begin != 0 && end > begin)
9193 .ok_or(SemanticTransitionError::ObservationMismatch)?;
9194 for &(other, other_bytes) in original.iter().chain(&output[..ordinal]) {
9195 let other_end = other
9196 .checked_add(other_bytes as u64)
9197 .ok_or(SemanticTransitionError::ObservationMismatch)?;
9198 if begin < other_end && other < end {
9199 return Err(publication_input_error(
9200 "fixed step outputs overlap original storage or another output",
9201 ));
9202 }
9203 }
9204 }
9205 Ok(())
9206 }
9207
9208 fn initialize(&self, provider: &CudaKernelProvider) -> Result<(), SemanticTransitionError> {
9211 for bank in 0..2 {
9212 upload_publication(provider, &self.binding_values[bank], &self.bindings[bank])?;
9213 }
9214 Ok(())
9215 }
9216
9217 fn enqueue(
9218 &self,
9219 domain: &ResidentExecutionDomain,
9220 poisoned: &mut bool,
9221 ) -> Result<(), SemanticTransitionError> {
9222 let mut recorder = domain.new_strict_recorder();
9223 recorder.read(&self.reader);
9224 recorder.read(&self.storage.control);
9225 recorder.read(&self.storage.storage);
9226 recorder.read(&self.storage.contract);
9227 recorder.read(&self.storage.role_counts);
9228 recorder.read(&self.storage.terminals);
9229 for bank in &self.storage.banks {
9230 recorder.read(bank);
9231 }
9232 for directory in &self.storage.directories {
9233 recorder.read(directory);
9234 }
9235 for allocation in &self.storage.allocations {
9236 recorder.read(allocation);
9237 }
9238 for bindings in &self.bindings {
9239 recorder.read(bindings);
9240 }
9241 recorder.write(&self.header);
9242 recorder.write(&self.source);
9243 recorder.write(&self.ranges);
9244 recorder.write(&self.metadata_digests);
9245 for allocation in &self.private {
9246 recorder.write(allocation);
9247 }
9248 let arguments = (
9249 self.storage.control.device_ptr_value(),
9250 *self.reader.device_ptr(),
9251 self.bindings[0].device_ptr_value(),
9252 self.bindings[1].device_ptr_value(),
9253 self.bindings[0].len() as u64,
9254 self.header.device_ptr_value(),
9255 self.source.device_ptr_value(),
9256 self.ranges.device_ptr_value(),
9257 self.metadata_digests.device_ptr_value(),
9258 );
9259 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
9260 unsafe {
9263 self.execute.clone().launch_in(
9264 enqueue,
9265 LaunchConfig {
9266 grid_dim: (1, 1, 1),
9267 block_dim: (1, 1, 1),
9268 shared_mem_bytes: 0,
9269 },
9270 arguments,
9271 )
9272 }
9273 .map_err(|error| XlogError::Kernel(error.to_string()))
9274 })
9275 }
9276
9277 fn verify(
9278 &self,
9279 domain: &ResidentExecutionDomain,
9280 poisoned: &mut bool,
9281 ) -> Result<(), SemanticTransitionError> {
9282 self.verify_basis(domain, poisoned, None, false)
9283 }
9284
9285 fn verify_completed(
9286 &self,
9287 domain: &ResidentExecutionDomain,
9288 poisoned: &mut bool,
9289 custody: Option<&PreparedReplayCustody>,
9290 ) -> Result<(), SemanticTransitionError> {
9291 self.verify_basis(domain, poisoned, custody, true)
9292 }
9293
9294 fn verify_basis(
9295 &self,
9296 domain: &ResidentExecutionDomain,
9297 poisoned: &mut bool,
9298 custody: Option<&PreparedReplayCustody>,
9299 completed: bool,
9300 ) -> Result<(), SemanticTransitionError> {
9301 let mut recorder = domain.new_strict_recorder();
9302 recorder.read(&self.header);
9303 recorder.read(&self.source);
9304 recorder.read(&self.ranges);
9305 recorder.read(&self.reader);
9306 for bindings in &self.bindings {
9307 recorder.read(bindings);
9308 }
9309 recorder.read(&self.metadata_digests);
9310 for bank in &self.views {
9311 for view in bank.values() {
9312 recorder.read(view);
9313 }
9314 }
9315 for allocation in &self.private {
9316 recorder.read(allocation);
9317 }
9318 let bindings = if let Some(custody) = custody {
9319 if !custody.owns_inputs(self) {
9320 return Err(publication_input_error(
9321 "retained input guard belongs to another original step",
9322 ));
9323 }
9324 let bindings = custody.input_bindings();
9325 recorder.read(bindings);
9326 for input in &self.plans {
9327 if matches!(input.role, 1 | 4 | 5 | 18..=25) {
9328 let view = custody.input_view(input.role, input.index)?.0;
9329 recorder.read(&view);
9330 if matches!(input.role, 18..=25) {
9331 recorder.read(
9332 &view
9333 .allocation_view()
9334 .ok_or(SemanticTransitionError::ObservationMismatch)?,
9335 );
9336 }
9337 }
9338 }
9339 [bindings, bindings]
9340 } else {
9341 [&self.bindings[0], &self.bindings[1]]
9342 };
9343 let arguments = (
9344 *self.reader.device_ptr(),
9345 self.header.device_ptr_value(),
9346 self.source.device_ptr_value(),
9347 bindings[0].device_ptr_value(),
9348 bindings[1].device_ptr_value(),
9349 bindings[0].len() as u64,
9350 self.ranges.device_ptr_value(),
9351 self.metadata_digests.device_ptr_value(),
9352 );
9353 let guard = if completed {
9354 &self.completed_guard
9355 } else {
9356 &self.guard
9357 };
9358 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
9359 unsafe {
9362 guard.clone().launch_in(
9363 enqueue,
9364 LaunchConfig {
9365 grid_dim: (1, 1, 1),
9366 block_dim: (1, 1, 1),
9367 shared_mem_bytes: 0,
9368 },
9369 arguments,
9370 )
9371 }
9372 .map_err(|error| XlogError::Kernel(error.to_string()))
9373 })
9374 }
9375
9376 fn field_view(
9377 &self,
9378 field: PublicationBankField,
9379 ) -> Result<DeviceMemoryView<u8>, SemanticTransitionError> {
9380 let (span, _, _) = field.layout();
9381 unsafe {
9384 match field {
9385 PublicationBankField::Source => self
9386 .source
9387 .view()
9388 .cast::<u8>()
9389 .ok_or(SemanticTransitionError::ObservationMismatch),
9390 _ => self
9391 .header
9392 .view()
9393 .cast::<u8>()
9394 .map(|view| view.slice(span))
9395 .ok_or(SemanticTransitionError::ObservationMismatch),
9396 }
9397 }
9398 }
9399
9400 fn training_coordinates_view(&self) -> Result<DeviceMemoryView<u64>, SemanticTransitionError> {
9401 let begin = std::mem::offset_of!(PublicationHeader, training_cursor);
9402 let end = begin
9403 .checked_add(5 * size_of::<u64>())
9404 .ok_or(SemanticTransitionError::GenerationExhausted)?;
9405 unsafe {
9406 self.header
9407 .view()
9408 .cast::<u8>()
9409 .map(|view| view.slice(begin..end))
9410 .and_then(|view| view.cast::<u64>())
9411 .ok_or(SemanticTransitionError::ObservationMismatch)
9412 }
9413 }
9414
9415 fn owns_tensor(
9416 &self,
9417 tensor: &PreparedSemanticTensor,
9418 ) -> Result<bool, SemanticTransitionError> {
9419 let bytes = tensor.source.as_ref().map_or(0, DeviceMemoryView::len);
9420 for field in [
9421 PublicationBankField::Source,
9422 PublicationBankField::PrefixExtent,
9423 PublicationBankField::RingHead,
9424 PublicationBankField::Terminal,
9425 ] {
9426 let view = self.field_view(field)?;
9427 let start = *view.device_ptr();
9428 if !step_input_overlap(tensor.data, bytes, start, view.len())? {
9429 continue;
9430 }
9431 let (_, shape, strides) = field.layout();
9432 let mut layout = SemanticTensorLayout {
9433 role: 0,
9434 index: tensor.layout.index,
9435 scalar_type: 3,
9436 element_bytes: 8,
9437 rank: shape.len() as u64,
9438 logical_axis: u64::MAX,
9439 ..SemanticTensorLayout::default()
9440 };
9441 for (axis, dimension) in shape.into_iter().enumerate() {
9442 layout.dimensions[axis] = dimension as u64;
9443 }
9444 for (axis, stride) in strides.into_iter().enumerate() {
9445 layout.strides_bytes[axis] = stride as u64 * 8;
9446 }
9447 if tensor.data != start
9448 || bytes != view.len()
9449 || tensor.layout != layout
9450 || (tensor.logical_begin, tensor.logical_end) != (0, 0)
9451 {
9452 return Err(publication_input_error("native source and scalar aliases must retain their exact exported type and extent"));
9453 }
9454 if !step_input_allocation_matches(tensor, &view) {
9455 return Err(publication_input_error(
9456 "native source and scalar allocation origin does not match its producer",
9457 ));
9458 }
9459 return Ok(true);
9460 }
9461 for (pointer, capacity) in [
9462 (
9463 self.header.device_ptr_value(),
9464 size_of::<PublicationHeader>(),
9465 ),
9466 (
9467 self.ranges.device_ptr_value(),
9468 self.ranges.len() * size_of::<PublicationRange>(),
9469 ),
9470 (
9471 self.bindings[0].device_ptr_value(),
9472 self.bindings[0].len() * size_of::<PublicationStepInput>(),
9473 ),
9474 (
9475 self.bindings[1].device_ptr_value(),
9476 self.bindings[1].len() * size_of::<PublicationStepInput>(),
9477 ),
9478 (
9479 self.metadata_digests.device_ptr_value(),
9480 self.metadata_digests.len() * size_of::<u64>(),
9481 ),
9482 ] {
9483 if step_input_overlap(tensor.data, bytes, pointer, capacity)? {
9484 return Err(publication_input_error("native private header, range and digest storage cannot become a content operand"));
9485 }
9486 }
9487 if let Some(input) = self
9490 .plans
9491 .iter()
9492 .find(|input| (input.role, input.index) == (tensor.layout.role, tensor.layout.index))
9493 {
9494 if (18..=25).contains(&input.role) && bytes == 0 && tensor.native_allocation.is_none() {
9495 return Err(publication_input_error("empty prepared model inputs require their original native allocation provenance"));
9496 }
9497 for bank in 0..2 {
9498 let view = &self.views[bank][&(input.role, input.index)];
9499 let range = self.storage.bank_templates[bank]
9500 .iter()
9501 .find(|range| (range.role, range.index) == (input.role, input.index))
9502 .ok_or(SemanticTransitionError::ObservationMismatch)?;
9503 if step_input_alias_matches(
9504 input,
9505 range,
9506 *view.device_ptr(),
9507 view.len(),
9508 tensor_content_identity(tensor),
9509 ) && step_input_allocation_matches(tensor, view)
9510 {
9511 return Ok(true);
9512 }
9513 }
9514 }
9515 for bank in 0..2 {
9516 for input in &self.plans {
9517 let view = &self.views[bank][&(input.role, input.index)];
9518 let start = *view.device_ptr();
9519 if !(step_input_overlap(tensor.data, bytes, start, view.len())?
9520 || input.role == 1 && bytes == 0 && tensor.data == start)
9521 {
9522 continue;
9523 }
9524 let range = self.storage.bank_templates[bank]
9525 .iter()
9526 .find(|range| (range.role, range.index) == (input.role, input.index))
9527 .ok_or(SemanticTransitionError::ObservationMismatch)?;
9528 if input.role == 1
9529 && step_input_alias_matches(
9530 input,
9531 range,
9532 start,
9533 view.len(),
9534 tensor_content_identity(tensor),
9535 )
9536 && step_input_allocation_matches(tensor, view)
9537 {
9538 return Ok(true);
9539 }
9540 return Err(publication_input_error("native step aliases must retain their original type, capacity, interval and coordinate"));
9541 }
9542 }
9543 for allocation in &self.private {
9544 let retained_origin = tensor.native_allocation.as_ref().is_some_and(|origin| {
9545 allocation
9546 .view()
9547 .allocation_provenance()
9548 .is_some_and(|expected| origin.same_allocation(&expected))
9549 });
9550 if retained_origin
9551 || step_input_overlap(
9552 tensor.data,
9553 bytes,
9554 allocation.device_ptr_value(),
9555 allocation.len(),
9556 )?
9557 {
9558 return Err(publication_input_error(
9559 "native step backing padding cannot become a separate content operand",
9560 ));
9561 }
9562 }
9563 Ok(false)
9564 }
9565
9566 fn owns_bank_model_tensor(
9567 &self,
9568 bank: usize,
9569 tensor: &PreparedSemanticTensor,
9570 ) -> Result<bool, SemanticTransitionError> {
9571 if bank > 1 || !(18..=25).contains(&tensor.layout.role) {
9572 return Ok(false);
9573 }
9574 let Some(input) = self
9575 .plans
9576 .iter()
9577 .find(|input| (input.role, input.index) == (tensor.layout.role, tensor.layout.index))
9578 else {
9579 return Ok(false);
9580 };
9581 let view = &self.views[bank][&(input.role, input.index)];
9582 let range = self.storage.bank_templates[bank]
9583 .iter()
9584 .find(|range| (range.role, range.index) == (input.role, input.index))
9585 .ok_or(SemanticTransitionError::ObservationMismatch)?;
9586 Ok(step_input_alias_matches(
9587 input,
9588 range,
9589 *view.device_ptr(),
9590 view.len(),
9591 tensor_content_identity(tensor),
9592 ) && step_input_allocation_matches(tensor, view))
9593 }
9594}
9595
9596fn step_input_allocation_matches(
9597 tensor: &PreparedSemanticTensor,
9598 view: &DeviceMemoryView<u8>,
9599) -> bool {
9600 match &tensor.native_allocation {
9601 Some(origin) => view
9602 .allocation_provenance()
9603 .is_some_and(|expected| origin.same_allocation(&expected)),
9604 None => !view.is_empty(),
9607 }
9608}
9609
9610fn step_input_alias_matches(
9611 input: &StepInputPlan,
9612 range: &PublicationRange,
9613 data: u64,
9614 capacity: usize,
9615 actual: (SemanticTensorLayout, u64, u64, u64, usize),
9616) -> bool {
9617 if actual.3 != data {
9618 return false;
9619 }
9620 let typed_capacity = actual.4 == capacity
9621 && actual.0 == input.layout
9622 && (actual.1, actual.2) == (range.logical_begin, range.logical_end);
9623 let raw_prefix = input.role == 1
9627 && input.index == 0
9628 && range.role == 1
9629 && range.index == 0
9630 && actual.0 == publication_record_layout(range)
9631 && (actual.1, actual.2) == (0, 0)
9632 && u64::try_from(actual.4).ok() == Some(range.length_bytes)
9633 && actual.4 <= capacity;
9634 typed_capacity || raw_prefix
9635}
9636
9637struct StepContentStorage {
9641 identity: Option<SemanticPublishedIdentity>,
9642 content_witnesses: Arc<()>,
9643 aliases: Arc<()>,
9644 consumer_streams: BTreeSet<u64>,
9645 inputs: Option<Arc<PreparedStepInputs>>,
9646 feedback: Vec<FeedbackBuffers>,
9649 content: Vec<TensorContentBuffers>,
9650 #[cfg_attr(
9651 not(feature = "semantic-policy"),
9652 expect(
9653 dead_code,
9654 reason = "adjoints are consumed by the semantic-policy VJP path"
9655 )
9656 )]
9657 adjoints: Vec<DeviceMemoryView<u8>>,
9658 #[cfg(feature = "semantic-policy")]
9659 policy_vjp_workspaces: Vec<Arc<PolicyVjpWorkspace>>,
9660 prepared: Option<PreparedStepStorage>,
9661 #[cfg(feature = "semantic-policy")]
9662 evaluation: Option<model_evaluation::EvaluationStorage>,
9663}
9664
9665impl StepContentStorage {
9666 fn new() -> Self {
9667 Self {
9668 identity: None,
9669 content_witnesses: Arc::new(()),
9670 aliases: Arc::new(()),
9671 consumer_streams: BTreeSet::new(),
9672 inputs: None,
9673 feedback: Vec::new(),
9674 content: Vec::new(),
9675 adjoints: Vec::new(),
9676 #[cfg(feature = "semantic-policy")]
9677 policy_vjp_workspaces: Vec::new(),
9678 prepared: None,
9679 #[cfg(feature = "semantic-policy")]
9680 evaluation: None,
9681 }
9682 }
9683}
9684
9685#[derive(Clone, Debug)]
9688pub struct SemanticPreparedStep {
9689 issuer: Arc<()>,
9690 scope: Arc<()>,
9691 token: u64,
9692}
9693
9694impl SemanticPreparedStep {
9695 pub fn same_handle(&self, other: &Self) -> bool {
9696 Arc::ptr_eq(&self.issuer, &other.issuer)
9697 && Arc::ptr_eq(&self.scope, &other.scope)
9698 && self.token == other.token
9699 }
9700}
9701
9702#[cfg(feature = "semantic-policy")]
9705pub struct SemanticCompletedExecutionObservation {
9706 original: SemanticPreparedStep,
9707 requested_transition: SemanticTransitionKind,
9708 outcome: SemanticPreparedStepOutcome,
9709 predecessor: Option<SemanticPublishedIdentity>,
9710 successor: Option<SemanticPublishedIdentity>,
9711 model_binding: Option<(u64, Identity256, Identity256)>,
9712 quantities: [u64; 4],
9713}
9714
9715#[cfg(feature = "semantic-policy")]
9716impl SemanticCompletedExecutionObservation {
9717 pub fn quantities(&self) -> [u64; 4] {
9718 self.quantities
9719 }
9720
9721 pub fn same_execution(&self, other: &Self) -> bool {
9722 self.original.same_handle(&other.original)
9723 }
9724
9725 pub fn belongs_to(&self, session: &SemanticTransitionSession) -> bool {
9726 Arc::ptr_eq(&self.original.issuer, &session.publication_issuer)
9727 }
9728
9729 pub fn predecessor(&self) -> Option<SemanticPublishedIdentity> {
9730 self.predecessor
9731 }
9732
9733 pub fn successor(&self) -> Option<SemanticPublishedIdentity> {
9734 self.successor
9735 }
9736
9737 pub fn outcome(&self) -> &SemanticPreparedStepOutcome {
9739 &self.outcome
9740 }
9741
9742 pub fn requested_transition(&self) -> SemanticTransitionKind {
9743 self.requested_transition
9744 }
9745
9746 pub fn model_binding(&self) -> Option<(u64, Identity256, Identity256)> {
9747 self.model_binding
9748 }
9749}
9750
9751pub struct SemanticPreparedSegmentCapture {
9754 builder: crate::cuda_graph::ConditionalCudaGraphSequenceBuilder,
9755 scope: Arc<()>,
9756}
9757
9758impl SemanticPreparedSegmentCapture {
9759 pub fn add_conditional_if<P, F, E>(
9760 &mut self,
9761 stream: &CudaStream,
9762 preflight: P,
9763 body: F,
9764 ) -> Result<u64, crate::cuda_graph::CudaConditionalGraphUnavailable>
9765 where
9766 P: FnOnce(u64) -> Result<(), E>,
9767 E: fmt::Display,
9768 F: FnOnce(
9769 &crate::cuda_graph::ConditionalCudaGraphBody,
9770 ) -> Result<(), crate::cuda_graph::CudaConditionalGraphUnavailable>,
9771 {
9772 self.builder.add_conditional_if(stream, preflight, body)
9773 }
9774
9775 pub fn instantiate(self) -> Result<SemanticPreparedExecutable, SemanticTransitionError> {
9776 let graph = self
9777 .builder
9778 .instantiate()
9779 .map_err(|error| runtime_error("bounded segment instantiation", error))?;
9780 Ok(SemanticPreparedExecutable {
9781 scope: self.scope,
9782 graph,
9783 })
9784 }
9785}
9786
9787pub struct SemanticPreparedExecutable {
9790 scope: Arc<()>,
9791 graph: CapturedCudaGraph,
9792}
9793
9794struct PreparedSegmentState {
9795 issuer: Arc<()>,
9796 scope: Arc<()>,
9797 tokens: Vec<u64>,
9798 transitions: Vec<SemanticTransitionKind>,
9799 cold_capacity: SemanticSegmentColdCapacity,
9800 cold_reservation: Option<GpuMemoryReservation>,
9801 next: usize,
9802 active: bool,
9803 finished: bool,
9804 capturing: bool,
9805 submitted: bool,
9806 completed: bool,
9807}
9808
9809impl PreparedSegmentState {
9810 fn new(
9811 issuer: Arc<()>,
9812 tokens: Vec<u64>,
9813 transitions: impl ExactSizeIterator<Item = SemanticTransitionKind> + Clone,
9814 cold_capacity: SemanticSegmentColdCapacity,
9815 ) -> Result<Self, SemanticTransitionError> {
9816 if tokens.is_empty()
9817 || tokens.contains(&0)
9818 || tokens.iter().copied().collect::<BTreeSet<_>>().len() != tokens.len()
9819 || tokens.len() != transitions.len()
9820 || transitions
9821 .clone()
9822 .any(|kind| kind == SemanticTransitionKind::Drain)
9823 {
9824 return Err(publication_input_error("a prepared segment requires distinct owned steps and one frozen proposal, recompute, or update mode per step"));
9825 }
9826 let mut owned = Vec::new();
9827 owned
9828 .try_reserve_exact(transitions.len())
9829 .map_err(|error| runtime_error("prepared schedule reservation", error))?;
9830 owned.extend(transitions);
9831 cold_capacity.external_floor()?;
9832 Ok(Self {
9833 issuer,
9834 scope: Arc::new(()),
9835 tokens,
9836 transitions: owned,
9837 cold_capacity,
9838 cold_reservation: None,
9839 next: 0,
9840 active: false,
9841 finished: false,
9842 capturing: false,
9843 submitted: false,
9844 completed: false,
9845 })
9846 }
9847
9848 fn handles(&self) -> Result<Vec<SemanticPreparedStep>, SemanticTransitionError> {
9849 let mut handles = Vec::new();
9850 handles
9851 .try_reserve_exact(self.tokens.len())
9852 .map_err(|error| runtime_error("prepared handle reservation", error))?;
9853 handles.extend(self.tokens.iter().map(|&token| SemanticPreparedStep {
9854 issuer: Arc::clone(&self.issuer),
9855 scope: Arc::clone(&self.scope),
9856 token,
9857 }));
9858 Ok(handles)
9859 }
9860
9861 fn check(
9862 &self,
9863 step: &SemanticPreparedStep,
9864 issuer: &Arc<()>,
9865 recording: bool,
9866 ) -> Result<(), SemanticTransitionError> {
9867 self.check_retained(step, issuer)?;
9868 if self.finished
9869 || (recording && (!self.active || self.tokens.get(self.next) != Some(&step.token)))
9870 {
9871 return Err(publication_input_error(
9872 "prepared step differs from its owning Session or active construction scope",
9873 ));
9874 }
9875 Ok(())
9876 }
9877
9878 fn check_retained(
9879 &self,
9880 step: &SemanticPreparedStep,
9881 issuer: &Arc<()>,
9882 ) -> Result<(), SemanticTransitionError> {
9883 if !Arc::ptr_eq(issuer, &self.issuer)
9884 || !Arc::ptr_eq(&step.issuer, issuer)
9885 || !Arc::ptr_eq(&step.scope, &self.scope)
9886 || !self.tokens.contains(&step.token)
9887 {
9888 return Err(publication_input_error(
9889 "retained prepared step differs from its original Session and construction scope",
9890 ));
9891 }
9892 Ok(())
9893 }
9894
9895 fn requested_kind(
9896 &self,
9897 step: &SemanticPreparedStep,
9898 issuer: &Arc<()>,
9899 ) -> Result<SemanticTransitionKind, SemanticTransitionError> {
9900 self.check_retained(step, issuer)?;
9901 let index = self
9902 .tokens
9903 .iter()
9904 .position(|&token| token == step.token)
9905 .ok_or(SemanticTransitionError::ObservationMismatch)?;
9906 Ok(self.transitions[index])
9907 }
9908
9909 fn enter(
9910 &mut self,
9911 step: &SemanticPreparedStep,
9912 issuer: &Arc<()>,
9913 ) -> Result<SemanticTransitionKind, SemanticTransitionError> {
9914 self.check(step, issuer, false)?;
9915 if self.active || self.tokens.get(self.next) != Some(&step.token) {
9916 return Err(publication_input_error(
9917 "prepared steps must record once in their original bounded order",
9918 ));
9919 }
9920 self.active = true;
9921 Ok(self.transitions[self.next])
9922 }
9923
9924 fn leave(
9925 &mut self,
9926 step: &SemanticPreparedStep,
9927 issuer: &Arc<()>,
9928 ) -> Result<(), SemanticTransitionError> {
9929 self.check(step, issuer, true)?;
9930 self.active = false;
9931 self.next += 1;
9932 Ok(())
9933 }
9934
9935 fn finish(&mut self) -> Result<(), SemanticTransitionError> {
9936 if self.finished || self.active || self.next != self.tokens.len() {
9937 return Err(publication_input_error(
9938 "prepared segment has unrecorded or unfinished steps",
9939 ));
9940 }
9941 self.finished = true;
9942 Ok(())
9943 }
9944
9945 #[cfg(any(test, feature = "semantic-policy"))]
9946 fn submit(&mut self) -> Result<(), SemanticTransitionError> {
9947 if !self.finished
9948 || self.active
9949 || self.next != self.tokens.len()
9950 || self.submitted
9951 || self.completed
9952 {
9953 return Err(publication_input_error(
9954 "prepared segment submission requires one complete unused construction",
9955 ));
9956 }
9957 self.submitted = true;
9958 Ok(())
9959 }
9960}
9961
9962struct PreparedStepStorage {
9963 reader: TrackedCudaSlice<PublicationLease>,
9964 replay_custody: Option<PreparedReplayCustody>,
9965 branches: [PreparedBranchStorage; 2],
9966 digests: Option<Arc<TrackedCudaSlice<u64>>>,
9967 next_digest: usize,
9968 model_work: Option<PreparedModelWork>,
9969 admit: CudaFunction,
9970 kind_gate: CudaFunction,
9971 kind_bank_gate: CudaFunction,
9972 active_gate: CudaFunction,
9973 #[cfg_attr(
9974 not(feature = "semantic-policy"),
9975 expect(
9976 dead_code,
9977 reason = "drain preparation is captured by the semantic-policy graph"
9978 )
9979 )]
9980 drain_prepare: CudaFunction,
9981 release: CudaFunction,
9982 witness: CudaFunction,
9983 content_guard: CudaFunction,
9984 inputs_recorded: bool,
9985 model_content_recorded: u8,
9986 transition_recorded: u8,
9987 drain_recorded: bool,
9988 observed: bool,
9989 #[cfg(feature = "semantic-policy")]
9992 observed_outcome: Option<SemanticPreparedStepOutcome>,
9993 #[cfg(feature = "semantic-policy")]
9994 observed_parent: Option<PublicationHeader>,
9995 #[cfg(feature = "semantic-policy")]
9996 observed_result: Option<PreparedStepResult>,
9997 result: TrackedCudaSlice<PreparedStepResult>,
9998 training_origin: Option<DeviceMemoryView<SemanticTrainingViewOriginRecord>>,
9999 training_view: Option<SemanticSelectedTrainingView>,
10000 #[cfg(feature = "semantic-policy")]
10001 group_vjp_members: [BTreeSet<u64>; 2],
10002 #[cfg(feature = "semantic-policy")]
10003 group_edit_members: [BTreeSet<u64>; 2],
10004 #[cfg(feature = "semantic-policy")]
10005 group_imported_vjp_members: [BTreeSet<u64>; 2],
10006 #[cfg(feature = "semantic-policy")]
10007 group_gradient_members: [BTreeSet<u64>; 2],
10008 #[cfg(feature = "semantic-policy")]
10009 group_critic_recorded: u8,
10010 #[cfg(feature = "semantic-policy")]
10011 group_update_published: bool,
10012 result_kernel: CudaFunction,
10013}
10014
10015struct PreparedBranchStorage {
10016 model_update: Option<PreparedModelUpdate>,
10017 continuation: Option<PreparedContinuation>,
10018 numerical_block_snapshot: Option<Arc<TrackedCudaSlice<f64>>>,
10019 #[cfg(feature = "semantic-policy")]
10020 policy_buffers: Option<PolicyBuffers>,
10021 #[cfg(feature = "semantic-policy")]
10022 policy: Option<PolicyStorage>,
10023 #[cfg(feature = "semantic-policy")]
10024 support: Option<TrackedCudaSlice<u8>>,
10025 #[cfg(feature = "semantic-policy")]
10026 receipts: Option<TrackedCudaSlice<SemanticTransitionReceipt>>,
10027 #[cfg(feature = "semantic-policy")]
10028 state: TrackedCudaSlice<DeviceState>,
10029 #[cfg(feature = "semantic-policy")]
10030 policy_sources: Vec<PreparedSemanticTensor>,
10031 #[cfg(feature = "semantic-policy")]
10032 policy_witness: Option<SemanticTensorContentWitness>,
10033}
10034
10035struct PreparedModelUpdate {
10036 bindings: TrackedCudaSlice<ModelUpdateBinding>,
10037 evidence: Arc<TrackedCudaSlice<ModelUpdateEvidenceSource>>,
10038 evidence_owners: Arc<Vec<ModelUpdateEvidenceOwner>>,
10039 forward_seals: TrackedCudaSlice<ModelForwardSealInput>,
10040 forward_receipts: TrackedCudaSlice<ModelForwardReceipt>,
10041 admissibility: TrackedCudaSlice<u8>,
10042 canary_results: TrackedCudaSlice<SemanticTrainingCanaryResultRecord>,
10043 refusal: TrackedCudaSlice<SemanticTrainingCanaryRefusalRecord>,
10044 output: Option<BoundModelUpdate>,
10045 forward_recorded: u8,
10046 #[cfg_attr(
10047 not(feature = "semantic-policy"),
10048 expect(
10049 dead_code,
10050 reason = "update admissibility is copied by the semantic-policy graph"
10051 )
10052 )]
10053 admissibility_copy: CudaFunction,
10054 forward_receipt: CudaFunction,
10055 #[cfg_attr(
10056 not(feature = "semantic-policy"),
10057 expect(
10058 dead_code,
10059 reason = "model updates are copied by the semantic-policy graph"
10060 )
10061 )]
10062 copy: CudaFunction,
10063}
10064
10065struct BoundModelUpdate {
10066 values: Vec<ModelUpdateBinding>,
10067 forward_seal_values: Vec<ModelForwardSealInput>,
10068 digest_cells: Vec<Arc<TrackedCudaSlice<u64>>>,
10069 allocations: Vec<PreparedSemanticTensor>,
10070 admissibility: PreparedSemanticTensor,
10071 baseline_logits: PreparedSemanticTensor,
10072 candidate_logits: PreparedSemanticTensor,
10073 _slab_backing: PreparedSemanticTensor,
10074 #[cfg(feature = "semantic-policy")]
10075 accounted_reserved_bytes: u64,
10076 #[cfg(feature = "semantic-policy")]
10077 copy_bytes: u64,
10078 _witness: SemanticTensorContentWitness,
10079 _forward_witnesses: [SemanticModelForwardWitness; 2],
10080}
10081
10082struct ModelUpdateEvidenceOwner {
10083 lease: DeviceMemoryView<PublicationLease>,
10084 parent_header: DeviceMemoryView<PublicationHeader>,
10085 result: DeviceMemoryView<PreparedStepResult>,
10086 origin: DeviceMemoryView<SemanticTrainingViewOriginRecord>,
10087 states: [DeviceMemoryView<DeviceState>; 2],
10088}
10089
10090impl PreparedModelUpdate {
10091 #[cfg(feature = "semantic-policy")]
10092 fn accounted_allocation_bytes(&self) -> Result<u64, SemanticTransitionError> {
10093 let mut allocations = Vec::new();
10094 account_tracked_allocation(&mut allocations, &self.bindings)?;
10095 account_tracked_allocation(&mut allocations, self.evidence.as_ref())?;
10096 account_tracked_allocation(&mut allocations, &self.forward_seals)?;
10097 account_tracked_allocation(&mut allocations, &self.forward_receipts)?;
10098 account_tracked_allocation(&mut allocations, &self.admissibility)?;
10099 account_tracked_allocation(&mut allocations, &self.canary_results)?;
10100 account_tracked_allocation(&mut allocations, &self.refusal)?;
10101 accounted_tracked_bytes(allocations)
10102 }
10103
10104 fn descriptor(&self) -> ModelUpdateContinuationInputs {
10105 ModelUpdateContinuationInputs {
10106 bindings: self.bindings.device_ptr_value(),
10107 binding_count: self.bindings.len() as u64,
10108 admissibility: self.admissibility.device_ptr_value(),
10109 refusal: self.refusal.device_ptr_value(),
10110 canary_results: self.canary_results.device_ptr_value(),
10111 }
10112 }
10113
10114 fn record(&self, recorder: &mut LaunchRecorder) {
10115 recorder.read(&self.bindings);
10116 recorder.read(self.evidence.as_ref());
10117 for evidence in self.evidence_owners.iter() {
10118 recorder.read(&evidence.lease);
10119 recorder.read(&evidence.parent_header);
10120 recorder.read(&evidence.result);
10121 recorder.read(&evidence.origin);
10122 recorder.read(&evidence.states[0]);
10123 recorder.read(&evidence.states[1]);
10124 }
10125 recorder.read(&self.forward_seals);
10126 recorder.read_write(&self.forward_receipts);
10127 recorder.read_write(&self.admissibility);
10128 recorder.read_write(&self.refusal);
10129 recorder.read(&self.canary_results);
10130 if let Some(output) = &self.output {
10131 for allocation in &output.allocations {
10132 if let Some(source) = &allocation.source {
10133 recorder.read(source);
10134 }
10135 }
10136 if let Some(source) = &output.admissibility.source {
10137 recorder.read(source);
10138 }
10139 if let Some(source) = &output.baseline_logits.source {
10140 recorder.read(source);
10141 }
10142 if let Some(source) = &output.candidate_logits.source {
10143 recorder.read(source);
10144 }
10145 for cells in &output.digest_cells {
10146 recorder.read(cells.as_ref());
10147 }
10148 }
10149 }
10150
10151 #[cfg(feature = "semantic-policy")]
10152 #[expect(
10153 clippy::too_many_arguments,
10154 reason = "the update gate joins publication, training, task and original model-work owners"
10155 )]
10156 fn enqueue_copy(
10157 &self,
10158 domain: &ResidentExecutionDomain,
10159 poisoned: &mut bool,
10160 storage: &PublicationStorage,
10161 reader: &TrackedCudaSlice<PublicationLease>,
10162 training_view: &SemanticSelectedTrainingView,
10163 task: &TrackedCudaSlice<u64>,
10164 model_work: &PreparedModelWork,
10165 ) -> Result<(), SemanticTransitionError> {
10166 let output = self.output.as_ref().ok_or_else(|| {
10167 publication_input_error("prepared update has no original model output binding")
10168 })?;
10169 let allocation_count = u32::try_from(output.values.len())
10170 .map_err(|_| SemanticTransitionError::GenerationExhausted)?;
10171 if allocation_count == 0 || allocation_count > 65_535 {
10172 return Err(publication_input_error(
10173 "prepared update model allocation roster exceeds the CUDA launch geometry",
10174 ));
10175 }
10176 let maximum_bytes = output
10177 .values
10178 .iter()
10179 .map(|binding| binding.bytes)
10180 .max()
10181 .unwrap_or(0);
10182 let blocks = maximum_bytes.div_ceil(256).clamp(1, 65_535) as u32;
10183 let mut recorder = domain.new_strict_recorder();
10184 storage.record(&mut recorder);
10185 recorder.read(reader);
10186 self.record(&mut recorder);
10187 model_work.record_reads(&mut recorder);
10188 recorder.read(task);
10189 let selection = training_view.selection();
10190 let roster_rows = training_view.roster_rows();
10191 let objective = training_view.objective();
10192 let canaries = training_view.canaries();
10193 let protected_members = training_view.protected_members();
10194 let retention_labels = training_view.retention_labels();
10195 let kinds = training_view.kinds();
10196 recorder.read(&selection);
10197 recorder.read(&roster_rows);
10198 recorder.read(&objective);
10199 recorder.read(&canaries);
10200 recorder.read(&protected_members);
10201 recorder.read(&retention_labels);
10202 recorder.read(&kinds);
10203 recorder.write(&self.canary_results);
10204 recorder.write(&self.admissibility);
10205 recorder.write(&self.refusal);
10206 let admissibility_source = output.admissibility.data;
10207 let canary_results = self.canary_results.device_ptr_value();
10208 let admissibility_destination = self.admissibility.device_ptr_value();
10209 let refusal_destination = self.refusal.device_ptr_value();
10210 let training_view_bytes = training_view.accounted_allocation_bytes()?;
10211 let model_work_bytes = model_work.accounted_allocation_bytes()?;
10212 let update_bytes = self.accounted_allocation_bytes()?;
10213 let task_bytes = task
10214 .view()
10215 .allocation_provenance()
10216 .ok_or(SemanticTransitionError::ObservationMismatch)?
10217 .allocation_bytes();
10218 let accounted_reserved_bytes = output
10219 .accounted_reserved_bytes
10220 .checked_add(storage.accounted_allocation_bytes()?)
10221 .and_then(|bytes| bytes.checked_add(training_view_bytes))
10222 .and_then(|bytes| bytes.checked_add(task_bytes))
10223 .and_then(|bytes| bytes.checked_add(model_work_bytes))
10224 .and_then(|bytes| bytes.checked_add(update_bytes))
10225 .ok_or(SemanticTransitionError::GenerationExhausted)?;
10226 let logits = output.baseline_logits.layout;
10227 let canary_inputs = ModelUpdateCanaryInputs {
10228 control: storage.control.device_ptr_value(),
10229 lease: reader.device_ptr_value(),
10230 selection: *selection.device_ptr(),
10231 roster_rows: *roster_rows.device_ptr(),
10232 objective: *objective.device_ptr(),
10233 canaries: *canaries.device_ptr(),
10234 canary_count: canaries.len() as u64,
10235 protected_members: *protected_members.device_ptr(),
10236 protected_member_count: protected_members.len() as u64,
10237 task: task.device_ptr_value(),
10238 task_words: task.len() as u64,
10239 evidence: self.evidence.device_ptr_value(),
10240 evidence_count: self.evidence.len() as u64,
10241 forward_receipts: self.forward_receipts.device_ptr_value(),
10242 candidate_seal_count: self.forward_seals.len() as u64,
10243 retention_labels: *retention_labels.device_ptr(),
10244 kinds: *kinds.device_ptr(),
10245 baseline_logits: output.baseline_logits.data,
10246 candidate_logits: output.candidate_logits.data,
10247 scalar_type: logits.scalar_type,
10248 row_count: logits.dimensions[0],
10249 capacity: logits.dimensions[1],
10250 vocabulary: logits.dimensions[2],
10251 row_stride_bytes: logits.strides_bytes[0],
10252 position_stride_bytes: logits.strides_bytes[1],
10253 vocabulary_stride_bytes: logits.strides_bytes[2],
10254 model_work: model_work.descriptor(),
10255 accounted_reserved_bytes,
10256 copy_bytes: output.copy_bytes,
10257 admissibility_source,
10258 results: canary_results,
10259 admissibility_destination,
10260 refusal_destination,
10261 };
10262 let arguments = (
10263 storage.control.device_ptr_value(),
10264 reader.device_ptr_value(),
10265 );
10266 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
10267 unsafe {
10271 self.admissibility_copy.clone().launch_in(
10272 enqueue,
10273 LaunchConfig {
10274 grid_dim: (1, 1, 1),
10275 block_dim: (1, 1, 1),
10276 shared_mem_bytes: 0,
10277 },
10278 (canary_inputs,),
10279 )
10280 }
10281 .map_err(|error| XlogError::Kernel(error.to_string()))?;
10282 unsafe {
10286 self.copy.clone().launch_in(
10287 enqueue,
10288 LaunchConfig {
10289 grid_dim: (blocks, allocation_count, 1),
10290 block_dim: (256, 1, 1),
10291 shared_mem_bytes: 0,
10292 },
10293 arguments,
10294 )
10295 }
10296 .map_err(|error| XlogError::Kernel(error.to_string()))
10297 })
10298 }
10299}
10300
10301struct PreparedModelWork {
10302 recording: ModelWorkRecording,
10303 device: TrackedCudaSlice<ModelWorkEvent>,
10304 actual: TrackedCudaSlice<u64>,
10305 reset: CudaFunction,
10306 invocation: CudaFunction,
10307 capture_bank: Option<usize>,
10308 replay_cursor: usize,
10309 evaluation_recording: bool,
10310}
10311
10312const PREPARED_TRANSITION_BANKS: u8 = 0b11;
10313
10314#[repr(C)]
10315#[derive(Clone, Copy, Default)]
10316struct ModelWorkInput {
10317 events: u64,
10318 count: u64,
10319 bound: u64,
10320}
10321
10322#[repr(C)]
10323#[derive(Clone, Copy, Default)]
10324struct ModelUpdateCanaryInputs {
10325 control: u64,
10326 lease: u64,
10327 selection: u64,
10328 roster_rows: u64,
10329 objective: u64,
10330 canaries: u64,
10331 canary_count: u64,
10332 protected_members: u64,
10333 protected_member_count: u64,
10334 task: u64,
10335 task_words: u64,
10336 evidence: u64,
10337 evidence_count: u64,
10338 forward_receipts: u64,
10339 candidate_seal_count: u64,
10340 retention_labels: u64,
10341 kinds: u64,
10342 baseline_logits: u64,
10343 candidate_logits: u64,
10344 scalar_type: u64,
10345 row_count: u64,
10346 capacity: u64,
10347 vocabulary: u64,
10348 row_stride_bytes: u64,
10349 position_stride_bytes: u64,
10350 vocabulary_stride_bytes: u64,
10351 model_work: ModelWorkInput,
10352 accounted_reserved_bytes: u64,
10353 copy_bytes: u64,
10354 admissibility_source: u64,
10355 results: u64,
10356 admissibility_destination: u64,
10357 refusal_destination: u64,
10358}
10359
10360const _: () = assert!(size_of::<ModelUpdateCanaryInputs>() == 280);
10361
10362struct ModelForwardReceiptInputsParam(ModelForwardReceiptInputs);
10363
10364impl crate::cuda_compat::KernelParamStorage for ModelForwardReceiptInputsParam {
10365 fn as_kernel_param(&self) -> *mut std::ffi::c_void {
10366 (&self.0 as *const ModelForwardReceiptInputs)
10367 .cast_mut()
10368 .cast()
10369 }
10370}
10371
10372impl crate::cuda_compat::IntoKernelParamStorage for ModelForwardReceiptInputs {
10373 type Storage = ModelForwardReceiptInputsParam;
10374
10375 fn into_kernel_param_storage(self) -> Self::Storage {
10376 ModelForwardReceiptInputsParam(self)
10377 }
10378}
10379
10380struct ModelUpdateCanaryInputsParam(ModelUpdateCanaryInputs);
10381
10382impl crate::cuda_compat::KernelParamStorage for ModelUpdateCanaryInputsParam {
10383 fn as_kernel_param(&self) -> *mut std::ffi::c_void {
10384 (&self.0 as *const ModelUpdateCanaryInputs)
10385 .cast_mut()
10386 .cast()
10387 }
10388}
10389
10390impl crate::cuda_compat::IntoKernelParamStorage for ModelUpdateCanaryInputs {
10391 type Storage = ModelUpdateCanaryInputsParam;
10392
10393 fn into_kernel_param_storage(self) -> Self::Storage {
10394 ModelUpdateCanaryInputsParam(self)
10395 }
10396}
10397
10398impl PreparedModelWork {
10399 fn allocate(
10400 provider: &Arc<CudaKernelProvider>,
10401 reservation: &mut crate::memory::GpuMemoryReservation,
10402 capacity: usize,
10403 ) -> Result<Self, SemanticTransitionError> {
10404 let recording = ModelWorkRecording::new(capacity).map_err(publication_input_error)?;
10405 let reset = provider
10406 .device()
10407 .inner()
10408 .get_func("xlog_semantic_transition", "semantic_model_work_reset")
10409 .ok_or_else(|| runtime_error("kernel lookup", "model work reset unavailable"))?;
10410 let invocation = provider
10411 .device()
10412 .inner()
10413 .get_func("xlog_semantic_transition", "semantic_model_invocation")
10414 .ok_or_else(|| runtime_error("kernel lookup", "model invocation marker unavailable"))?;
10415 Ok(Self {
10416 recording,
10417 device: reservation
10418 .alloc(capacity)
10419 .map_err(|error| runtime_error("original model work allocation", error))?,
10420 actual: reservation
10421 .alloc(
10422 capacity
10423 .checked_mul(3)
10424 .ok_or(SemanticTransitionError::GenerationExhausted)?,
10425 )
10426 .map_err(|error| runtime_error("original device work allocation", error))?,
10427 reset,
10428 invocation,
10429 capture_bank: None,
10430 replay_cursor: 0,
10431 evaluation_recording: false,
10432 })
10433 }
10434
10435 #[cfg(feature = "semantic-policy")]
10436 fn accounted_allocation_bytes(&self) -> Result<u64, SemanticTransitionError> {
10437 let mut allocations = Vec::new();
10438 account_tracked_allocation(&mut allocations, &self.device)?;
10439 account_tracked_allocation(&mut allocations, &self.actual)?;
10440 accounted_tracked_bytes(allocations)
10441 }
10442
10443 #[cfg(feature = "semantic-policy")]
10444 fn record_reads(&self, recorder: &mut LaunchRecorder) {
10445 recorder.read(&self.device);
10446 recorder.read(&self.actual);
10447 }
10448
10449 #[cfg(feature = "semantic-policy")]
10450 fn begin_capture(&mut self, bank: usize, recorded: u8) -> Result<(), &'static str> {
10451 if bank > 1 || self.capture_bank.is_some() || self.evaluation_recording {
10452 return Err("model work capture requires one inactive bank recording");
10453 }
10454 if (bank == 0 && (recorded != 0 || self.recording.frozen_bound().is_some()))
10455 || (bank == 1 && (recorded != 1 || self.recording.frozen_bound().is_none()))
10456 {
10457 return Err("model work banks must record in zero then one order");
10458 }
10459 self.capture_bank = Some(bank);
10460 self.replay_cursor = 0;
10461 Ok(())
10462 }
10463
10464 fn next_slot(&self) -> Result<usize, &'static str> {
10465 match self.capture_bank {
10466 Some(0) => Ok(self.recording.events().len()),
10467 Some(1) => Ok(self.replay_cursor),
10468 None if self.evaluation_recording => Ok(self.recording.events().len()),
10469 _ => Err("model work event requires an active prepared bank capture"),
10470 }
10471 }
10472
10473 fn record_event(&mut self, event: ModelWorkEvent) -> Result<usize, &'static str> {
10474 let slot = self.next_slot()?;
10475 match self.capture_bank {
10476 Some(0) => self.recording.push(event)?,
10477 None if self.evaluation_recording => self.recording.push(event)?,
10478 Some(1) => {
10479 if self.recording.events().get(slot) != Some(&event) {
10480 return Err("second model branch differs from original work geometry");
10481 }
10482 self.replay_cursor += 1;
10483 }
10484 _ => return Err("model work event requires an active prepared bank capture"),
10485 }
10486 Ok(slot)
10487 }
10488
10489 #[cfg(feature = "semantic-policy")]
10490 fn finish_capture(&mut self, bank: usize) -> Result<(), &'static str> {
10491 if self.capture_bank != Some(bank) {
10492 return Err("prepared transition differs from its active model work bank");
10493 }
10494 if bank == 0 {
10495 self.recording.require_model_invocations()?;
10496 self.recording.freeze()?;
10497 } else if self.replay_cursor != self.recording.events().len() {
10498 return Err("second model branch omitted original work occurrences");
10499 }
10500 self.capture_bank = None;
10501 self.replay_cursor = 0;
10502 Ok(())
10503 }
10504
10505 fn reset_slots(
10506 &self,
10507 domain: &ResidentExecutionDomain,
10508 poisoned: &mut bool,
10509 first: usize,
10510 count: usize,
10511 ) -> Result<(), SemanticTransitionError> {
10512 let end = first
10513 .checked_add(count)
10514 .filter(|end| *end <= self.actual.len() / 3)
10515 .ok_or(SemanticTransitionError::ObservationMismatch)?;
10516 let mut recorder = domain.new_strict_recorder();
10517 recorder.write(&self.actual);
10518 let arguments = (
10519 self.actual.device_ptr_value() + (first * 3 * size_of::<u64>()) as u64,
10520 ((end - first) * 3) as u64,
10521 );
10522 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
10523 unsafe {
10526 self.reset.clone().launch_in(
10527 enqueue,
10528 LaunchConfig {
10529 grid_dim: (1, 1, 1),
10530 block_dim: (32, 1, 1),
10531 shared_mem_bytes: 0,
10532 },
10533 arguments,
10534 )
10535 }
10536 .map_err(|error| XlogError::Kernel(error.to_string()))
10537 })
10538 }
10539
10540 fn record_invocation(
10541 &mut self,
10542 domain: &ResidentExecutionDomain,
10543 poisoned: &mut bool,
10544 ) -> Result<(), SemanticTransitionError> {
10545 let slot = self.next_slot().map_err(publication_input_error)?;
10546 if slot >= self.actual.len() / 3 {
10547 return Err(publication_input_error(
10548 "model invocation exceeds its original cold event capacity",
10549 ));
10550 }
10551 let actual = self
10552 .actual
10553 .device_ptr_value()
10554 .checked_add((slot * 3 * size_of::<u64>()) as u64)
10555 .ok_or(SemanticTransitionError::GenerationExhausted)?;
10556 let event = ModelWorkEvent::invocation(actual).map_err(publication_input_error)?;
10557 self.record_event(event).map_err(publication_input_error)?;
10558 self.reset_slots(domain, poisoned, slot, 1)?;
10559 let mut recorder = domain.new_strict_recorder();
10560 recorder.write(&self.actual);
10561 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
10562 unsafe {
10565 self.invocation.clone().launch_in(
10566 enqueue,
10567 LaunchConfig {
10568 grid_dim: (1, 1, 1),
10569 block_dim: (1, 1, 1),
10570 shared_mem_bytes: 0,
10571 },
10572 (actual,),
10573 )
10574 }
10575 .map_err(|error| XlogError::Kernel(error.to_string()))
10576 })
10577 }
10578
10579 #[cfg(feature = "semantic-policy")]
10580 fn completed_model_calls(
10581 &self,
10582 actual: &[u64],
10583 executed: bool,
10584 ) -> Result<u64, SemanticTransitionError> {
10585 if actual.len() != self.actual.len() || self.recording.frozen_bound().is_none() {
10586 return Err(SemanticTransitionError::ObservationMismatch);
10587 }
10588 let mut calls = 0u64;
10589 let mut original_markers = 0u64;
10590 for (slot, event) in self.recording.events().iter().enumerate() {
10591 if event.kind != ModelWorkKind::ModelInvocation as u64 {
10592 continue;
10593 }
10594 original_markers = original_markers
10595 .checked_add(1)
10596 .ok_or(SemanticTransitionError::GenerationExhausted)?;
10597 let value = &actual[slot * 3..slot * 3 + 3];
10598 match value {
10599 [0, 0, 0] if !executed => (),
10600 [1, 0, 1] => {
10601 calls = calls
10602 .checked_add(1)
10603 .ok_or(SemanticTransitionError::GenerationExhausted)?;
10604 }
10605 _ => return Err(SemanticTransitionError::ObservationMismatch),
10606 }
10607 }
10608 if (executed && (original_markers == 0 || calls != original_markers))
10612 || (!executed && calls != 0)
10613 {
10614 return Err(SemanticTransitionError::ObservationMismatch);
10615 }
10616 Ok(calls)
10617 }
10618
10619 fn descriptor(&self) -> ModelWorkInput {
10620 ModelWorkInput {
10621 events: self.device.device_ptr_value(),
10622 count: self.recording.events().len() as u64,
10623 bound: self
10624 .recording
10625 .frozen_bound()
10626 .expect("original work frozen before enqueue"),
10627 }
10628 }
10629}
10630
10631#[repr(C)]
10632#[derive(Clone, Copy, Default, PartialEq, Eq)]
10633struct PreparedStepResult {
10634 abi: u64,
10635 word: u64,
10636 refusal: u64,
10637 header: PublicationHeader,
10638 advanced: u64,
10639 attempt: AttemptReceipt,
10640}
10641
10642#[derive(Clone, Copy)]
10643#[cfg(feature = "semantic-policy")]
10644struct PreparedTransitionEvidence {
10645 transition: SemanticTransitionKind,
10646 canary_refusal: Option<SemanticTrainingCanaryRefusalRecord>,
10647}
10648
10649unsafe impl DeviceRepr for PreparedStepResult {}
10652
10653#[derive(Clone)]
10659pub struct SemanticTensorContentWitness {
10660 issuer: Arc<()>,
10661 reader_token: u64,
10662 index: usize,
10663 _witness: Arc<()>,
10664}
10665
10666#[derive(Clone)]
10669pub struct SemanticModelForwardWitness {
10670 issuer: Arc<()>,
10671 reader_token: u64,
10672 bank: usize,
10673 role: usize,
10674 content: SemanticTensorContentWitness,
10675}
10676
10677struct TensorContentBuffers {
10678 tensors: Vec<PreparedSemanticTensor>,
10679 seals: TensorContentSeals,
10680 verification_inputs: Vec<PreparedSemanticTensor>,
10683}
10684
10685enum TensorContentSeals {
10686 Captured(Vec<CapturedTensorDigest>),
10687 Model(ModelContentSeals),
10690}
10691
10692struct ModelContentSeals {
10693 ranges: TrackedCudaSlice<PublicationRange>,
10694 contract: TrackedCudaSlice<u8>,
10695 guard: CudaFunction,
10696 prepared: Option<PreparedModelContentSeals>,
10697}
10698
10699struct PreparedModelContentSeals {
10700 bank: usize,
10701 #[cfg(feature = "semantic-policy")]
10702 storage: Arc<PublicationStorage>,
10703 #[cfg(feature = "semantic-policy")]
10704 reader: DeviceMemoryView<PublicationLease>,
10705 roster: TrackedCudaSlice<u64>,
10706 #[cfg(feature = "semantic-policy")]
10707 execute: CudaFunction,
10708}
10709
10710struct ModelContentCopyPlan {
10711 directory_offsets: Vec<usize>,
10712 contract_storage_slot: usize,
10713 contract_span: std::ops::Range<usize>,
10714}
10715
10716fn model_content_copy_plan(
10717 directory: &[PublicationRange],
10718 tensor_ranges: &[usize],
10719 allocation_bytes: &[usize],
10720) -> Result<ModelContentCopyPlan, SemanticTransitionError> {
10721 let mut contracts = directory
10722 .iter()
10723 .enumerate()
10724 .filter(|(_, range)| range.role == 44);
10725 let (contract_index, contract) = contracts
10726 .next()
10727 .ok_or(SemanticTransitionError::ObservationMismatch)?;
10728 let mut seen = BTreeSet::new();
10729 if contracts.next().is_some()
10730 || contract.index != 0
10731 || contract.generation != 1
10732 || contract.length_bytes == 0
10733 || tensor_ranges.is_empty()
10734 || tensor_ranges.iter().any(|&index| {
10735 !seen.insert(index)
10736 || directory
10737 .get(index)
10738 .is_none_or(|range| !matches!(range.role, 18..=20))
10739 })
10740 {
10741 return Err(SemanticTransitionError::ObservationMismatch);
10742 }
10743 let contract_storage_slot = usize::try_from(contract.storage_slot)
10744 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
10745 let allocation = *allocation_bytes
10746 .get(contract_storage_slot)
10747 .ok_or(SemanticTransitionError::ObservationMismatch)?;
10748 let begin = usize::try_from(contract.offset_bytes)
10749 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
10750 let bytes = usize::try_from(contract.length_bytes)
10751 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
10752 let end = begin
10753 .checked_add(bytes)
10754 .filter(|&end| end <= allocation)
10755 .ok_or(SemanticTransitionError::ObservationMismatch)?;
10756 let directory_offsets = tensor_ranges
10757 .iter()
10758 .copied()
10759 .chain(std::iter::once(contract_index))
10760 .map(|index| {
10761 index
10762 .checked_mul(size_of::<PublicationRange>())
10763 .ok_or(SemanticTransitionError::ObservationMismatch)
10764 })
10765 .collect::<Result<Vec<_>, _>>()?;
10766 directory_offsets
10767 .len()
10768 .checked_mul(size_of::<PublicationRange>())
10769 .ok_or(SemanticTransitionError::ObservationMismatch)?;
10770 Ok(ModelContentCopyPlan {
10771 directory_offsets,
10772 contract_storage_slot,
10773 contract_span: begin..end,
10774 })
10775}
10776
10777impl ModelContentSeals {
10778 fn allocate(
10779 provider: &CudaKernelProvider,
10780 plan: &ModelContentCopyPlan,
10781 ) -> Result<Self, SemanticTransitionError> {
10782 Self::with_allocations(
10783 provider,
10784 allocate_publication(provider, plan.directory_offsets.len())?,
10785 allocate_publication(provider, plan.contract_span.len())?,
10786 )
10787 }
10788
10789 fn allocate_reserved(
10790 provider: &CudaKernelProvider,
10791 plan: &ModelContentCopyPlan,
10792 reservation: &mut GpuMemoryReservation,
10793 ) -> Result<Self, SemanticTransitionError> {
10794 Self::with_allocations(
10795 provider,
10796 reservation
10797 .alloc(plan.directory_offsets.len())
10798 .map_err(|error| runtime_error("prepared model seal range allocation", error))?,
10799 reservation
10800 .alloc(plan.contract_span.len())
10801 .map_err(|error| runtime_error("prepared model contract allocation", error))?,
10802 )
10803 }
10804
10805 fn with_allocations(
10806 provider: &CudaKernelProvider,
10807 ranges: TrackedCudaSlice<PublicationRange>,
10808 contract: TrackedCudaSlice<u8>,
10809 ) -> Result<Self, SemanticTransitionError> {
10810 let guard = provider
10811 .device()
10812 .inner()
10813 .get_func(
10814 "xlog_semantic_transition",
10815 "semantic_retained_model_contract_guard",
10816 )
10817 .ok_or_else(|| {
10818 runtime_error("kernel lookup", "retained model contract guard unavailable")
10819 })?;
10820 Ok(Self {
10821 ranges,
10822 contract,
10823 guard,
10824 prepared: None,
10825 })
10826 }
10827
10828 #[cfg(feature = "semantic-policy")]
10829 fn snapshot_prepared(
10830 &self,
10831 domain: &ResidentExecutionDomain,
10832 poisoned: &mut bool,
10833 ) -> Result<(), SemanticTransitionError> {
10834 let source = self
10835 .prepared
10836 .as_ref()
10837 .ok_or(SemanticTransitionError::ObservationMismatch)?;
10838 let mut recorder = domain.new_strict_recorder();
10839 source.storage.record(&mut recorder);
10840 recorder.read(&source.reader);
10841 recorder.read(&source.roster);
10842 recorder.write(&self.ranges);
10843 recorder.write(&self.contract);
10844 let arguments = (
10845 source.storage.control.device_ptr_value(),
10846 *source.reader.device_ptr(),
10847 source.roster.device_ptr_value(),
10848 (source.roster.len() / 2) as u64,
10849 self.ranges.device_ptr_value(),
10850 self.contract.device_ptr_value(),
10851 self.contract.len() as u64,
10852 );
10853 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
10854 unsafe {
10858 source.execute.clone().launch_in(
10859 enqueue,
10860 LaunchConfig {
10861 grid_dim: (1, 1, 1),
10862 block_dim: (1, 1, 1),
10863 shared_mem_bytes: 0,
10864 },
10865 arguments,
10866 )
10867 }
10868 .map_err(|error| XlogError::Kernel(error.to_string()))
10869 })
10870 }
10871
10872 fn snapshot(
10873 &self,
10874 domain: &ResidentExecutionDomain,
10875 poisoned: &mut bool,
10876 directory: &TrackedCudaSlice<PublicationRange>,
10877 source: &TrackedCudaSlice<u8>,
10878 plan: &ModelContentCopyPlan,
10879 ) -> Result<(), SemanticTransitionError> {
10880 let row_bytes = size_of::<PublicationRange>();
10881 let directory_bytes = directory
10882 .len()
10883 .checked_mul(row_bytes)
10884 .ok_or(SemanticTransitionError::ObservationMismatch)?;
10885 if self.ranges.len() != plan.directory_offsets.len()
10886 || self.contract.len() != plan.contract_span.len()
10887 || plan.contract_span.end > source.len()
10888 || plan.directory_offsets.iter().any(|&offset| {
10889 offset
10890 .checked_add(row_bytes)
10891 .is_none_or(|end| end > directory_bytes)
10892 })
10893 {
10894 return Err(SemanticTransitionError::ObservationMismatch);
10895 }
10896 let mut recorder = domain.new_strict_recorder();
10897 recorder.read(directory);
10898 recorder.read(source);
10899 recorder.write(&self.ranges);
10900 recorder.write(&self.contract);
10901 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
10902 unsafe {
10906 for (index, &offset) in plan.directory_offsets.iter().enumerate() {
10907 sys::cuMemcpyDtoDAsync_v2(
10908 self.ranges.device_ptr_value() + (index * row_bytes) as u64,
10909 directory.device_ptr_value() + offset as u64,
10910 row_bytes,
10911 enqueue.stream().cu_stream(),
10912 )
10913 .result()
10914 .map_err(|e| XlogError::Kernel(format!("original model seal snapshot: {e}")))?;
10915 }
10916 sys::cuMemcpyDtoDAsync_v2(
10917 self.contract.device_ptr_value(),
10918 source.device_ptr_value() + plan.contract_span.start as u64,
10919 self.contract.len(),
10920 enqueue.stream().cu_stream(),
10921 )
10922 .result()
10923 .map_err(|e| XlogError::Kernel(format!("original model contract snapshot: {e}")))?;
10924 }
10925 Ok::<(), XlogError>(())
10926 })
10927 }
10928
10929 fn verify_contract(
10930 &self,
10931 domain: &ResidentExecutionDomain,
10932 poisoned: &mut bool,
10933 ) -> Result<(), SemanticTransitionError> {
10934 let mut recorder = domain.new_strict_recorder();
10935 recorder.read(&self.ranges);
10936 recorder.read(&self.contract);
10937 let arguments = (
10938 self.contract.device_ptr_value(),
10939 self.contract.len() as u64,
10940 self.ranges.device_ptr_value()
10941 + ((self.ranges.len() - 1) * size_of::<PublicationRange>()) as u64,
10942 );
10943 let execute = self.guard.clone();
10944 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
10945 unsafe {
10949 execute.launch_in(
10950 enqueue,
10951 LaunchConfig {
10952 grid_dim: (1, 1, 1),
10953 block_dim: (1, 1, 1),
10954 shared_mem_bytes: 0,
10955 },
10956 arguments,
10957 )
10958 }
10959 .map_err(|e| XlogError::Kernel(e.to_string()))
10960 })
10961 }
10962}
10963
10964enum CapturedTensorDigest {
10965 Tensor {
10966 cells: Arc<TrackedCudaSlice<u64>>,
10967 offset: usize,
10968 producer_sealed: bool,
10970 },
10971 Publication(Arc<PreparedStepInputs>),
10974}
10975
10976fn captured_tensor_digest_pointer(
10977 digests: &[CapturedTensorDigest],
10978 index: usize,
10979) -> Result<(u64, Arc<TrackedCudaSlice<u64>>), SemanticTransitionError> {
10980 let CapturedTensorDigest::Tensor { cells, offset, .. } = digests
10981 .get(index)
10982 .ok_or(SemanticTransitionError::ObservationMismatch)?
10983 else {
10984 return Err(publication_input_error(
10985 "model forward receipt requires an original transient tensor seal",
10986 ));
10987 };
10988 if offset.checked_add(4).is_none_or(|end| end > cells.len()) {
10989 return Err(SemanticTransitionError::ObservationMismatch);
10990 }
10991 Ok((
10992 cells.device_ptr_value() + (*offset * size_of::<u64>()) as u64,
10993 Arc::clone(cells),
10994 ))
10995}
10996
10997fn tensor_content_identity(
10998 tensor: &PreparedSemanticTensor,
10999) -> (SemanticTensorLayout, u64, u64, u64, usize) {
11000 (
11001 tensor.layout,
11002 tensor.logical_begin,
11003 tensor.logical_end,
11004 tensor.data,
11005 tensor.source.as_ref().map_or(0, DeviceMemoryView::len),
11006 )
11007}
11008
11009#[cfg(feature = "semantic-policy")]
11010fn cuda_backing_allocation(
11011 pointer: u64,
11012 required_bytes: usize,
11013) -> Result<(u64, u64), SemanticTransitionError> {
11014 if pointer == 0 || required_bytes == 0 {
11015 return Err(publication_input_error(
11016 "accounted update tensor requires a nonempty CUDA allocation",
11017 ));
11018 }
11019 let mut base = 0;
11020 let mut bytes = 0usize;
11021 let result = unsafe { sys::cuMemGetAddressRange_v2(&mut base, &mut bytes, pointer) };
11024 if result != sys::cudaError_enum::CUDA_SUCCESS {
11025 return Err(runtime_error(
11026 "update backing-allocation query",
11027 format!("cuMemGetAddressRange_v2 failed with {result:?}"),
11028 ));
11029 }
11030 let bytes = u64::try_from(bytes).map_err(|_| SemanticTransitionError::GenerationExhausted)?;
11031 let required =
11032 u64::try_from(required_bytes).map_err(|_| SemanticTransitionError::GenerationExhausted)?;
11033 if pointer < base
11034 || pointer
11035 .checked_add(required)
11036 .is_none_or(|end| end > base.saturating_add(bytes))
11037 {
11038 return Err(publication_input_error(
11039 "update tensor span exceeds its actual CUDA backing allocation",
11040 ));
11041 }
11042 Ok((base, bytes))
11043}
11044
11045#[cfg(feature = "semantic-policy")]
11046fn accounted_tensor_allocations(
11047 tensors: &[&PreparedSemanticTensor],
11048 slab: &PreparedSemanticTensor,
11049) -> Result<u64, SemanticTransitionError> {
11050 let slab_bytes = tensor_layout_bytes(&slab.layout)?;
11051 let slab_end = slab
11052 .data
11053 .checked_add(slab_bytes as u64)
11054 .ok_or(SemanticTransitionError::GenerationExhausted)?;
11055 let (slab_base, slab_allocation_bytes) = cuda_backing_allocation(slab.data, slab_bytes)?;
11056 for tensor in tensors {
11057 let bytes = tensor_layout_bytes(&tensor.layout)?;
11058 if bytes == 0 {
11059 continue;
11060 }
11061 let (base, allocation_bytes) = cuda_backing_allocation(tensor.data, bytes)?;
11062 if tensor.data < slab.data
11063 || tensor
11064 .data
11065 .checked_add(bytes as u64)
11066 .is_none_or(|end| end > slab_end)
11067 || base != slab_base
11068 || allocation_bytes != slab_allocation_bytes
11069 {
11070 return Err(publication_input_error(
11071 "update output or logits differ from the original slab backing allocation",
11072 ));
11073 }
11074 }
11075 Ok(slab_allocation_bytes)
11076}
11077
11078fn same_tensor_content_owner(
11079 expected: &PreparedSemanticTensor,
11080 actual: &PreparedSemanticTensor,
11081) -> bool {
11082 tensor_content_identity(expected) == tensor_content_identity(actual)
11083 && match (&expected.native_allocation, &actual.native_allocation) {
11084 (Some(expected), Some(actual)) => expected.same_allocation(actual),
11085 (None, None) => true,
11086 _ => false,
11087 }
11088}
11089
11090impl StepContentStorage {
11091 fn feedback_origin_digest(
11092 &self,
11093 tensor: &PreparedSemanticTensor,
11094 ) -> Result<Option<CapturedTensorDigest>, SemanticTransitionError> {
11095 let bytes = tensor.source.as_ref().map_or(0, DeviceMemoryView::len) as u64;
11096 let end = tensor
11097 .data
11098 .checked_add(bytes)
11099 .ok_or(SemanticTransitionError::ObservationMismatch)?;
11100 for feedback in &self.feedback {
11101 for (index, original) in feedback.content.tensors.iter().enumerate() {
11102 let source = original
11103 .source
11104 .as_ref()
11105 .expect("native feedback output owner");
11106 let original_end = original
11107 .data
11108 .checked_add(source.len() as u64)
11109 .ok_or(SemanticTransitionError::ObservationMismatch)?;
11110 if bytes == 0 || tensor.data >= original_end || original.data >= end {
11111 continue;
11112 }
11113 if tensor_content_identity(tensor) != tensor_content_identity(original) {
11114 return Err(publication_input_error("native feedback aliases must retain their original type, shape, interval and roster coordinate"));
11115 }
11116 let TensorContentSeals::Captured(digests) = &feedback.content.seals else {
11117 return Err(SemanticTransitionError::ObservationMismatch);
11118 };
11119 let CapturedTensorDigest::Tensor { cells, offset, .. } = &digests[index] else {
11120 return Err(SemanticTransitionError::ObservationMismatch);
11121 };
11122 return Ok(Some(CapturedTensorDigest::Tensor {
11123 cells: Arc::clone(cells),
11124 offset: *offset,
11125 producer_sealed: true,
11126 }));
11127 }
11128 }
11129 Ok(None)
11130 }
11131}
11132
11133impl TensorContentBuffers {
11134 fn enqueue(
11135 &self,
11136 domain: &ResidentExecutionDomain,
11137 poisoned: &mut bool,
11138 execute: &CudaFunction,
11139 verify: bool,
11140 ) -> Result<(), SemanticTransitionError> {
11141 self.enqueue_with_custody(domain, poisoned, execute, verify, None, false)
11142 }
11143
11144 fn enqueue_with_custody(
11145 &self,
11146 domain: &ResidentExecutionDomain,
11147 poisoned: &mut bool,
11148 execute: &CudaFunction,
11149 verify: bool,
11150 custody: Option<&PreparedReplayCustody>,
11151 completed: bool,
11152 ) -> Result<(), SemanticTransitionError> {
11153 if let TensorContentSeals::Model(model) = &self.seals {
11154 if !verify || model.ranges.len() != self.tensors.len() + 1 {
11155 return Err(SemanticTransitionError::ObservationMismatch);
11156 }
11157 model.verify_contract(domain, poisoned)?;
11158 }
11159 for (ordinal, tensor) in self.tensors.iter().enumerate() {
11160 if let TensorContentSeals::Captured(digests) = &self.seals {
11161 if let CapturedTensorDigest::Publication(inputs) = &digests[ordinal] {
11162 if !digests[..ordinal].iter().any(|digest| matches!(digest,
11163 CapturedTensorDigest::Publication(previous) if Arc::ptr_eq(inputs, previous))) {
11164 if completed {
11165 inputs.verify_completed(domain, poisoned, custody)?;
11166 } else {
11167 inputs.verify(domain, poisoned)?;
11168 }
11169 }
11170 continue;
11173 }
11174 }
11175 let retained;
11179 let retained_view = match (&self.seals, custody) {
11180 (TensorContentSeals::Model(model), Some(custody)) => {
11181 let bank = model
11182 .prepared
11183 .as_ref()
11184 .ok_or(SemanticTransitionError::ObservationMismatch)?
11185 .bank;
11186 custody.model_content_view(tensor, bank)?
11187 }
11188 _ => None,
11189 };
11190 let tensor = if let Some((view, layout)) = retained_view {
11191 if layout != tensor.layout {
11192 return Err(SemanticTransitionError::ObservationMismatch);
11193 }
11194 retained = PreparedSemanticTensor {
11195 layout,
11196 data: *view.device_ptr(),
11197 native_allocation: view.allocation_provenance(),
11198 source: Some(view),
11199 ..tensor.clone()
11200 };
11201 &retained
11202 } else {
11203 tensor
11204 };
11205 let (pointer, bytes) = tensor
11206 .source
11207 .as_ref()
11208 .map_or((0, 0), |source| (*source.device_ptr(), source.len()));
11209 let range = tensor_content_range(
11210 &tensor.layout,
11211 tensor.logical_begin,
11212 tensor.logical_end,
11213 bytes,
11214 )?;
11215 let mut recorder = domain.new_strict_recorder();
11216 if let Some(source) = &tensor.source {
11217 recorder.read(source);
11218 }
11219 let (expected, verify) = match &self.seals {
11220 TensorContentSeals::Captured(digests) => {
11221 let CapturedTensorDigest::Tensor {
11222 cells,
11223 offset,
11224 producer_sealed,
11225 } = &digests[ordinal]
11226 else {
11227 return Err(SemanticTransitionError::ObservationMismatch);
11228 };
11229 let verify = verify || *producer_sealed;
11230 if verify {
11231 recorder.read(cells.as_ref());
11232 } else {
11233 recorder.write(cells.as_ref());
11234 }
11235 if offset.checked_add(4).is_none_or(|end| end > cells.len()) {
11236 return Err(SemanticTransitionError::ObservationMismatch);
11237 }
11238 (
11239 cells.device_ptr_value() + (*offset * size_of::<u64>()) as u64,
11240 verify,
11241 )
11242 }
11243 TensorContentSeals::Model(model) => {
11244 recorder.read(&model.ranges);
11245 (
11246 model.ranges.device_ptr_value()
11247 + (ordinal * size_of::<PublicationRange>()
11248 + std::mem::offset_of!(PublicationRange, digest))
11249 as u64,
11250 true,
11251 )
11252 }
11253 };
11254 let arguments = (
11255 pointer,
11256 bytes as u64,
11257 range,
11258 tensor.layout,
11259 expected,
11260 u64::from(verify),
11261 );
11262 let execute = execute.clone();
11263 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
11264 unsafe {
11268 execute.launch_in(
11269 enqueue,
11270 LaunchConfig {
11271 grid_dim: (1, 1, 1),
11272 block_dim: (1, 1, 1),
11273 shared_mem_bytes: 0,
11274 },
11275 arguments,
11276 )
11277 }
11278 .map_err(|e| XlogError::Kernel(e.to_string()))
11279 })?;
11280 }
11281 Ok(())
11282 }
11283}
11284
11285#[cfg(feature = "semantic-policy")]
11286type InitialPrefillSealSource = (u64, u64, Arc<TrackedCudaSlice<u64>>, usize);
11287
11288#[cfg(feature = "semantic-policy")]
11289fn initial_prefill_seal_sources(
11290 content: &TensorContentBuffers,
11291) -> Result<Vec<InitialPrefillSealSource>, SemanticTransitionError> {
11292 let TensorContentSeals::Captured(digests) = &content.seals else {
11293 return Err(SemanticTransitionError::ObservationMismatch);
11294 };
11295 if content.tensors.len() != digests.len() {
11296 return Err(SemanticTransitionError::ObservationMismatch);
11297 }
11298 content
11299 .tensors
11300 .iter()
11301 .zip(digests)
11302 .map(|(tensor, digest)| {
11303 let CapturedTensorDigest::Tensor { cells, offset, .. } = digest else {
11304 return Err(SemanticTransitionError::ObservationMismatch);
11305 };
11306 if offset.checked_add(4).is_none_or(|end| end > cells.len()) {
11307 return Err(SemanticTransitionError::ObservationMismatch);
11308 }
11309 Ok((
11310 tensor.layout.role,
11311 tensor.layout.index,
11312 Arc::clone(cells),
11313 *offset,
11314 ))
11315 })
11316 .collect()
11317}
11318
11319fn model_content_ranges(
11320 directory: &[PublicationRange],
11321 layouts: &BTreeMap<(u64, u64), SemanticTensorLayout>,
11322 tensors: impl Iterator<Item = (SemanticTensorLayout, u64, u64, usize)>,
11323) -> Result<Vec<usize>, SemanticTransitionError> {
11324 if directory.iter().filter(|range| range.role == 44).count() != 1
11327 || !directory.iter().any(|range| {
11328 range.role == 44 && range.index == 0 && range.generation == 1 && range.length_bytes != 0
11329 })
11330 || !directory.iter().any(|range| range.role == 18)
11331 {
11332 return Err(publication_input_error(
11333 "model content requires the complete original roster and sealed model contract",
11334 ));
11335 }
11336 let expected: BTreeSet<_> = directory
11337 .iter()
11338 .filter(|range| matches!(range.role, 18..=20))
11339 .map(|range| (range.role, range.index))
11340 .collect();
11341 let mut seen = BTreeSet::new();
11342 let mut ranges = Vec::new();
11343 for (actual, begin, end, bytes) in tensors {
11344 let key = (actual.role, actual.index);
11345 if !expected.contains(&key) || !seen.insert(key) {
11346 return Err(publication_input_error(
11347 "model content must name each original model tensor exactly once",
11348 ));
11349 }
11350 tensor_content_range(&actual, begin, end, bytes)?;
11351 let (ordinal, range) = directory
11352 .iter()
11353 .enumerate()
11354 .find(|(_, range)| (range.role, range.index) == key)
11355 .ok_or(SemanticTransitionError::ObservationMismatch)?;
11356 let mut original = *layouts
11357 .get(&key)
11358 .ok_or(SemanticTransitionError::ObservationMismatch)?;
11359 if original.logical_axis != u64::MAX {
11360 let axis = usize::try_from(original.logical_axis)
11361 .ok()
11362 .filter(|&axis| axis < 4)
11363 .ok_or(SemanticTransitionError::ObservationMismatch)?;
11364 original.dimensions[axis] = range
11365 .logical_end
11366 .checked_sub(range.logical_begin)
11367 .ok_or(SemanticTransitionError::ObservationMismatch)?;
11368 }
11369 original.strides_bytes = actual.strides_bytes;
11372 if original != actual
11373 || range.generation != 1
11374 || (range.logical_begin, range.logical_end) != (begin, end)
11375 {
11376 return Err(publication_input_error(
11377 "live model tensor differs from the original logical type, shape or interval",
11378 ));
11379 }
11380 ranges.push(ordinal);
11381 }
11382 if seen != expected {
11383 return Err(publication_input_error(
11384 "model content omits an original model tensor",
11385 ));
11386 }
11387 Ok(ranges)
11388}
11389
11390fn tensor_content_range(
11391 layout: &SemanticTensorLayout,
11392 begin: u64,
11393 end: u64,
11394 bytes: usize,
11395) -> Result<PublicationRange, SemanticTransitionError> {
11396 if (layout.role != 0 && SemanticStateRole::from_code(layout.role).is_none())
11397 || end < begin
11398 || tensor_layout_bytes(layout)? != bytes
11399 || if layout.logical_axis == u64::MAX {
11400 begin != 0 || end != 0
11401 } else {
11402 end - begin != layout.dimensions[layout.logical_axis as usize]
11403 }
11404 {
11405 return Err(publication_input_error(
11406 "content tensor must retain its exact type, shape, interval and byte extent",
11407 ));
11408 }
11409 Ok(PublicationRange {
11410 role: layout.role,
11411 index: layout.index,
11412 length_bytes: bytes as u64,
11413 logical_begin: begin,
11414 logical_end: end,
11415 ..PublicationRange::default()
11416 })
11417}
11418
11419fn validate_content_coordinates(
11420 coordinates: impl Iterator<Item = (u64, u64)>,
11421) -> Result<(), SemanticTransitionError> {
11422 validate_content_coordinates_after(coordinates, 0)
11423}
11424
11425fn validate_content_coordinates_after(
11426 coordinates: impl Iterator<Item = (u64, u64)>,
11427 private_prefix: usize,
11428) -> Result<(), SemanticTransitionError> {
11429 let mut distinct = BTreeSet::new();
11430 for (ordinal, (role, index)) in coordinates.enumerate() {
11431 if (role == 0
11432 && ordinal
11433 .checked_sub(private_prefix)
11434 .is_none_or(|allocation| index != allocation as u64))
11435 || (role != 0 && SemanticStateRole::from_code(role).is_none())
11436 || !distinct.insert((role, index))
11437 {
11438 return Err(publication_input_error(
11439 "content coordinates require unique state roles or exact private capture positions",
11440 ));
11441 }
11442 }
11443 Ok(())
11444}
11445
11446pub struct SemanticPublishedLease {
11449 issuer: Arc<()>,
11450 token: u64,
11451 identity: SemanticPublishedIdentity,
11452 header: PublicationHeader,
11453 source: [SemanticTextSlot; 32],
11454 directory: Vec<PublicationRange>,
11455 active: bool,
11456}
11457
11458fn committed_prefix_layout(
11459 range: &PublicationRange,
11460 prefix_capacity: u64,
11461) -> Result<SemanticTensorLayout, SemanticTransitionError> {
11462 let row_bytes = size_of::<SemanticTextSlot>() as u64;
11463 if range.role != SemanticStateRole::PrefixSource as u64
11464 || range.index != 0
11465 || range.logical_begin != 0
11466 || range.logical_end > prefix_capacity
11467 || range.logical_end.checked_mul(row_bytes) != Some(range.length_bytes)
11468 || i64::try_from(prefix_capacity).is_err()
11469 || !range
11470 .offset_bytes
11471 .is_multiple_of(std::mem::align_of::<SemanticTextSlot>() as u64)
11472 {
11473 return Err(SemanticTransitionError::ObservationMismatch);
11474 }
11475 let layout = SemanticTensorLayout {
11476 role: SemanticStateRole::PrefixSource as u64,
11477 index: 0,
11478 scalar_type: 3,
11479 element_bytes: 8,
11480 rank: 2,
11481 logical_axis: 0,
11482 dimensions: [prefix_capacity, 8, 0, 0],
11483 strides_bytes: [row_bytes, 8, 0, 0],
11484 };
11485 tensor_layout_bytes(&layout)?;
11486 Ok(layout)
11487}
11488
11489fn publication_export_span(
11493 range: &PublicationRange,
11494 layout: &SemanticTensorLayout,
11495 allocation_bytes: usize,
11496) -> Result<std::ops::Range<usize>, SemanticTransitionError> {
11497 let bytes = tensor_layout_bytes(layout)?;
11498 let begin = usize::try_from(range.offset_bytes)
11499 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
11500 let sealed_bytes = usize::try_from(range.length_bytes)
11501 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
11502 let capacity = matches!(range.role, 1 | 4 | 5 | 51..=54);
11503 if range.generation != 1
11504 || (range.role, range.index) != (layout.role, layout.index)
11505 || !range.offset_bytes.is_multiple_of(layout.element_bytes)
11506 || begin
11507 .checked_add(sealed_bytes)
11508 .is_none_or(|end| end > allocation_bytes)
11509 || range.logical_end < range.logical_begin
11510 || (layout.logical_axis != u64::MAX
11511 && (range.logical_begin != 0
11512 || range.logical_end > layout.dimensions[layout.logical_axis as usize]))
11513 || (!capacity && bytes > sealed_bytes)
11514 {
11515 return Err(SemanticTransitionError::ObservationMismatch);
11516 }
11517 let end = begin
11518 .checked_add(bytes.max(sealed_bytes))
11519 .filter(|&end| end <= allocation_bytes)
11520 .ok_or(SemanticTransitionError::ObservationMismatch)?;
11521 Ok(begin..end)
11522}
11523
11524fn publication_record_layout(range: &PublicationRange) -> SemanticTensorLayout {
11525 SemanticTensorLayout {
11526 role: range.role,
11527 index: range.index,
11528 element_bytes: 1,
11529 scalar_type: 1,
11530 rank: 1,
11531 logical_axis: u64::MAX,
11532 dimensions: [range.length_bytes, 0, 0, 0],
11533 strides_bytes: [1, 0, 0, 0],
11534 }
11535}
11536
11537impl SemanticPublishedLease {
11538 fn model_context_header(&self) -> Result<PublicationHeader, SemanticTransitionError> {
11539 let header = self.header;
11540 if header.abi != 1
11541 || header.instance != self.identity.instance
11542 || header.publication_word != self.identity.word
11543 || header.sealed_epoch != self.identity.word >> 1
11544 || header.logical_digest != self.identity.logical_digest
11545 || header.state_digest != self.identity.state_digest
11546 {
11547 return Err(SemanticTransitionError::ObservationMismatch);
11548 }
11549 Ok(header)
11550 }
11551}
11552
11553#[derive(Clone, Debug, PartialEq, Eq)]
11555pub struct SemanticFeedbackSchema {
11556 pub identity: [u8; 32],
11557 pub statement_bytes: usize,
11558 pub feature_width: usize,
11559}
11560
11561impl SemanticFeedbackSchema {
11562 pub fn new(statements: [&[u8]; 3]) -> Result<Self, SemanticTransitionError> {
11563 if statements.iter().any(|statement| statement.is_empty()) {
11564 return Err(publication_input_error(
11565 "native feedback requires three nonempty typed statements",
11566 ));
11567 }
11568 let statement_bytes = statements
11569 .iter()
11570 .map(|statement| statement.len())
11571 .max()
11572 .unwrap();
11573 let feature_width = statement_bytes
11574 .checked_mul(9)
11575 .and_then(|n| n.checked_add(4))
11576 .filter(|&n| i64::try_from(n).is_ok())
11577 .ok_or_else(|| publication_input_error("native feedback schema width overflows"))?;
11578 let mut hash = Sha256::new();
11579 hash.update(b"xlog.feedback.flat-bit-presence.v1\0");
11580 hash.update((statement_bytes as u64).to_le_bytes());
11581 hash.update(b"byte[i]:bits[0..8],presence;pro,1,contra,1;invalid:all-zero");
11582 Ok(Self {
11583 identity: hash.finalize().into(),
11584 statement_bytes,
11585 feature_width,
11586 })
11587 }
11588}
11589
11590pub const SEMANTIC_FEEDBACK_SUPPORT_FIELDS: [&str; 12] = [
11593 "original_statement",
11594 "original_support",
11595 "support_slot",
11596 "support_generation",
11597 "version_slot",
11598 "version_generation",
11599 "insertion_ordinal",
11600 "polarity",
11601 "support_digest_0",
11602 "support_digest_1",
11603 "support_digest_2",
11604 "support_digest_3",
11605];
11606
11607pub struct SemanticFeedback {
11610 pub parent: SemanticPublishedIdentity,
11611 pub schema: SemanticFeedbackSchema,
11612 features: DlpackManagedTensor,
11613 device_validity: DlpackManagedTensor,
11614 query_receipts: DlpackManagedTensor,
11615 original_statements: DlpackManagedTensor,
11616 support_offsets: DlpackManagedTensor,
11617 supports: DlpackManagedTensor,
11618}
11619
11620impl SemanticFeedback {
11621 pub fn into_dlpack(self) -> [DlpackManagedTensor; 6] {
11626 [
11627 self.features,
11628 self.device_validity,
11629 self.query_receipts,
11630 self.original_statements,
11631 self.support_offsets,
11632 self.supports,
11633 ]
11634 }
11635}
11636
11637struct FeedbackBuffers {
11638 schema: SemanticFeedbackSchema,
11639 slots: usize,
11640 support_capacity: usize,
11641 encode: CudaFunction,
11642 project: CudaFunction,
11643 witness: CudaFunction,
11644 content: TensorContentBuffers,
11645 features: TrackedCudaSlice<f32>,
11646 validity: TrackedCudaSlice<u8>,
11647 status: TrackedCudaSlice<u64>,
11648 query_receipts: TrackedCudaSlice<u64>,
11649 original_statements: TrackedCudaSlice<u64>,
11650 support_offsets: TrackedCudaSlice<u64>,
11651 supports: TrackedCudaSlice<u64>,
11652}
11653
11654#[derive(Clone, Copy)]
11655struct FeedbackAllocationPlan {
11656 slots: usize,
11657 support_capacity: usize,
11658 cells: usize,
11659 query_cells: usize,
11660 support_cells: usize,
11661 offset_cells: usize,
11662 bytes: usize,
11663}
11664
11665impl FeedbackAllocationPlan {
11666 fn new(
11667 schema: &SemanticFeedbackSchema,
11668 slots: u64,
11669 support_capacity: u64,
11670 ) -> Result<Self, SemanticTransitionError> {
11671 let slots = usize::try_from(slots)
11672 .ok()
11673 .filter(|&n| n >= 2 && i64::try_from(n).is_ok())
11674 .ok_or_else(|| {
11675 publication_input_error("feedback slot capacity is not representable")
11676 })?;
11677 let support_capacity = usize::try_from(support_capacity)
11678 .ok()
11679 .filter(|&n| n != 0 && i64::try_from(n).is_ok())
11680 .ok_or_else(|| {
11681 publication_input_error("feedback support capacity is not representable")
11682 })?;
11683 let cells = slots
11684 .checked_mul(schema.feature_width)
11685 .ok_or_else(|| publication_input_error("feedback feature extent overflows"))?;
11686 let query_cells = slots
11687 .checked_mul(42)
11688 .ok_or_else(|| publication_input_error("feedback receipt extent overflows"))?;
11689 let support_cells = support_capacity
11690 .checked_mul(SEMANTIC_FEEDBACK_SUPPORT_FIELDS.len())
11691 .ok_or_else(|| publication_input_error("feedback support extent overflows"))?;
11692 let offset_cells = slots
11693 .checked_add(1)
11694 .ok_or_else(|| publication_input_error("feedback offset extent overflows"))?;
11695 let service_bytes = query_cells
11696 .checked_add(slots)
11697 .and_then(|n| n.checked_add(offset_cells))
11698 .and_then(|n| n.checked_add(support_cells))
11699 .and_then(|n| n.checked_mul(8))
11700 .ok_or_else(|| publication_input_error("feedback service extent overflows"))?;
11701 let bytes = cells
11702 .checked_mul(size_of::<f32>())
11703 .and_then(|n| {
11704 slots
11705 .checked_mul(9)
11706 .and_then(|metadata| n.checked_add(metadata))
11707 })
11708 .and_then(|n| n.checked_add(service_bytes))
11709 .and_then(|n| n.checked_add(6 * 4 * size_of::<u64>()))
11710 .ok_or_else(|| publication_input_error("feedback allocation extent overflows"))?;
11711 Ok(Self {
11712 slots,
11713 support_capacity,
11714 cells,
11715 query_cells,
11716 support_cells,
11717 offset_cells,
11718 bytes,
11719 })
11720 }
11721}
11722
11723impl FeedbackBuffers {
11724 fn allocate(
11727 provider: &CudaKernelProvider,
11728 schema: SemanticFeedbackSchema,
11729 slots: u64,
11730 support_capacity: u64,
11731 ) -> Result<Self, SemanticTransitionError> {
11732 let plan = FeedbackAllocationPlan::new(&schema, slots, support_capacity)?;
11733 let mut reservation = provider
11734 .memory()
11735 .reserve_bytes(plan.bytes as u64)
11736 .map_err(|error| runtime_error("feedback reservation", error))?;
11737 Self::allocate_reserved(provider, schema, plan, &mut reservation)
11738 }
11739
11740 fn allocate_reserved(
11741 provider: &CudaKernelProvider,
11742 schema: SemanticFeedbackSchema,
11743 plan: FeedbackAllocationPlan,
11744 reservation: &mut GpuMemoryReservation,
11745 ) -> Result<Self, SemanticTransitionError> {
11746 let FeedbackAllocationPlan {
11747 slots,
11748 support_capacity,
11749 cells,
11750 query_cells,
11751 support_cells,
11752 offset_cells,
11753 ..
11754 } = plan;
11755 let encode = provider
11756 .device()
11757 .inner()
11758 .get_func("xlog_semantic_transition", "semantic_feedback_encode")
11759 .ok_or_else(|| {
11760 runtime_error("kernel lookup", "semantic feedback kernel unavailable")
11761 })?;
11762 let project = provider
11763 .device()
11764 .inner()
11765 .get_func("xlog_semantic_transition", "semantic_feedback_project")
11766 .ok_or_else(|| {
11767 runtime_error("kernel lookup", "semantic feedback projection unavailable")
11768 })?;
11769 let witness = provider
11770 .device()
11771 .inner()
11772 .get_func(
11773 "xlog_semantic_transition",
11774 "semantic_tensor_content_witness",
11775 )
11776 .ok_or_else(|| runtime_error("kernel lookup", "tensor content witness unavailable"))?;
11777 let mut buffers = Self {
11778 schema,
11779 slots,
11780 support_capacity,
11781 encode,
11782 project,
11783 witness,
11784 content: TensorContentBuffers {
11785 tensors: Vec::new(),
11786 seals: TensorContentSeals::Captured(Vec::new()),
11787 verification_inputs: Vec::new(),
11788 },
11789 features: reservation
11790 .alloc::<f32>(cells)
11791 .map_err(|error| runtime_error("feedback features allocation", error))?,
11792 validity: reservation
11793 .alloc::<u8>(slots)
11794 .map_err(|error| runtime_error("feedback validity allocation", error))?,
11795 status: reservation
11796 .alloc::<u64>(slots)
11797 .map_err(|error| runtime_error("feedback status allocation", error))?,
11798 query_receipts: reservation
11799 .alloc::<u64>(query_cells)
11800 .map_err(|error| runtime_error("feedback receipt allocation", error))?,
11801 original_statements: reservation
11802 .alloc::<u64>(slots)
11803 .map_err(|error| runtime_error("feedback origin allocation", error))?,
11804 support_offsets: reservation
11805 .alloc::<u64>(offset_cells)
11806 .map_err(|error| runtime_error("feedback offset allocation", error))?,
11807 supports: reservation
11808 .alloc::<u64>(support_cells)
11809 .map_err(|error| runtime_error("feedback support allocation", error))?,
11810 };
11811 let words = |view: DeviceMemoryView<u64>| {
11812 unsafe { view.cast::<u8>() }.ok_or(SemanticTransitionError::ObservationMismatch)
11815 };
11816 let features = unsafe { buffers.features.view().cast::<u8>() }
11818 .ok_or(SemanticTransitionError::ObservationMismatch)?;
11819 let originals = [
11820 features,
11821 buffers.validity.view(),
11822 words(buffers.query_receipts.view())?,
11823 words(buffers.original_statements.view())?,
11824 words(buffers.support_offsets.view())?,
11825 words(buffers.supports.view())?,
11826 ];
11827 let shapes = [
11828 (
11829 6,
11830 4,
11831 2,
11832 [slots as u64, buffers.schema.feature_width as u64, 0, 0],
11833 ),
11834 (8, 1, 1, [slots as u64, 0, 0, 0]),
11835 (3, 8, 2, [slots as u64, 42, 0, 0]),
11836 (3, 8, 1, [slots as u64, 0, 0, 0]),
11837 (3, 8, 1, [offset_cells as u64, 0, 0, 0]),
11838 (3, 8, 2, [support_capacity as u64, 12, 0, 0]),
11839 ];
11840 let mut digests = Vec::with_capacity(originals.len());
11841 for (index, (source, (scalar_type, element_bytes, rank, dimensions))) in
11842 originals.into_iter().zip(shapes).enumerate()
11843 {
11844 let layout = canonical_tensor_layout(SemanticTensorLayout {
11845 role: 0,
11846 index: index as u64,
11847 scalar_type,
11848 element_bytes,
11849 rank,
11850 dimensions,
11851 logical_axis: u64::MAX,
11852 strides_bytes: [0; 4],
11853 })?;
11854 tensor_content_range(&layout, 0, 0, source.len())?;
11855 buffers.content.tensors.push(PreparedSemanticTensor {
11856 layout,
11857 logical_begin: 0,
11858 logical_end: 0,
11859 data: *source.device_ptr(),
11860 source: Some(source),
11861 native_allocation: None,
11862 _empty_owner: None,
11863 });
11864 digests.push(CapturedTensorDigest::Tensor {
11865 cells: Arc::new(
11866 reservation
11867 .alloc::<u64>(4)
11868 .map_err(|error| runtime_error("feedback witness allocation", error))?,
11869 ),
11870 offset: 0,
11871 producer_sealed: false,
11872 });
11873 }
11874 buffers.content.seals = TensorContentSeals::Captured(digests);
11875 Ok(buffers)
11876 }
11877
11878 #[expect(
11882 clippy::too_many_arguments,
11883 reason = "feedback execution records every retained native owner explicitly"
11884 )]
11885 fn enqueue(
11886 &self,
11887 domain: &ResidentExecutionDomain,
11888 poisoned: &mut bool,
11889 graph: &SemanticHypergraph,
11890 storage: &PublicationStorage,
11891 task: &TrackedCudaSlice<u64>,
11892 lease: &TrackedCudaSlice<PublicationLease>,
11893 descriptor: Descriptor,
11894 ) -> Result<(), SemanticTransitionError> {
11895 let mut recorder = domain.new_strict_recorder();
11896 recorder.read(lease);
11897 recorder.read(&storage.control);
11898 recorder.read(&storage.storage);
11899 recorder.read(&storage.contract);
11900 for bank in &storage.banks {
11901 recorder.read(bank);
11902 }
11903 for directory in &storage.directories {
11904 recorder.read(directory);
11905 }
11906 for allocation in &storage.allocations {
11907 recorder.read(allocation);
11908 }
11909 recorder.write(&self.features);
11910 recorder.write(&self.validity);
11911 recorder.write(&self.status);
11912 let arguments = (
11913 storage.control.device_ptr_value(),
11914 lease.device_ptr_value(),
11915 self.schema.statement_bytes as u64,
11916 self.slots as u64,
11917 self.features.device_ptr_value(),
11918 self.validity.device_ptr_value(),
11919 self.status.device_ptr_value(),
11920 );
11921 enqueue_recorded(domain, poisoned, recorder, |stream| {
11922 unsafe {
11926 self.encode.clone().launch_in(
11927 stream,
11928 LaunchConfig {
11929 grid_dim: (self.slots.min(65535) as u32, 1, 1),
11930 block_dim: (256, 1, 1),
11931 shared_mem_bytes: 0,
11932 },
11933 arguments,
11934 )
11935 }
11936 .map_err(|error| XlogError::Kernel(error.to_string()))
11937 })?;
11938 let mut recorder = domain.new_strict_recorder();
11939 graph.record_transition(&mut recorder);
11940 storage.record(&mut recorder);
11941 recorder.read(lease);
11942 recorder.read(task);
11943 recorder.read_write(&self.status);
11944 recorder.write(&self.query_receipts);
11945 recorder.write(&self.original_statements);
11946 recorder.write(&self.support_offsets);
11947 recorder.write(&self.supports);
11948 let arguments = (
11949 descriptor,
11950 lease.device_ptr_value(),
11951 self.slots as u64,
11952 self.query_receipts.device_ptr_value(),
11953 self.original_statements.device_ptr_value(),
11954 self.support_offsets.device_ptr_value(),
11955 self.supports.device_ptr_value(),
11956 self.support_capacity as u64,
11957 self.status.device_ptr_value(),
11958 );
11959 enqueue_recorded(domain, poisoned, recorder, |stream| {
11960 unsafe {
11964 self.project.clone().launch_in(
11965 stream,
11966 LaunchConfig {
11967 grid_dim: (1, 1, 1),
11968 block_dim: (1, 1, 1),
11969 shared_mem_bytes: 0,
11970 },
11971 arguments,
11972 )
11973 }
11974 .map_err(|error| XlogError::Kernel(error.to_string()))
11975 })?;
11976 self.content.enqueue(domain, poisoned, &self.witness, false)
11979 }
11980}
11981
11982impl SemanticPublishedLease {
11983 pub fn is_active(&self) -> bool {
11984 self.active
11985 }
11986}
11987
11988#[expect(
11989 clippy::too_many_arguments,
11990 reason = "DLPack export retains independent shape, type, alias, and publication owners"
11991)]
11992fn export_owned_allocation(
11993 view: DeviceMemoryView<u8>,
11994 shape: Vec<i64>,
11995 strides: Vec<i64>,
11996 dtype: (u8, u8),
11997 device_id: i32,
11998 alias_guard: Arc<()>,
11999 publication: Arc<PublicationStorage>,
12000 continuation: Option<Arc<TextBindingStorage>>,
12001 retained_owner: Option<Arc<dyn Send + Sync>>,
12002) -> DlpackManagedTensor {
12003 let mut export = Box::new(PublishedTensorExport {
12004 managed: crate::dlpack::DLManagedTensor {
12005 dl_tensor: crate::dlpack::DLTensor {
12006 data: *view.device_ptr() as usize as *mut std::ffi::c_void,
12007 device: crate::dlpack::DLDevice {
12008 device_type: 2,
12009 device_id,
12010 },
12011 ndim: shape.len() as i32,
12012 dtype: crate::dlpack::DLDataType {
12013 code: dtype.0,
12014 bits: dtype.1,
12015 lanes: 1,
12016 },
12017 shape: std::ptr::null_mut(),
12018 strides: std::ptr::null_mut(),
12019 byte_offset: 0,
12020 },
12021 manager_ctx: std::ptr::null_mut(),
12022 deleter: Some(delete_published_tensor),
12023 },
12024 shape,
12025 strides,
12026 _view: view,
12027 _alias_guard: alias_guard,
12028 _publication: publication,
12029 _continuation: continuation,
12030 _retained_owner: retained_owner,
12031 });
12032 export.managed.dl_tensor.shape = export.shape.as_mut_ptr();
12033 export.managed.dl_tensor.strides = export.strides.as_mut_ptr();
12034 let owner = Box::into_raw(export);
12035 unsafe {
12038 (*owner).managed.manager_ctx = owner.cast();
12039 DlpackManagedTensor::from_raw(&mut (*owner).managed)
12040 }
12041}
12042
12043struct PublishedTensorExport {
12044 managed: crate::dlpack::DLManagedTensor,
12045 shape: Vec<i64>,
12046 strides: Vec<i64>,
12047 _view: DeviceMemoryView<u8>,
12048 _alias_guard: Arc<()>,
12049 _publication: Arc<PublicationStorage>,
12050 _continuation: Option<Arc<TextBindingStorage>>,
12051 _retained_owner: Option<Arc<dyn Send + Sync>>,
12052}
12053
12054unsafe extern "C" fn delete_published_tensor(managed: *mut crate::dlpack::DLManagedTensor) {
12055 if managed.is_null() {
12056 return;
12057 }
12058 let owner = unsafe { (*managed).manager_ctx.cast::<PublishedTensorExport>() };
12061 if !owner.is_null() {
12062 drop(unsafe { Box::from_raw(owner) });
12063 }
12064}
12065
12066fn dlpack_consumer_stream(stream: u64) -> Result<sys::CUstream, SemanticTransitionError> {
12067 if matches!(stream, 0 | 2) {
12068 return Err(publication_input_error("DLPack consumer requires legacy default stream 1 or an explicit live stream; zero and per-thread default are unsupported"));
12069 }
12070 Ok(if stream == 1 {
12071 std::ptr::null_mut()
12072 } else {
12073 stream as usize as sys::CUstream
12074 })
12075}
12076
12077fn publication_abi_bytes<T: DeviceRepr>(records: &[T]) -> Vec<u8> {
12080 unsafe { std::slice::from_raw_parts(records.as_ptr().cast(), std::mem::size_of_val(records)) }
12083 .to_vec()
12084}
12085
12086fn initial_intent_records(
12087 effect: &[u8],
12088 entry_capacity: u64,
12089 payload_capacity: usize,
12090 final_payload_bytes: u64,
12091) -> Result<[SemanticStateRecord; 2], SemanticTransitionError> {
12092 let entries_bytes = usize::try_from(entry_capacity)
12093 .ok()
12094 .and_then(|count| count.checked_mul(size_of::<IntentEntry>()))
12095 .and_then(|bytes| bytes.checked_add(size_of::<IntentQueueHeader>()))
12096 .ok_or_else(|| {
12097 publication_input_error("intent entry capacity overflows its native allocation")
12098 })?;
12099 let required_payload = u64::try_from(effect.len())
12100 .ok()
12101 .and_then(|bytes| bytes.checked_add(final_payload_bytes));
12102 if effect.is_empty()
12103 || entry_capacity == 0
12104 || final_payload_bytes == 0
12105 || required_payload.is_none_or(|bytes| bytes > payload_capacity as u64)
12106 {
12107 return Err(publication_input_error(
12108 "initial intent requires its actual effect and reserved final-output capacity",
12109 ));
12110 }
12111 let header = IntentQueueHeader {
12112 abi: 1,
12113 count: 0,
12114 capacity: entry_capacity,
12115 payload_used_bytes: effect.len() as u64,
12116 payload_capacity_bytes: payload_capacity as u64,
12117 effect_offset_bytes: 0,
12118 effect_length_bytes: effect.len() as u64,
12119 chain_head: Identity256::default(),
12120 };
12121 Ok([
12122 SemanticStateRecord {
12123 role: SemanticStateRole::IntentEntries,
12124 index: 0,
12125 bytes: publication_abi_bytes(&[header]),
12126 capacity_bytes: entries_bytes,
12127 },
12128 SemanticStateRecord {
12129 role: SemanticStateRole::IntentPayload,
12130 index: 0,
12131 bytes: effect.to_vec(),
12132 capacity_bytes: payload_capacity,
12133 },
12134 ])
12135}
12136
12137fn initial_acknowledgement_record(
12138 entry_capacity: u64,
12139 payload_capacity: usize,
12140 intent_payload_capacity: usize,
12141 effect_len: usize,
12142) -> Result<SemanticStateRecord, SemanticTransitionError> {
12143 let count = usize::try_from(entry_capacity).map_err(|_| {
12144 publication_input_error("acknowledgement entry capacity overflows this host")
12145 })?;
12146 let required_receipts = count
12147 .checked_mul(169)
12148 .and_then(|bytes| bytes.checked_add(intent_payload_capacity))
12149 .and_then(|bytes| bytes.checked_add(count.saturating_sub(1).checked_mul(effect_len)?))
12150 .ok_or_else(|| {
12151 publication_input_error("complete acknowledgement reserve overflows this host")
12152 })?;
12153 let capacity_bytes = usize::try_from(entry_capacity)
12154 .ok()
12155 .and_then(|count| count.checked_mul(size_of::<AcknowledgementEntry>()))
12156 .and_then(|bytes| bytes.checked_add(payload_capacity))
12157 .and_then(|bytes| bytes.checked_add(size_of::<AcknowledgementQueueHeader>()))
12158 .ok_or_else(|| {
12159 publication_input_error("acknowledgement capacity overflows its native allocation")
12160 })?;
12161 if entry_capacity == 0 || effect_len == 0 || payload_capacity < required_receipts {
12162 return Err(publication_input_error("acknowledgement queue cannot retain every full receipt within its native intent bounds"));
12163 }
12164 Ok(SemanticStateRecord {
12165 role: SemanticStateRole::Acknowledgements,
12166 index: 0,
12167 bytes: publication_abi_bytes(&[AcknowledgementQueueHeader {
12168 abi: 1,
12169 count: 0,
12170 capacity: entry_capacity,
12171 payload_used_bytes: 0,
12172 payload_capacity_bytes: payload_capacity as u64,
12173 chain_head: Identity256::default(),
12174 }]),
12175 capacity_bytes,
12176 })
12177}
12178
12179fn publication_mutable_role(role: u64) -> bool {
12180 matches!(role, 3..=15 | 18..=25 | 30 | 32 | 33 | 39 | 44 | 51..=55)
12181}
12182
12183fn continuation_role(role: u64) -> bool {
12184 matches!(role, 1 | 4..=13 | 39 | 51..=55)
12185}
12186
12187fn validate_parent_records(
12188 parent: &SemanticParentBinding,
12189 tensors: &[PreparedSemanticTensor],
12190) -> Result<(), SemanticTransitionError> {
12191 validate_publication_counts(&parent.role_counts)?;
12192 validate_text_parent(
12193 &parent.source,
12194 parent.prefix.len() as u64,
12195 parent.prefix_capacity,
12196 parent.feedback_capacity,
12197 parent.max_position,
12198 parent.ring_head,
12199 parent.provenance_records,
12200 )?;
12201 if parent.feedback_capacity < 3
12202 || parent.rng.stream_serial >= 1 << 56
12203 || u64::from(parent.rng.model_generation) != parent.model_generation
12204 || parent.pad_token >= TEXT_CARDINALITY as u64
12205 || parent.terminal_tokens.is_empty()
12206 || parent
12207 .terminal_tokens
12208 .iter()
12209 .any(|&token| token >= TEXT_CARDINALITY as u64)
12210 || parent
12211 .terminal_tokens
12212 .iter()
12213 .copied()
12214 .collect::<BTreeSet<_>>()
12215 .len()
12216 != parent.terminal_tokens.len()
12217 {
12218 return Err(publication_input_error(
12219 "parent generations, feedback extent, or token contract mismatch",
12220 ));
12221 }
12222 for (position, slot) in parent.prefix.iter().enumerate() {
12223 if slot.kind != 1
12224 || slot.valid != 1
12225 || slot.committed != 1
12226 || slot.logical_position != position as u64
12227 || slot.token >= TEXT_CARDINALITY as u64
12228 || !matches!(slot.provenance, 1 | 2)
12229 || slot.provenance_record >= parent.provenance_records
12230 || slot.recomputed > 1
12231 {
12232 return Err(publication_input_error(
12233 "committed prefix source is not the exact ordered valid prefix",
12234 ));
12235 }
12236 }
12237 let mut keys = BTreeSet::new();
12238 for record in &parent.records {
12239 let role = record.role as u64;
12240 if is_tensor_role(role)
12241 || matches!(role, 1 | 3 | 14..=16 | 33 | 43 | 47 | 48 | 55)
12242 || record.index >= parent.role_counts[role as usize - 1]
12243 || (record.bytes.is_empty() && role != 2)
12244 || record.bytes.len() > record.capacity_bytes
12245 || !keys.insert((role, record.index))
12246 {
12247 return Err(publication_input_error(
12248 "duplicate, generated, tensor, empty, or out-of-capacity control record",
12249 ));
12250 }
12251 if role == 2
12252 && (parent
12253 .provenance_records
12254 .checked_mul(size_of::<TokenProvenance>() as u64)
12255 != Some(record.bytes.len() as u64)
12256 || (parent.provenance_records + 32)
12257 .checked_mul(size_of::<TokenProvenance>() as u64)
12258 .is_none_or(|n| n > record.capacity_bytes as u64))
12259 {
12260 return Err(publication_input_error(
12261 "token provenance records or append capacity differ from the actual source ledger",
12262 ));
12263 }
12264 if role == 44 {
12265 parent
12266 .model_contract_layout
12267 .validate(record.bytes.len() as u64)?;
12268 }
12269 if role == 30 {
12270 if record.bytes.len() < size_of::<IntentQueueHeader>() {
12271 return Err(publication_input_error(
12272 "intent queue has no complete owner header",
12273 ));
12274 }
12275 let header = unsafe {
12277 record
12278 .bytes
12279 .as_ptr()
12280 .cast::<IntentQueueHeader>()
12281 .read_unaligned()
12282 };
12283 if header.abi != 1
12284 || header.count > header.capacity
12285 || header
12286 .count
12287 .checked_mul(size_of::<IntentEntry>() as u64)
12288 .and_then(|n| n.checked_add(size_of::<IntentQueueHeader>() as u64))
12289 != Some(record.bytes.len() as u64)
12290 || header
12291 .capacity
12292 .checked_mul(size_of::<IntentEntry>() as u64)
12293 .and_then(|n| n.checked_add(size_of::<IntentQueueHeader>() as u64))
12294 != Some(record.capacity_bytes as u64)
12295 || header.payload_used_bytes > header.payload_capacity_bytes
12296 || header.effect_length_bytes == 0
12297 || header
12298 .effect_offset_bytes
12299 .checked_add(header.effect_length_bytes)
12300 .is_none_or(|n| n > header.payload_used_bytes)
12301 {
12302 return Err(publication_input_error(
12303 "intent queue count, capacity, or actual effect payload is inconsistent",
12304 ));
12305 }
12306 let payload = parent
12307 .records
12308 .iter()
12309 .find(|record| record.role == SemanticStateRole::IntentPayload)
12310 .ok_or_else(|| publication_input_error("intent queue payload owner is absent"))?;
12311 if payload.bytes.len() as u64 != header.payload_used_bytes
12312 || payload.capacity_bytes as u64 != header.payload_capacity_bytes
12313 {
12314 return Err(publication_input_error(
12315 "intent queue does not resolve to its actual payload allocation",
12316 ));
12317 }
12318 }
12319 if role == 32 {
12320 acknowledgement_receipts(&record.bytes, record.capacity_bytes)?;
12321 }
12322 }
12323 for tensor in tensors {
12324 let layout = &tensor.layout;
12325 if !is_tensor_role(layout.role)
12326 || layout.role >= 51
12327 || layout.index >= parent.role_counts[layout.role as usize - 1]
12328 || !keys.insert((layout.role, layout.index))
12329 {
12330 return Err(publication_input_error("initial parent tensor role is duplicate, uncomputed-active, or outside its model roster"));
12331 }
12332 tensor_layout_bytes(layout)?;
12333 if matches!(layout.role, 4 | 5) {
12334 if tensor.logical_begin != 0
12335 || tensor.logical_end != parent.prefix.len() as u64
12336 || layout.dimensions[2] != parent.prefix.len() as u64
12337 {
12338 return Err(publication_input_error(
12339 "initial attention tensor does not cover exactly the acquired prefix",
12340 ));
12341 }
12342 prefix_capacity_layout(*layout, parent.prefix_capacity)?;
12343 } else if layout.logical_axis != u64::MAX
12344 || (matches!(layout.role, 18..=25)
12345 && (tensor.logical_begin != 0 || tensor.logical_end != 0))
12346 {
12347 return Err(publication_input_error(
12348 "non-positional model tensors require a non-sliced exact layout",
12349 ));
12350 }
12351 if matches!(layout.role, 8..=13) && (layout.scalar_type != 6 || layout.element_bytes != 4) {
12352 return Err(publication_input_error(
12353 "value and edit accumulators require original FP32 storage",
12354 ));
12355 }
12356 }
12357 for layout in &parent.active_layouts {
12358 if !matches!(layout.role, 51..=54)
12359 || layout.index >= parent.role_counts[layout.role as usize - 1]
12360 || !keys.insert((layout.role, layout.index))
12361 || tensor_layout_bytes(layout)? == 0
12362 {
12363 return Err(publication_input_error("active output capacity layout is absent, duplicate, or outside the cold model roster"));
12364 }
12365 validate_active_capacity(
12366 layout,
12367 32u64
12368 .checked_add(parent.feedback_capacity)
12369 .ok_or_else(|| publication_input_error("active row capacity overflow"))?,
12370 )?;
12371 }
12372 for role in 1..=55u64 {
12373 if matches!(role, 1 | 3 | 14..=16 | 33 | 43 | 47 | 48 | 55) {
12374 continue;
12375 }
12376 for index in 0..parent.role_counts[role as usize - 1] {
12377 if !keys.contains(&(role, index)) {
12378 return Err(publication_input_error(
12379 "publication role lacks its actual cold owner",
12380 ));
12381 }
12382 }
12383 }
12384 Ok(())
12385}
12386
12387fn validate_text_parent(
12390 slots: &[SourceSlot; 32],
12391 prefix_extent: u64,
12392 prefix_capacity: u64,
12393 feedback_capacity: u64,
12394 max_position: u64,
12395 ring_head: u64,
12396 provenance_records: u64,
12397) -> Result<u64, SemanticTransitionError> {
12398 let invalid = |detail: &str| SemanticTransitionError::InvalidInput {
12399 detail: detail.into(),
12400 };
12401 let text_limit = prefix_capacity
12402 .checked_add(32)
12403 .ok_or_else(|| invalid("text capacity overflow"))?;
12404 if prefix_extent > prefix_capacity
12405 || ring_head >= 32
12406 || text_limit
12407 .checked_add(feedback_capacity)
12408 .is_none_or(|limit| limit > max_position)
12409 || max_position != 262144
12410 {
12411 return Err(invalid("text prefix, ring or position capacity mismatch"));
12412 }
12413 let mut positions = BTreeSet::new();
12414 let mut filled = BTreeSet::new();
12415 for slot in slots {
12416 if slot.kind > 2
12417 || (if slot.kind == 2 {
12418 slot.token != MASK_TOKEN as u64
12419 } else {
12420 slot.token >= TEXT_CARDINALITY as u64
12421 })
12422 {
12423 return Err(invalid(
12424 "text token or row kind is outside its cold contract",
12425 ));
12426 }
12427 if slot.kind == 0 {
12428 if slot.logical_position != 0
12429 || slot.provenance != 0
12430 || slot.valid != 0
12431 || slot.committed != 0
12432 || slot.recomputed != 0
12433 || slot.provenance_record != 0
12434 {
12435 return Err(invalid("padding source slot carries active metadata"));
12436 }
12437 continue;
12438 }
12439 if slot.valid != 1
12440 || slot.committed != 0
12441 || slot.recomputed > 1
12442 || slot.logical_position < prefix_extent
12443 || slot.logical_position >= text_limit
12444 || !positions.insert(slot.logical_position)
12445 {
12446 return Err(invalid(
12447 "active source slot has inconsistent position or provenance",
12448 ));
12449 }
12450 if slot.kind == 1 {
12451 if !matches!(slot.provenance, 1 | 2) || slot.provenance_record >= provenance_records {
12452 return Err(invalid(
12453 "filled source slot requires source or generated provenance",
12454 ));
12455 }
12456 filled.insert(slot.logical_position);
12457 } else if slot.provenance != 0 || slot.provenance_record != 0 || slot.recomputed != 0 {
12458 return Err(invalid(
12459 "mask source slot cannot carry filled-token coverage",
12460 ));
12461 }
12462 }
12463 let mut structural_end = prefix_extent;
12464 while filled.contains(&structural_end) {
12465 if structural_end == prefix_capacity {
12466 return Err(invalid(
12467 "contiguous source completion exceeds prefix capacity",
12468 ));
12469 }
12470 structural_end += 1;
12471 }
12472 Ok(structural_end)
12473}
12474
12475#[repr(C)]
12476#[derive(Clone, Copy)]
12477struct Descriptor {
12478 logits: u64,
12479 support: u64,
12480 scratch: u64,
12481 receipts: u64,
12482 state: u64,
12483 components: u64,
12484 codebooks: u64,
12485 arena: [u64; 7],
12486 policy: PolicyDescriptor,
12487 backward: PolicyBackward,
12488 task: u64,
12489 task_words: u64,
12490 task_return_bound: u64,
12491 publication: PublicationCommand,
12492 text: TextBinding,
12493 model_work: ModelWorkInput,
12494 replay: PreparedReplayDescriptor,
12495}
12496
12497#[derive(Clone, Copy)]
12498struct TransitionKernelPointers {
12499 logits: u64,
12500 support: u64,
12501 receipts: u64,
12502 state: u64,
12503 lease: u64,
12504 text: TextBinding,
12505 policy: PolicyDescriptor,
12506 model_work: ModelWorkInput,
12507}
12508
12509impl Descriptor {
12510 fn with_transition(mut self, original: TransitionKernelPointers) -> Self {
12511 self.logits = original.logits;
12512 self.support = original.support;
12513 self.receipts = original.receipts;
12514 self.state = original.state;
12515 self.publication.lease = original.lease;
12516 self.text = original.text;
12517 self.policy = original.policy;
12518 self.model_work = original.model_work;
12519 self
12520 }
12521}
12522
12523struct TransitionKernelIo<'a> {
12524 logits: &'a TrackedCudaSlice<f32>,
12525 support: &'a TrackedCudaSlice<u8>,
12526 receipts: &'a TrackedCudaSlice<SemanticTransitionReceipt>,
12527 state: &'a TrackedCudaSlice<DeviceState>,
12528 text: Option<&'a TextBindingStorage>,
12529 lease: Option<&'a TrackedCudaSlice<PublicationLease>>,
12530 model_work: Option<&'a PreparedModelWork>,
12531 replay_custody: Option<&'a PreparedReplayCustody>,
12532 model_update: Option<&'a PreparedModelUpdate>,
12533 training_selection: Option<&'a DeviceMemoryView<SemanticTrainingViewSelection>>,
12534 #[cfg(feature = "semantic-policy")]
12535 policy: Option<&'a PolicyStorage>,
12536}
12537
12538#[repr(C)]
12539#[derive(Clone, Copy, Default)]
12540struct PolicyField {
12541 embeddings: u64,
12542 biases: u64,
12543 cardinality: u32,
12544 null_category: i32,
12545 retained_offset: u64,
12546}
12547
12548#[repr(C)]
12549#[derive(Clone, Copy, Default)]
12550struct PolicyDescriptor {
12551 z: u64,
12552 recurrence: u64,
12553 positions: u64,
12554 hidden: u64,
12555 scores: u64,
12556 recurrent: u64,
12557 retained_scores: u64,
12558 retained_score_stride: u64,
12559 final_masks: u64,
12560 active_sets: u64,
12561 pwl_cells: u64,
12562 selected_score_vjps: u64,
12563 component_baselines: u64,
12564 fields: [PolicyField; 18],
12565 numerical: PolicyNumericalDescriptor,
12566}
12567
12568#[repr(C)]
12569#[derive(Clone, Copy, Default)]
12570struct PolicyNumericalDescriptor {
12571 parameter_errors: u64,
12572 baseline_errors: u64,
12573 parameter_domains: u64,
12574 text_domains: u64,
12575 baseline_domains: u64,
12576 hidden_errors: u64,
12577 score_errors: u64,
12578 recurrent_errors: u64,
12579 parameter_cells: u64,
12580 parameter_envelopes: u64,
12581 baseline_envelopes: u64,
12582 uniform: u64,
12583}
12584
12585#[repr(C)]
12586#[derive(Clone, Copy)]
12587struct PolicyUniformDescriptor {
12588 outputs: [u64; 3],
12589 roots: [u64; 3],
12590 recurrent: u64,
12591 hidden: u64,
12592 scores: u64,
12593 recurrent_cotangents: u64,
12594 score_cotangents: u64,
12595 score_roots: u64,
12596 status: u64,
12597 work: u64,
12598 training_rows: u64,
12599 return_bound: u64,
12600 loss_coefficients: [f64; 4],
12601}
12602
12603unsafe impl DeviceRepr for PolicyUniformDescriptor {}
12606
12607#[cfg(feature = "semantic-policy")]
12608struct PolicyUniformBuffers {
12609 descriptor: TrackedCudaSlice<PolicyUniformDescriptor>,
12610 initial_descriptor: PolicyUniformDescriptor,
12611 outputs: [TrackedCudaSlice<f64>; 3],
12612 roots: [TrackedCudaSlice<f64>; 3],
12613 scratch: [TrackedCudaSlice<f64>; 6],
12614 status: TrackedCudaSlice<u64>,
12615 work: TrackedCudaSlice<u64>,
12616 execute: CudaFunction,
12617}
12618
12619#[cfg(feature = "semantic-policy")]
12620impl PolicyUniformBuffers {
12621 fn record(&self, recorder: &mut LaunchRecorder) {
12622 recorder.read(&self.descriptor);
12623 for buffer in self.outputs.iter().chain(&self.roots).chain(&self.scratch) {
12624 recorder.read_write(buffer);
12625 }
12626 recorder.read_write(&self.status);
12627 recorder.read_write(&self.work);
12628 }
12629}
12630
12631#[repr(C)]
12632#[derive(Clone, Copy, Default)]
12633struct PolicyBackward {
12634 cotangents: u64,
12635 parameters: u64,
12636 text: u64,
12637 baselines: u64,
12638 recurrent: u64,
12639 scores: u64,
12640 status: u64,
12641 parameter_cells: u64,
12642 text_cells: u64,
12643 selection: u64,
12644 objective: u64,
12645 objective_groups: u64,
12646 objective_group_members: u64,
12647 roster_rows: u64,
12648 origin_candidate: u64,
12649 origin_lease: u64,
12650 origin_bank: u64,
12651 mode: u64,
12652 member_ordinal: u64,
12653 critic_term: u64,
12654 numerical: PolicyAdjointNumericalDescriptor,
12655}
12656
12657#[repr(C)]
12658#[derive(Clone, Copy, Default)]
12659struct PolicyAdjointNumericalDescriptor {
12660 parameter_errors: u64,
12661 text_errors: u64,
12662 baseline_errors: u64,
12663 parameter_domains: u64,
12664 text_domains: u64,
12665 baseline_domains: u64,
12666 recurrent_errors: u64,
12667 score_errors: u64,
12668 coefficient_errors: u64,
12669 parameter_cotangents: u64,
12670 text_cotangents: u64,
12671 baseline_cotangents: u64,
12672}
12673
12674#[cfg(feature = "semantic-policy")]
12675#[expect(
12676 clippy::too_many_arguments,
12677 reason = "policy VJP launch retains each original producer and destination explicitly"
12678)]
12679fn record_policy_vjp(
12680 domain: &ResidentExecutionDomain,
12681 poisoned: &mut bool,
12682 recorder: LaunchRecorder,
12683 execute: CudaFunction,
12684 descriptor: Descriptor,
12685 coefficients: &TrackedCudaSlice<f64>,
12686 score_cotangents: Option<&DeviceMemoryView<f64>>,
12687 baseline_snapshot: Option<&DeviceMemoryView<f32>>,
12688) -> Result<(), SemanticTransitionError> {
12689 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
12690 unsafe {
12696 if let Some(score_cotangents) = score_cotangents {
12697 sys::cuMemcpyDtoDAsync_v2(
12698 coefficients.device_ptr_value(),
12699 *score_cotangents.device_ptr(),
12700 COMPONENT_COUNT * 8,
12701 enqueue.stream().cu_stream(),
12702 )
12703 .result()
12704 .map_err(|error| {
12705 XlogError::Kernel(format!("policy cotangent snapshot: {error}"))
12706 })?;
12707 }
12708 if let Some(baseline_snapshot) = baseline_snapshot {
12709 sys::cuMemcpyDtoDAsync_v2(
12710 descriptor.backward.baselines,
12711 *baseline_snapshot.device_ptr(),
12712 COMPONENT_COUNT * 4,
12713 enqueue.stream().cu_stream(),
12714 )
12715 .result()
12716 .map_err(|error| XlogError::Kernel(format!("policy baseline snapshot: {error}")))?;
12717 }
12718 execute
12719 .launch_in(
12720 enqueue,
12721 LaunchConfig {
12722 grid_dim: (1, 1, 1),
12723 block_dim: (256, 1, 1),
12724 shared_mem_bytes: 0,
12725 },
12726 (descriptor,),
12727 )
12728 .map_err(|error| XlogError::Kernel(format!("policy backward launch: {error}")))?;
12729 }
12730 Ok::<(), XlogError>(())
12731 })
12732}
12733
12734#[cfg(feature = "semantic-policy")]
12737pub struct SemanticPolicyGradients {
12738 pub binding: SemanticCatalogueBinding,
12739 pub invocation: SemanticRngBinding,
12740 pub layout: SemanticPolicyLayout,
12741 pub parameters: TrackedCudaSlice<f32>,
12742 pub text_logits: TrackedCudaSlice<f32>,
12743 pub component_baselines: TrackedCudaSlice<f32>,
12744 numerical: Arc<PolicyAdjointNumerical>,
12745 provider: Arc<CudaKernelProvider>,
12746 step_aliases: Arc<()>,
12747 publication: Arc<PublicationStorage>,
12748 continuation: Arc<TextBindingStorage>,
12749 vjp_workspace: Arc<PolicyVjpWorkspace>,
12750 support_cells: usize,
12751}
12752
12753#[cfg(feature = "semantic-policy")]
12754impl SemanticPolicyGradients {
12755 pub fn into_dlpack(self) -> Result<[DlpackManagedTensor; 9], SemanticTransitionError> {
12761 let retained_owner: Arc<dyn Send + Sync> = self.vjp_workspace;
12762 export_policy_gradients(
12763 [
12764 self.parameters.into_bytes().view(),
12765 self.text_logits.into_bytes().view(),
12766 self.component_baselines.into_bytes().view(),
12767 ],
12768 &self.numerical,
12769 self.support_cells,
12770 self.layout.parameter_cells,
12771 self.provider.device().ordinal() as i32,
12772 self.step_aliases,
12773 self.publication,
12774 self.continuation,
12775 retained_owner,
12776 )
12777 }
12778}
12779
12780#[cfg(feature = "semantic-policy")]
12785pub struct SemanticSelectedPolicyGradients {
12786 pub binding: SemanticCatalogueBinding,
12787 pub invocation: SemanticRngBinding,
12788 pub layout: SemanticPolicyLayout,
12789 pub parameters: TrackedCudaSlice<f32>,
12790 pub text_logits: TrackedCudaSlice<f32>,
12791 pub component_baselines: TrackedCudaSlice<f32>,
12792 numerical: Arc<PolicyAdjointNumerical>,
12793 provider: Arc<CudaKernelProvider>,
12794 step_aliases: Arc<()>,
12795 publication: Arc<PublicationStorage>,
12796 continuation: Arc<TextBindingStorage>,
12797 vjp_workspace: Arc<PolicyVjpWorkspace>,
12798 support_cells: usize,
12799}
12800
12801#[cfg(feature = "semantic-policy")]
12805pub struct SemanticPreparedPolicyGradients {
12806 pub layout: SemanticPolicyLayout,
12807 parameters: DeviceMemoryView<f32>,
12808 text_logits: DeviceMemoryView<f32>,
12809 component_baselines: DeviceMemoryView<f32>,
12810 provider: Arc<CudaKernelProvider>,
12811 step_aliases: Arc<()>,
12812 publication: Arc<PublicationStorage>,
12813 continuation: Arc<TextBindingStorage>,
12814 owner: Arc<PolicyAdjointBuffers>,
12815 support_cells: usize,
12816}
12817
12818#[cfg(feature = "semantic-policy")]
12822pub struct SemanticPreparedGroupCritic {
12823 value: DeviceMemoryView<f32>,
12824 provider: Arc<CudaKernelProvider>,
12825 step_aliases: Arc<()>,
12826 publication: Arc<PublicationStorage>,
12827}
12828
12829#[cfg(feature = "semantic-policy")]
12830impl SemanticPreparedGroupCritic {
12831 pub fn into_dlpack(self) -> Result<DlpackManagedTensor, SemanticTransitionError> {
12832 Ok(export_owned_allocation(
12833 unsafe { self.value.cast::<u8>() }.expect("FP32 group critic byte view"),
12834 vec![1],
12835 vec![1],
12836 (2, 32),
12837 self.provider.device().ordinal() as i32,
12838 self.step_aliases,
12839 self.publication,
12840 None,
12841 None,
12842 ))
12843 }
12844}
12845
12846#[cfg(feature = "semantic-policy")]
12847impl SemanticPreparedPolicyGradients {
12848 pub fn into_dlpack(self) -> Result<[DlpackManagedTensor; 9], SemanticTransitionError> {
12849 let retained_owner: Arc<dyn Send + Sync> = self.owner.clone();
12850 let values = [self.parameters, self.text_logits, self.component_baselines].map(|view| {
12851 unsafe { view.cast::<u8>() }.expect("FP32 policy adjoint byte view")
12853 });
12854 export_policy_gradients(
12855 values,
12856 &self.owner.numerical,
12857 self.support_cells,
12858 self.layout.parameter_cells,
12859 self.provider.device().ordinal() as i32,
12860 self.step_aliases,
12861 self.publication,
12862 self.continuation,
12863 retained_owner,
12864 )
12865 }
12866}
12867
12868#[cfg(feature = "semantic-policy")]
12869impl SemanticSelectedPolicyGradients {
12870 pub fn into_dlpack(self) -> Result<[DlpackManagedTensor; 9], SemanticTransitionError> {
12874 let retained_owner: Arc<dyn Send + Sync> = self.vjp_workspace;
12875 export_policy_gradients(
12876 [
12877 self.parameters.into_bytes().view(),
12878 self.text_logits.into_bytes().view(),
12879 self.component_baselines.into_bytes().view(),
12880 ],
12881 &self.numerical,
12882 self.support_cells,
12883 self.layout.parameter_cells,
12884 self.provider.device().ordinal() as i32,
12885 self.step_aliases,
12886 self.publication,
12887 self.continuation,
12888 retained_owner,
12889 )
12890 }
12891}
12892
12893#[cfg(feature = "semantic-policy")]
12894#[expect(
12895 clippy::too_many_arguments,
12896 reason = "all exports retain one original native tape and its final-use owners"
12897)]
12898fn export_policy_gradients(
12899 values: [DeviceMemoryView<u8>; 3],
12900 numerical: &PolicyAdjointNumerical,
12901 support_cells: usize,
12902 parameter_cells: usize,
12903 device: i32,
12904 step_aliases: Arc<()>,
12905 publication: Arc<PublicationStorage>,
12906 continuation: Arc<TextBindingStorage>,
12907 owner: Arc<dyn Send + Sync>,
12908) -> Result<[DlpackManagedTensor; 9], SemanticTransitionError> {
12909 let original = policy_numerical_producer_layouts(support_cells, parameter_cells)?;
12910 let mut text_error = original[7];
12911 text_error.dimensions[2] = 2;
12912 text_error.strides_bytes = [0; 4];
12913 let text_error = canonical_tensor_layout(text_error)?;
12914 let layouts = [
12917 original[2],
12918 original[0],
12919 original[3],
12920 original[4],
12921 text_error,
12922 original[5],
12923 paired_cotangent_domain(original[6])?,
12924 paired_cotangent_domain(original[7])?,
12925 paired_cotangent_domain(original[8])?,
12926 ];
12927 let numerical_views = numerical.roots.iter().map(|buffer| {
12928 unsafe { buffer.view().cast::<u8>() }.expect("FP64 policy numerical byte view")
12930 });
12931 let tensors = values
12932 .into_iter()
12933 .chain(numerical_views)
12934 .zip(layouts)
12935 .map(|(view, layout)| {
12936 let rank = layout.rank as usize;
12937 export_owned_allocation(
12938 view,
12939 layout.dimensions[..rank]
12940 .iter()
12941 .map(|&n| n as i64)
12942 .collect(),
12943 layout.strides_bytes[..rank]
12944 .iter()
12945 .map(|&n| (n / layout.element_bytes) as i64)
12946 .collect(),
12947 (2, (layout.element_bytes * 8) as u8),
12948 device,
12949 Arc::clone(&step_aliases),
12950 Arc::clone(&publication),
12951 Some(Arc::clone(&continuation)),
12952 Some(Arc::clone(&owner)),
12953 )
12954 })
12955 .collect::<Vec<_>>();
12956 Ok(tensors
12957 .try_into()
12958 .unwrap_or_else(|_| unreachable!("nine original policy gradient exports")))
12959}
12960
12961#[cfg(feature = "semantic-policy")]
12962fn policy_producer_layouts(
12963 support_cells: usize,
12964 parameter_cells: usize,
12965) -> Result<[SemanticTensorLayout; 4], SemanticTransitionError> {
12966 let layout = |index, scalar_type, element_bytes, rank, dimensions| {
12967 canonical_tensor_layout(SemanticTensorLayout {
12968 role: 0,
12969 index,
12970 scalar_type,
12971 element_bytes,
12972 rank,
12973 dimensions,
12974 logical_axis: u64::MAX,
12975 strides_bytes: [0; 4],
12976 })
12977 };
12978 Ok([
12979 layout(0, 6, 4, 2, [32, TEXT_CARDINALITY as u64, 0, 0])?,
12980 layout(1, 8, 1, 1, [support_cells as u64, 0, 0, 0])?,
12981 layout(2, 6, 4, 1, [parameter_cells as u64, 0, 0, 0])?,
12982 layout(3, 6, 4, 2, [1, COMPONENT_COUNT as u64, 0, 0])?,
12983 ])
12984}
12985
12986#[cfg(feature = "semantic-policy")]
12987fn policy_numerical_producer_layouts(
12988 support_cells: usize,
12989 parameter_cells: usize,
12990) -> Result<[SemanticTensorLayout; 9], SemanticTransitionError> {
12991 let values = policy_producer_layouts(support_cells, parameter_cells)?;
12992 let layout = |index, rank, dimensions| {
12993 canonical_tensor_layout(SemanticTensorLayout {
12994 role: 0,
12995 index,
12996 scalar_type: 9,
12997 element_bytes: 8,
12998 rank,
12999 dimensions,
13000 logical_axis: u64::MAX,
13001 strides_bytes: [0; 4],
13002 })
13003 };
13004 Ok([
13005 values[0],
13006 values[1],
13007 values[2],
13008 values[3],
13009 layout(4, 2, [parameter_cells as u64, 2, 0, 0])?,
13010 layout(5, 3, [1, COMPONENT_COUNT as u64, 2, 0])?,
13011 layout(6, 2, [parameter_cells as u64, 4, 0, 0])?,
13012 layout(7, 3, [32, TEXT_CARDINALITY as u64, 4, 0])?,
13013 layout(8, 3, [1, COMPONENT_COUNT as u64, 4, 0])?,
13014 ])
13015}
13016
13017#[cfg(feature = "semantic-policy")]
13018struct PolicyNumericalBuffers {
13019 parameter_errors: TrackedCudaSlice<f64>,
13020 baseline_errors: TrackedCudaSlice<f64>,
13021 parameter_domains: TrackedCudaSlice<f64>,
13022 text_domains: TrackedCudaSlice<f64>,
13023 baseline_domains: TrackedCudaSlice<f64>,
13024 hidden_errors: TrackedCudaSlice<f64>,
13025 score_errors: TrackedCudaSlice<f64>,
13026 recurrent_errors: TrackedCudaSlice<f64>,
13027 parameter_envelopes: TrackedCudaSlice<f64>,
13028 baseline_envelopes: TrackedCudaSlice<f64>,
13029 uniform: Arc<PolicyUniformBuffers>,
13030}
13031
13032#[cfg(feature = "semantic-policy")]
13033fn paired_cotangent_domain(
13034 mut layout: SemanticTensorLayout,
13035) -> Result<SemanticTensorLayout, SemanticTransitionError> {
13036 let rank = layout.rank as usize;
13037 layout.dimensions.copy_within(0..rank, 1);
13038 layout.dimensions[0] = 2;
13039 layout.rank += 1;
13040 layout.strides_bytes = [0; 4];
13041 canonical_tensor_layout(layout)
13042}
13043
13044#[cfg(feature = "semantic-policy")]
13045fn enqueue_policy_uniform_domains(
13046 domain: &ResidentExecutionDomain,
13047 poisoned: &mut bool,
13048 buffers: &PolicyBuffers,
13049 components: &TrackedCudaSlice<SemanticComponent>,
13050 support: &TrackedCudaSlice<u8>,
13051) -> Result<(), SemanticTransitionError> {
13052 let mut recorder = domain.new_strict_recorder();
13053 recorder.read(&buffers.parameters);
13054 recorder.read(&buffers.component_baselines);
13055 recorder.read(components);
13056 recorder.read(support);
13057 buffers.numerical.record(&mut recorder);
13058 recorder.write(&buffers.numerical.uniform.descriptor);
13059 let descriptor = SemanticTransitionSession::retained_policy_descriptor(buffers);
13060 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
13061 unsafe {
13066 buffers.numerical.uniform.execute.clone().launch_in(
13067 enqueue,
13068 LaunchConfig {
13069 grid_dim: (1, 1, 1),
13070 block_dim: (256, 1, 1),
13071 shared_mem_bytes: 0,
13072 },
13073 (
13074 descriptor,
13075 buffers.numerical.uniform.initial_descriptor,
13076 components.device_ptr_value(),
13077 support.device_ptr_value(),
13078 ),
13079 )
13080 }
13081 .map_err(|error| XlogError::Kernel(error.to_string()))
13082 })
13083}
13084
13085#[cfg(feature = "semantic-policy")]
13086fn export_policy_uniform_domains(
13087 buffers: &PolicyBuffers,
13088 support_cells: usize,
13089 device: i32,
13090 aliases: Arc<()>,
13091 publication: Arc<PublicationStorage>,
13092) -> Result<[DlpackManagedTensor; 3], SemanticTransitionError> {
13093 let original =
13094 policy_numerical_producer_layouts(support_cells, buffers.layout.parameter_cells)?;
13095 let owner: Arc<dyn Send + Sync> = buffers.numerical.uniform.clone();
13096 let tensors = buffers
13097 .numerical
13098 .uniform
13099 .outputs
13100 .iter()
13101 .zip([original[6], original[7], original[8]])
13102 .map(|(buffer, layout)| {
13103 let layout = paired_cotangent_domain(layout)?;
13104 let rank = layout.rank as usize;
13105 let view = unsafe { buffer.view().cast::<u8>() }.expect("FP64 domain byte view");
13108 Ok(export_owned_allocation(
13109 view,
13110 layout.dimensions[..rank]
13111 .iter()
13112 .map(|&n| n as i64)
13113 .collect(),
13114 layout.strides_bytes[..rank]
13115 .iter()
13116 .map(|&n| (n / 8) as i64)
13117 .collect(),
13118 (2, 64),
13119 device,
13120 Arc::clone(&aliases),
13121 Arc::clone(&publication),
13122 None,
13123 Some(Arc::clone(&owner)),
13124 ))
13125 })
13126 .collect::<Result<Vec<_>, SemanticTransitionError>>()?;
13127 Ok(tensors
13128 .try_into()
13129 .unwrap_or_else(|_| unreachable!("three uniform domain roots")))
13130}
13131
13132#[cfg(feature = "semantic-policy")]
13133impl PolicyNumericalBuffers {
13134 fn buffers(&self) -> [&TrackedCudaSlice<f64>; 10] {
13135 [
13136 &self.parameter_errors,
13137 &self.baseline_errors,
13138 &self.parameter_domains,
13139 &self.text_domains,
13140 &self.baseline_domains,
13141 &self.hidden_errors,
13142 &self.score_errors,
13143 &self.recurrent_errors,
13144 &self.parameter_envelopes,
13145 &self.baseline_envelopes,
13146 ]
13147 }
13148
13149 fn record(&self, recorder: &mut LaunchRecorder) {
13150 for buffer in self.buffers() {
13151 recorder.read_write(buffer);
13152 }
13153 self.uniform.record(recorder);
13154 }
13155
13156 fn descriptor(&self, parameter_cells: usize) -> PolicyNumericalDescriptor {
13157 PolicyNumericalDescriptor {
13158 parameter_errors: self.parameter_errors.device_ptr_value(),
13159 baseline_errors: self.baseline_errors.device_ptr_value(),
13160 parameter_domains: self.parameter_domains.device_ptr_value(),
13161 text_domains: self.text_domains.device_ptr_value(),
13162 baseline_domains: self.baseline_domains.device_ptr_value(),
13163 hidden_errors: self.hidden_errors.device_ptr_value(),
13164 score_errors: self.score_errors.device_ptr_value(),
13165 recurrent_errors: self.recurrent_errors.device_ptr_value(),
13166 parameter_cells: parameter_cells as u64,
13167 parameter_envelopes: self.parameter_envelopes.device_ptr_value(),
13168 baseline_envelopes: self.baseline_envelopes.device_ptr_value(),
13169 uniform: self.uniform.descriptor.device_ptr_value(),
13170 }
13171 }
13172}
13173
13174#[cfg(feature = "semantic-policy")]
13175struct PolicyBuffers {
13176 layout: SemanticPolicyLayout,
13177 parameters: TrackedCudaSlice<f32>,
13178 hidden: TrackedCudaSlice<f32>,
13179 scores: TrackedCudaSlice<f32>,
13180 retained_scores: TrackedCudaSlice<f32>,
13181 final_masks: TrackedCudaSlice<u8>,
13182 active_sets: TrackedCudaSlice<u8>,
13183 pwl_cells: TrackedCudaSlice<SemanticPolicyPwlCell>,
13184 selected_score_vjps: TrackedCudaSlice<SemanticPolicySelectedScoreVjp>,
13185 recurrent: TrackedCudaSlice<f32>,
13186 text_logits: TrackedCudaSlice<f32>,
13187 component_baselines: TrackedCudaSlice<f32>,
13188 numerical: PolicyNumericalBuffers,
13189 adjoints: Option<PolicyAdjointBuffers>,
13190 temporal_adjoints: Arc<PolicyAdjointBuffers>,
13191}
13192
13193#[cfg(feature = "semantic-policy")]
13196struct PolicyAdjointBuffers {
13197 parameters: TrackedCudaSlice<f32>,
13198 text_logits: TrackedCudaSlice<f32>,
13199 component_baselines: TrackedCudaSlice<f32>,
13200 recurrent: TrackedCudaSlice<f32>,
13201 scores: TrackedCudaSlice<f32>,
13202 coefficients: TrackedCudaSlice<f64>,
13203 status: TrackedCudaSlice<u64>,
13204 numerical: Arc<PolicyAdjointNumerical>,
13205}
13206
13207#[cfg(feature = "semantic-policy")]
13208struct PolicyAdjointNumerical {
13209 roots: [TrackedCudaSlice<f64>; 6],
13210 recurrent_errors: TrackedCudaSlice<f64>,
13211 score_errors: TrackedCudaSlice<f64>,
13212 coefficient_errors: TrackedCudaSlice<f64>,
13213 root_cotangents: [TrackedCudaSlice<f64>; 3],
13214}
13215
13216#[cfg(feature = "semantic-policy")]
13217impl PolicyAdjointNumerical {
13218 fn buffers(&self) -> [&TrackedCudaSlice<f64>; 12] {
13219 [
13220 &self.roots[0],
13221 &self.roots[1],
13222 &self.roots[2],
13223 &self.roots[3],
13224 &self.roots[4],
13225 &self.roots[5],
13226 &self.recurrent_errors,
13227 &self.score_errors,
13228 &self.coefficient_errors,
13229 &self.root_cotangents[0],
13230 &self.root_cotangents[1],
13231 &self.root_cotangents[2],
13232 ]
13233 }
13234
13235 fn descriptor(&self) -> PolicyAdjointNumericalDescriptor {
13236 let pointers = self.buffers().map(TrackedCudaSlice::device_ptr_value);
13237 PolicyAdjointNumericalDescriptor {
13238 parameter_errors: pointers[0],
13239 text_errors: pointers[1],
13240 baseline_errors: pointers[2],
13241 parameter_domains: pointers[3],
13242 text_domains: pointers[4],
13243 baseline_domains: pointers[5],
13244 recurrent_errors: pointers[6],
13245 score_errors: pointers[7],
13246 coefficient_errors: pointers[8],
13247 parameter_cotangents: pointers[9],
13248 text_cotangents: pointers[10],
13249 baseline_cotangents: pointers[11],
13250 }
13251 }
13252}
13253
13254#[cfg(feature = "semantic-policy")]
13258struct PolicyVjpWorkspace {
13259 _component_baselines: Option<TrackedCudaSlice<f32>>,
13260 _recurrent: TrackedCudaSlice<f32>,
13261 _scores: TrackedCudaSlice<f32>,
13262 coefficients: TrackedCudaSlice<f64>,
13263 _status: TrackedCudaSlice<u64>,
13264 score_cotangents: Option<DeviceMemoryView<f64>>,
13265 _numerical: Arc<PolicyAdjointNumerical>,
13266}
13267
13268#[cfg(feature = "semantic-policy")]
13269struct PolicyStorage {
13270 buffers: PolicyBuffers,
13271 text_binding: Arc<TextBindingStorage>,
13272 _policy_witness: Option<SemanticTensorContentWitness>,
13273 replacement: Option<PolicyReplacement>,
13274 tape_live: bool,
13275 temporal_vjp_recorded: BTreeSet<(u64, usize)>,
13276}
13277
13278#[cfg(feature = "semantic-policy")]
13281struct PendingPolicyStorage {
13282 buffers: PolicyBuffers,
13283 replacement: PolicyReplacement,
13284 witness: Option<(SemanticTensorContentWitness, u64)>,
13285 invocation: SemanticRngBinding,
13286}
13287
13288#[cfg(feature = "semantic-policy")]
13289impl std::ops::Deref for PolicyStorage {
13290 type Target = PolicyBuffers;
13291 fn deref(&self) -> &Self::Target {
13292 &self.buffers
13293 }
13294}
13295
13296#[cfg(feature = "semantic-policy")]
13297struct PolicyProducerViews {
13298 text_logits: DeviceMemoryView<f32>,
13299 product_support: DeviceMemoryView<u8>,
13300 parameters: DeviceMemoryView<f32>,
13301 component_baselines: DeviceMemoryView<f32>,
13302 numerical: [DeviceMemoryView<f64>; 5],
13303}
13304
13305#[cfg(feature = "semantic-policy")]
13306fn policy_source_views(
13307 originals: &[PreparedSemanticTensor],
13308) -> Result<PolicyProducerViews, SemanticTransitionError> {
13309 if originals.len() != 9 {
13310 return Err(publication_input_error(
13311 "policy requires its complete original producer roster",
13312 ));
13313 }
13314 let source = |index: usize| {
13315 originals[index]
13316 .source
13317 .clone()
13318 .ok_or_else(|| publication_input_error("policy producer storage is empty"))
13319 };
13320 let text_logits = unsafe { source(0)?.cast::<f32>() }.ok_or_else(|| {
13323 publication_input_error("original text logits are not aligned F32 storage")
13324 })?;
13325 let parameters = unsafe { source(2)?.cast::<f32>() }.ok_or_else(|| {
13327 publication_input_error("original policy parameters are not aligned F32 storage")
13328 })?;
13329 let component_baselines = unsafe { source(3)?.cast::<f32>() }.ok_or_else(|| {
13332 publication_input_error("original component baselines are not aligned F32 storage")
13333 })?;
13334 let mut numerical = Vec::with_capacity(5);
13335 for index in 4..9 {
13336 numerical.push(unsafe { source(index)?.cast::<f64>() }.ok_or_else(|| {
13338 publication_input_error("original policy numerical view is not aligned F64 storage")
13339 })?);
13340 }
13341 Ok(PolicyProducerViews {
13342 text_logits,
13343 product_support: source(1)?,
13344 parameters,
13345 component_baselines,
13346 numerical: numerical
13347 .try_into()
13348 .unwrap_or_else(|_| unreachable!("five numerical producers")),
13349 })
13350}
13351
13352#[cfg(feature = "semantic-policy")]
13353fn enqueue_policy_snapshots(
13354 domain: &ResidentExecutionDomain,
13355 poisoned: &mut bool,
13356 buffers: &PolicyBuffers,
13357 support: &TrackedCudaSlice<u8>,
13358 original: &PolicyProducerViews,
13359) -> Result<(), SemanticTransitionError> {
13360 if original.text_logits.len() != buffers.text_logits.len()
13361 || original.product_support.len() != support.len()
13362 || original.parameters.len() != buffers.parameters.len()
13363 || original.component_baselines.len() != buffers.component_baselines.len()
13364 {
13365 return Err(publication_input_error(
13366 "original policy producers differ from their fixed native capacities",
13367 ));
13368 }
13369 let numerical_destinations = &buffers.numerical.buffers()[..5];
13370 if numerical_destinations
13371 .iter()
13372 .zip(&original.numerical)
13373 .any(|(destination, source)| destination.len() != source.len())
13374 {
13375 return Err(publication_input_error(
13376 "original numerical policy capacities differ",
13377 ));
13378 }
13379 let mut recorder = domain.new_strict_recorder();
13380 recorder.read(&original.text_logits);
13381 recorder.read(&original.product_support);
13382 recorder.read(&original.parameters);
13383 recorder.read(&original.component_baselines);
13384 recorder.write(&buffers.text_logits);
13385 recorder.write(support);
13386 recorder.write(&buffers.parameters);
13387 recorder.write(&buffers.component_baselines);
13388 for (destination, source) in numerical_destinations.iter().zip(&original.numerical) {
13389 recorder.read(source);
13390 recorder.write(*destination);
13391 }
13392 enqueue_recorded(domain, poisoned, recorder, |enqueue| {
13393 for (destination, source, bytes) in [
13394 (
13395 buffers.text_logits.device_ptr_value(),
13396 *original.text_logits.device_ptr(),
13397 original.text_logits.len() * 4,
13398 ),
13399 (
13400 support.device_ptr_value(),
13401 *original.product_support.device_ptr(),
13402 original.product_support.len(),
13403 ),
13404 (
13405 buffers.parameters.device_ptr_value(),
13406 *original.parameters.device_ptr(),
13407 original.parameters.len() * 4,
13408 ),
13409 (
13410 buffers.component_baselines.device_ptr_value(),
13411 *original.component_baselines.device_ptr(),
13412 original.component_baselines.len() * 4,
13413 ),
13414 ] {
13415 unsafe {
13418 sys::cuMemcpyDtoDAsync_v2(destination, source, bytes, enqueue.stream().cu_stream())
13419 }
13420 .result()
13421 .map_err(|error| XlogError::Kernel(error.to_string()))?;
13422 }
13423 for (destination, source) in numerical_destinations.iter().zip(&original.numerical) {
13424 unsafe {
13426 sys::cuMemcpyDtoDAsync_v2(
13427 destination.device_ptr_value(),
13428 *source.device_ptr(),
13429 source.len() * 8,
13430 enqueue.stream().cu_stream(),
13431 )
13432 }
13433 .result()
13434 .map_err(|error| XlogError::Kernel(error.to_string()))?;
13435 }
13436 Ok::<(), XlogError>(())
13437 })
13438}
13439
13440#[cfg(feature = "semantic-policy")]
13441struct PolicyReplacement {
13442 support: TrackedCudaSlice<u8>,
13443 receipts: TrackedCudaSlice<SemanticTransitionReceipt>,
13444 state: TrackedCudaSlice<DeviceState>,
13445}
13446
13447#[cfg(feature = "semantic-policy")]
13450struct PolicyTape {
13451 invocation: SemanticRngBinding,
13452 refusal: Option<SemanticTransitionRefusal>,
13453 binding: SemanticCatalogueBinding,
13454 policy: PolicyStorage,
13455 support: TrackedCudaSlice<u8>,
13456 receipts: TrackedCudaSlice<SemanticTransitionReceipt>,
13457 prepared_bank: Option<usize>,
13458 origin_state: Option<TrackedCudaSlice<DeviceState>>,
13461 components: DeviceMemoryView<SemanticComponent>,
13464 codebooks: DeviceMemoryView<u64>,
13465}
13466
13467#[cfg(feature = "semantic-policy")]
13468struct PolicyVjpRecording {
13469 descriptor: Descriptor,
13470 recorder: LaunchRecorder,
13471}
13472
13473#[cfg(feature = "semantic-policy")]
13474#[derive(Clone, Copy)]
13475enum PolicyVjpInput<'a> {
13476 External(&'a DeviceMemoryView<f64>),
13477 UpdateObjective {
13478 training: &'a SemanticSelectedTrainingView,
13479 origin_candidate: u64,
13480 origin_lease: &'a TrackedCudaSlice<PublicationLease>,
13481 origin_bank: usize,
13482 },
13483 GroupMember {
13484 training: &'a SemanticSelectedTrainingView,
13485 member_ordinal: u64,
13486 origin_candidate: u64,
13487 origin_lease: &'a TrackedCudaSlice<PublicationLease>,
13488 origin_bank: usize,
13489 critic_term: &'a DeviceMemoryView<f32>,
13490 },
13491 EditMember {
13492 training: &'a SemanticSelectedTrainingView,
13493 member_ordinal: u64,
13494 origin_candidate: u64,
13495 origin_lease: &'a TrackedCudaSlice<PublicationLease>,
13496 origin_bank: usize,
13497 },
13498}
13499
13500impl crate::cuda_compat::KernelParamStorage for Descriptor {
13501 fn as_kernel_param(&self) -> *mut std::ffi::c_void {
13502 (self as *const Self).cast_mut().cast()
13503 }
13504}
13505impl crate::cuda_compat::IntoKernelParamStorage for Descriptor {
13506 type Storage = Self;
13507 fn into_kernel_param_storage(self) -> Self {
13508 self
13509 }
13510}
13511
13512macro_rules! content_kernel_parameter {
13513 ($ty:ty) => {
13514 impl crate::cuda_compat::KernelParamStorage for $ty {
13515 fn as_kernel_param(&self) -> *mut std::ffi::c_void {
13516 (self as *const Self).cast_mut().cast()
13517 }
13518 }
13519 impl crate::cuda_compat::IntoKernelParamStorage for $ty {
13520 type Storage = Self;
13521 fn into_kernel_param_storage(self) -> Self {
13522 self
13523 }
13524 }
13525 };
13526}
13527content_kernel_parameter!(PublicationRange);
13528content_kernel_parameter!(SemanticTensorLayout);
13529content_kernel_parameter!(ContinuationInputs);
13530content_kernel_parameter!(PolicyDescriptor);
13531content_kernel_parameter!(prepared_replay::ReplayCopyDescriptor);
13532content_kernel_parameter!(learning_phase::FoldDeviceAssignment);
13533#[cfg(feature = "semantic-policy")]
13534content_kernel_parameter!(PolicyUniformDescriptor);
13535
13536const _: () = assert!(size_of::<PendingContinuation>() == 344);
13537const _: () = assert!(size_of::<ContinuationInputs>() == 208);
13538const _: () = assert!(size_of::<SemanticTransitionReceipt>() == 296);
13539const _: () = assert!(size_of::<SemanticTaskFacts>() == 88);
13540const _: () = assert!(size_of::<DeviceTaskEvaluation>() == 3328);
13541const _: () = assert!(size_of::<DeviceState>() == 7568);
13542const _: () = assert!(size_of::<PolicyField>() == 32);
13543const _: () = assert!(size_of::<PolicyNumericalDescriptor>() == 96);
13544const _: () = assert!(size_of::<PolicyUniformDescriptor>() == 160);
13545const _: () = assert!(size_of::<PolicyAdjointNumericalDescriptor>() == 96);
13546const _: () = assert!(size_of::<PolicyDescriptor>() == 776);
13547const _: () = assert!(size_of::<PolicyBackward>() == 256);
13548const _: () = assert!(size_of::<Descriptor>() == 1368);
13549const OBSERVATION_BYTES: usize =
13550 size_of::<DeviceState>() + COMPONENT_COUNT * size_of::<SemanticTransitionReceipt>();
13551
13552#[cfg(test)]
13553mod task_state_contract {
13554 use super::*;
13555
13556 #[test]
13557 fn text_null_requires_the_complete_singleton_receipt() {
13558 let mut receipt = SemanticTransitionReceipt {
13559 kind: COMPONENT_KIND_TEXT as u32,
13560 choice: TEXT_NULL as u32,
13561 legal_count: 1,
13562 active_count: 1,
13563 p: [1, 0, 0],
13564 q: [1, 0, 0],
13565 factor_denominator: [1, 0, 0],
13566 cdf_end: 1 << 63,
13567 mass: 1 << 63,
13568 ..SemanticTransitionReceipt::default()
13569 };
13570 assert!(canonical_text_null(&receipt));
13571 let exact = receipt;
13572 receipt.choice = 0;
13573 assert!(!canonical_text_null(&receipt));
13574 receipt = exact;
13575 receipt.p[1] = 1;
13576 assert!(!canonical_text_null(&receipt));
13577 receipt = exact;
13578 receipt.cdf_start = 1;
13579 assert!(!canonical_text_null(&receipt));
13580 receipt = exact;
13581 receipt.active_count = 2;
13582 assert!(!canonical_text_null(&receipt));
13583 receipt = exact;
13584 receipt.mass -= 1;
13585 assert!(!canonical_text_null(&receipt));
13586 }
13587
13588 #[test]
13589 fn task_state_bank_includes_actual_query_receipts() {
13590 assert_eq!(size_of::<DeviceState>(), 7568);
13591 assert_eq!(size_of::<Descriptor>(), 1368);
13592 }
13593
13594 #[test]
13595 fn ordinary_refusal_requires_original_coordinates_and_completed_cleanup() {
13596 let rng = SemanticRngBinding {
13597 model_generation: 3,
13598 family_id: 4,
13599 stream_serial: 5,
13600 proposal: 6,
13601 };
13602 let binding = SemanticActionCatalogue::current().binding();
13603 let original = DeviceState {
13604 model_generation: rng.model_generation,
13605 family_id: u32::from(rng.family_id),
13606 stream_serial: rng.stream_serial,
13607 proposal: 6,
13608 next_proposal: 6,
13609 catalogue_generation: binding.generation,
13610 catalogue_digest: binding.digest,
13611 binding_digest: binding.digest,
13612 status: 5,
13613 ..DeviceState::default()
13614 };
13615 assert_eq!(
13616 refused_terminal(&original, rng, binding, binding.digest, None).unwrap(),
13617 SemanticTransitionRefusal::NonFinitePolicyInput { completed_draws: 0 }
13618 );
13619 for mutation in 0..8 {
13620 let mut state = original;
13621 match mutation {
13622 0 => state.model_generation += 1,
13623 1 => state.family_id += 1,
13624 2 => state.stream_serial += 1,
13625 3 => state.next_proposal += 1,
13626 4 => state.blocks = COMPONENT_COUNT as u64,
13627 5 => state.importance_weight = 1.0,
13628 6 => state.cleanup_receipts[0][0] = 1,
13629 _ => state.retired_roots_mask = 4,
13630 }
13631 assert!(refused_terminal(&state, rng, binding, binding.digest, None).is_err());
13632 }
13633 for status in [0, 1, 3, 4, 6, 7, 8, 9, 10] {
13634 let mut state = original;
13635 state.status = status;
13636 assert!(refused_terminal(&state, rng, binding, binding.digest, None).is_err());
13637 }
13638 let mut state = original;
13639 state.status = 2;
13640 state.blocks = 50;
13641 assert_eq!(
13642 refused_terminal(&state, rng, binding, binding.digest, None).unwrap(),
13643 SemanticTransitionRefusal::InvalidFinalSupport {
13644 completed_draws: 50
13645 }
13646 );
13647 state.status = 11;
13648 assert!(refused_terminal(&state, rng, binding, binding.digest, None).is_err());
13649 state.execution_work.overflow = 1;
13650 assert_eq!(
13651 refused_terminal(&state, rng, binding, binding.digest, None).unwrap(),
13652 SemanticTransitionRefusal::WorkCounterOverflow {
13653 completed_draws: 50
13654 }
13655 );
13656 state.next_proposal += 1;
13657 assert!(refused_terminal(&state, rng, binding, binding.digest, None).is_err());
13658 }
13659
13660 #[test]
13661 fn refused_seal_cleanup_distinguishes_aliases_from_retired_private_roots() {
13662 let mut state = DeviceState::default();
13663 assert!(refused_root_cleanup(&state, 17, 2, 3).is_ok());
13664 state.semantic_receipts[3][33] = 1;
13665 state.semantic_receipts[3][39] = 17;
13666 state.semantic_receipts[3][1] = 2;
13667 state.semantic_receipts[3][34] = 2;
13668 state.semantic_receipts[3][35] = 3;
13669 assert!(refused_root_cleanup(&state, 17, 2, 3).is_err());
13670 state.retired_roots_mask = 1;
13671 assert!(refused_root_cleanup(&state, 17, 2, 3).is_ok());
13672 state.cleanup_receipts[1][39] = 17;
13673 assert!(
13674 refused_root_cleanup(&state, 17, 2, 3).is_err(),
13675 "base aliases are never retired"
13676 );
13677 state.semantic_receipts[3][1] = 1;
13678 state.semantic_receipts[3][34] = 7;
13679 state.cleanup_receipts[1][3] = 7;
13680 state.cleanup_receipts[1][4] = 4;
13681 assert!(refused_root_cleanup(&state, 17, 2, 3).is_ok());
13682 state.cleanup_receipts[1][4] = 3;
13683 assert!(refused_root_cleanup(&state, 17, 2, 3).is_err());
13684 state.cleanup_receipts[1][4] = 4;
13685 state.retired_roots_mask = 3;
13686 assert!(
13687 refused_root_cleanup(&state, 17, 2, 3).is_err(),
13688 "no seal exists in the other lane"
13689 );
13690 }
13691}
13692
13693#[derive(Clone, Debug, PartialEq)]
13696#[expect(
13697 clippy::large_enum_variant,
13698 reason = "published outcomes retain the original invocation owner without another allocation"
13699)]
13700pub enum SemanticTransitionOutcome {
13701 Published(SemanticTransitionObservation),
13702 Refused(SemanticTransitionRefusal),
13703}
13704
13705impl SemanticTransitionOutcome {
13706 pub fn as_published(&self) -> Result<&SemanticTransitionObservation, SemanticTransitionError> {
13709 match self {
13710 Self::Published(observation) => Ok(observation),
13711 Self::Refused(refusal) => Err(refusal.into_error()),
13712 }
13713 }
13714
13715 pub fn into_published(self) -> Result<SemanticTransitionObservation, SemanticTransitionError> {
13716 match self {
13717 Self::Published(observation) => Ok(observation),
13718 Self::Refused(refusal) => Err(refusal.into_error()),
13719 }
13720 }
13721}
13722
13723#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13725pub enum SemanticTransitionRefusal {
13726 InvalidFinalSupport {
13727 completed_draws: u64,
13728 },
13729 NonFinitePolicyInput {
13730 completed_draws: u64,
13731 },
13732 WorkCounterOverflow {
13733 completed_draws: u64,
13734 },
13735 InvalidTrainingView {
13736 status: u64,
13737 },
13738 RejectedModelUpdate {
13739 evidence: SemanticTrainingCanaryRefusalRecord,
13740 },
13741}
13742
13743impl SemanticTransitionRefusal {
13744 fn into_error(self) -> SemanticTransitionError {
13745 match self {
13746 Self::InvalidFinalSupport { completed_draws } => {
13747 SemanticTransitionError::InvalidFinalSupport { completed_draws }
13748 }
13749 Self::NonFinitePolicyInput { completed_draws } => {
13750 SemanticTransitionError::NonFinitePolicyInput { completed_draws }
13751 }
13752 Self::WorkCounterOverflow { completed_draws } => {
13753 SemanticTransitionError::WorkCounterOverflow { completed_draws }
13754 }
13755 Self::InvalidTrainingView { status } => {
13756 SemanticTransitionError::InvalidTrainingView { status }
13757 }
13758 Self::RejectedModelUpdate { evidence } => {
13759 SemanticTransitionError::RejectedModelUpdate {
13760 evidence: Box::new(evidence),
13761 }
13762 }
13763 }
13764 }
13765}
13766
13767#[cfg(feature = "semantic-policy")]
13768fn decode_canary_refusal(
13769 record: SemanticTrainingCanaryRefusalRecord,
13770 results: &[SemanticTrainingCanaryResultRecord],
13771) -> Result<Option<SemanticTrainingCanaryRefusalRecord>, SemanticTransitionError> {
13772 if record.abi != 1 {
13773 return Err(SemanticTransitionError::ObservationMismatch);
13774 }
13775 if record.reason == 0 {
13776 let success = SemanticTrainingCanaryRefusalRecord {
13777 abi: 1,
13778 ..SemanticTrainingCanaryRefusalRecord::default()
13779 };
13780 return (record == success)
13781 .then_some(None)
13782 .ok_or(SemanticTransitionError::ObservationMismatch);
13783 }
13784 let reason = record
13785 .reason()
13786 .ok_or(SemanticTransitionError::ObservationMismatch)?;
13787 let original = results
13788 .iter()
13789 .find(|result| result.kind == record.kind)
13790 .ok_or(SemanticTransitionError::ObservationMismatch)?;
13791 if original.abi != 1
13792 || original.availability > 2
13793 || original.reason != record.reason
13794 || original.row_ordinal != record.row_ordinal
13795 || original.identity != record.identity
13796 || original.measurement_bits != record.measurement_bits
13797 || original.memory_used != record.memory_used
13798 || original.work_used != record.work_used
13799 {
13800 return Err(SemanticTransitionError::ObservationMismatch);
13801 }
13802 let lower = f64::from_bits(record.lower_bound_bits);
13803 let upper = f64::from_bits(record.upper_bound_bits);
13804 let measurement = f64::from_bits(record.measurement_bits);
13805 if !(1..=5).contains(&record.kind)
13806 || !lower.is_finite()
13807 || !upper.is_finite()
13808 || lower > upper
13809 || record.memory_limit == 0
13810 || record.work_limit == 0
13811 || (original.availability == 2
13812 && match reason {
13813 SemanticTrainingCanaryRefusalReason::NonFiniteMeasurement => {
13814 measurement.is_finite()
13815 }
13816 SemanticTrainingCanaryRefusalReason::OutsideBounds => {
13817 !measurement.is_finite() || (measurement >= lower && measurement <= upper)
13818 }
13819 SemanticTrainingCanaryRefusalReason::MemoryLimitExceeded => {
13820 !measurement.is_finite()
13821 || measurement < lower
13822 || measurement > upper
13823 || record.memory_used <= record.memory_limit
13824 }
13825 SemanticTrainingCanaryRefusalReason::WorkLimitExceeded => {
13826 record.work_used <= record.work_limit
13830 }
13831 SemanticTrainingCanaryRefusalReason::IncompleteOperands
13832 | SemanticTrainingCanaryRefusalReason::ProtectedRetentionLost
13833 | SemanticTrainingCanaryRefusalReason::GoalWitnessInvalid
13834 | SemanticTrainingCanaryRefusalReason::WorkOverflow
13835 | SemanticTrainingCanaryRefusalReason::GenerationMismatch => false,
13836 })
13837 {
13838 return Err(SemanticTransitionError::ObservationMismatch);
13839 }
13840 Ok(Some(record))
13841}
13842
13843fn refused_terminal(
13844 state: &DeviceState,
13845 rng: SemanticRngBinding,
13846 catalogue: SemanticCatalogueBinding,
13847 binding_digest: Identity256,
13848 canary_refusal: Option<SemanticTrainingCanaryRefusalRecord>,
13849) -> Result<SemanticTransitionRefusal, SemanticTransitionError> {
13850 if state.model_generation != rng.model_generation
13851 || state.family_id != u32::from(rng.family_id)
13852 || state.stream_serial != rng.stream_serial
13853 || state.proposal != u64::from(rng.proposal)
13854 || state.next_proposal != state.proposal
13855 || state.blocks >= COMPONENT_COUNT as u64
13856 || state.catalogue_generation != catalogue.generation
13857 || state.catalogue_digest != catalogue.digest
13858 || state.binding_digest != binding_digest
13859 || state.importance_weight != 0.0
13860 || state.retired_roots_mask & !3 != 0
13861 || state.cleanup_receipts.iter().any(|receipt| receipt[0] != 0)
13862 {
13863 return Err(SemanticTransitionError::ObservationMismatch);
13864 }
13865 match state.status {
13866 2 => Ok(SemanticTransitionRefusal::InvalidFinalSupport {
13867 completed_draws: state.blocks,
13868 }),
13869 5 => Ok(SemanticTransitionRefusal::NonFinitePolicyInput {
13870 completed_draws: state.blocks,
13871 }),
13872 11 if state.execution_work.overflow == 1 => {
13873 Ok(SemanticTransitionRefusal::WorkCounterOverflow {
13874 completed_draws: state.blocks,
13875 })
13876 }
13877 12..=14 if state.execution_work.overflow == 0 && state.blocks == 0 => {
13878 Ok(SemanticTransitionRefusal::InvalidTrainingView {
13879 status: state.status - 11,
13880 })
13881 }
13882 15 if state.execution_work.overflow == 0 && state.blocks == 0 => {
13883 Ok(SemanticTransitionRefusal::RejectedModelUpdate {
13884 evidence: canary_refusal.ok_or(SemanticTransitionError::ObservationMismatch)?,
13885 })
13886 }
13887 _ => Err(SemanticTransitionError::ObservationMismatch),
13888 }
13889}
13890
13891fn refused_root_cleanup(
13892 state: &DeviceState,
13893 owner: u64,
13894 base_slot: u64,
13895 base_generation: u64,
13896) -> Result<(), SemanticTransitionError> {
13897 let mismatch = || SemanticTransitionError::ObservationMismatch;
13898 let cleanup = &state.cleanup_receipts[0];
13902 if cleanup.iter().any(|&word| word != 0) && (cleanup[0] != 0 || cleanup[39] != owner) {
13903 return Err(mismatch());
13904 }
13905 for lane in 0..2 {
13906 let sealed = &state.semantic_receipts[3 + lane * 3];
13907 let cleanup = &state.cleanup_receipts[1 + lane];
13908 let consumed = state.retired_roots_mask & (1 << lane) != 0;
13909 if sealed[0] != 0 || sealed[33] != 1 {
13911 if consumed || cleanup.iter().any(|&word| word != 0) {
13912 return Err(mismatch());
13913 }
13914 continue;
13915 }
13916 if !consumed || sealed[39] != owner {
13917 return Err(mismatch());
13918 }
13919 match sealed[1] {
13920 2 if sealed[34] == base_slot
13923 && sealed[35] == base_generation
13924 && cleanup.iter().all(|&word| word == 0) => {}
13925 1 if cleanup[0] == 0
13926 && cleanup[1] == 0
13927 && cleanup[39] == owner
13928 && cleanup[3] == sealed[34]
13929 && sealed[35].checked_add(1) == Some(cleanup[4]) => {}
13930 _ => return Err(mismatch()),
13931 }
13932 }
13933 Ok(())
13934}
13935
13936#[derive(Clone, Debug, PartialEq)]
13937pub struct SemanticTransitionObservation {
13938 pub components: Vec<SemanticTransitionReceipt>,
13939 pub root_handle: SemanticRootHandle,
13940 pub root: SemanticRootSnapshot,
13941 pub next_proposal: u64,
13942 pub lanes: [SemanticTransitionLane; 2],
13943 pub importance_weight: f64,
13947 pub task_evaluation: Option<SemanticTaskEvaluation>,
13949}
13950
13951#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13953pub enum SemanticTaskRefusal {
13954 Scope,
13955 HardConstraint,
13956 FactCapacity,
13957 FuelExhausted,
13958}
13959
13960impl SemanticTaskRefusal {
13961 pub const fn canonical_kind(self) -> &'static str {
13962 match self {
13963 Self::Scope => "task-scope",
13964 Self::HardConstraint => "hard-constraint",
13965 Self::FactCapacity => "fact-capacity",
13966 Self::FuelExhausted => "fuel-exhausted",
13967 }
13968 }
13969}
13970
13971#[derive(Clone, Debug, PartialEq, Eq)]
13974pub struct SemanticTaskEvaluation {
13975 pub binding: Identity256,
13976 pub query_count: u64,
13977 pub winner: u64,
13978 pub return_value: i64,
13979 pub facts: [SemanticTaskFacts; 3],
13980}
13981
13982#[derive(Clone, Debug, PartialEq, Eq)]
13985pub struct SemanticTransitionLane {
13986 pub root: Option<Result<(SemanticRootHandle, SemanticRootSnapshot), SemanticHypergraphError>>,
13989 pub task_refusal: Option<SemanticTaskRefusal>,
13990 pub program_rules: [Option<crate::SemanticProgramRule>; 2],
13993 pub edits: [Result<Option<SemanticInsertOutcome>, SemanticHypergraphError>; 2],
13994 pub work: SemanticTransitionWork,
13996}
13997
13998#[repr(C)]
14001#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
14002pub struct SemanticTransitionWork {
14003 pub edit_commands: u64,
14006 pub added_supports: u64,
14009 pub defined_truth_changes: u64,
14012}
14013
14014impl SemanticTransitionWork {
14015 #[cfg(any(test, feature = "semantic-policy"))]
14016 fn raw_structural_cost(self) -> u64 {
14017 self.edit_commands + self.added_supports + self.defined_truth_changes
14018 }
14019
14020 fn is_valid(self, editable_program: bool) -> bool {
14021 if self.edit_commands > 2 {
14022 return false;
14023 }
14024 if editable_program {
14025 self.added_supports <= crate::semantic_program::RESIDENT_PROGRAM_FACT_CAPACITY as u64
14026 && self.defined_truth_changes <= 3
14027 && (self.edit_commands != 0
14028 || (self.added_supports == 0 && self.defined_truth_changes == 0))
14029 } else {
14030 self.added_supports <= self.edit_commands
14031 && self.defined_truth_changes <= self.added_supports
14032 }
14033 }
14034}
14035
14036#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14039pub struct SemanticTransitionHostIoStats {
14040 pub htod_bytes: u64,
14041 pub dtoh_bytes: u64,
14042 pub htod_calls: u64,
14043 pub dtoh_calls: u64,
14044 pub launch_metadata_bytes: u64,
14045 pub launch_metadata_calls: u64,
14046 pub metadata_dtoh_calls: u64,
14047 pub observation_bytes: u64,
14048 pub observation_calls: u64,
14049 pub session_stream_waits: u64,
14050}
14051
14052#[derive(Clone, Debug, PartialEq, Eq)]
14053pub enum SemanticTransitionError {
14054 CatalogueMismatch,
14055 InvalidInput {
14056 detail: String,
14057 },
14058 InvalidFinalSupport {
14059 completed_draws: u64,
14060 },
14061 NonFinitePolicyInput {
14062 completed_draws: u64,
14063 },
14064 WorkCounterOverflow {
14065 completed_draws: u64,
14066 },
14067 InvalidPolicyGradient {
14068 status: u64,
14069 },
14070 InvalidTrainingView {
14071 status: u64,
14072 },
14073 RejectedModelUpdate {
14074 evidence: Box<SemanticTrainingCanaryRefusalRecord>,
14075 },
14076 InvalidTaskBank,
14077 InvalidTaskBase,
14078 TaskOwnerFailure,
14079 PublicationRefused {
14080 status: u64,
14081 },
14082 OverlappingInputs,
14083 OverlappingLaunch,
14084 UnconsumedPolicyTape,
14085 UnpublishedTask,
14086 NotBound,
14087 NotCaptured,
14088 NoPendingLaunch,
14089 GenerationExhausted,
14090 ObservationMismatch,
14091 Poisoned,
14092 Semantic(SemanticHypergraphError),
14093 Runtime {
14094 operation: &'static str,
14095 detail: String,
14096 },
14097}
14098
14099impl fmt::Display for SemanticTransitionError {
14100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14101 write!(f, "{self:?}")
14102 }
14103}
14104impl std::error::Error for SemanticTransitionError {}
14105
14106fn runtime_error(operation: &'static str, error: impl fmt::Display) -> SemanticTransitionError {
14107 SemanticTransitionError::Runtime {
14108 operation,
14109 detail: error.to_string(),
14110 }
14111}
14112
14113struct PinnedObservation {
14115 buffer: crate::device::PinnedHostBuffer,
14116}
14117
14118impl PinnedObservation {
14119 fn new(stream: Arc<CudaStream>) -> Result<Self, SemanticTransitionError> {
14120 Ok(Self {
14121 buffer: crate::device::PinnedHostBuffer::new(&stream, OBSERVATION_BYTES)
14122 .map_err(|error| runtime_error("pinned observation allocation", error))?,
14123 })
14124 }
14125
14126 fn enqueue_copy(&mut self, state: u64, receipts: u64, stream: &CudaStream) -> XlogResult<()> {
14127 unsafe {
14130 self.buffer.enqueue(stream, |ptr| {
14131 for (offset, source, len) in [
14132 (0, state, size_of::<DeviceState>()),
14133 (
14134 size_of::<DeviceState>(),
14135 receipts,
14136 OBSERVATION_BYTES - size_of::<DeviceState>(),
14137 ),
14138 ] {
14139 let code = {
14142 sys::cuMemcpyDtoHAsync_v2(
14143 ptr.add(offset).cast(),
14144 source,
14145 len,
14146 stream.cu_stream(),
14147 )
14148 };
14149 code.result()?;
14150 }
14151 Ok(())
14152 })
14153 }
14154 .map_err(|error| XlogError::Kernel(format!("semantic final observation copy: {error}")))
14155 }
14156
14157 unsafe fn read(
14159 &mut self,
14160 ) -> Result<(DeviceState, Vec<SemanticTransitionReceipt>), SemanticTransitionError> {
14161 let bytes = unsafe { self.buffer.read_vec::<u8>(OBSERVATION_BYTES) }
14163 .map_err(|error| runtime_error("pinned observation read", error))?;
14164 let state = unsafe { bytes.as_ptr().cast::<DeviceState>().read_unaligned() };
14167 let components = (0..COMPONENT_COUNT)
14168 .map(|i| unsafe {
14169 bytes
14170 .as_ptr()
14171 .add(size_of::<DeviceState>() + i * size_of::<SemanticTransitionReceipt>())
14172 .cast::<SemanticTransitionReceipt>()
14173 .read_unaligned()
14174 })
14175 .collect();
14176 Ok((state, components))
14177 }
14178}
14179
14180pub struct SemanticTransitionSession {
14183 captured: Option<CapturedCudaGraph>,
14185 domain: ResidentExecutionDomain,
14186 stream: Arc<CudaStream>,
14187 graph: std::mem::ManuallyDrop<SemanticHypergraph>,
14188 root: SemanticRootHandle,
14189 base_snapshot: SemanticRootSnapshot,
14190 codebooks: ActionCodebooks,
14191 device_codebooks: TrackedCudaSlice<u64>,
14192 device_components: TrackedCudaSlice<SemanticComponent>,
14193 task: Option<(TaskEvaluationBinding, TrackedCudaSlice<u64>)>,
14195 cold_content: Option<(SemanticTaskContentIdentity, [crate::SemanticTruth; 3])>,
14198 initial_prefill: Option<InitialPrefillStage>,
14199 retained_initial_prefill: Option<RetainedInitialPrefillContent>,
14200 checkpoint_initial_prefill: Option<CheckpointInitialPrefill>,
14201 training_views: Option<Arc<SemanticTrainingViewArena>>,
14202 training_origins: Option<Arc<TrackedCudaSlice<SemanticTrainingViewOriginRecord>>>,
14203 task_epoch: u64,
14204 task_observed: bool,
14207 publication: Option<Arc<PublicationStorage>>,
14208 learning_phases: Vec<SemanticLearningPhaseRecord>,
14209 publication_uploads: Vec<(usize, PublicationPayload)>,
14210 publication_issuer: Arc<()>,
14211 readers: BTreeMap<u64, PublishedReader>,
14212 steps: BTreeMap<u64, StepContentStorage>,
14213 prepared_segment: Option<PreparedSegmentState>,
14214 prepared_resources: Vec<Arc<dyn Send + Sync>>,
14215 next_reader: u64,
14216 continuation_base: Option<u64>,
14217 text_binding: Option<Arc<TextBindingStorage>>,
14218 admitted_transition: Option<(u64, u64, SemanticTransitionKind)>,
14219 release_events: Vec<cudarc::driver::CudaEvent>,
14220 logits: TrackedCudaSlice<f32>,
14221 support: TrackedCudaSlice<u8>,
14222 scratch: TrackedCudaSlice<u64>,
14223 receipts: TrackedCudaSlice<SemanticTransitionReceipt>,
14224 state: TrackedCudaSlice<DeviceState>,
14225 pinned: PinnedObservation,
14226 execute: CudaFunction,
14227 #[cfg(feature = "semantic-policy")]
14228 policy: Option<PolicyStorage>,
14229 #[cfg(feature = "semantic-policy")]
14230 pending_policy: Option<PendingPolicyStorage>,
14231 #[cfg(feature = "semantic-policy")]
14232 policy_tapes: Vec<PolicyTape>,
14233 rng: Option<SemanticRngBinding>,
14234 next_proposal: u64,
14235 pending: bool,
14236 poisoned: bool,
14237 stream_waits: u64,
14238 provider: Arc<CudaKernelProvider>,
14240}
14241
14242#[derive(Clone, Debug)]
14247#[expect(
14248 clippy::large_enum_variant,
14249 reason = "completed outcomes retain their original invocation and step owners"
14250)]
14251pub enum SemanticPreparedStepOutcome {
14252 Skipped {
14253 step: SemanticPreparedStep,
14254 status: u64,
14255 },
14256 Completed {
14257 step: SemanticPreparedStep,
14258 invocation: SemanticRngBinding,
14259 bank: u8,
14260 transition: SemanticTransitionKind,
14261 outcome: SemanticTransitionOutcome,
14262 },
14263}
14264
14265const _: () = assert!(
14266 size_of::<PreparedStepResult>()
14267 == size_of::<PublicationHeader>() + 32 + size_of::<AttemptReceipt>()
14268);
14269
14270fn prepared_step_allocation_bytes(
14271 input_bytes: usize,
14272 feedback_bytes: usize,
14273 policy_bytes: usize,
14274) -> Result<u64, SemanticTransitionError> {
14275 [
14276 size_of::<PublicationLease>(),
14277 size_of::<PreparedStepResult>(),
14278 input_bytes,
14279 feedback_bytes,
14280 policy_bytes,
14281 ]
14282 .into_iter()
14283 .try_fold(0usize, |sum, bytes| {
14284 sum.checked_add(bytes)
14285 .ok_or(SemanticTransitionError::GenerationExhausted)
14286 })
14287 .and_then(|bytes| {
14288 u64::try_from(bytes).map_err(|_| SemanticTransitionError::GenerationExhausted)
14289 })
14290}
14291
14292fn prepared_segment_allocation_bytes(
14293 step_bytes: u64,
14294 transition_bound: usize,
14295 training_origin_bytes: usize,
14296) -> Result<u64, SemanticTransitionError> {
14297 if transition_bound == 0 {
14298 return Err(publication_input_error(
14299 "a prepared segment requires a positive transition bound",
14300 ));
14301 }
14302 u64::try_from(transition_bound)
14303 .ok()
14304 .and_then(|bound| step_bytes.checked_mul(bound))
14305 .and_then(|bytes| {
14306 u64::try_from(training_origin_bytes)
14307 .ok()
14308 .and_then(|origin_bytes| bytes.checked_add(origin_bytes))
14309 })
14310 .ok_or(SemanticTransitionError::GenerationExhausted)
14311}
14312
14313#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14317pub struct SemanticSegmentColdCapacity {
14318 pub tensor_content_capacity: usize,
14319 pub model_work_capacity: usize,
14320 pub segment_capacity_bytes: u64,
14321 pub other_external_cuda_bytes: u64,
14322}
14323
14324impl SemanticSegmentColdCapacity {
14325 fn external_floor(self) -> Result<u64, SemanticTransitionError> {
14326 if self.tensor_content_capacity == 0
14327 || self.model_work_capacity == 0
14328 || self.segment_capacity_bytes == 0
14329 {
14330 return Err(publication_input_error(
14331 "prepared segment requires positive frozen native capacities and external slab bytes",
14332 ));
14333 }
14334 self.segment_capacity_bytes
14335 .checked_add(self.other_external_cuda_bytes)
14336 .ok_or(SemanticTransitionError::GenerationExhausted)
14337 }
14338
14339 fn content_cells(self) -> Result<usize, SemanticTransitionError> {
14340 self.tensor_content_capacity
14341 .checked_mul(4)
14342 .ok_or(SemanticTransitionError::GenerationExhausted)
14343 }
14344
14345 fn content_bytes(self) -> Result<u64, SemanticTransitionError> {
14346 self.content_cells()?
14347 .checked_mul(size_of::<u64>())
14348 .and_then(|bytes| u64::try_from(bytes).ok())
14349 .ok_or(SemanticTransitionError::GenerationExhausted)
14350 }
14351
14352 fn model_work_bytes(self) -> Result<u64, SemanticTransitionError> {
14353 self.model_work_capacity
14354 .checked_mul(size_of::<ModelWorkEvent>() + 3 * size_of::<u64>())
14355 .and_then(|bytes| u64::try_from(bytes).ok())
14356 .ok_or(SemanticTransitionError::GenerationExhausted)
14357 }
14358
14359 fn late_native_bytes(self, steps: usize) -> Result<u64, SemanticTransitionError> {
14360 self.content_bytes()?
14361 .checked_add(self.model_work_bytes()?)
14362 .and_then(|bytes| bytes.checked_mul(u64::try_from(steps).ok()?))
14363 .ok_or(SemanticTransitionError::GenerationExhausted)
14364 }
14365}
14366
14367#[cfg(feature = "semantic-policy")]
14368fn policy_buffer_bytes(
14369 layout: &SemanticPolicyLayout,
14370 mask_cells: usize,
14371) -> Result<usize, SemanticTransitionError> {
14372 let differentiable_cells = [
14373 layout.parameter_cells,
14374 layout.score_cells(),
14375 layout.recurrent_cells(),
14376 32 * TEXT_CARDINALITY,
14377 ]
14378 .into_iter()
14379 .try_fold(0usize, |sum, cells| {
14380 sum.checked_add(cells)
14381 .ok_or(SemanticTransitionError::GenerationExhausted)
14382 })?;
14383 let primal_cells = differentiable_cells
14384 .checked_add(layout.retained_score_cells())
14385 .ok_or(SemanticTransitionError::GenerationExhausted)?;
14386 let adjoint_cells = differentiable_cells
14387 .checked_add(COMPONENT_COUNT)
14388 .ok_or(SemanticTransitionError::GenerationExhausted)?;
14389 let adjoint_cells = adjoint_cells
14390 .checked_mul(2)
14391 .ok_or(SemanticTransitionError::GenerationExhausted)?;
14392 let numerical_cells = [
14393 (layout.parameter_cells, 9usize),
14395 (COMPONENT_COUNT, 9),
14396 (32 * TEXT_CARDINALITY, 4),
14397 (128, 3),
14398 (layout.score_cells(), 3),
14399 (layout.recurrent_cells(), 3),
14400 ]
14401 .into_iter()
14402 .try_fold(0usize, |total, (cells, width)| {
14403 cells
14404 .checked_mul(width)
14405 .and_then(|cells| total.checked_add(cells))
14406 .ok_or(SemanticTransitionError::GenerationExhausted)
14407 })?;
14408 let adjoint_numerical_cells = differentiable_cells
14409 .checked_add(COMPONENT_COUNT)
14410 .and_then(|cells| cells.checked_mul(8))
14411 .and_then(|cells| {
14412 layout
14413 .parameter_cells
14414 .checked_add(32 * TEXT_CARDINALITY)
14415 .and_then(|roots| roots.checked_add(COMPONENT_COUNT))
14416 .and_then(|roots| roots.checked_mul(10))
14419 .and_then(|roots| cells.checked_add(roots))
14420 })
14421 .and_then(|cells| cells.checked_add(8 * COMPONENT_COUNT))
14422 .and_then(|cells| cells.checked_mul(2))
14423 .ok_or(SemanticTransitionError::GenerationExhausted)?;
14424 let numerical_cells = numerical_cells
14425 .checked_add(adjoint_numerical_cells)
14426 .ok_or(SemanticTransitionError::GenerationExhausted)?;
14427 let uniform_cells = layout
14428 .parameter_cells
14429 .checked_add(COMPONENT_COUNT)
14430 .and_then(|cells| cells.checked_mul(2))
14431 .and_then(|cells| cells.checked_add(33 * TEXT_CARDINALITY))
14434 .and_then(|cells| cells.checked_mul(8))
14436 .and_then(|cells| cells.checked_add(layout.recurrent_cells() * 12))
14437 .and_then(|cells| cells.checked_add(layout.score_cells() * 12))
14438 .and_then(|cells| cells.checked_add(128 * 4 + COMPONENT_COUNT * 8))
14439 .ok_or(SemanticTransitionError::GenerationExhausted)?;
14440 let numerical_cells = numerical_cells
14441 .checked_add(uniform_cells)
14442 .ok_or(SemanticTransitionError::GenerationExhausted)?;
14443 primal_cells
14444 .checked_add(adjoint_cells)
14449 .and_then(|cells| cells.checked_add(128))
14450 .and_then(|cells| cells.checked_add(COMPONENT_COUNT))
14451 .and_then(|cells| cells.checked_mul(size_of::<f32>()))
14452 .and_then(|bytes| bytes.checked_add(2 * COMPONENT_COUNT * size_of::<f64>()))
14453 .and_then(|bytes| bytes.checked_add(2 * size_of::<u64>()))
14454 .and_then(|bytes| {
14455 bytes.checked_add(12 * size_of::<u64>() + size_of::<PolicyUniformDescriptor>())
14456 })
14457 .and_then(|bytes| {
14458 numerical_cells
14459 .checked_mul(8)
14460 .and_then(|extra| bytes.checked_add(extra))
14461 })
14462 .and_then(|bytes| bytes.checked_add(COMPONENT_COUNT * size_of::<SemanticPolicyPwlCell>()))
14463 .and_then(|bytes| {
14464 bytes.checked_add(COMPONENT_COUNT * size_of::<SemanticPolicySelectedScoreVjp>())
14465 })
14466 .and_then(|bytes| {
14467 mask_cells
14468 .checked_mul(2)
14469 .and_then(|masks| bytes.checked_add(masks))
14470 })
14471 .ok_or(SemanticTransitionError::GenerationExhausted)
14472}
14473
14474fn validate_rebinding_ownership(
14475 prepared_segment: Option<&PreparedSegmentState>,
14476 unreconciled_acquisition: bool,
14477) -> Result<(), SemanticTransitionError> {
14478 if prepared_segment.is_some() {
14479 return Err(publication_input_error(
14480 "a prepared segment still owns its executable and native resources",
14481 ));
14482 }
14483 if unreconciled_acquisition {
14484 return Err(publication_input_error(
14485 "an unreconciled acquisition still owns its native step",
14486 ));
14487 }
14488 Ok(())
14489}
14490
14491fn validate_prepared_completion(
14492 lease: &PublicationLease,
14493 parent: &PublicationHeader,
14494 result: &PreparedStepResult,
14495 instance: Identity256,
14496) -> Result<SemanticTransitionKind, SemanticTransitionError> {
14497 if lease.abi != 1
14498 || lease.status != 0
14499 || lease.active != 0
14500 || lease.instance != instance
14501 || lease.bank > 1
14502 || lease.bank != lease.word & 1
14503 || lease.epoch != lease.word >> 1
14504 || parent.abi != 1
14505 || parent.instance != instance
14506 || parent.publication_word != lease.word
14507 || parent.sealed_epoch != lease.epoch
14508 || result.abi != 1
14509 || result.header.abi != 1
14510 || result.header.instance != instance
14511 || result.header.publication_word != result.word
14512 || result.header.sealed_epoch != result.word >> 1
14513 || result.advanced > 1
14514 || result.advanced != u64::from(result.word != lease.word && result.refusal == 0)
14515 {
14516 return Err(SemanticTransitionError::ObservationMismatch);
14517 }
14518 if result.word != lease.word {
14519 let epoch = lease
14520 .epoch
14521 .checked_add(1)
14522 .filter(|&epoch| epoch <= u64::MAX >> 1)
14523 .ok_or(SemanticTransitionError::ObservationMismatch)?;
14524 if result.word != (epoch << 1) | ((lease.word ^ 1) & 1)
14525 || result.header.base_word != lease.word
14526 || result.attempt.abi != 2
14527 || result.attempt.transition_kind != lease.transition_kind
14528 || result.attempt.instance != result.header.instance
14529 || result.attempt.base_word != lease.word
14530 || result.attempt.next_word != result.word
14531 || result.attempt.logical_digest != result.header.logical_digest
14532 {
14533 return Err(SemanticTransitionError::ObservationMismatch);
14534 }
14535 } else if result.attempt != AttemptReceipt::default() {
14536 return Err(SemanticTransitionError::ObservationMismatch);
14537 }
14538 match lease.transition_kind {
14539 1 => Ok(SemanticTransitionKind::Proposal),
14540 2 => Ok(SemanticTransitionKind::Recompute),
14541 3 => Ok(SemanticTransitionKind::Drain),
14542 4 => Ok(SemanticTransitionKind::Update),
14543 _ => Err(SemanticTransitionError::ObservationMismatch),
14544 }
14545}
14546
14547#[cfg(feature = "semantic-policy")]
14548impl SemanticTransitionSession {
14549 pub fn launch_prepared_segment(
14552 &mut self,
14553 authority_decisions: Vec<u8>,
14554 ) -> Result<(), SemanticTransitionError> {
14555 self.ensure_quiescent()?;
14556 let storage = Arc::clone(
14557 self.publication
14558 .as_ref()
14559 .ok_or(SemanticTransitionError::NotBound)?,
14560 );
14561 let build = self
14562 .prepared_segment
14563 .as_ref()
14564 .ok_or(SemanticTransitionError::NotCaptured)?;
14565 if !build.finished
14566 || build.submitted
14567 || self.captured.is_none()
14568 || authority_decisions.is_empty()
14569 {
14570 return Err(publication_input_error(
14571 "prepared submission requires one unused graph and fresh canonical authority bytes",
14572 ));
14573 }
14574 for token in &build.tokens {
14575 let prepared = self
14576 .steps
14577 .get(token)
14578 .and_then(|step| step.prepared.as_ref())
14579 .ok_or(SemanticTransitionError::ObservationMismatch)?;
14580 if prepared.transition_recorded != PREPARED_TRANSITION_BANKS
14581 || prepared.branches.iter().any(|branch| {
14582 branch.continuation.as_ref().is_none_or(|continuation| {
14583 continuation.inputs.authority_bytes != authority_decisions.len() as u64
14584 })
14585 })
14586 {
14587 return Err(publication_input_error(
14588 "fresh authority snapshot differs from the captured continuation byte extent",
14589 ));
14590 }
14591 }
14592 let authority = storage
14593 .continuation_templates
14594 .iter()
14595 .find(|range| range.role == 39 && range.index == 0)
14596 .ok_or(SemanticTransitionError::ObservationMismatch)?;
14597 let slot = usize::try_from(authority.storage_slot)
14598 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
14599 let destination = storage
14600 .allocations
14601 .get(slot)
14602 .ok_or(SemanticTransitionError::ObservationMismatch)?;
14603 if authority.offset_bytes != 0 || authority_decisions.len() > destination.len() {
14604 return Err(publication_input_error(
14605 "fresh authority snapshot exceeds its original fixed allocation",
14606 ));
14607 }
14608 let recorder = self.prepared_segment_recorder()?;
14609 self.prepared_segment
14610 .as_mut()
14611 .expect("checked segment")
14612 .submit()?;
14613 self.publication_uploads = vec![(slot, PublicationPayload::Metadata(authority_decisions))];
14614 let result = (|| {
14615 let PublicationPayload::Metadata(bytes) = &self.publication_uploads[0].1 else {
14616 unreachable!("owned authority metadata")
14617 };
14618 let mut destination = storage.allocations[slot].view().slice(..bytes.len());
14619 self.provider
14620 .htod_launch_metadata_sync_copy_into(bytes, &mut destination)
14621 .map_err(|error| runtime_error("prepared fresh authority upload", error))?;
14622 let graph = self
14623 .captured
14624 .as_ref()
14625 .expect("checked original captured graph");
14626 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
14627 graph.launch_in(enqueue)
14628 })
14629 })();
14630 if result.is_err() {
14631 self.poisoned = true;
14632 return result;
14633 }
14634 self.pending = true;
14635 Ok(())
14636 }
14637
14638 pub fn prepared_segment_completion_known(&self) -> bool {
14642 self.prepared_segment
14643 .as_ref()
14644 .is_some_and(|build| build.completed)
14645 }
14646
14647 pub fn complete_prepared_segment(
14648 &mut self,
14649 ) -> Result<Vec<SemanticPreparedStepOutcome>, SemanticTransitionError> {
14650 if self.is_poisoned() {
14651 return Err(SemanticTransitionError::Poisoned);
14652 }
14653 if !self.pending
14654 || !self
14655 .prepared_segment
14656 .as_ref()
14657 .is_some_and(|build| build.submitted && !build.completed)
14658 {
14659 return Err(SemanticTransitionError::NoPendingLaunch);
14660 }
14661 let result = self.complete_prepared_segment_inner();
14662 if result.is_err() {
14663 self.poisoned = true;
14664 } else {
14665 self.pending = false;
14666 self.publication_uploads.clear();
14667 self.continuation_base = None;
14668 self.admitted_transition = None;
14669 self.text_binding = None;
14670 }
14671 result
14672 }
14673
14674 fn complete_prepared_segment_inner(
14675 &mut self,
14676 ) -> Result<Vec<SemanticPreparedStepOutcome>, SemanticTransitionError> {
14677 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
14678 .map_err(|error| runtime_error("prepared completion stream admission", error))?;
14679 wait_on_stream(
14680 &self.stream,
14681 &mut self.poisoned,
14682 &mut self.stream_waits,
14683 "prepared graph terminal wait",
14684 CudaStream::synchronize,
14685 )?;
14686 let handles = self
14687 .prepared_segment
14688 .as_ref()
14689 .expect("submitted segment")
14690 .handles()?;
14691 let storage = Arc::clone(
14692 self.publication
14693 .as_ref()
14694 .ok_or(SemanticTransitionError::NotBound)?,
14695 );
14696 let mut outcomes = Vec::new();
14697 outcomes
14698 .try_reserve_exact(handles.len())
14699 .map_err(|error| runtime_error("prepared outcome reservation", error))?;
14700 let mut previous = None;
14701 for step in handles {
14702 let prepared = self.steps[&step.token]
14703 .prepared
14704 .as_ref()
14705 .ok_or(SemanticTransitionError::ObservationMismatch)?;
14706 let reader = prepared.reader.view();
14707 let result_view = prepared.result.view();
14708 let lease = self.publication_read(reader)?[0];
14709 let result = self.publication_read(result_view)?[0];
14710 if result.abi == 0 {
14711 if lease.active != 0
14712 || lease.abi != 0
14713 || lease.transition_kind != 0
14714 || !matches!(lease.status, 1..=5 | 7)
14715 {
14716 return Err(SemanticTransitionError::ObservationMismatch);
14717 }
14718 #[cfg(feature = "semantic-policy")]
14719 let token = step.token;
14720 let outcome = SemanticPreparedStepOutcome::Skipped {
14721 step,
14722 status: lease.status,
14723 };
14724 #[cfg(feature = "semantic-policy")]
14725 {
14726 self.steps
14727 .get_mut(&token)
14728 .expect("retained original step")
14729 .prepared
14730 .as_mut()
14731 .expect("retained original prepared owner")
14732 .observed_outcome = Some(outcome.clone());
14733 }
14734 outcomes.push(outcome);
14735 continue;
14736 }
14737 let inputs = Arc::clone(
14738 self.steps[&step.token]
14739 .inputs
14740 .as_ref()
14741 .ok_or(SemanticTransitionError::ObservationMismatch)?,
14742 );
14743 let parent = self.publication_read(inputs.header.view())?[0];
14744 if previous.is_some_and(|header| header != parent) {
14745 return Err(SemanticTransitionError::ObservationMismatch);
14746 }
14747 let transition =
14748 validate_prepared_completion(&lease, &parent, &result, storage.instance)?;
14749 let bank = u8::try_from(lease.bank)
14750 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
14751 let (state_view, receipts, update_refusal_view) = {
14752 let prepared = self.steps[&step.token]
14753 .prepared
14754 .as_ref()
14755 .expect("original prepared owner");
14756 let branch = prepared
14757 .branches
14758 .get(usize::from(bank))
14759 .ok_or(SemanticTransitionError::ObservationMismatch)?;
14760 (
14761 branch.state.view(),
14762 branch
14763 .receipts
14764 .as_ref()
14765 .ok_or(SemanticTransitionError::ObservationMismatch)?
14766 .view(),
14767 branch
14768 .model_update
14769 .as_ref()
14770 .map(|update| (update.refusal.view(), update.canary_results.view())),
14771 )
14772 };
14773 let canary_refusal = match (transition, update_refusal_view) {
14774 (SemanticTransitionKind::Update, Some((view, results))) => {
14775 let results = self.publication_read(results)?;
14776 decode_canary_refusal(self.publication_read(view)?[0], &results)?
14777 }
14778 (SemanticTransitionKind::Update, None) | (_, Some(_)) => {
14779 return Err(SemanticTransitionError::ObservationMismatch);
14780 }
14781 (_, None) => None,
14782 };
14783 let state = self.publication_read(state_view)?[0];
14784 if transition != SemanticTransitionKind::Drain {
14785 let work = self.steps[&step.token]
14786 .prepared
14787 .as_ref()
14788 .expect("original prepared owner")
14789 .model_work
14790 .as_ref()
14791 .ok_or(SemanticTransitionError::ObservationMismatch)?;
14792 if !state
14793 .execution_work
14794 .validate_model(&work.recording, state.status == 11)
14795 {
14796 return Err(SemanticTransitionError::ObservationMismatch);
14797 }
14798 }
14799 let components = if transition == SemanticTransitionKind::Proposal {
14800 self.publication_read(receipts)?
14801 } else {
14802 Vec::new()
14803 };
14804 let invocation = parent.rng_binding()?;
14805 let outcome = self.reconcile_prepared_transition(
14806 &parent,
14807 &result,
14808 state,
14809 components,
14810 invocation,
14811 PreparedTransitionEvidence {
14812 transition,
14813 canary_refusal,
14814 },
14815 )?;
14816 previous = Some(result.header);
14817 #[cfg(feature = "semantic-policy")]
14818 if transition == SemanticTransitionKind::Proposal {
14819 self.take_prepared_policy_tape(
14820 &step,
14821 usize::from(bank),
14822 invocation,
14823 match &outcome {
14824 SemanticTransitionOutcome::Refused(refusal) => Some(*refusal),
14825 _ => None,
14826 },
14827 )?;
14828 }
14829 self.steps
14830 .get_mut(&step.token)
14831 .expect("retained original step")
14832 .prepared
14833 .as_mut()
14834 .expect("retained original prepared owner")
14835 .observed = true;
14836 #[cfg(feature = "semantic-policy")]
14837 if transition == SemanticTransitionKind::Update
14838 && matches!(&outcome, SemanticTransitionOutcome::Published(_))
14839 {
14840 self.steps
14841 .get_mut(&step.token)
14842 .expect("retained original step")
14843 .prepared
14844 .as_mut()
14845 .expect("retained original prepared owner")
14846 .group_update_published = true;
14847 }
14848 #[cfg(feature = "semantic-policy")]
14849 let token = step.token;
14850 let outcome = SemanticPreparedStepOutcome::Completed {
14851 step,
14852 invocation,
14853 bank,
14854 transition,
14855 outcome,
14856 };
14857 #[cfg(feature = "semantic-policy")]
14858 {
14859 let prepared = self
14860 .steps
14861 .get_mut(&token)
14862 .expect("retained original step")
14863 .prepared
14864 .as_mut()
14865 .expect("retained original prepared owner");
14866 prepared.observed_parent = Some(parent);
14867 prepared.observed_result = Some(result);
14868 prepared.observed_outcome = Some(outcome.clone());
14869 }
14870 outcomes.push(outcome);
14871 }
14872 let control = self.publication_read(storage.control.view())?[0];
14873 if control.abi != 1
14874 || control.instance != storage.instance
14875 || control.reader_gate != 0
14876 || previous.is_some_and(|header| control.word != header.publication_word)
14877 {
14878 return Err(SemanticTransitionError::ObservationMismatch);
14879 }
14880 self.prepared_segment
14881 .as_mut()
14882 .expect("submitted segment")
14883 .completed = true;
14884 Ok(outcomes)
14885 }
14886
14887 fn reconcile_prepared_transition(
14888 &mut self,
14889 parent: &PublicationHeader,
14890 result: &PreparedStepResult,
14891 state: DeviceState,
14892 components: Vec<SemanticTransitionReceipt>,
14893 invocation: SemanticRngBinding,
14894 evidence: PreparedTransitionEvidence,
14895 ) -> Result<SemanticTransitionOutcome, SemanticTransitionError> {
14896 let PreparedTransitionEvidence {
14897 transition,
14898 canary_refusal,
14899 } = evidence;
14900 if result.refusal != 0 || state.status == 10 {
14901 return Err(SemanticTransitionError::PublicationRefused {
14902 status: result.refusal,
14903 });
14904 }
14905 if matches!(state.status, 2 | 5 | 11 | 12..=15) {
14906 let canary_refusal = if state.status == 15 {
14907 Some(canary_refusal.ok_or(SemanticTransitionError::ObservationMismatch)?)
14908 } else {
14909 None
14910 };
14911 let refusal = refused_terminal(
14912 &state,
14913 invocation,
14914 SemanticActionCatalogue::current().binding(),
14915 self.binding().digest,
14916 canary_refusal,
14917 )?;
14918 if result.word != parent.publication_word || result.header != *parent {
14919 return Err(SemanticTransitionError::ObservationMismatch);
14920 }
14921 let (root, snapshot) = self.observe_publication_root(&state, parent, 0)?;
14922 refused_root_cleanup(
14923 &state,
14924 self.graph.transition_arena()[1],
14925 u64::from(root.slot()),
14926 root.generation(),
14927 )?;
14928 self.root = root;
14929 self.base_snapshot = snapshot;
14930 self.next_proposal = parent.proposal;
14931 return Ok(SemanticTransitionOutcome::Refused(refusal));
14932 }
14933 match state.status {
14934 7 => return Err(SemanticTransitionError::InvalidTaskBank),
14935 8 => return Err(SemanticTransitionError::InvalidTaskBase),
14936 9 => return Err(SemanticTransitionError::TaskOwnerFailure),
14937 _ => {}
14938 }
14939 let next = parent
14940 .proposal
14941 .checked_add(u64::from(transition == SemanticTransitionKind::Proposal))
14942 .ok_or(SemanticTransitionError::GenerationExhausted)?;
14943 if state.status != 0
14944 || result.word == parent.publication_word
14945 || result.header.proposal != next
14946 {
14947 return Err(SemanticTransitionError::ObservationMismatch);
14948 }
14949 let winner = if transition == SemanticTransitionKind::Proposal {
14950 state.task_evaluation.winner
14951 } else {
14952 0
14953 };
14954 let index = match winner {
14955 0 => 0,
14956 1 => 3,
14957 2 => 6,
14958 _ => return Err(SemanticTransitionError::ObservationMismatch),
14959 };
14960 if winner > 0 && state.retired_roots_mask & (1 << (winner - 1)) != 0 {
14961 return Err(SemanticTransitionError::ObservationMismatch);
14962 }
14963 let root = self.observe_publication_root(&state, &result.header, index)?;
14964 self.finish_observed_transition(
14965 state,
14966 components,
14967 invocation,
14968 Some((result.header, root, transition)),
14969 true,
14970 )
14971 }
14972}
14973
14974#[cfg(test)]
14975mod prepared_completion_tests {
14976 use super::*;
14977
14978 #[test]
14979 fn prepared_allocation_plan_counts_original_banks_before_expanding_bound() {
14980 let schema = SemanticFeedbackSchema::new([&[1u8; 64], &[2u8; 64], &[3u8; 64]]).unwrap();
14981 let feedback = FeedbackAllocationPlan::new(&schema, 2, 3).unwrap();
14982 let expected_feedback = 2 * schema.feature_width * size_of::<f32>()
14983 + 2 * 9
14984 + (2 * 42 + 2 + 3 + 3 * SEMANTIC_FEEDBACK_SUPPORT_FIELDS.len()) * size_of::<u64>()
14985 + 6 * 4 * size_of::<u64>();
14986 assert_eq!(feedback.bytes, expected_feedback);
14987 let input_bytes = PreparedStepInputs::allocation_bytes(&[]).unwrap();
14988 assert_eq!(
14989 input_bytes,
14990 size_of::<PublicationHeader>() + 32 * size_of::<SourceSlot>() + u64::BITS as usize
14991 );
14992 let plans = [
14993 StepInputPlan {
14994 role: 1,
14995 index: 0,
14996 layout: SemanticTensorLayout::default(),
14997 banks: [
14998 StepInputBankPlan {
14999 storage_slot: 0,
15000 span: 0..1024,
15001 },
15002 StepInputBankPlan {
15003 storage_slot: 0,
15004 span: 0..1024,
15005 },
15006 ],
15007 },
15008 StepInputPlan {
15009 role: 2,
15010 index: 0,
15011 layout: SemanticTensorLayout::default(),
15012 banks: [
15013 StepInputBankPlan {
15014 storage_slot: 1,
15015 span: 0..32,
15016 },
15017 StepInputBankPlan {
15018 storage_slot: 2,
15019 span: 0..32,
15020 },
15021 ],
15022 },
15023 ];
15024 assert_eq!(
15025 PreparedStepInputs::allocation_bytes(&plans).unwrap(),
15026 input_bytes
15027 + 2 * (size_of::<PublicationRange>() + 2 * size_of::<PublicationStepInput>())
15028 + 32
15029 );
15030 assert!(PreparedStepInputs::allocation_bytes(&[StepInputPlan {
15031 banks: [
15032 StepInputBankPlan {
15033 storage_slot: 1,
15034 span: 0..usize::MAX,
15035 },
15036 StepInputBankPlan {
15037 storage_slot: 2,
15038 span: 0..usize::MAX,
15039 },
15040 ],
15041 ..plans[1].clone()
15042 }])
15043 .is_err());
15044 let step_bytes = prepared_step_allocation_bytes(input_bytes, feedback.bytes, 0).unwrap();
15045 assert_eq!(
15046 step_bytes,
15047 (input_bytes
15048 + feedback.bytes
15049 + size_of::<PublicationLease>()
15050 + size_of::<PreparedStepResult>()) as u64
15051 );
15052 assert_eq!(
15053 prepared_segment_allocation_bytes(step_bytes, 3, 0).unwrap(),
15054 3 * step_bytes
15055 );
15056 assert!(prepared_segment_allocation_bytes(step_bytes, 0, 0).is_err());
15057 assert!(prepared_segment_allocation_bytes(step_bytes, usize::MAX, 0).is_err());
15058 }
15059
15060 #[test]
15061 fn prepared_scope_blocks_ordinary_rebinding_until_retirement() {
15062 let issuer = Arc::new(());
15063 let mut build = PreparedSegmentState::new(
15064 Arc::clone(&issuer),
15065 vec![1],
15066 std::iter::once(SemanticTransitionKind::Proposal),
15067 SemanticSegmentColdCapacity {
15068 tensor_content_capacity: 1,
15069 model_work_capacity: 1,
15070 segment_capacity_bytes: 1,
15071 other_external_cuda_bytes: 0,
15072 },
15073 )
15074 .unwrap();
15075 assert!(validate_rebinding_ownership(None, false).is_ok());
15076 assert!(validate_rebinding_ownership(None, true).is_err());
15077 assert!(validate_rebinding_ownership(Some(&build), false).is_err());
15078 let step = build.handles().unwrap().remove(0);
15079 build.enter(&step, &issuer).unwrap();
15080 build.leave(&step, &issuer).unwrap();
15081 build.finish().unwrap();
15082 build.submit().unwrap();
15083 build.completed = true;
15084 assert!(validate_rebinding_ownership(Some(&build), false).is_err());
15085 }
15086
15087 #[test]
15088 fn prepared_submission_is_once_only_after_complete_construction() {
15089 let issuer = Arc::new(());
15090 let mut build = PreparedSegmentState::new(
15091 Arc::clone(&issuer),
15092 vec![1],
15093 std::iter::once(SemanticTransitionKind::Proposal),
15094 SemanticSegmentColdCapacity {
15095 tensor_content_capacity: 1,
15096 model_work_capacity: 1,
15097 segment_capacity_bytes: 1,
15098 other_external_cuda_bytes: 0,
15099 },
15100 )
15101 .unwrap();
15102 assert!(build.submit().is_err());
15103 let step = build.handles().unwrap().remove(0);
15104 build.enter(&step, &issuer).unwrap();
15105 build.leave(&step, &issuer).unwrap();
15106 build.finish().unwrap();
15107 build.submit().unwrap();
15108 assert!(build.submit().is_err());
15109 build.completed = true;
15110 assert!(build.submit().is_err());
15111 }
15112
15113 #[test]
15114 fn completion_uses_original_parent_and_requires_device_release() {
15115 let parent = PublicationHeader {
15116 abi: 1,
15117 publication_word: 2,
15118 neural_bank: 1,
15120 sealed_epoch: 1,
15121 proposal: 37,
15122 model_generation: 9,
15123 family_id: 3,
15124 stream_serial: 91,
15125 ..PublicationHeader::default()
15126 };
15127 let mut lease = PublicationLease {
15128 abi: 1,
15129 word: 2,
15130 epoch: 1,
15131 transition_kind: 1,
15132 ..PublicationLease::default()
15133 };
15134 let mut result = PreparedStepResult {
15135 abi: 1,
15136 word: 5,
15137 advanced: 1,
15138 header: PublicationHeader {
15139 abi: 1,
15140 base_word: 2,
15141 publication_word: 5,
15142 sealed_epoch: 2,
15143 proposal: 38,
15144 ..parent
15145 },
15146 attempt: AttemptReceipt {
15147 abi: 2,
15148 transition_kind: 1,
15149 instance: parent.instance,
15150 base_word: 2,
15151 next_word: 5,
15152 logical_digest: parent.logical_digest,
15153 ..AttemptReceipt::default()
15154 },
15155 ..PreparedStepResult::default()
15156 };
15157 assert_eq!(
15158 validate_prepared_completion(&lease, &parent, &result, parent.instance).unwrap(),
15159 SemanticTransitionKind::Proposal
15160 );
15161 assert_eq!(parent.rng_binding().unwrap().proposal, 37);
15162 lease.active = 1;
15163 assert!(validate_prepared_completion(&lease, &parent, &result, parent.instance).is_err());
15164 lease.active = 0;
15165 result.word = 8;
15166 assert!(validate_prepared_completion(&lease, &parent, &result, parent.instance).is_err());
15167 result.word = 5;
15168 lease.transition_kind = 0;
15169 assert!(validate_prepared_completion(&lease, &parent, &result, parent.instance).is_err());
15170 }
15171}
15172
15173struct UnreleasedPublicationOwners {
15174 _graph: SemanticHypergraph,
15175 _publication: Arc<PublicationStorage>,
15176 _training_views: Option<Arc<SemanticTrainingViewArena>>,
15177 _training_origins: Option<Arc<TrackedCudaSlice<SemanticTrainingViewOriginRecord>>>,
15178 _readers: BTreeMap<u64, PublishedReader>,
15179 _steps: BTreeMap<u64, StepContentStorage>,
15180 _initial_prefill_content: Option<RetainedInitialPrefillContent>,
15181 _prepared_resources: Vec<Arc<dyn Send + Sync>>,
15182 _prepared_segment: Option<PreparedSegmentState>,
15183 _text_binding: Option<Arc<TextBindingStorage>>,
15184 #[cfg(feature = "semantic-policy")]
15185 _policy: Option<PolicyStorage>,
15186 #[cfg(feature = "semantic-policy")]
15187 _pending_policy: Option<PendingPolicyStorage>,
15188 #[cfg(feature = "semantic-policy")]
15189 _policy_tapes: Vec<PolicyTape>,
15190 _events: Vec<cudarc::driver::CudaEvent>,
15191 _uploads: Vec<(usize, PublicationPayload)>,
15192 _stream: Arc<CudaStream>,
15193}
15194
15195thread_local! {
15196 static UNRELEASED_PUBLICATIONS: std::cell::RefCell<Vec<std::mem::ManuallyDrop<UnreleasedPublicationOwners>>> = const { std::cell::RefCell::new(Vec::new()) };
15200}
15201
15202impl Drop for SemanticTransitionSession {
15203 fn drop(&mut self) {
15204 drop(self.captured.take());
15206 if !self.readers.is_empty()
15207 || !self.steps.is_empty()
15208 || self
15209 .prepared_segment
15210 .as_ref()
15211 .is_some_and(|build| (build.capturing || build.submitted) && !build.completed)
15212 {
15213 if let Some(publication) = self.publication.take() {
15214 let graph = unsafe { std::mem::ManuallyDrop::take(&mut self.graph) };
15217 let owners = UnreleasedPublicationOwners {
15218 _graph: graph,
15219 _publication: publication,
15220 _training_views: self.training_views.take(),
15221 _training_origins: self.training_origins.take(),
15222 _readers: std::mem::take(&mut self.readers),
15223 _events: std::mem::take(&mut self.release_events),
15224 _steps: std::mem::take(&mut self.steps),
15225 _initial_prefill_content: self.retained_initial_prefill.take(),
15226 _text_binding: self.text_binding.take(),
15227 _prepared_resources: std::mem::take(&mut self.prepared_resources),
15228 _prepared_segment: self.prepared_segment.take(),
15229 #[cfg(feature = "semantic-policy")]
15230 _policy: self.policy.take(),
15231 #[cfg(feature = "semantic-policy")]
15232 _pending_policy: self.pending_policy.take(),
15233 #[cfg(feature = "semantic-policy")]
15234 _policy_tapes: std::mem::take(&mut self.policy_tapes),
15235 _uploads: std::mem::take(&mut self.publication_uploads),
15236 _stream: Arc::clone(&self.stream),
15237 };
15238 eprintln!("semantic publication owners retained: Session dropped with unreleased readers or retained steps");
15239 let owners = std::mem::ManuallyDrop::new(owners);
15240 let _ = UNRELEASED_PUBLICATIONS
15241 .try_with(|quarantine| quarantine.borrow_mut().push(owners));
15242 return;
15243 }
15244 }
15245 unsafe { std::mem::ManuallyDrop::drop(&mut self.graph) };
15248 }
15249}
15250
15251impl SemanticTransitionSession {
15252 pub fn checkpoint_allocation_domain(
15257 &self,
15258 ) -> Result<(Arc<CudaKernelProvider>, ResidentExecutionDomain), SemanticTransitionError> {
15259 self.ensure_quiescent()?;
15260 Ok((Arc::clone(&self.provider), self.domain.clone()))
15261 }
15262
15263 pub fn state_material_admission(
15268 bytes: &[u8],
15269 ) -> Result<SemanticAdmissionRecords, SemanticTransitionError> {
15270 PublicationMaterial::decode(bytes)?
15271 .graph
15272 .admission_records()
15273 .map_err(SemanticTransitionError::Semantic)
15274 }
15275
15276 pub const CHECKPOINT_REFERENT_BYTES: usize = b"XLOG-CHECKPOINT-REFERENT\0".len()
15278 + 4
15279 + 32
15280 + 8
15281 + 104
15282 + 32
15283 + 8
15284 + 32
15285 + 32
15286 + 8
15287 + 3 * 32
15288 + 5 * 32
15289 + 1;
15290
15291 pub fn state_material_projection(
15294 bytes: &[u8],
15295 ) -> Result<SemanticCheckpointNativeProjection, SemanticTransitionError> {
15296 let material = PublicationMaterial::decode(bytes)?;
15297 let header = material.bank.header;
15298 Ok(SemanticCheckpointNativeProjection {
15299 publication: SemanticPublishedIdentity {
15300 instance: header.instance,
15301 word: header.publication_word,
15302 logical_digest: header.logical_digest,
15303 state_digest: header.state_digest,
15304 },
15305 semantic_root: header.semantic_digest,
15306 model_generation: header.model_generation,
15307 })
15308 }
15309
15310 pub fn state_material_input_projection(
15313 bytes: &[u8],
15314 ) -> Result<SemanticPublicationInputProjection, SemanticTransitionError> {
15315 let material = PublicationMaterial::decode(bytes)?;
15316 let header = material.bank.header;
15317 let range = |role| {
15318 material
15319 .ranges
15320 .iter()
15321 .find(|item| (item.range.role, item.range.index) == (role, 0))
15322 .ok_or(SemanticTransitionError::ObservationMismatch)
15323 };
15324 let prefix_material = range(1)?;
15325 let provenance_material = range(2)?;
15326 if prefix_material.range.logical_begin != 0
15327 || prefix_material.range.logical_end != header.prefix_extent
15328 || header
15329 .prefix_extent
15330 .checked_mul(size_of::<SemanticTextSlot>() as u64)
15331 != Some(prefix_material.bytes.len() as u64)
15332 || !provenance_material
15333 .bytes
15334 .len()
15335 .is_multiple_of(size_of::<TokenProvenance>())
15336 || header.prefix_extent > material.contract.prefix_capacity
15337 || header.ring_head >= 32
15338 {
15339 return Err(publication_input_error(
15340 "publication text material has inconsistent extents",
15341 ));
15342 }
15343 let prefix = prefix_material
15346 .bytes
15347 .as_chunks::<{ size_of::<SemanticTextSlot>() }>()
15348 .0
15349 .iter()
15350 .map(|bytes| unsafe { bytes.as_ptr().cast::<SemanticTextSlot>().read_unaligned() })
15351 .collect::<Vec<_>>();
15352 let records = provenance_material
15353 .bytes
15354 .as_chunks::<{ size_of::<TokenProvenance>() }>()
15355 .0
15356 .iter()
15357 .map(|bytes| unsafe { bytes.as_ptr().cast::<TokenProvenance>().read_unaligned() })
15358 .collect::<Vec<_>>();
15359 for (position, slot) in prefix.iter().enumerate() {
15360 if slot.logical_position != position as u64
15361 || slot.kind != 1
15362 || slot.valid != 1
15363 || slot.committed != 1
15364 || slot.recomputed != 1
15365 {
15366 return Err(publication_input_error(
15367 "publication prefix is not the exact committed ordered prefix",
15368 ));
15369 }
15370 }
15371 for slot in prefix.iter().chain(&material.bank.source) {
15372 if slot.kind != 1 {
15373 if slot.provenance != 0 || slot.provenance_record != 0 {
15374 return Err(publication_input_error(
15375 "unfilled source carries token provenance",
15376 ));
15377 }
15378 continue;
15379 }
15380 let record = usize::try_from(slot.provenance_record)
15381 .ok()
15382 .and_then(|index| records.get(index))
15383 .ok_or(SemanticTransitionError::ObservationMismatch)?;
15384 if !matches!(slot.provenance, 1 | 2)
15385 || record.logical_position != slot.logical_position
15386 || record.token != slot.token
15387 || record.origin_logical_digest == Identity256::default()
15388 || record.authority_closure_digest == Identity256::default()
15389 || record.record_digest == Identity256::default()
15390 || (slot.provenance == 1)
15391 != (record.action_receipt_digest == Identity256::default())
15392 {
15393 return Err(publication_input_error(
15394 "publication token differs from its original source or generated origin",
15395 ));
15396 }
15397 }
15398 let prefix_identity = Identity256::from_bytes(
15399 range(3)?
15400 .bytes
15401 .as_slice()
15402 .try_into()
15403 .map_err(|_| SemanticTransitionError::ObservationMismatch)?,
15404 );
15405 let cache = material
15406 .ranges
15407 .iter()
15408 .filter(|item| matches!(item.range.role, 4..=13))
15409 .map(|item| {
15410 item.cache_projection(
15411 *material
15412 .layouts
15413 .get(&(item.range.role, item.range.index))
15414 .ok_or(SemanticTransitionError::ObservationMismatch)?,
15415 )
15416 })
15417 .collect::<Result<Vec<_>, _>>()?;
15418 let token_provenance = records
15419 .into_iter()
15420 .map(|record| SemanticTokenProvenance {
15421 source_slot: record.source_slot,
15422 logical_position: record.logical_position,
15423 token: record.token,
15424 base_word: record.base_word,
15425 proposal: record.proposal,
15426 ordinal: record.ordinal,
15427 action_receipt_digest: record.action_receipt_digest,
15428 authority_generation: record.authority_generation,
15429 origin_logical_digest: record.origin_logical_digest,
15430 authority_closure_digest: record.authority_closure_digest,
15431 record_digest: record.record_digest,
15432 })
15433 .collect();
15434 Ok(SemanticPublicationInputProjection {
15435 publication: SemanticPublishedIdentity {
15436 instance: header.instance,
15437 word: header.publication_word,
15438 logical_digest: header.logical_digest,
15439 state_digest: header.state_digest,
15440 },
15441 semantic_root: header.semantic_digest,
15442 model_generation: header.model_generation,
15443 model_geometry_digest: header.model_geometry_digest,
15444 model_numerical_digest: header.model_numerical_digest,
15445 neural_generation: header.neural_generation,
15446 cache_generation: header.cache_generation,
15447 prefix_extent: header.prefix_extent,
15448 ring_head: header.ring_head,
15449 prefix_identity,
15450 prefix,
15451 source: material.bank.source,
15452 token_provenance,
15453 cache,
15454 })
15455 }
15456
15457 pub fn prepare_segment_steps(
15461 &mut self,
15462 transitions: impl ExactSizeIterator<Item = SemanticTransitionKind> + Clone,
15463 cold_capacity: SemanticSegmentColdCapacity,
15464 ) -> Result<Vec<SemanticPreparedStep>, SemanticTransitionError> {
15465 self.ensure_rebindable()?;
15466 let external_floor = cold_capacity.external_floor()?;
15467 let transitions = transitions.collect::<Vec<_>>();
15468 if transitions.is_empty() || transitions.contains(&SemanticTransitionKind::Drain) {
15469 return Err(publication_input_error(
15470 "a prepared segment requires frozen proposal, recompute, or update steps",
15471 ));
15472 }
15473 let update_count = transitions
15474 .iter()
15475 .filter(|kind| **kind == SemanticTransitionKind::Update)
15476 .count();
15477 let training_view = if update_count == 0 {
15478 None
15479 } else {
15480 Some(Arc::clone(self.training_views.as_ref().ok_or_else(
15481 || {
15482 publication_input_error(
15483 "prepared updates require the native training-view arena",
15484 )
15485 },
15486 )?))
15487 };
15488 if self.prepared_segment.is_some()
15489 || !self.readers.is_empty()
15490 || self.captured.is_some()
15491 || self.admitted_transition.is_some()
15492 || self.text_binding.is_some()
15493 {
15494 return Err(publication_input_error("segment construction requires an idle Session with no acquired reader or prior executable"));
15495 }
15496 let storage = Arc::clone(
15497 self.publication
15498 .as_ref()
15499 .ok_or(SemanticTransitionError::NotBound)?,
15500 );
15501 let transition_bound = transitions.len();
15502 let replay_bytes = PreparedReplayCustody::allocation_bytes(
15503 &storage,
15504 self.graph.transition_arena_view().len(),
15505 )?
15506 .checked_mul(transition_bound as u64)
15507 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15508 let bound = u64::try_from(transition_bound)
15509 .map_err(|_| SemanticTransitionError::GenerationExhausted)?;
15510 let end = self
15511 .next_reader
15512 .checked_add(bound)
15513 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15514 let schema = SemanticFeedbackSchema::new(self.feedback_statement_bytes()?)?;
15515 let descriptor = self.descriptor();
15516 let input_plans = PreparedStepInputs::plan(&storage)?;
15517 let feedback_plan = FeedbackAllocationPlan::new(
15518 &schema,
15519 storage.contract_value.feedback_capacity,
15520 descriptor.arena[4],
15521 )?;
15522 let block_bytes = storage
15523 .physical_parameter_roster
15524 .as_ref()
15525 .map_or(Some(0usize), |roster| {
15526 roster.len().checked_mul(6 * size_of::<f64>())
15527 })
15528 .and_then(|bytes| bytes.checked_mul(2))
15529 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15530 #[cfg(not(feature = "semantic-policy"))]
15531 let policy_bytes = block_bytes;
15532 #[cfg(feature = "semantic-policy")]
15533 let policy_bytes = policy_buffer_bytes(&self.policy_layout()?, self.codebooks.input_cells)?
15534 .checked_add(self.codebooks.input_cells)
15535 .and_then(|n| n.checked_add(COMPONENT_COUNT * size_of::<SemanticTransitionReceipt>()))
15536 .and_then(|n| n.checked_add(size_of::<DeviceState>()))
15537 .and_then(|n| n.checked_mul(2))
15538 .and_then(|n| n.checked_add(block_bytes))
15539 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15540 let step_bytes = prepared_step_allocation_bytes(
15541 PreparedStepInputs::allocation_bytes(&input_plans)?,
15542 feedback_plan.bytes,
15543 policy_bytes,
15544 )?;
15545 let training_origin_bytes = if self.training_views.is_some() {
15546 transition_bound
15547 .checked_mul(size_of::<SemanticTrainingViewOriginRecord>())
15548 .ok_or(SemanticTransitionError::GenerationExhausted)?
15549 } else {
15550 0
15551 };
15552 let training_view_bytes = training_view.as_ref().map_or(Ok(0usize), |arena| {
15553 arena
15554 .selection_bytes()?
15555 .checked_mul(update_count)
15556 .ok_or(SemanticTransitionError::GenerationExhausted)
15557 })?;
15558 let model_forward_seal_count = storage.bank_templates[0]
15559 .iter()
15560 .filter(|range| matches!(range.role, 18..=25))
15561 .count();
15562 let model_update_bank_metadata_bytes = model_forward_seal_count
15563 .checked_mul(size_of::<ModelForwardSealInput>())
15564 .and_then(|bytes| {
15565 bytes.checked_add(
15566 1 + 5 * size_of::<SemanticTrainingCanaryResultRecord>()
15567 + size_of::<SemanticTrainingCanaryRefusalRecord>()
15568 + 2 * size_of::<ModelForwardReceipt>(),
15569 )
15570 })
15571 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15572 let update_binding_bytes = update_count
15573 .checked_mul(2)
15574 .and_then(|count| count.checked_mul(storage.model_slots.len()))
15575 .and_then(|count| count.checked_mul(size_of::<ModelUpdateBinding>()))
15576 .and_then(|bytes| {
15577 update_count
15578 .checked_mul(2)
15579 .and_then(|count| count.checked_mul(model_update_bank_metadata_bytes))
15580 .and_then(|metadata| bytes.checked_add(metadata))
15581 })
15582 .and_then(|bytes| {
15583 update_count
15584 .checked_mul(transition_bound)
15585 .and_then(|count| count.checked_mul(size_of::<ModelUpdateEvidenceSource>()))
15586 .and_then(|evidence| bytes.checked_add(evidence))
15587 })
15588 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15589 let update_binding_bytes = u64::try_from(update_binding_bytes)
15590 .map_err(|_| SemanticTransitionError::GenerationExhausted)?;
15591 let base_bytes =
15592 prepared_segment_allocation_bytes(step_bytes, transition_bound, training_origin_bytes)?
15593 .checked_add(
15594 u64::try_from(training_view_bytes)
15595 .map_err(|_| SemanticTransitionError::GenerationExhausted)?,
15596 )
15597 .and_then(|bytes| bytes.checked_add(update_binding_bytes))
15598 .and_then(|bytes| bytes.checked_add(replay_bytes))
15599 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15600 let publication_allocation_bytes = storage
15604 .allocations
15605 .iter()
15606 .map(TrackedCudaSlice::len)
15607 .collect::<Vec<_>>();
15608 let model_content_bytes = storage
15609 .bank_templates
15610 .iter()
15611 .try_fold(0u64, |total, directory| {
15612 if !directory.iter().any(|range| range.role == 18) {
15613 return Ok(total);
15614 }
15615 let ranges = directory
15616 .iter()
15617 .enumerate()
15618 .filter_map(|(index, range)| matches!(range.role, 18..=20).then_some(index))
15619 .collect::<Vec<_>>();
15620 let plan =
15621 model_content_copy_plan(directory, &ranges, &publication_allocation_bytes)?;
15622 let bytes = plan
15623 .directory_offsets
15624 .len()
15625 .checked_mul(size_of::<PublicationRange>())
15626 .and_then(|bytes| bytes.checked_add(plan.contract_span.len()))
15627 .and_then(|bytes| {
15628 ranges
15629 .len()
15630 .checked_mul(2 * size_of::<u64>())
15631 .and_then(|roster| bytes.checked_add(roster))
15632 })
15633 .and_then(|bytes| u64::try_from(bytes).ok())
15634 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15635 total
15636 .checked_add(bytes)
15637 .ok_or(SemanticTransitionError::GenerationExhausted)
15638 })?
15639 .checked_mul(bound)
15640 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15641 let late_native_bytes = cold_capacity.late_native_bytes(transition_bound)?;
15642 let bytes = base_bytes
15643 .checked_add(model_content_bytes)
15644 .and_then(|bytes| bytes.checked_add(late_native_bytes))
15645 .and_then(|bytes| bytes.checked_add(external_floor))
15646 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15647 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
15648 .map_err(|error| runtime_error("segment preparation stream admission", error))?;
15649 let mut free_bytes = 0usize;
15650 let mut total_bytes = 0usize;
15651 unsafe { sys::cuMemGetInfo_v2(&mut free_bytes, &mut total_bytes) }
15654 .result()
15655 .map_err(|error| runtime_error("prepared segment physical memory snapshot", error))?;
15656 if u128::from(bytes) > free_bytes as u128 {
15657 return Err(runtime_error(
15658 "prepared segment physical memory admission",
15659 format!("declared cold claim {bytes} bytes exceeds {free_bytes} free CUDA bytes"),
15660 ));
15661 }
15662 let mut reservation = self
15665 .provider
15666 .memory()
15667 .reserve_bytes(bytes)
15668 .map_err(|error| runtime_error("prepared segment reservation", error))?;
15669 let training_origins = if training_origin_bytes == 0 {
15670 None
15671 } else {
15672 let origins = reservation
15673 .alloc::<SemanticTrainingViewOriginRecord>(transition_bound)
15674 .map_err(|error| runtime_error("training origin roster allocation", error))?;
15675 upload_publication(
15676 &self.provider,
15677 &vec![SemanticTrainingViewOriginRecord::default(); transition_bound],
15678 &origins,
15679 )?;
15680 Some(Arc::new(origins))
15681 };
15682 let mut tokens = Vec::new();
15683 tokens
15684 .try_reserve_exact(transition_bound)
15685 .map_err(|error| runtime_error("prepared token reservation", error))?;
15686 tokens.extend((self.next_reader..end).map(|token| token + 1));
15687 let build = PreparedSegmentState::new(
15688 Arc::clone(&self.publication_issuer),
15689 tokens,
15690 transitions.iter().copied(),
15691 cold_capacity,
15692 )?;
15693 let handles = build.handles()?;
15694 let kernel = |name| {
15695 self.provider
15696 .device()
15697 .inner()
15698 .get_func("xlog_semantic_transition", name)
15699 .ok_or_else(|| runtime_error("kernel lookup", format!("{name} unavailable")))
15700 };
15701 let admit = kernel("semantic_publication_step_admit")?;
15702 let kind_gate = kernel("semantic_publication_step_kind_gate")?;
15703 let kind_bank_gate = kernel("semantic_publication_step_kind_bank_gate")?;
15704 let active_gate = kernel("semantic_publication_step_active_gate")?;
15705 let drain_prepare = kernel("semantic_publication_prepare_drain")?;
15706 let release = kernel("semantic_publication_step_release")?;
15707 let witness = kernel("semantic_tensor_content_witness")?;
15708 let content_guard = kernel("semantic_publication_content_guard")?;
15709 let result_kernel = kernel("semantic_publication_step_result")?;
15710 let model_update_admissibility_copy =
15711 kernel("semantic_publication_prepare_model_update_admissibility")?;
15712 let model_update_forward_receipt =
15713 kernel("semantic_publication_record_model_forward_receipts")?;
15714 let model_update_copy = kernel("semantic_publication_apply_model_update")?;
15715 self.prepared_segment = Some(build);
15716 self.next_reader = end;
15717 let result = (|| {
15718 for (ordinal, (handle, kind)) in handles.iter().zip(&transitions).enumerate() {
15719 let reader = reservation
15720 .alloc(1)
15721 .map_err(|error| runtime_error("prepared reader allocation", error))?;
15722 let result = reservation
15723 .alloc(1)
15724 .map_err(|error| runtime_error("prepared result allocation", error))?;
15725 let (update_evidence, update_evidence_owners) = if *kind
15726 == SemanticTransitionKind::Update
15727 {
15728 #[cfg(feature = "semantic-policy")]
15729 let mut values = vec![ModelUpdateEvidenceSource::default(); transition_bound];
15730 #[cfg(not(feature = "semantic-policy"))]
15731 let values = vec![ModelUpdateEvidenceSource::default(); transition_bound];
15732 #[cfg(feature = "semantic-policy")]
15733 let mut owners = Vec::new();
15734 #[cfg(not(feature = "semantic-policy"))]
15735 let owners = Vec::new();
15736 #[cfg(feature = "semantic-policy")]
15737 for source_ordinal in 0..ordinal {
15738 if transitions[source_ordinal] != SemanticTransitionKind::Proposal {
15739 continue;
15740 }
15741 let source = &self.steps[&handles[source_ordinal].token];
15742 let prepared = source
15743 .prepared
15744 .as_ref()
15745 .ok_or(SemanticTransitionError::ObservationMismatch)?;
15746 let inputs = source
15747 .inputs
15748 .as_ref()
15749 .ok_or(SemanticTransitionError::ObservationMismatch)?;
15750 let origin = prepared
15751 .training_origin
15752 .clone()
15753 .ok_or(SemanticTransitionError::ObservationMismatch)?;
15754 let owner = ModelUpdateEvidenceOwner {
15755 lease: prepared.reader.view(),
15756 parent_header: inputs.header.view(),
15757 result: prepared.result.view(),
15758 origin,
15759 states: [
15760 prepared.branches[0].state.view(),
15761 prepared.branches[1].state.view(),
15762 ],
15763 };
15764 values[source_ordinal] = ModelUpdateEvidenceSource {
15765 lease: *owner.lease.device_ptr(),
15766 parent_header: *owner.parent_header.device_ptr(),
15767 result: *owner.result.device_ptr(),
15768 origin: *owner.origin.device_ptr(),
15769 states: [*owner.states[0].device_ptr(), *owner.states[1].device_ptr()],
15770 };
15771 owners.push(owner);
15772 }
15773 let evidence = reservation
15774 .alloc::<ModelUpdateEvidenceSource>(transition_bound)
15775 .map_err(|error| {
15776 runtime_error("model update evidence allocation", error)
15777 })?;
15778 upload_publication(&self.provider, &values, &evidence)?;
15779 (Some(Arc::new(evidence)), Some(Arc::new(owners)))
15780 } else {
15781 (None, None)
15782 };
15783 let mut allocate_model_update = || {
15784 if *kind != SemanticTransitionKind::Update {
15785 return Ok(None);
15786 }
15787 let bindings = reservation
15788 .alloc::<ModelUpdateBinding>(storage.model_slots.len())
15789 .map_err(|error| runtime_error("model update binding allocation", error))?;
15790 upload_publication(
15791 &self.provider,
15792 &vec![ModelUpdateBinding::default(); storage.model_slots.len()],
15793 &bindings,
15794 )?;
15795 let forward_seals = reservation
15796 .alloc::<ModelForwardSealInput>(model_forward_seal_count)
15797 .map_err(|error| runtime_error("model forward seal allocation", error))?;
15798 upload_publication(
15799 &self.provider,
15800 &vec![ModelForwardSealInput::default(); model_forward_seal_count],
15801 &forward_seals,
15802 )?;
15803 let forward_receipts =
15804 reservation
15805 .alloc::<ModelForwardReceipt>(2)
15806 .map_err(|error| {
15807 runtime_error("model forward receipt allocation", error)
15808 })?;
15809 upload_publication(
15810 &self.provider,
15811 &[ModelForwardReceipt::default(); 2],
15812 &forward_receipts,
15813 )?;
15814 let admissibility = reservation.alloc::<u8>(1).map_err(|error| {
15815 runtime_error("model update admissibility allocation", error)
15816 })?;
15817 upload_publication(&self.provider, &[0u8], &admissibility)?;
15818 let canary_results = reservation
15819 .alloc::<SemanticTrainingCanaryResultRecord>(5)
15820 .map_err(|error| {
15821 runtime_error("model update canary result allocation", error)
15822 })?;
15823 upload_publication(
15824 &self.provider,
15825 &[SemanticTrainingCanaryResultRecord::default(); 5],
15826 &canary_results,
15827 )?;
15828 let refusal = reservation
15829 .alloc::<SemanticTrainingCanaryRefusalRecord>(1)
15830 .map_err(|error| runtime_error("model update refusal allocation", error))?;
15831 upload_publication(
15832 &self.provider,
15833 &[SemanticTrainingCanaryRefusalRecord::default()],
15834 &refusal,
15835 )?;
15836 Ok(Some(PreparedModelUpdate {
15837 bindings,
15838 evidence: Arc::clone(
15839 update_evidence
15840 .as_ref()
15841 .ok_or(SemanticTransitionError::ObservationMismatch)?,
15842 ),
15843 evidence_owners: Arc::clone(
15844 update_evidence_owners
15845 .as_ref()
15846 .ok_or(SemanticTransitionError::ObservationMismatch)?,
15847 ),
15848 forward_seals,
15849 forward_receipts,
15850 admissibility,
15851 canary_results,
15852 refusal,
15853 output: None,
15854 forward_recorded: 0,
15855 admissibility_copy: model_update_admissibility_copy.clone(),
15856 forward_receipt: model_update_forward_receipt.clone(),
15857 copy: model_update_copy.clone(),
15858 }))
15859 };
15860 let model_updates: [Option<PreparedModelUpdate>; 2] =
15861 [allocate_model_update()?, allocate_model_update()?];
15862 let inputs = Arc::new(PreparedStepInputs::allocate_reserved(
15863 &self.provider,
15864 Arc::clone(&storage),
15865 reader.view(),
15866 input_plans.clone(),
15867 &mut reservation,
15868 )?);
15869 let feedback = FeedbackBuffers::allocate_reserved(
15870 &self.provider,
15871 schema.clone(),
15872 feedback_plan,
15873 &mut reservation,
15874 )?;
15875 let mut allocate_block_slot = || -> Result<_, SemanticTransitionError> {
15876 storage
15877 .physical_parameter_roster
15878 .as_ref()
15879 .map(|roster| {
15880 let cells = roster
15881 .len()
15882 .checked_mul(6)
15883 .ok_or(SemanticTransitionError::GenerationExhausted)?;
15884 reservation
15885 .alloc::<f64>(cells)
15886 .map(Arc::new)
15887 .map_err(|error| {
15888 runtime_error("prepared block bound allocation", error)
15889 })
15890 })
15891 .transpose()
15892 };
15893 let [blocks_zero, blocks_one] = [allocate_block_slot()?, allocate_block_slot()?];
15894 #[cfg(feature = "semantic-policy")]
15895 let [branch_zero, branch_one] = [
15896 self.prepare_step_policy_storage(&mut reservation)?,
15897 self.prepare_step_policy_storage(&mut reservation)?,
15898 ];
15899 let [model_update_zero, model_update_one] = model_updates;
15900 #[cfg(feature = "semantic-policy")]
15901 let (policy_buffers_zero, support_zero, receipts_zero, state_zero) = branch_zero;
15902 #[cfg(feature = "semantic-policy")]
15903 let (policy_buffers_one, support_one, receipts_one, state_one) = branch_one;
15904 let branches = [
15905 PreparedBranchStorage {
15906 model_update: model_update_zero,
15907 continuation: None,
15908 numerical_block_snapshot: blocks_zero,
15909 #[cfg(feature = "semantic-policy")]
15910 policy_buffers: Some(policy_buffers_zero),
15911 #[cfg(feature = "semantic-policy")]
15912 policy: None,
15913 #[cfg(feature = "semantic-policy")]
15914 support: Some(support_zero),
15915 #[cfg(feature = "semantic-policy")]
15916 receipts: Some(receipts_zero),
15917 #[cfg(feature = "semantic-policy")]
15918 state: state_zero,
15919 #[cfg(feature = "semantic-policy")]
15920 policy_sources: Vec::new(),
15921 #[cfg(feature = "semantic-policy")]
15922 policy_witness: None,
15923 },
15924 PreparedBranchStorage {
15925 model_update: model_update_one,
15926 continuation: None,
15927 numerical_block_snapshot: blocks_one,
15928 #[cfg(feature = "semantic-policy")]
15929 policy_buffers: Some(policy_buffers_one),
15930 #[cfg(feature = "semantic-policy")]
15931 policy: None,
15932 #[cfg(feature = "semantic-policy")]
15933 support: Some(support_one),
15934 #[cfg(feature = "semantic-policy")]
15935 receipts: Some(receipts_one),
15936 #[cfg(feature = "semantic-policy")]
15937 state: state_one,
15938 #[cfg(feature = "semantic-policy")]
15939 policy_sources: Vec::new(),
15940 #[cfg(feature = "semantic-policy")]
15941 policy_witness: None,
15942 },
15943 ];
15944 let mut step = StepContentStorage::new();
15945 step.inputs = Some(Arc::clone(&inputs));
15946 step.feedback.push(feedback);
15947 step.prepared = Some(PreparedStepStorage {
15948 reader,
15949 replay_custody: Some(PreparedReplayCustody::allocate(
15952 &self.provider,
15953 &storage,
15954 &inputs,
15955 self.graph.transition_arena_view().len(),
15956 &mut reservation,
15957 &self.learning_phases,
15958 )?),
15959 branches,
15960 digests: None,
15961 next_digest: 0,
15962 model_work: None,
15963 admit: admit.clone(),
15964 kind_gate: kind_gate.clone(),
15965 kind_bank_gate: kind_bank_gate.clone(),
15966 active_gate: active_gate.clone(),
15967 drain_prepare: drain_prepare.clone(),
15968 release: release.clone(),
15969 witness: witness.clone(),
15970 content_guard: content_guard.clone(),
15971 inputs_recorded: false,
15972 model_content_recorded: 0,
15973 transition_recorded: 0,
15974 drain_recorded: false,
15975 observed: false,
15976 #[cfg(feature = "semantic-policy")]
15977 observed_outcome: None,
15978 #[cfg(feature = "semantic-policy")]
15979 observed_parent: None,
15980 #[cfg(feature = "semantic-policy")]
15981 observed_result: None,
15982 result,
15983 training_origin: training_origins
15984 .as_ref()
15985 .and_then(|origins| origins.view().try_slice(ordinal..ordinal + 1)),
15986 training_view: if *kind == SemanticTransitionKind::Update {
15987 Some(
15988 training_view
15989 .as_ref()
15990 .expect("validated update training-view owner")
15991 .allocate_selection_reserved(
15992 &mut reservation,
15993 training_origins.clone(),
15994 )?,
15995 )
15996 } else {
15997 None
15998 },
15999 #[cfg(feature = "semantic-policy")]
16000 group_vjp_members: [BTreeSet::new(), BTreeSet::new()],
16001 #[cfg(feature = "semantic-policy")]
16002 group_edit_members: [BTreeSet::new(), BTreeSet::new()],
16003 #[cfg(feature = "semantic-policy")]
16004 group_imported_vjp_members: [BTreeSet::new(), BTreeSet::new()],
16005 #[cfg(feature = "semantic-policy")]
16006 group_gradient_members: [BTreeSet::new(), BTreeSet::new()],
16007 #[cfg(feature = "semantic-policy")]
16008 group_critic_recorded: 0,
16009 #[cfg(feature = "semantic-policy")]
16010 group_update_published: false,
16011 result_kernel: result_kernel.clone(),
16012 });
16013 self.steps.insert(handle.token, step);
16014 let prepared = self.steps[&handle.token]
16015 .prepared
16016 .as_ref()
16017 .expect("installed fixed step");
16018 #[cfg(feature = "semantic-policy")]
16021 for branch in &prepared.branches {
16022 upload_publication(
16023 &self.provider,
16024 &[DeviceState {
16025 catalogue_generation: self.binding().generation,
16026 catalogue_digest: Identity256::from_bytes(CATALOGUE_DIGEST),
16027 binding_digest: self.binding().digest,
16028 ..DeviceState::default()
16029 }],
16030 &branch.state,
16031 )?;
16032 }
16033 upload_publication(
16034 &self.provider,
16035 &[PublicationLease::default()],
16036 &prepared.reader,
16037 )?;
16038 upload_publication(
16039 &self.provider,
16040 &[PreparedStepResult::default()],
16041 &prepared.result,
16042 )?;
16043 inputs.initialize(&self.provider)?;
16044 }
16045 if reservation.remaining_bytes() != bytes - base_bytes {
16046 return Err(SemanticTransitionError::ObservationMismatch);
16047 }
16048 self.training_origins = training_origins;
16049 Ok(handles)
16050 })();
16051 match result {
16052 Ok(handles) => {
16053 self.prepared_segment
16054 .as_mut()
16055 .expect("installed prepared segment")
16056 .cold_reservation = Some(reservation);
16057 Ok(handles)
16058 }
16059 Err(error) => {
16060 self.poisoned = true;
16061 Err(error)
16062 }
16063 }
16064 }
16065
16066 fn checked_prepared_step(
16067 &self,
16068 step: &SemanticPreparedStep,
16069 recording: bool,
16070 ) -> Result<&StepContentStorage, SemanticTransitionError> {
16071 self.ensure_quiescent()?;
16072 let build = self
16073 .prepared_segment
16074 .as_ref()
16075 .ok_or_else(|| publication_input_error("Session has no prepared segment"))?;
16076 if recording {
16077 build.check(step, &self.publication_issuer, true)?;
16078 } else {
16079 build.check_retained(step, &self.publication_issuer)?;
16080 }
16081 self.steps
16082 .get(&step.token)
16083 .filter(|owner| owner.prepared.is_some() && owner.identity.is_none())
16084 .ok_or_else(|| {
16085 publication_input_error("prepared step has no original native storage owner")
16086 })
16087 }
16088
16089 pub fn prepared_transition_kind(
16092 &self,
16093 step: &SemanticPreparedStep,
16094 ) -> Result<SemanticTransitionKind, SemanticTransitionError> {
16095 self.checked_prepared_step(step, false)?;
16096 let build = self
16097 .prepared_segment
16098 .as_ref()
16099 .expect("checked prepared scope");
16100 build.check(step, &self.publication_issuer, false)?;
16101 build.requested_kind(step, &self.publication_issuer)
16102 }
16103
16104 #[cfg(feature = "semantic-policy")]
16107 fn completed_prepared_transition_kind(
16108 &self,
16109 step: &SemanticPreparedStep,
16110 ) -> Result<SemanticTransitionKind, SemanticTransitionError> {
16111 let owner = self.checked_prepared_step(step, false)?;
16112 let build = self
16113 .prepared_segment
16114 .as_ref()
16115 .expect("checked prepared scope");
16116 if !build.completed
16117 || !owner
16118 .prepared
16119 .as_ref()
16120 .expect("checked prepared owner")
16121 .observed
16122 {
16123 return Err(publication_input_error(
16124 "completed schedule observation requires this step's known execution",
16125 ));
16126 }
16127 build.requested_kind(step, &self.publication_issuer)
16128 }
16129
16130 fn check_prepared_cold(
16131 &self,
16132 step: &SemanticPreparedStep,
16133 ) -> Result<(), SemanticTransitionError> {
16134 self.checked_prepared_step(step, false)?;
16135 if self
16136 .prepared_segment
16137 .as_ref()
16138 .expect("checked build")
16139 .capturing
16140 {
16141 return Err(publication_input_error(
16142 "fixed resources must be prepared before capture begins",
16143 ));
16144 }
16145 Ok(())
16146 }
16147
16148 pub fn prepared_stream(
16149 &self,
16150 step: &SemanticPreparedStep,
16151 ) -> Result<Arc<CudaStream>, SemanticTransitionError> {
16152 self.checked_prepared_step(step, false)?;
16153 Ok(Arc::clone(&self.stream))
16154 }
16155
16156 pub fn reserve_tensor_content(
16159 &mut self,
16160 step: &SemanticPreparedStep,
16161 tensor_capacity: usize,
16162 ) -> Result<(), SemanticTransitionError> {
16163 self.check_prepared_cold(step)?;
16164 if tensor_capacity == 0 {
16165 return Err(publication_input_error(
16166 "content reservation requires a positive original tensor capacity",
16167 ));
16168 }
16169 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
16170 .map_err(|error| runtime_error("content reservation stream admission", error))?;
16171 if self.steps[&step.token]
16172 .prepared
16173 .as_ref()
16174 .expect("prepared owner")
16175 .digests
16176 .is_some()
16177 {
16178 return Err(publication_input_error(
16179 "original content capacity is reserved once per fixed step",
16180 ));
16181 }
16182 let build = self.prepared_segment.as_mut().expect("checked build");
16183 if tensor_capacity != build.cold_capacity.tensor_content_capacity {
16184 return Err(publication_input_error(
16185 "content capacity differs from the frozen segment claim",
16186 ));
16187 }
16188 let cells = build.cold_capacity.content_cells()?;
16189 let bytes = build.cold_capacity.content_bytes()?;
16190 let floor = build.cold_capacity.external_floor()?;
16191 let reservation = build
16192 .cold_reservation
16193 .as_mut()
16194 .ok_or(SemanticTransitionError::ObservationMismatch)?;
16195 if reservation
16196 .remaining_bytes()
16197 .checked_sub(bytes)
16198 .is_none_or(|remaining| remaining < floor)
16199 {
16200 return Err(SemanticTransitionError::ObservationMismatch);
16201 }
16202 let digest = Arc::new(
16203 reservation
16204 .alloc::<u64>(cells)
16205 .map_err(|error| runtime_error("original content allocation", error))?,
16206 );
16207 self.steps
16208 .get_mut(&step.token)
16209 .expect("checked fixed step")
16210 .prepared
16211 .as_mut()
16212 .expect("checked prepared owner")
16213 .digests = Some(digest);
16214 Ok(())
16215 }
16216
16217 pub fn reserve_model_work(
16220 &mut self,
16221 step: &SemanticPreparedStep,
16222 event_capacity: usize,
16223 ) -> Result<(), SemanticTransitionError> {
16224 self.check_prepared_cold(step)?;
16225 if self.steps[&step.token]
16226 .prepared
16227 .as_ref()
16228 .expect("prepared owner")
16229 .model_work
16230 .is_some()
16231 {
16232 return Err(publication_input_error(
16233 "original model work capacity is reserved once per step",
16234 ));
16235 }
16236 let build = self.prepared_segment.as_ref().expect("checked build");
16237 if event_capacity != build.cold_capacity.model_work_capacity {
16238 return Err(publication_input_error(
16239 "model work capacity differs from the frozen segment claim",
16240 ));
16241 }
16242 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
16243 .map_err(|error| runtime_error("model work reservation stream admission", error))?;
16244 let bytes = build.cold_capacity.model_work_bytes()?;
16245 let floor = build.cold_capacity.external_floor()?;
16246 let work = {
16247 let reservation = self
16248 .prepared_segment
16249 .as_mut()
16250 .expect("checked build")
16251 .cold_reservation
16252 .as_mut()
16253 .ok_or(SemanticTransitionError::ObservationMismatch)?;
16254 if reservation
16255 .remaining_bytes()
16256 .checked_sub(bytes)
16257 .is_none_or(|remaining| remaining < floor)
16258 {
16259 return Err(SemanticTransitionError::ObservationMismatch);
16260 }
16261 PreparedModelWork::allocate(&self.provider, reservation, event_capacity)?
16262 };
16263 work.reset_slots(&self.domain, &mut self.poisoned, 0, event_capacity)?;
16266 self.steps
16267 .get_mut(&step.token)
16268 .expect("checked original step")
16269 .prepared
16270 .as_mut()
16271 .expect("prepared owner")
16272 .model_work = Some(work);
16273 Ok(())
16274 }
16275
16276 pub fn model_work_buffer(
16280 &mut self,
16281 step: &SemanticPreparedStep,
16282 consumer_stream: u64,
16283 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16284 self.check_prepared_cold(step)?;
16285 if consumer_stream != self.stream.cu_stream() as u64 {
16286 return Err(publication_input_error(
16287 "model work producers must use the original native recording stream",
16288 ));
16289 }
16290 let work = self.steps[&step.token]
16291 .prepared
16292 .as_ref()
16293 .expect("prepared owner")
16294 .model_work
16295 .as_ref()
16296 .ok_or_else(|| publication_input_error("model work requires its cold reservation"))?;
16297 let capacity = i64::try_from(work.actual.len() / 3)
16298 .map_err(|_| SemanticTransitionError::GenerationExhausted)?;
16299 let view = unsafe { work.actual.view().cast::<u8>() }
16302 .ok_or(SemanticTransitionError::ObservationMismatch)?;
16303 self.export_prepared_view(
16304 step,
16305 view,
16306 vec![capacity, 3],
16307 vec![3, 1],
16308 (1, 64),
16309 consumer_stream,
16310 )
16311 }
16312
16313 pub fn record_model_device_work(
16317 &mut self,
16318 step: &SemanticPreparedStep,
16319 kind: ModelWorkKind,
16320 upper_dimensions: &[u64],
16321 ) -> Result<usize, SemanticTransitionError> {
16322 self.check_prepared_content_stream(step, self.stream.cu_stream() as u64)?;
16323 let result = (|| {
16324 let work = self
16325 .steps
16326 .get_mut(&step.token)
16327 .expect("checked original step")
16328 .prepared
16329 .as_mut()
16330 .expect("prepared owner")
16331 .model_work
16332 .as_mut()
16333 .ok_or_else(|| {
16334 publication_input_error("model work requires its cold reservation")
16335 })?;
16336 let slot = work.next_slot().map_err(publication_input_error)?;
16337 if slot >= work.actual.len() / 3 {
16338 return Err(publication_input_error(
16339 "model work exceeds its cold event capacity",
16340 ));
16341 }
16342 let actual = work
16343 .actual
16344 .device_ptr_value()
16345 .checked_add((slot * 3 * size_of::<u64>()) as u64)
16346 .ok_or(SemanticTransitionError::GenerationExhausted)?;
16347 let event = ModelWorkEvent::device_operation(kind, upper_dimensions, actual)
16348 .map_err(publication_input_error)?;
16349 let recorded = work.record_event(event).map_err(publication_input_error)?;
16350 debug_assert_eq!(recorded, slot);
16351 work.reset_slots(&self.domain, &mut self.poisoned, slot, 1)?;
16352 Ok(slot)
16353 })();
16354 if result.is_err() {
16355 self.poisoned = true;
16356 }
16357 result
16358 }
16359
16360 pub fn record_model_work(
16364 &mut self,
16365 step: &SemanticPreparedStep,
16366 kind: ModelWorkKind,
16367 dimensions: &[u64],
16368 ) -> Result<(), SemanticTransitionError> {
16369 self.check_prepared_content_stream(step, self.stream.cu_stream() as u64)?;
16370 let result = (|| {
16371 let event =
16372 ModelWorkEvent::operation(kind, dimensions).map_err(publication_input_error)?;
16373 let work = self
16374 .steps
16375 .get_mut(&step.token)
16376 .expect("checked original step")
16377 .prepared
16378 .as_mut()
16379 .expect("prepared owner")
16380 .model_work
16381 .as_mut()
16382 .ok_or_else(|| {
16383 publication_input_error("model work requires its original cold reservation")
16384 })?;
16385 work.record_event(event)
16386 .map(|_| ())
16387 .map_err(publication_input_error)
16388 })();
16389 if result.is_err() {
16390 self.poisoned = true;
16391 }
16392 result
16393 }
16394
16395 pub fn record_model_invocation(
16398 &mut self,
16399 step: &SemanticPreparedStep,
16400 ) -> Result<(), SemanticTransitionError> {
16401 self.check_prepared_content_stream(step, self.stream.cu_stream() as u64)?;
16402 let result = self
16403 .steps
16404 .get_mut(&step.token)
16405 .expect("checked original step")
16406 .prepared
16407 .as_mut()
16408 .expect("prepared owner")
16409 .model_work
16410 .as_mut()
16411 .ok_or_else(|| {
16412 publication_input_error(
16413 "model invocation requires its original cold work reservation",
16414 )
16415 })?
16416 .record_invocation(&self.domain, &mut self.poisoned);
16417 if result.is_err() {
16418 self.poisoned = true;
16419 }
16420 result
16421 }
16422
16423 pub fn record_saved_tensor_work(
16427 &mut self,
16428 step: &SemanticPreparedStep,
16429 witness: &SemanticTensorContentWitness,
16430 ) -> Result<(), SemanticTransitionError> {
16431 self.check_prepared_content_stream(step, self.stream.cu_stream() as u64)?;
16432 let result = (|| {
16433 let owner = self
16434 .steps
16435 .get_mut(&step.token)
16436 .expect("checked original step");
16437 if !Arc::ptr_eq(&witness.issuer, &self.publication_issuer)
16438 || witness.reader_token != step.token
16439 || !Arc::ptr_eq(&witness._witness, &owner.content_witnesses)
16440 {
16441 return Err(publication_input_error(
16442 "saved work requires this original step and tensor witness",
16443 ));
16444 }
16445 let content = owner.content.get(witness.index).ok_or_else(|| {
16446 publication_input_error("saved work has no retained original tensor occurrence")
16447 })?;
16448 let work = owner
16449 .prepared
16450 .as_mut()
16451 .expect("prepared owner")
16452 .model_work
16453 .as_mut()
16454 .ok_or_else(|| {
16455 publication_input_error("saved work requires its original cold reservation")
16456 })?;
16457 for (index, tensor) in content.tensors.iter().enumerate() {
16458 let layout = &tensor.layout;
16459 let dimensions = layout
16460 .dimensions
16461 .get(..layout.rank as usize)
16462 .ok_or(SemanticTransitionError::ObservationMismatch)?;
16463 let event = ModelWorkEvent::saved(
16464 witness.index as u64,
16465 index as u64,
16466 dimensions,
16467 layout.element_bytes,
16468 )
16469 .map_err(publication_input_error)?;
16470 work.record_event(event).map_err(publication_input_error)?;
16471 }
16472 Ok(())
16473 })();
16474 if result.is_err() {
16475 self.poisoned = true;
16476 }
16477 result
16478 }
16479
16480 fn export_prepared_view(
16481 &mut self,
16482 step: &SemanticPreparedStep,
16483 view: DeviceMemoryView<u8>,
16484 shape: Vec<i64>,
16485 strides: Vec<i64>,
16486 dtype: (u8, u8),
16487 consumer_stream: u64,
16488 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16489 self.check_prepared_cold(step)?;
16490 let guard = Arc::clone(&self.steps[&step.token].aliases);
16491 self.steps
16492 .get_mut(&step.token)
16493 .expect("checked fixed step")
16494 .consumer_streams
16495 .insert(consumer_stream);
16496 self.export_owned_view(view, shape, strides, dtype, guard, consumer_stream)
16497 }
16498
16499 pub fn prepared_source(
16500 &mut self,
16501 step: &SemanticPreparedStep,
16502 consumer_stream: u64,
16503 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16504 self.check_prepared_cold(step)?;
16505 let (_, shape, strides) = PublicationBankField::Source.layout();
16506 let view = self.steps[&step.token]
16507 .inputs
16508 .as_ref()
16509 .expect("fixed input owner")
16510 .field_view(PublicationBankField::Source)?;
16511 self.export_prepared_view(step, view, shape, strides, (1, 64), consumer_stream)
16512 }
16513
16514 pub fn prepared_prefix(
16515 &mut self,
16516 step: &SemanticPreparedStep,
16517 bank: usize,
16518 consumer_stream: u64,
16519 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16520 self.prepared_tensor(
16521 step,
16522 SemanticStateRole::PrefixSource,
16523 0,
16524 bank,
16525 consumer_stream,
16526 )
16527 }
16528
16529 pub fn prepared_record(
16530 &mut self,
16531 step: &SemanticPreparedStep,
16532 role: SemanticStateRole,
16533 index: u64,
16534 consumer_stream: u64,
16535 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16536 self.check_prepared_cold(step)?;
16537 if is_tensor_role(role as u64) {
16538 return Err(publication_input_error(
16539 "tensor roles require their original model layout",
16540 ));
16541 }
16542 if role == SemanticStateRole::PrefixSource {
16543 return Err(publication_input_error(
16544 "prepared prefixes require the fixed typed capacity and original device extent",
16545 ));
16546 }
16547 let storage = self.publication.as_ref().expect("prepared publication");
16548 let key = (role as u64, index);
16549 let inputs = self.steps[&step.token]
16550 .inputs
16551 .as_ref()
16552 .expect("fixed inputs");
16553 let view = if let Some(view) = inputs.views[0].get(&key) {
16554 view.clone()
16555 } else {
16556 let original = storage.bank_templates[0]
16557 .iter()
16558 .find(|range| (range.role, range.index) == key)
16559 .ok_or_else(|| {
16560 publication_input_error("record has no original fixed declaration")
16561 })?;
16562 let other = storage.bank_templates[1]
16563 .iter()
16564 .find(|range| (range.role, range.index) == key)
16565 .ok_or(SemanticTransitionError::ObservationMismatch)?;
16566 if publication_mutable_role(role as u64)
16567 || original.storage_slot != other.storage_slot
16568 || original.offset_bytes != other.offset_bytes
16569 || original.length_bytes != other.length_bytes
16570 {
16571 return Err(publication_input_error(
16572 "bank-varying records require a private prepared input producer",
16573 ));
16574 }
16575 let begin = original.offset_bytes as usize;
16576 let end = begin
16577 .checked_add(original.length_bytes as usize)
16578 .ok_or(SemanticTransitionError::ObservationMismatch)?;
16579 storage.allocations[original.storage_slot as usize]
16580 .view()
16581 .slice(begin..end)
16582 };
16583 let bytes =
16584 i64::try_from(view.len()).map_err(|_| SemanticTransitionError::ObservationMismatch)?;
16585 self.export_prepared_view(step, view, vec![bytes], vec![1], (1, 8), consumer_stream)
16586 }
16587
16588 pub fn prepared_range_keys(
16589 &self,
16590 step: &SemanticPreparedStep,
16591 ) -> Result<Vec<(SemanticStateRole, u64)>, SemanticTransitionError> {
16592 self.checked_prepared_step(step, false)?;
16593 self.publication
16594 .as_ref()
16595 .expect("prepared publication")
16596 .bank_templates[0]
16597 .iter()
16598 .map(|range| {
16599 SemanticStateRole::from_code(range.role)
16600 .map(|role| (role, range.index))
16601 .ok_or(SemanticTransitionError::ObservationMismatch)
16602 })
16603 .collect()
16604 }
16605
16606 pub fn prepared_tensor(
16608 &mut self,
16609 step: &SemanticPreparedStep,
16610 role: SemanticStateRole,
16611 index: u64,
16612 bank: usize,
16613 consumer_stream: u64,
16614 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16615 let (view, layout) = self.prepared_tensor_view(step, role, index, bank)?;
16616 let shape = layout.dimensions[..layout.rank as usize]
16617 .iter()
16618 .map(|&value| {
16619 i64::try_from(value).map_err(|_| SemanticTransitionError::ObservationMismatch)
16620 })
16621 .collect::<Result<Vec<_>, _>>()?;
16622 let strides = layout.strides_bytes[..layout.rank as usize]
16623 .iter()
16624 .map(|&value| {
16625 i64::try_from(value / layout.element_bytes)
16626 .map_err(|_| SemanticTransitionError::ObservationMismatch)
16627 })
16628 .collect::<Result<Vec<_>, _>>()?;
16629 let dtype = match layout.scalar_type {
16630 1 => (1, 8),
16631 2 => (1, 32),
16632 3 => (1, 64),
16633 4 => (2, 16),
16634 5 => (4, 16),
16635 6 => (2, 32),
16636 7 => (0, 64),
16637 8 => (6, 8),
16638 9 => (2, 64),
16639 _ => return Err(SemanticTransitionError::ObservationMismatch),
16640 };
16641 self.export_prepared_view(step, view, shape, strides, dtype, consumer_stream)
16642 }
16643
16644 pub fn prepared_training_view_port(
16647 &mut self,
16648 step: &SemanticPreparedStep,
16649 port: SemanticTrainingViewPort,
16650 consumer_stream: u64,
16651 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16652 self.check_prepared_cold(step)?;
16653 if self.prepared_transition_kind(step)? != SemanticTransitionKind::Update {
16654 return Err(publication_input_error(
16655 "native selected training views belong only to prepared updates",
16656 ));
16657 }
16658 let (view, shape, strides, dtype) = self.steps[&step.token]
16659 .prepared
16660 .as_ref()
16661 .expect("prepared owner")
16662 .training_view
16663 .as_ref()
16664 .ok_or(SemanticTransitionError::NotBound)?
16665 .port(port)?;
16666 self.export_prepared_view(step, view, shape, strides, dtype, consumer_stream)
16667 }
16668
16669 pub fn prepared_tensor_allocation(
16673 &mut self,
16674 step: &SemanticPreparedStep,
16675 role: SemanticStateRole,
16676 index: u64,
16677 bank: usize,
16678 consumer_stream: u64,
16679 ) -> Result<(DeviceAllocationProvenance, DlpackManagedTensor), SemanticTransitionError> {
16680 dlpack_consumer_stream(consumer_stream)?;
16681 let (view, _) = self.prepared_tensor_view(step, role, index, bank)?;
16682 let provenance = view.allocation_provenance().ok_or_else(|| {
16683 publication_input_error("prepared tensor has no complete native allocation owner")
16684 })?;
16685 let allocation = view
16686 .allocation_view()
16687 .ok_or(SemanticTransitionError::ObservationMismatch)?;
16688 let bytes = i64::try_from(allocation.len())
16689 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
16690 let tensor = self.export_prepared_view(
16691 step,
16692 allocation,
16693 vec![bytes],
16694 vec![1],
16695 (1, 8),
16696 consumer_stream,
16697 )?;
16698 Ok((provenance, tensor))
16699 }
16700
16701 fn prepared_tensor_view(
16702 &mut self,
16703 step: &SemanticPreparedStep,
16704 role: SemanticStateRole,
16705 index: u64,
16706 bank: usize,
16707 ) -> Result<(DeviceMemoryView<u8>, SemanticTensorLayout), SemanticTransitionError> {
16708 self.check_prepared_cold(step)?;
16709 if bank > 1 {
16710 return Err(publication_input_error(
16711 "prepared tensor bank must be zero or one",
16712 ));
16713 }
16714 let retained = self
16715 .prepared_segment
16716 .as_ref()
16717 .expect("checked prepared scope")
16718 .finished;
16719 if retained {
16720 let actual_bank = self.prepared_completed_parent_bank(step.token)?;
16721 if actual_bank != bank {
16722 return Err(publication_input_error(
16723 "completed tensor requires the original executed branch bank",
16724 ));
16725 }
16726 }
16727 let inputs = self.steps[&step.token]
16728 .inputs
16729 .as_ref()
16730 .expect("fixed input owner");
16731 let plan = inputs
16732 .plans
16733 .iter()
16734 .find(|plan| (plan.role, plan.index) == (role as u64, index))
16735 .ok_or_else(|| {
16736 publication_input_error("prepared tensor has no fixed original input owner")
16737 })?;
16738 let custody = self.steps[&step.token]
16739 .prepared
16740 .as_ref()
16741 .expect("checked prepared owner")
16742 .replay_custody
16743 .as_ref();
16744 let view = if let Some(custody) =
16745 custody.filter(|_| retained && matches!(role as u64, 1 | 4 | 5 | 18..=25))
16746 {
16747 custody.input_view(role as u64, index)?.0
16748 } else {
16749 inputs.views[bank][&(role as u64, index)].clone()
16750 };
16751 Ok((view, plan.layout))
16752 }
16753
16754 pub fn prepared_terminal(
16755 &mut self,
16756 step: &SemanticPreparedStep,
16757 consumer_stream: u64,
16758 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16759 self.prepared_bank_field(step, PublicationBankField::Terminal, consumer_stream)
16760 }
16761
16762 pub fn prepared_prefix_extent(
16763 &mut self,
16764 step: &SemanticPreparedStep,
16765 consumer_stream: u64,
16766 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16767 self.prepared_bank_field(step, PublicationBankField::PrefixExtent, consumer_stream)
16768 }
16769
16770 pub fn prepared_ring_head(
16771 &mut self,
16772 step: &SemanticPreparedStep,
16773 consumer_stream: u64,
16774 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16775 self.prepared_bank_field(step, PublicationBankField::RingHead, consumer_stream)
16776 }
16777
16778 fn prepared_bank_field(
16779 &mut self,
16780 step: &SemanticPreparedStep,
16781 field: PublicationBankField,
16782 consumer_stream: u64,
16783 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
16784 self.check_prepared_cold(step)?;
16785 let inputs = self.steps[&step.token]
16786 .inputs
16787 .as_ref()
16788 .expect("prepared input owner");
16789 let (_, shape, strides) = field.layout();
16790 self.export_prepared_view(
16791 step,
16792 inputs.field_view(field)?,
16793 shape,
16794 strides,
16795 (1, 64),
16796 consumer_stream,
16797 )
16798 }
16799
16800 pub fn prepared_model_geometry(
16802 &self,
16803 step: &SemanticPreparedStep,
16804 ) -> Result<(Identity256, Identity256, u64, u64, u64, u64), SemanticTransitionError> {
16805 self.checked_prepared_step(step, false)?;
16806 let contract = self
16807 .publication
16808 .as_ref()
16809 .expect("prepared publication")
16810 .contract_value;
16811 Ok((
16812 contract.topology_identity,
16813 contract.table_identity,
16814 contract.model_generation,
16815 contract.prefix_capacity,
16816 contract.feedback_capacity,
16817 contract.max_position,
16818 ))
16819 }
16820
16821 pub fn prepared_model_binding(
16834 &mut self,
16835 step: &SemanticPreparedStep,
16836 consumer_streams: &[u64],
16837 ) -> Result<
16838 (
16839 SemanticPublishedIdentity,
16840 Option<SemanticPublishedIdentity>,
16841 u64,
16842 Identity256,
16843 Identity256,
16844 ),
16845 SemanticTransitionError,
16846 > {
16847 let owner = self.checked_prepared_step(step, false)?;
16848 let prepared = owner.prepared.as_ref().expect("checked prepared owner");
16849 if !self
16850 .prepared_segment
16851 .as_ref()
16852 .expect("checked prepared scope")
16853 .completed
16854 || !prepared.observed
16855 {
16856 return Err(publication_input_error(
16857 "model input observation requires this step's known completed execution",
16858 ));
16859 }
16860 let inputs = Arc::clone(
16861 owner
16862 .inputs
16863 .as_ref()
16864 .ok_or(SemanticTransitionError::ObservationMismatch)?,
16865 );
16866 let reader = prepared.reader.view();
16867 let result = prepared.result.view();
16868 let _ordinary =
16869 crate::cuda_graph::reserve_uncaptured_stream(&self.stream).map_err(|error| {
16870 runtime_error("completed model observation stream admission", error)
16871 })?;
16872 self.complete_step_consumers_by_token(step.token, consumer_streams)?;
16873 let custody = self.steps[&step.token]
16874 .prepared
16875 .as_ref()
16876 .expect("checked prepared owner")
16877 .replay_custody
16878 .as_ref();
16879 inputs.verify_completed(&self.domain, &mut self.poisoned, custody)?;
16880 let parent = self.publication_read(inputs.header.view())?[0];
16881 let reader = self.publication_read(reader)?[0];
16882 let result = self.publication_read(result)?[0];
16883 if validate_prepared_completion(&reader, &parent, &result, inputs.storage.instance).is_err()
16884 || (result.advanced == 0 && result.header != parent)
16885 {
16886 self.poisoned = true;
16887 return Err(SemanticTransitionError::ObservationMismatch);
16888 }
16889 let identity = |header: PublicationHeader| SemanticPublishedIdentity {
16890 instance: header.instance,
16891 word: header.publication_word,
16892 logical_digest: header.logical_digest,
16893 state_digest: header.state_digest,
16894 };
16895 Ok((
16896 identity(parent),
16897 (result.advanced == 1).then(|| identity(result.header)),
16898 parent.model_generation,
16899 parent.model_geometry_digest,
16900 parent.model_numerical_digest,
16901 ))
16902 }
16903
16904 #[cfg(feature = "semantic-policy")]
16908 pub fn prepared_execution_measurements(
16909 &mut self,
16910 step: &SemanticPreparedStep,
16911 ) -> Result<SemanticCompletedExecutionObservation, SemanticTransitionError> {
16912 let original = self.checked_prepared_step(step, false)?;
16913 if !self
16914 .prepared_segment
16915 .as_ref()
16916 .expect("checked prepared scope")
16917 .completed
16918 {
16919 return Err(publication_input_error(
16920 "execution measurements require the original segment's known completion",
16921 ));
16922 }
16923 let prepared = original.prepared.as_ref().expect("checked original step");
16924 let requested_transition = self
16925 .prepared_segment
16926 .as_ref()
16927 .expect("checked prepared scope")
16928 .requested_kind(step, &self.publication_issuer)?;
16929 let original_outcome = prepared
16930 .observed_outcome
16931 .as_ref()
16932 .ok_or(SemanticTransitionError::ObservationMismatch)?
16933 .clone();
16934 let original_parent = prepared.observed_parent;
16935 let original_result = prepared.observed_result;
16936 let reader = prepared.reader.view();
16937 let result = prepared.result.view();
16938 let mut streams = original.consumer_streams.clone();
16939 if let Some(reader) = self.readers.get(&step.token) {
16940 streams.extend(reader.consumer_streams.iter().copied());
16941 }
16942 let observation = (|| {
16943 self.complete_step_consumers_by_token(
16944 step.token,
16945 &streams.into_iter().collect::<Vec<_>>(),
16946 )?;
16947 let lease = self.publication_read(reader)?[0];
16948 let result = self.publication_read(result)?[0];
16949 let prepared = self.steps[&step.token]
16950 .prepared
16951 .as_ref()
16952 .expect("retained original step");
16953 let work = prepared
16954 .model_work
16955 .as_ref()
16956 .ok_or(SemanticTransitionError::ObservationMismatch)?;
16957 let actual = work.actual.view();
16958 let actual = self.publication_read(actual)?;
16959 if result.abi == 0 {
16960 if lease.active != 0
16961 || lease.abi != 0
16962 || lease.transition_kind != 0
16963 || !matches!(lease.status, 1..=5 | 7)
16964 || original_parent.is_some()
16965 || original_result.is_some()
16966 || !matches!(&original_outcome,
16967 SemanticPreparedStepOutcome::Skipped { step: issued, status }
16968 if issued.same_handle(step) && *status == lease.status)
16969 {
16970 return Err(SemanticTransitionError::ObservationMismatch);
16971 }
16972 self.steps[&step.token]
16973 .prepared
16974 .as_ref()
16975 .expect("retained original step")
16976 .model_work
16977 .as_ref()
16978 .expect("original work checked above")
16979 .completed_model_calls(&actual, false)?;
16980 return Ok(SemanticCompletedExecutionObservation {
16981 original: step.clone(),
16982 requested_transition,
16983 outcome: original_outcome,
16984 predecessor: None,
16985 successor: None,
16986 model_binding: None,
16987 quantities: [0; 4],
16988 });
16989 }
16990 let parent = self.steps[&step.token]
16991 .inputs
16992 .as_ref()
16993 .ok_or(SemanticTransitionError::ObservationMismatch)?
16994 .header
16995 .view();
16996 let parent = self.publication_read(parent)?[0];
16997 let transition =
16998 validate_prepared_completion(&lease, &parent, &result, parent.instance)?;
16999 if original_parent != Some(parent)
17000 || original_result != Some(result)
17001 || !matches!(&original_outcome,
17002 SemanticPreparedStepOutcome::Completed {
17003 step: issued, bank, transition: issued_transition, ..
17004 } if issued.same_handle(step)
17005 && u64::from(*bank) == lease.bank
17006 && *issued_transition == transition)
17007 {
17008 return Err(SemanticTransitionError::ObservationMismatch);
17009 }
17010 let prepared = self.steps[&step.token]
17011 .prepared
17012 .as_ref()
17013 .expect("retained original step");
17014 if !prepared.observed {
17015 return Err(SemanticTransitionError::ObservationMismatch);
17016 }
17017 let state = prepared
17018 .branches
17019 .get(
17020 usize::try_from(lease.bank)
17021 .map_err(|_| SemanticTransitionError::ObservationMismatch)?,
17022 )
17023 .ok_or(SemanticTransitionError::ObservationMismatch)?
17024 .state
17025 .view();
17026 let state = self.publication_read(state)?[0];
17027 let work = state.execution_work;
17028 if work.overflow != 0
17029 || work.model_once.checked_add(work.native_attempt) != Some(work.raw)
17030 || (transition != SemanticTransitionKind::Drain
17031 && !work.validate_model(
17032 &self.steps[&step.token]
17033 .prepared
17034 .as_ref()
17035 .expect("retained original step")
17036 .model_work
17037 .as_ref()
17038 .expect("original work checked above")
17039 .recording,
17040 false,
17041 ))
17042 {
17043 return Err(SemanticTransitionError::ObservationMismatch);
17044 }
17045 let calls = self.steps[&step.token]
17046 .prepared
17047 .as_ref()
17048 .expect("retained original step")
17049 .model_work
17050 .as_ref()
17051 .expect("original work checked above")
17052 .completed_model_calls(&actual, transition != SemanticTransitionKind::Drain)?;
17053 let identity = |header: PublicationHeader| SemanticPublishedIdentity {
17054 instance: header.instance,
17055 word: header.publication_word,
17056 logical_digest: header.logical_digest,
17057 state_digest: header.state_digest,
17058 };
17059 Ok(SemanticCompletedExecutionObservation {
17060 original: step.clone(),
17061 requested_transition,
17062 outcome: original_outcome,
17063 predecessor: Some(identity(parent)),
17064 successor: (result.advanced == 1).then(|| identity(result.header)),
17065 model_binding: Some((
17066 parent.model_generation,
17067 parent.model_geometry_digest,
17068 parent.model_numerical_digest,
17069 )),
17070 quantities: [work.raw, work.model_once, work.native_attempt, calls],
17071 })
17072 })();
17073 if observation.is_err() {
17074 self.poisoned = true;
17075 }
17076 observation
17077 }
17078
17079 #[cfg(feature = "semantic-policy")]
17083 pub fn prepared_update_measurements(
17084 &mut self,
17085 step: &SemanticPreparedStep,
17086 ) -> Result<Option<SemanticUpdateMeasurements>, SemanticTransitionError> {
17087 let original = self.checked_prepared_step(step, false)?;
17088 let mut streams = original.consumer_streams.clone();
17089 if let Some(reader) = self.readers.get(&step.token) {
17090 streams.extend(reader.consumer_streams.iter().copied());
17091 }
17092 let streams = streams.into_iter().collect::<Vec<_>>();
17093 let binding = self.prepared_model_binding(step, &streams)?;
17094 let observation = (|| {
17095 let prepared = self.steps[&step.token]
17096 .prepared
17097 .as_ref()
17098 .expect("checked owner");
17099 let lease_view = prepared.reader.view();
17100 let result_view = prepared.result.view();
17101 let parent_view = self.steps[&step.token]
17102 .inputs
17103 .as_ref()
17104 .ok_or(SemanticTransitionError::ObservationMismatch)?
17105 .header
17106 .view();
17107 let parent = self.publication_read(parent_view)?[0];
17108 let lease = self.publication_read(lease_view)?[0];
17109 let result = self.publication_read(result_view)?[0];
17110 let transition =
17111 validate_prepared_completion(&lease, &parent, &result, parent.instance)?;
17112 if transition != SemanticTransitionKind::Update {
17113 return Ok(None);
17114 }
17115 let bank = usize::try_from(lease.bank)
17116 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
17117 let (
17118 selection,
17119 canaries,
17120 rows,
17121 protected,
17122 results,
17123 receipts,
17124 refusal,
17125 state,
17126 logits,
17127 work_count,
17128 ) = {
17129 let prepared = self.steps[&step.token]
17130 .prepared
17131 .as_ref()
17132 .expect("checked owner");
17133 let view = prepared
17134 .training_view
17135 .as_ref()
17136 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17137 let branch = prepared
17138 .branches
17139 .get(bank)
17140 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17141 let update = branch
17142 .model_update
17143 .as_ref()
17144 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17145 let output = update
17146 .output
17147 .as_ref()
17148 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17149 let work = prepared
17150 .model_work
17151 .as_ref()
17152 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17153 (
17154 view.selection(),
17155 view.canaries(),
17156 view.roster_rows(),
17157 view.protected_members(),
17158 update.canary_results.view(),
17159 update.forward_receipts.view(),
17160 update.refusal.view(),
17161 branch.state.view(),
17162 [
17163 (output.baseline_logits.data, output.baseline_logits.layout),
17164 (output.candidate_logits.data, output.candidate_logits.layout),
17165 ],
17166 work.recording.events().len() as u64,
17167 )
17168 };
17169 let selection = self.publication_read(selection)?[0];
17170 let canaries = self.publication_read(canaries)?;
17171 let rows = self.publication_read(rows)?;
17172 let protected = self.publication_read(protected)?;
17173 let results = self.publication_read(results)?;
17174 let receipts = self.publication_read(receipts)?;
17175 let refusal = decode_canary_refusal(self.publication_read(refusal)?[0], &results)?;
17176 let state = self.publication_read(state)?[0];
17177 if canaries.len() != 5
17178 || results.len() != 5
17179 || receipts.len() != 2
17180 || selection.status > 3
17181 || selection.row_count != rows.len() as u64
17182 {
17183 return Err(SemanticTransitionError::ObservationMismatch);
17184 }
17185 let mut observations = Vec::with_capacity(5);
17186 for (index, (frozen, measured)) in canaries.into_iter().zip(&results).enumerate() {
17187 let row = rows
17188 .get(
17189 usize::try_from(frozen.row_ordinal)
17190 .map_err(|_| SemanticTransitionError::ObservationMismatch)?,
17191 )
17192 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17193 let lower = f64::from_bits(frozen.lower_bound_bits);
17194 let upper = f64::from_bits(frozen.upper_bound_bits);
17195 let value = f64::from_bits(measured.measurement_bits);
17196 let complete = measured.availability == 2;
17197 let reason_valid = match measured.reason {
17198 0 => {
17199 complete
17200 && value.is_finite()
17201 && value >= lower
17202 && value <= upper
17203 && measured.memory_used <= frozen.memory_limit
17204 && measured.work_used <= frozen.work_limit
17205 }
17206 1 => measured.availability == 1 || (complete && !value.is_finite()),
17207 2 => complete && value.is_finite() && (value < lower || value > upper),
17208 3 => complete && measured.memory_used > frozen.memory_limit,
17209 4 => measured.work_used > frozen.work_limit,
17210 5 => !complete,
17211 6 => complete && frozen.kind == 2,
17212 7 => {
17213 (measured.availability == 1 && matches!(frozen.kind, 1 | 4))
17214 || (complete && frozen.kind == 4)
17215 }
17216 8 => true,
17217 9 => measured.availability == 0,
17218 _ => false,
17219 };
17220 if frozen.evaluator_abi != 3
17221 || frozen.kind != index as u64 + 1
17222 || frozen.task_identity
17223 != identity_words(
17224 *self
17225 .publication
17226 .as_ref()
17227 .expect("checked publication")
17228 .contract_value
17229 .task_identity
17230 .as_bytes(),
17231 )
17232 || row.ordinal != frozen.row_ordinal
17233 || row.identity != frozen.row_identity
17234 || row.content_identity != frozen.row_content_identity
17235 || measured.abi != 1
17236 || measured.kind != frozen.kind
17237 || measured.row_ordinal != frozen.row_ordinal
17238 || measured.identity != frozen.identity
17239 || measured.availability > 2
17240 || !reason_valid
17241 || !lower.is_finite()
17242 || !upper.is_finite()
17243 || lower > upper
17244 || frozen.memory_limit == 0
17245 || frozen.work_limit == 0
17246 || measured.memory_used != results[0].memory_used
17247 || measured.work_used != results[0].work_used
17248 {
17249 return Err(SemanticTransitionError::ObservationMismatch);
17250 }
17251 let begin = usize::try_from(frozen.protected_member_offset)
17252 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
17253 let count = usize::try_from(frozen.protected_member_count)
17254 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
17255 let end = begin
17256 .checked_add(count)
17257 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17258 let positions = protected
17259 .get(begin..end)
17260 .ok_or(SemanticTransitionError::ObservationMismatch)?
17261 .to_vec();
17262 observations.push(SemanticUpdateCanaryMeasurement {
17263 frozen,
17264 protected_positions: positions,
17265 availability: measured.availability,
17266 reason: measured.reason,
17267 measurement_bits: complete.then_some(measured.measurement_bits),
17268 memory_used: measured.memory_used,
17269 work_used: measured.work_used,
17270 });
17271 }
17272 let winning = results
17273 .iter()
17274 .filter(|check| check.reason != 0)
17275 .min_by_key(|check| (check.reason, check.kind));
17276 if winning.map(|check| (check.reason, check.kind))
17277 != refusal.map(|record| (record.reason, record.kind))
17278 || refusal.is_some_and(|record| {
17279 let frozen = &observations[(record.kind - 1) as usize].frozen;
17280 record.selection_identity != selection.identity
17281 || record.lower_bound_bits != frozen.lower_bound_bits
17282 || record.upper_bound_bits != frozen.upper_bound_bits
17283 || record.memory_limit != frozen.memory_limit
17284 || record.work_limit != frozen.work_limit
17285 })
17286 || (result.advanced == 1
17287 && (state.status != 0
17288 || refusal.is_some()
17289 || observations.iter().any(|check| check.availability != 2)))
17290 {
17291 return Err(SemanticTransitionError::ObservationMismatch);
17292 }
17293 let mut forwards = Vec::with_capacity(2);
17294 for (role, receipt) in receipts.iter().enumerate() {
17295 if receipt.availability > 2 {
17296 return Err(SemanticTransitionError::ObservationMismatch);
17297 }
17298 let bytes = receipt.canonical_bytes();
17299 let material = if receipt.availability == 2 {
17300 let (address, layout) = logits[role];
17301 let digest: [u8; 32] = Sha256::digest(&bytes[..bytes.len() - 32]).into();
17302 if receipt.abi != 1
17303 || receipt.role != role as u64
17304 || receipt.work_sequence == 0
17305 || receipt.work_sequence > work_count
17306 || receipt.logits != address
17307 || receipt.scalar_type != layout.scalar_type
17308 || [receipt.row_count, receipt.capacity, receipt.vocabulary]
17309 != layout.dimensions[..3]
17310 || receipt.strides_bytes != layout.strides_bytes[..3]
17311 || receipt.model_geometry_digest != binding.3
17312 || receipt.identity != Identity256::from_bytes(digest)
17313 || receipt.model_numerical_digest == Identity256::default()
17314 || (role == 0
17315 && (receipt.generation != binding.2
17316 || receipt.model_numerical_digest != binding.4))
17317 || (role == 1
17318 && result.advanced == 1
17319 && (receipt.generation != result.header.model_generation
17320 || receipt.model_numerical_digest
17321 != result.header.model_numerical_digest))
17322 {
17323 return Err(SemanticTransitionError::ObservationMismatch);
17324 }
17325 Some(SemanticUpdateForwardReceiptMaterial {
17326 role: receipt.role,
17327 generation: receipt.generation,
17328 work_sequence: receipt.work_sequence,
17329 scalar_type: receipt.scalar_type,
17330 dimensions: [receipt.row_count, receipt.capacity, receipt.vocabulary],
17331 strides_bytes: receipt.strides_bytes,
17332 model_geometry_digest: receipt.model_geometry_digest,
17333 model_numerical_digest: receipt.model_numerical_digest,
17334 logits_digest: receipt.logits_digest,
17335 identity: receipt.identity,
17336 canonical_bytes: bytes,
17337 })
17338 } else {
17339 let mut absent = *receipt;
17342 absent.availability = 0;
17343 if absent.canonical_bytes().iter().any(|&byte| byte != 0)
17344 || result.advanced == 1
17345 {
17346 return Err(SemanticTransitionError::ObservationMismatch);
17347 }
17348 None
17349 };
17350 forwards.push(SemanticUpdateForwardReceipt {
17351 availability: receipt.availability,
17352 material,
17353 });
17354 }
17355 if receipts.iter().all(|receipt| receipt.availability == 2)
17356 && (receipts[0].work_sequence >= receipts[1].work_sequence
17357 || receipts[0].identity == receipts[1].identity)
17358 {
17359 return Err(SemanticTransitionError::ObservationMismatch);
17360 }
17361 Ok(Some(SemanticUpdateMeasurements {
17362 predecessor: binding.0,
17363 successor: binding.1,
17364 bank: bank as u8,
17365 model_generation: binding.2,
17366 model_geometry_digest: binding.3,
17367 model_numerical_digest: binding.4,
17368 transition_status: state.status,
17369 selection,
17370 canaries: observations,
17371 forward_receipts: forwards
17372 .try_into()
17373 .map_err(|_| SemanticTransitionError::ObservationMismatch)?,
17374 canary_refusal: refusal,
17375 }))
17376 })();
17377 if observation.is_err() {
17378 self.poisoned = true;
17379 }
17380 let observation = observation?;
17381 if self.prepared_model_binding(step, &streams)? != binding {
17382 self.poisoned = true;
17383 return Err(SemanticTransitionError::ObservationMismatch);
17384 }
17385 Ok(observation)
17386 }
17387
17388 pub fn prepared_feedback(
17389 &mut self,
17390 step: &SemanticPreparedStep,
17391 consumer_stream: u64,
17392 ) -> Result<(SemanticFeedbackSchema, [DlpackManagedTensor; 6]), SemanticTransitionError> {
17393 self.check_prepared_cold(step)?;
17394 let feedback = &self.steps[&step.token].feedback[0];
17395 let schema = feedback.schema.clone();
17396 let layouts = feedback
17397 .content
17398 .tensors
17399 .iter()
17400 .map(|tensor| {
17401 (
17402 tensor.source.as_ref().expect("feedback owner").clone(),
17403 tensor.layout,
17404 )
17405 })
17406 .collect::<Vec<_>>();
17407 let mut outputs = Vec::with_capacity(6);
17408 for (view, layout) in layouts {
17409 let shape = layout.dimensions[..layout.rank as usize]
17410 .iter()
17411 .map(|&value| value as i64)
17412 .collect();
17413 let strides = layout.strides_bytes[..layout.rank as usize]
17414 .iter()
17415 .map(|&value| (value / layout.element_bytes) as i64)
17416 .collect();
17417 let dtype = match layout.scalar_type {
17418 3 => (1, 64),
17419 6 => (2, 32),
17420 8 => (6, 8),
17421 _ => return Err(SemanticTransitionError::ObservationMismatch),
17422 };
17423 outputs.push(self.export_prepared_view(
17424 step,
17425 view,
17426 shape,
17427 strides,
17428 dtype,
17429 consumer_stream,
17430 )?);
17431 }
17432 Ok((
17433 schema,
17434 outputs
17435 .try_into()
17436 .map_err(|_| SemanticTransitionError::ObservationMismatch)?,
17437 ))
17438 }
17439
17440 pub fn prepared_feedback_records(
17446 &mut self,
17447 step: &SemanticPreparedStep,
17448 consumer_streams: &[u64],
17449 ) -> Result<
17450 (
17451 SemanticPublishedIdentity,
17452 Option<SemanticPublishedIdentity>,
17453 Vec<SemanticFeedbackRecordMaterial>,
17454 ),
17455 SemanticTransitionError,
17456 > {
17457 let binding = self.prepared_model_binding(step, consumer_streams)?;
17458 let inputs = Arc::clone(
17459 self.checked_prepared_step(step, false)?
17460 .inputs
17461 .as_ref()
17462 .ok_or(SemanticTransitionError::ObservationMismatch)?,
17463 );
17464 let ranges = self.publication_read(inputs.ranges.view())?;
17465 let mut records = Vec::new();
17466 for range in ranges
17467 .into_iter()
17468 .filter(|range| matches!(range.role, 15..=17))
17469 {
17470 let original = inputs
17471 .storage
17472 .allocations
17473 .get(
17474 usize::try_from(range.storage_slot)
17475 .map_err(|_| SemanticTransitionError::ObservationMismatch)?,
17476 )
17477 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17478 let capacity = usize::try_from(range.offset_bytes)
17479 .ok()
17480 .and_then(|begin| original.len().checked_sub(begin))
17481 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17482 let view = inputs
17483 .views
17484 .first()
17485 .expect("two publication input banks")
17486 .get(&(range.role, range.index))
17487 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17488 let bytes = self.publication_read(view.clone())?;
17489 match (PublicationMaterialRange {
17490 range,
17491 capacity,
17492 bytes,
17493 })
17494 .into_feedback_record()
17495 {
17496 Ok(record) => records.push(record),
17497 Err(error) => {
17498 self.poisoned = true;
17499 return Err(error);
17500 }
17501 }
17502 }
17503 if self.prepared_model_binding(step, consumer_streams)? != binding {
17504 self.poisoned = true;
17505 return Err(SemanticTransitionError::ObservationMismatch);
17506 }
17507 Ok((binding.0, binding.1, records))
17508 }
17509
17510 #[cfg(feature = "semantic-policy")]
17513 fn prepared_completed_step_witnesses(
17514 &mut self,
17515 step: &SemanticPreparedStep,
17516 consumer_streams: &[u64],
17517 ) -> Result<SemanticCompletedStepWitnessMaterial, SemanticTransitionError> {
17518 let binding = self.prepared_model_binding(step, consumer_streams)?;
17519 let transition = match self.completed_prepared_transition_kind(step)? {
17520 SemanticTransitionKind::Proposal => 1,
17521 SemanticTransitionKind::Recompute => 2,
17522 SemanticTransitionKind::Update => 3,
17523 SemanticTransitionKind::Drain => 4,
17524 };
17525 let (header_view, result_view, actual_view, events) = {
17526 let owner = self.checked_prepared_step(step, false)?;
17527 let inputs = owner
17528 .inputs
17529 .as_ref()
17530 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17531 let prepared = owner.prepared.as_ref().expect("checked prepared owner");
17532 let work = prepared
17533 .model_work
17534 .as_ref()
17535 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17536 (
17537 inputs.header.view(),
17538 prepared.result.view(),
17539 work.actual.view(),
17540 work.recording.events().to_vec(),
17541 )
17542 };
17543 let header = self.publication_read(header_view)?[0];
17544 let result = self.publication_read(result_view)?[0];
17545 let actual = self.publication_read(actual_view)?;
17546 if actual.len() < events.len().saturating_mul(3) {
17547 self.poisoned = true;
17548 return Err(SemanticTransitionError::ObservationMismatch);
17549 }
17550
17551 let mut owner_binding = Vec::new();
17552 owner_binding.extend_from_slice(b"xlog.completed-step-witness-owner.v1\0");
17553 encode_publication_identity(&mut owner_binding, binding.0);
17554 material_u64(&mut owner_binding, u64::from(binding.1.is_some()));
17555 if let Some(successor) = binding.1 {
17556 encode_publication_identity(&mut owner_binding, successor);
17557 }
17558 material_u64(&mut owner_binding, step.token);
17559 material_u64(&mut owner_binding, transition);
17560 let mut owner_hash = Sha256::new();
17561 owner_hash.update(&owner_binding);
17562 let identity = Identity256::from_bytes(owner_hash.finalize().into());
17563
17564 let mut bytes = Vec::new();
17565 bytes.extend_from_slice(b"XLOG-COMPLETED-STEP-WITNESSES\0");
17566 material_u64(&mut bytes, 1);
17567 material_u64(&mut bytes, transition);
17568 encode_publication_identity(&mut bytes, binding.0);
17569 material_u64(&mut bytes, u64::from(binding.1.is_some()));
17570 if let Some(successor) = binding.1 {
17571 encode_publication_identity(&mut bytes, successor);
17572 }
17573 material_u64(&mut bytes, header.model_generation);
17574 material_u64(&mut bytes, header.stream_serial);
17575 material_u64(&mut bytes, header.family_id);
17576 material_u64(&mut bytes, header.proposal);
17577 material_u64(&mut bytes, header.training_cursor);
17578 for value in header.training_rng {
17579 material_u64(&mut bytes, value);
17580 }
17581 material_u64(&mut bytes, result.refusal);
17582 material_u64(&mut bytes, result.advanced);
17583 bytes.extend_from_slice(binding.3.as_bytes());
17584 bytes.extend_from_slice(binding.4.as_bytes());
17585 material_u64(&mut bytes, events.len() as u64);
17586 for (index, event) in events.iter().enumerate() {
17587 material_u64(&mut bytes, event.kind);
17588 material_u64(&mut bytes, event.witness);
17589 material_u64(&mut bytes, event.tensor);
17590 material_u64(&mut bytes, event.rank);
17591 for dimension in event.dimensions {
17592 material_u64(&mut bytes, dimension);
17593 }
17594 for value in &actual[index * 3..index * 3 + 3] {
17595 material_u64(&mut bytes, *value);
17596 }
17597 }
17598 if self.prepared_model_binding(step, consumer_streams)? != binding {
17599 self.poisoned = true;
17600 return Err(SemanticTransitionError::ObservationMismatch);
17601 }
17602 Ok(SemanticCompletedStepWitnessMaterial { identity, bytes })
17603 }
17604
17605 #[cfg(feature = "semantic-policy")]
17609 fn prepared_completed_action_witnesses(
17610 &mut self,
17611 step: &SemanticPreparedStep,
17612 consumer_streams: &[u64],
17613 ) -> Result<SemanticCompletedStepWitnessMaterial, SemanticTransitionError> {
17614 let binding = self.prepared_model_binding(step, consumer_streams)?;
17615 if self.completed_prepared_transition_kind(step)? != SemanticTransitionKind::Proposal {
17616 return Err(publication_input_error(
17617 "completed action witnesses require an original Proposal",
17618 ));
17619 }
17620 let result_view = self
17621 .checked_prepared_step(step, false)?
17622 .prepared
17623 .as_ref()
17624 .expect("checked prepared owner")
17625 .result
17626 .view();
17627 let result = self.publication_read(result_view)?[0];
17628 let tape_index = self.completed_prepared_policy_tape(step)?;
17629 let bank = self.policy_tapes[tape_index]
17630 .prepared_bank
17631 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17632 let (state_view, receipt_view) = {
17633 let prepared = self
17634 .checked_prepared_step(step, false)?
17635 .prepared
17636 .as_ref()
17637 .expect("checked prepared owner");
17638 let branch = &prepared.branches[bank];
17639 (
17640 branch.state.view(),
17641 self.policy_tapes[tape_index].receipts.view(),
17642 )
17643 };
17644 let state = self.publication_read(state_view)?[0];
17645 let receipts = self.publication_read(receipt_view)?;
17646 if result.refusal != 0
17647 || result.advanced != 1
17648 || state.status != 0
17649 || state.blocks != COMPONENT_COUNT as u64
17650 || receipts.len() != COMPONENT_COUNT
17651 || state.proposal.checked_add(1) != Some(state.next_proposal)
17652 || state.next_proposal != result.header.proposal
17653 || receipts
17654 .iter()
17655 .any(|receipt| receipt.proposal != state.proposal)
17656 {
17657 self.poisoned = true;
17658 return Err(SemanticTransitionError::ObservationMismatch);
17659 }
17660
17661 let mut owner_binding = Vec::new();
17662 owner_binding.extend_from_slice(b"xlog.completed-action-witness-owner.v1\0");
17663 encode_publication_identity(&mut owner_binding, binding.0);
17664 encode_publication_identity(
17665 &mut owner_binding,
17666 binding
17667 .1
17668 .ok_or(SemanticTransitionError::ObservationMismatch)?,
17669 );
17670 material_u64(&mut owner_binding, step.token);
17671 material_u64(&mut owner_binding, state.proposal);
17672 let mut owner_hash = Sha256::new();
17673 owner_hash.update(&owner_binding);
17674 let identity = Identity256::from_bytes(owner_hash.finalize().into());
17675
17676 let mut bytes = Vec::new();
17677 bytes.extend_from_slice(b"XLOG-COMPLETED-ACTION-WITNESSES\0");
17678 material_u64(&mut bytes, 1);
17679 encode_publication_identity(&mut bytes, binding.0);
17680 encode_publication_identity(
17681 &mut bytes,
17682 binding
17683 .1
17684 .ok_or(SemanticTransitionError::ObservationMismatch)?,
17685 );
17686 material_u64(&mut bytes, bank as u64);
17687 material_u64(&mut bytes, size_of::<DeviceState>() as u64);
17688 bytes.extend(publication_abi_bytes(&[state]));
17689 material_u64(&mut bytes, receipts.len() as u64);
17690 bytes.extend(publication_abi_bytes(&receipts));
17691 if self.prepared_model_binding(step, consumer_streams)? != binding {
17692 self.poisoned = true;
17693 return Err(SemanticTransitionError::ObservationMismatch);
17694 }
17695 Ok(SemanticCompletedStepWitnessMaterial { identity, bytes })
17696 }
17697
17698 #[cfg(feature = "semantic-policy")]
17699 fn original_initial_prefill_content(
17700 &mut self,
17701 predecessor: SemanticPublishedIdentity,
17702 semantic_root: Identity256,
17703 prefix_extent: u64,
17704 model_generation: u64,
17705 task_identity: Identity256,
17706 task_content: SemanticTaskContentIdentity,
17707 ) -> Result<Option<Vec<u8>>, SemanticTransitionError> {
17708 let Some(retained) = self.retained_initial_prefill.as_ref() else {
17709 return Ok(None);
17710 };
17711 if retained.record.predecessor != predecessor {
17712 return Ok(None);
17713 }
17714 let record = retained.record.clone();
17715 if record.semantic_root != semantic_root
17716 || record.model_generation != model_generation
17717 || record.task_identity != task_identity
17718 || record.task_content != task_content
17719 || record.task_epoch != self.task_epoch
17720 || record.task_identity != retained.task_identity
17721 || record.task_epoch != retained.task_epoch
17722 || record.model_generation != retained.model_generation
17723 || record.tokens.is_empty()
17724 || record.tokens.len() as u64 != prefix_extent
17725 || record.mapping.len() != record.tokens.len()
17726 || record.mapping.iter().enumerate().any(|(position, row)| {
17727 row.source.is_empty() || row.logical_position != position as u64
17728 })
17729 {
17730 self.poisoned = true;
17731 return Err(SemanticTransitionError::ObservationMismatch);
17732 }
17733 let model_seals = initial_prefill_seal_sources(&retained.model)?;
17734 let output_seals = initial_prefill_seal_sources(&retained.output)?;
17735 if model_seals.is_empty()
17736 || output_seals.is_empty()
17737 || model_seals
17738 .iter()
17739 .any(|(role, _, _, _)| !matches!(role, 0 | 18..=25))
17740 || output_seals
17741 .iter()
17742 .any(|(role, _, _, _)| !matches!(role, 4..=13))
17743 {
17744 self.poisoned = true;
17745 return Err(SemanticTransitionError::ObservationMismatch);
17746 }
17747 let mut bytes = Vec::new();
17748 bytes.extend_from_slice(record.semantic_root.as_bytes());
17749 material_u64(&mut bytes, record.model_generation);
17750 bytes.extend_from_slice(record.task_identity.as_bytes());
17751 material_u64(&mut bytes, record.task_epoch);
17752 for identity in [
17753 record.task_content.query,
17754 record.task_content.theory_program,
17755 record.task_content.result,
17756 ] {
17757 bytes.extend_from_slice(identity.as_bytes());
17758 }
17759 material_u64(&mut bytes, record.tokens.len() as u64);
17760 for token in &record.tokens {
17761 material_u64(&mut bytes, *token);
17762 }
17763 material_u64(&mut bytes, record.mapping.len() as u64);
17764 for row in &record.mapping {
17765 material_u64(&mut bytes, row.source.len() as u64);
17766 bytes.extend_from_slice(row.source.as_bytes());
17767 material_u64(&mut bytes, row.offset);
17768 material_u64(&mut bytes, row.logical_position);
17769 }
17770 for seals in [model_seals, output_seals] {
17771 material_u64(&mut bytes, seals.len() as u64);
17772 for (role, index, cells, offset) in seals {
17773 let digest = self.publication_read(cells.view())?;
17774 if offset.checked_add(4).is_none_or(|end| end > digest.len()) {
17775 self.poisoned = true;
17776 return Err(SemanticTransitionError::ObservationMismatch);
17777 }
17778 material_u64(&mut bytes, role);
17779 material_u64(&mut bytes, index);
17780 for word in &digest[offset..offset + 4] {
17781 material_u64(&mut bytes, *word);
17782 }
17783 }
17784 }
17785 Ok(Some(bytes))
17786 }
17787
17788 #[cfg(feature = "semantic-policy")]
17789 #[expect(
17790 clippy::too_many_arguments,
17791 reason = "the original prefill and actual recovered predecessor have independent owners"
17792 )]
17793 fn completed_initial_prefill_material(
17794 &mut self,
17795 predecessor: SemanticPublishedIdentity,
17796 recovered_instance: Identity256,
17797 semantic_root: Identity256,
17798 prefix_extent: u64,
17799 model_generation: u64,
17800 task_identity: Identity256,
17801 task_content: SemanticTaskContentIdentity,
17802 owner: Identity256,
17803 ) -> Result<Option<SemanticCompletedStepWitnessMaterial>, SemanticTransitionError> {
17804 let live_content = self.original_initial_prefill_content(
17805 predecessor,
17806 semantic_root,
17807 prefix_extent,
17808 model_generation,
17809 task_identity,
17810 task_content,
17811 )?;
17812 let (original, content, recovery_referent) =
17813 if let Some(saved) = &self.checkpoint_initial_prefill {
17814 if saved.original != predecessor {
17815 if saved.original.instance == predecessor.instance
17816 || predecessor.word != 0
17817 || recovered_instance != saved.original.instance
17818 || predecessor.logical_digest != saved.original.logical_digest
17819 || predecessor.state_digest != saved.original.state_digest
17820 || live_content.is_some()
17821 {
17822 self.poisoned = true;
17823 return Err(SemanticTransitionError::ObservationMismatch);
17824 }
17825 let referent = saved
17826 .recovery_referent
17827 .as_ref()
17828 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17829 (
17830 saved.original,
17831 saved.content.as_slice(),
17832 Some(referent.as_slice()),
17833 )
17834 } else {
17835 if live_content.as_deref() != Some(saved.content.as_slice()) {
17836 self.poisoned = true;
17837 return Err(SemanticTransitionError::ObservationMismatch);
17838 }
17839 (saved.original, saved.content.as_slice(), None)
17840 }
17841 } else {
17842 let Some(content) = live_content.as_deref() else {
17843 return Ok(None);
17844 };
17845 (predecessor, content, None)
17846 };
17847 let mut bytes = Vec::new();
17848 bytes.extend_from_slice(b"XLOG-INITIAL-PREFILL\0");
17849 material_u64(&mut bytes, 2);
17850 encode_publication_identity(&mut bytes, original);
17851 encode_publication_identity(&mut bytes, predecessor);
17852 if let Some(referent) = recovery_referent {
17853 bytes.push(2);
17854 material_u64(
17855 &mut bytes,
17856 u64::try_from(referent.len())
17857 .map_err(|_| publication_input_error("checkpoint referent exceeds u64"))?,
17858 );
17859 bytes.extend_from_slice(referent);
17860 } else {
17861 bytes.push(1);
17862 }
17863 bytes.extend_from_slice(content);
17864 Ok(Some(completed_action_child_material(
17865 owner,
17866 b"initial-prefill",
17867 0,
17868 &bytes,
17869 )))
17870 }
17871
17872 #[cfg(feature = "semantic-policy")]
17876 pub fn prepared_completed_material_capacity(
17877 &self,
17878 step: &SemanticPreparedStep,
17879 ) -> Result<SemanticCompletedMaterialCapacity, SemanticTransitionError> {
17880 let owner = self.checked_prepared_step(step, false)?;
17881 let build = self
17882 .prepared_segment
17883 .as_ref()
17884 .expect("checked prepared scope");
17885 if !build.finished || build.capturing || build.active || build.submitted || build.completed
17886 {
17887 return Err(publication_input_error(
17888 "completed material capacity requires finished capture before the first submit",
17889 ));
17890 }
17891 if build.requested_kind(step, &self.publication_issuer)? != SemanticTransitionKind::Proposal
17892 {
17893 return Err(publication_input_error(
17894 "completed material capacity requires an original Proposal",
17895 ));
17896 }
17897 let prepared = owner.prepared.as_ref().expect("checked prepared owner");
17898 let inputs = owner
17899 .inputs
17900 .as_ref()
17901 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17902 let work = prepared
17903 .model_work
17904 .as_ref()
17905 .ok_or(SemanticTransitionError::ObservationMismatch)?;
17906 let launches = self
17907 .captured
17908 .as_ref()
17909 .ok_or(SemanticTransitionError::ObservationMismatch)?
17910 .captured_launch_bindings();
17911 if launches.is_empty()
17912 || launches
17913 .iter()
17914 .any(|launch| launch.artifact_sha256.is_none())
17915 {
17916 return Err(SemanticTransitionError::ObservationMismatch);
17917 }
17918 let task = &self
17919 .task
17920 .as_ref()
17921 .ok_or(SemanticTransitionError::ObservationMismatch)?
17922 .0;
17923 let mut capacity = SemanticCompletedMaterialCapacity::default();
17924 let publication_identity_bytes = 3 * 32 + size_of::<u64>();
17925 let component_receipt_bytes = (2 + 9 + 2 + 4 + 4 + 4 + 4 * 3 + 2) * 8 + 2 * 32;
17927 let semantic_receipt_bytes = 42 * size_of::<u64>();
17928 let action_bytes = completed_material_extent(&[
17929 b"XLOG-COMPLETED-ACTION-WITNESSES\0".len(),
17930 4 * 8,
17931 2 * publication_identity_bytes,
17932 size_of::<DeviceState>(),
17933 repeated_material_extent(COMPONENT_COUNT, size_of::<SemanticTransitionReceipt>())?,
17934 ])?;
17935 capacity.add(action_bytes)?;
17936 if let Some(saved) = &self.checkpoint_initial_prefill {
17937 let referent = saved.recovery_referent.as_ref().map_or(0, Vec::len);
17938 capacity.child(
17939 b"initial-prefill",
17940 completed_material_extent(&[
17941 b"XLOG-INITIAL-PREFILL\0".len(),
17942 8,
17943 2 * publication_identity_bytes,
17944 1,
17945 8,
17946 referent,
17947 saved.content.len(),
17948 ])?,
17949 )?;
17950 } else if let Some(retained) = &self.retained_initial_prefill {
17951 let record = &retained.record;
17952 let mut content = completed_material_extent(&[
17953 2 * 32,
17954 2 * 8,
17955 3 * 32,
17956 2 * 8,
17957 repeated_material_extent(record.tokens.len(), 8)?,
17958 2 * 8,
17959 repeated_material_extent(
17960 initial_prefill_seal_sources(&retained.model)?.len(),
17961 6 * 8,
17962 )?,
17963 repeated_material_extent(
17964 initial_prefill_seal_sources(&retained.output)?.len(),
17965 6 * 8,
17966 )?,
17967 ])?;
17968 for row in &record.mapping {
17969 content = completed_material_extent(&[content, 3 * 8, row.source.len()])?;
17970 }
17971 capacity.child(
17972 b"initial-prefill",
17973 completed_material_extent(&[
17974 b"XLOG-INITIAL-PREFILL\0".len(),
17975 8,
17976 2 * publication_identity_bytes,
17977 1,
17978 content,
17979 ])?,
17980 )?;
17981 }
17982 capacity.add(
17983 self.graph
17984 .transition_root_material_capacity()
17985 .map_err(SemanticTransitionError::Semantic)?,
17986 )?;
17987 capacity.add(
17988 self.graph
17989 .admission()
17990 .ok_or(SemanticTransitionError::ObservationMismatch)?
17991 .schema_bytes()
17992 .len(),
17993 )?;
17994 capacity.add(SemanticActionCatalogue::current().canonical_bytes().len())?;
17995 capacity.add(repeated_material_extent(self.codebooks.words.len(), 8)?)?;
17996 capacity.add(completed_material_extent(&[
17997 b"xlog.semantic-action-roster.v1\0".len(),
17998 32 + 8,
17999 repeated_material_extent(self.codebooks.components.len(), 7 * 8)?,
18000 ])?)?;
18001 capacity.add(size_of::<SemanticActionBatchReceipt>())?;
18002 capacity.add(task.completed_result_material().bytes.len())?;
18003 for _ in 0..2 {
18004 capacity.child(b"action-rng", 4 * 8)?;
18005 capacity.child(b"logical-state", publication_identity_bytes)?;
18006 capacity.child(b"lane-admission", semantic_receipt_bytes)?;
18007 for _ in 0..2 {
18008 capacity.child(b"hard-decode-receipt", semantic_receipt_bytes)?;
18009 }
18010 }
18011 capacity.child(b"slot-zero-admission", semantic_receipt_bytes)?;
18012 for component in &self.codebooks.components {
18013 let mask = completed_material_extent(&[8, component.cardinality as usize])?;
18014 capacity.child(b"final-mask", mask)?;
18015 capacity.child(b"active-set", mask)?;
18016 capacity.child(b"component-receipt", component_receipt_bytes)?;
18017 capacity.child(b"pwl-cell", size_of::<SemanticPolicyPwlCell>())?;
18018 capacity.child(b"vjp", size_of::<SemanticPolicySelectedScoreVjp>())?;
18019 }
18020 let editable_program = task.spec().program.editable_program().is_some();
18024 let (delta_kind, evidence_kind, delta_bytes, evidence_prefix) = if editable_program {
18025 (
18026 b"theory-rule-delta".as_slice(),
18027 b"theory-rule-delta-evidence".as_slice(),
18028 b"XLOG-DECODED-RULE-INSERTION\0".len() + 8 + 2 * 32 + (18 + 10) * 4,
18029 2 * 32 + 3 * 8,
18030 )
18031 } else {
18032 (
18033 b"theory-delta".as_slice(),
18034 b"theory-delta-evidence".as_slice(),
18035 b"XLOG-DECODED-SUPPORT-INSERTION\0".len() + 8 + 3 * 32 + (18 + 1 + 10) * 4,
18036 32 + 3 * 8 + (1 + 10) * 4,
18037 )
18038 };
18039 for _ in 0..4 {
18040 capacity.child(delta_kind, delta_bytes)?;
18041 capacity.child(
18042 evidence_kind,
18043 completed_material_extent(&[
18044 evidence_prefix,
18045 2 * semantic_receipt_bytes,
18046 18 * component_receipt_bytes,
18047 ])?,
18048 )?;
18049 }
18050 let mut ground = completed_material_extent(&[
18051 b"XLOG-COMPLETED-TASK-GROUND\0".len(),
18052 17 * 8,
18053 10 * 32,
18054 publication_identity_bytes,
18055 3 * size_of::<SemanticTaskFacts>(),
18056 ])?;
18057 for level in task.priority_levels() {
18058 ground = completed_material_extent(&[
18059 ground,
18060 8,
18061 repeated_material_extent(level.goals.len(), 3 * 8)?,
18062 ])?;
18063 }
18064 capacity.child(b"task-ground", ground)?;
18065 capacity.child(
18066 b"task-scoring-law",
18067 task.spec()
18068 .scoring
18069 .completed_law_bytes(task.identity(), editable_program)?
18070 .len(),
18071 )?;
18072 capacity.child(
18073 b"edit-solution",
18074 b"XLOG-COMPLETED-EDIT-SOLUTION\0".len() + 8 + 64 + 32 + 6 * 8 + 3 * 64 + 68 * 5 * 64,
18075 )?;
18076 capacity.attempt_receipt_bytes = capacity.child(b"attempt-receipt", 4 * 8 + 10 * 32)?;
18077 if let Some(roster) = &inputs.storage.physical_parameter_roster {
18078 let mut names = 0;
18079 for name in roster {
18080 names = completed_material_extent(&[names, name.len()])?;
18081 }
18082 let mut original_records = 0;
18083 for bank in 0..2 {
18084 let model = inputs.views[bank]
18085 .get(&(44, 0))
18086 .ok_or(SemanticTransitionError::ObservationMismatch)?
18087 .len();
18088 let profile = inputs.storage.bank_templates[bank]
18089 .iter()
18090 .find(|range| range.role == 43 && range.index == 0)
18091 .and_then(|range| usize::try_from(range.length_bytes).ok())
18092 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18093 original_records =
18094 original_records.max(completed_material_extent(&[model, profile])?);
18095 }
18096 capacity.child(
18097 b"estimator-bound",
18098 completed_material_extent(&[
18099 b"XLOG-ESTIMATOR-BOUND\0".len(),
18100 4 * 8,
18101 publication_identity_bytes,
18102 8,
18103 3 * 32,
18104 2 * 64,
18105 2 * 32,
18106 6 * 8,
18107 3 * 8,
18108 original_records,
18109 repeated_material_extent(roster.len(), 7 * 8)?,
18110 names,
18111 ])?,
18112 )?;
18113 }
18114 let mut graph = b"XLOG-CAPTURED-CUDA-LAUNCH-BINDINGS\0".len() + 2 * 8;
18115 for launch in launches {
18116 graph = completed_material_extent(&[
18117 graph,
18118 13 * 8 + 32,
18119 launch.module_name.len(),
18120 launch.artifact_name.len(),
18121 launch.function_name.len(),
18122 ])?;
18123 }
18124 let work_bytes = completed_material_extent(&[
18125 b"XLOG-COMPLETED-STEP-WITNESSES\0".len(),
18126 15 * 8,
18127 2 * publication_identity_bytes,
18128 2 * 32,
18129 repeated_material_extent(work.recording.events().len(), (4 + 8 + 3) * 8)?,
18130 ])?;
18131 let numerical = completed_material_extent(&[
18132 b"XLOG-COMPLETED-NUMERICAL-REALIZATION\0".len(),
18133 4 * 8,
18134 graph,
18135 work_bytes,
18136 action_bytes,
18137 ])?;
18138 let mut logits = 0;
18139 for branch in &prepared.branches {
18140 let policy = branch
18141 .policy
18142 .as_ref()
18143 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18144 let field_count = repeated_material_extent(policy.layout.fields.len(), 4)?;
18145 let mut scores = 0;
18146 for field in &policy.layout.fields {
18147 scores = completed_material_extent(&[scores, field.cardinality])?;
18148 }
18149 logits = logits.max(completed_material_extent(&[
18150 b"XLOG-COMPLETED-EDIT-LOGITS\0".len(),
18151 2 * 8,
18152 repeated_material_extent(field_count, 5 * 8)?,
18153 repeated_material_extent(scores, 4 * 4)?,
18154 ])?);
18155 }
18156 let random = b"XLOG-COMPLETED-RANDOM-STATE\0".len() + 11 * 8 + COMPONENT_COUNT * 12 * 8;
18157 capacity.carrier_bytes = [numerical, logits, random];
18158 for bytes in capacity.carrier_bytes {
18159 capacity.add(bytes)?;
18160 }
18161 for plan in inputs
18162 .plans
18163 .iter()
18164 .filter(|plan| matches!(plan.role, 15..=17))
18165 {
18166 let mut bytes = 0;
18167 for bank in &plan.banks {
18168 bytes = bytes.max(
18169 bank.span
18170 .end
18171 .checked_sub(bank.span.start)
18172 .ok_or(SemanticTransitionError::ObservationMismatch)?,
18173 );
18174 }
18175 capacity.add(bytes)?;
18176 }
18177 let mut evidence = REPLAY_EVIDENCE_MAGIC.len() + 2 * 4 + 32 + publication_identity_bytes;
18178 for role in REPLAY_EVIDENCE_ROLES {
18179 let mut bytes = 0;
18180 for bank in &inputs.storage.bank_templates {
18181 let range = bank
18182 .iter()
18183 .find(|range| range.role == role && range.index == 0)
18184 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18185 let slot = usize::try_from(range.storage_slot)
18186 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
18187 let offset = usize::try_from(range.offset_bytes)
18188 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
18189 let allocation = inputs
18190 .storage
18191 .allocations
18192 .get(slot)
18193 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18194 bytes = bytes.max(
18195 allocation
18196 .len()
18197 .checked_sub(offset)
18198 .ok_or(SemanticTransitionError::ObservationMismatch)?,
18199 );
18200 }
18201 evidence = completed_material_extent(&[
18202 evidence,
18203 2 * 4 + size_of::<PublicationRange>() + 8,
18204 bytes,
18205 ])?;
18206 }
18207 capacity.publication_evidence_bytes = evidence;
18208 let custody = prepared
18209 .replay_custody
18210 .as_ref()
18211 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18212 let (parent, provenance) = custody.material_capacity(
18213 &inputs.storage,
18214 self.graph
18215 .transition_root_material_capacity()
18216 .map_err(SemanticTransitionError::Semantic)?,
18217 )?;
18218 capacity.add(parent)?;
18219 capacity.add(provenance)?;
18220 capacity.child(b"pre-action-checkpoint", Self::CHECKPOINT_REFERENT_BYTES)?;
18221 Ok(capacity)
18222 }
18223
18224 #[cfg(feature = "semantic-policy")]
18227 pub fn prepared_completed_action_projection(
18228 &mut self,
18229 step: &SemanticPreparedStep,
18230 consumer_streams: &[u64],
18231 ) -> Result<SemanticCompletedActionProjectionMaterial, SemanticTransitionError> {
18232 let binding = self.prepared_model_binding(step, consumer_streams)?;
18233 if self.completed_prepared_transition_kind(step)? != SemanticTransitionKind::Proposal {
18234 return Err(publication_input_error(
18235 "completed action projection requires an original Proposal",
18236 ));
18237 }
18238 let successor = binding
18239 .1
18240 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18241 let result_view = self
18242 .checked_prepared_step(step, false)?
18243 .prepared
18244 .as_ref()
18245 .expect("checked prepared owner")
18246 .result
18247 .view();
18248 let result = self.publication_read(result_view)?[0];
18249 let parent_header_view = self
18250 .checked_prepared_step(step, false)?
18251 .inputs
18252 .as_ref()
18253 .ok_or(SemanticTransitionError::ObservationMismatch)?
18254 .header
18255 .view();
18256 let parent_header = self.publication_read(parent_header_view)?[0];
18257 if (SemanticPublishedIdentity {
18258 instance: parent_header.instance,
18259 word: parent_header.publication_word,
18260 logical_digest: parent_header.logical_digest,
18261 state_digest: parent_header.state_digest,
18262 }) != binding.0
18263 {
18264 self.poisoned = true;
18265 return Err(SemanticTransitionError::ObservationMismatch);
18266 }
18267 let parent_semantic_digest = parent_header.semantic_digest;
18268 let world_root = self.prepared_parent_root_material(step, &parent_header)?;
18269 let world_root = SemanticCompletedStepWitnessMaterial {
18270 identity: Identity256::from_bytes(world_root.digest),
18271 bytes: world_root
18272 .encode()
18273 .map_err(SemanticTransitionError::Semantic)?,
18274 };
18275 let tape_index = self.completed_prepared_policy_tape(step)?;
18276 let bank = self.policy_tapes[tape_index]
18277 .prepared_bank
18278 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18279 let (
18280 state_view,
18281 receipt_view,
18282 final_mask_view,
18283 active_set_view,
18284 pwl_cell_view,
18285 selected_score_vjp_view,
18286 ) = {
18287 let prepared = self
18288 .checked_prepared_step(step, false)?
18289 .prepared
18290 .as_ref()
18291 .expect("checked prepared owner");
18292 let branch = &prepared.branches[bank];
18293 let tape = &self.policy_tapes[tape_index];
18294 let policy = &tape.policy;
18295 (
18296 branch.state.view(),
18297 tape.receipts.view(),
18298 policy.final_masks.view(),
18299 policy.active_sets.view(),
18300 policy.pwl_cells.view(),
18301 policy.selected_score_vjps.view(),
18302 )
18303 };
18304 let state = self.publication_read(state_view)?[0];
18305 let receipts = self.publication_read(receipt_view)?;
18306 let final_masks = self.publication_read(final_mask_view)?;
18307 let active_sets = self.publication_read(active_set_view)?;
18308 let pwl_cells = self.publication_read(pwl_cell_view)?;
18309 let selected_score_vjps = self.publication_read(selected_score_vjp_view)?;
18310 let schema_generation = {
18311 let admission = self
18312 .graph
18313 .admission()
18314 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18315 SemanticCompletedStepWitnessMaterial {
18316 identity: admission.schema_generation(),
18317 bytes: admission.schema_bytes().to_vec(),
18318 }
18319 };
18320 let catalogue = self.codebooks.binding;
18321 let batch_root = state.action_batch_root;
18322 let (
18323 task_identity,
18324 task_content,
18325 expected_truth,
18326 scoring,
18327 editable_program,
18328 objective_law,
18329 goal,
18330 priority_levels,
18331 task_result,
18332 ) = {
18333 let task = &self
18334 .task
18335 .as_ref()
18336 .ok_or(SemanticTransitionError::ObservationMismatch)?
18337 .0;
18338 (
18339 task.identity(),
18340 task.content_identity(),
18341 task.expected_truth(),
18342 task.spec().scoring,
18343 task.spec().program.editable_program().is_some(),
18344 task.objective_law,
18345 task.goal_witness()
18346 .ok_or(SemanticTransitionError::ObservationMismatch)?,
18347 task.priority_levels().to_vec(),
18348 task.completed_result_material(),
18349 )
18350 };
18351 let executed_slots = [
18355 true,
18356 matches!(state.task_evaluation.lane_refusal[0], 0 | 2),
18357 matches!(state.task_evaluation.lane_refusal[1], 0 | 2),
18358 ];
18359 let expected_query_count =
18360 executed_slots.iter().filter(|executed| **executed).count() as u64 * 3;
18361 let invalid_task_facts =
18362 state
18363 .task_evaluation
18364 .facts
18365 .iter()
18366 .zip(executed_slots)
18367 .any(|(facts, executed)| {
18368 facts.correct.iter().any(|&value| value > 1)
18369 || facts.g > 3
18370 || facts.p > 1
18371 || facts.eligible > 1
18372 || if executed {
18373 facts.truth.iter().any(|&value| value > 3)
18374 || facts
18375 .truth
18376 .iter()
18377 .zip(expected_truth)
18378 .zip(facts.correct)
18379 .any(|((&truth, expected), correct)| {
18380 correct != u64::from(truth == expected as u64)
18381 })
18382 || facts.g != facts.correct.iter().sum::<u64>()
18383 || facts.p != u64::from(facts.correct == [1; 3])
18384 } else {
18385 facts.truth != [0; 3]
18386 || facts.correct != [0; 3]
18387 || facts.g != 0
18388 || facts.p != 0
18389 || facts.eligible != 0
18390 }
18391 });
18392 let invalid_task_scoring = !validate_completed_task_scoring(
18393 scoring,
18394 editable_program,
18395 &priority_levels,
18396 &state.task_evaluation.facts,
18397 &state.work,
18398 state.task_evaluation.lane_refusal,
18399 state.task_evaluation.query_count,
18400 state.task_evaluation.winner,
18401 state.task_evaluation.return_value,
18402 );
18403 if result.refusal != 0
18404 || result.advanced != 1
18405 || state.status != 0
18406 || state.blocks != COMPONENT_COUNT as u64
18407 || receipts.len() != COMPONENT_COUNT
18408 || final_masks.len() != self.codebooks.input_cells
18409 || active_sets.len() != self.codebooks.input_cells
18410 || pwl_cells.len() != COMPONENT_COUNT
18411 || selected_score_vjps.len() != COMPONENT_COUNT
18412 || state.proposal.checked_add(1) != Some(state.next_proposal)
18413 || state.next_proposal != result.header.proposal
18414 || state.stream_serial != result.header.stream_serial
18415 || state.family_id as u64 != result.header.family_id
18416 || state.model_generation as u64 != result.header.model_generation
18417 || state.proposal > u32::MAX as u64
18418 || state.stream_serial >= 1 << 56
18419 || state.family_id > u8::MAX as u32
18420 || state.catalogue_generation > u32::MAX as u64
18421 || state.catalogue_generation != catalogue.generation
18422 || state.catalogue_digest != catalogue.digest
18423 || state.binding_digest != self.codebooks.binding.digest
18424 || self.codebooks.words[10..14]
18425 != identity_words(*schema_generation.identity.as_bytes())
18426 || state.task_evaluation.winner > 2
18427 || state.task_evaluation.query_count != expected_query_count
18428 || invalid_task_facts
18429 || invalid_task_scoring
18430 || state.task_evaluation.facts[state.task_evaluation.winner as usize].eligible != 1
18431 || state
18432 .task_evaluation
18433 .lane_refusal
18434 .iter()
18435 .any(|&code| code > 4)
18436 || (state.task_evaluation.winner != 0
18437 && state.task_evaluation.lane_refusal[state.task_evaluation.winner as usize - 1]
18438 != 0)
18439 || state
18440 .task_evaluation
18441 .facts
18442 .iter()
18443 .any(|facts| facts.eligible > 1)
18444 || final_masks
18445 .iter()
18446 .chain(&active_sets)
18447 .any(|&value| value > 1)
18448 || state.actor_eligible > 1
18449 || state.action_batch.abi != 1
18450 || publication_action_batch_root(&state.action_batch) != batch_root
18451 || result.attempt.action_receipts_digest != batch_root
18452 || state.action_batch.proposal != state.proposal
18453 || state.action_batch.stream_serial != state.stream_serial
18454 || state.action_batch.family_id != u64::from(state.family_id)
18455 || state.action_batch.action_law_generation != state.catalogue_generation
18456 || state.action_batch.model_generation != u64::from(state.model_generation)
18457 || state.action_batch.actor_eligible != state.actor_eligible
18458 || state.action_batch.component_count != COMPONENT_COUNT as u64
18459 || state.action_batch.candidate_count != 3
18460 || state.action_batch.winner != state.task_evaluation.winner
18461 || state.action_batch.total_return_bits != state.task_evaluation.return_value as u64
18462 || state.action_batch.base_word != binding.0.word
18463 || state.action_batch.next_word != successor.word
18464 || state.action_batch.rng_base != state.proposal * COMPONENT_COUNT as u64
18465 || state.action_batch.rng_span != COMPONENT_COUNT as u64
18466 || state.action_batch.rng_successor != state.next_proposal * COMPONENT_COUNT as u64
18467 || state.action_batch.catalogue_digest != state.catalogue_digest
18468 || state.action_batch.semantic_receipts_digest
18469 != publication_semantic_receipts_digest(&state.semantic_receipts)
18470 || state.action_batch.base_logical_digest != binding.0.logical_digest
18471 || state.action_batch.execution_work != state.execution_work
18472 || [0usize, 3, 6]
18473 .into_iter()
18474 .enumerate()
18475 .any(|(candidate, receipt)| {
18476 identity_words(*state.action_batch.candidate_roots[candidate].as_bytes())
18477 != state.semantic_receipts[receipt][16..20]
18478 })
18479 {
18480 self.poisoned = true;
18481 return Err(SemanticTransitionError::ObservationMismatch);
18482 }
18483
18484 let owner = self.prepared_completed_action_witnesses(step, consumer_streams)?;
18485 let owner_identity = owner.identity;
18486 let initial_prefill = self.completed_initial_prefill_material(
18487 binding.0,
18488 parent_header.recovered_instance,
18489 parent_semantic_digest,
18490 parent_header.prefix_extent,
18491 state.model_generation as u64,
18492 task_identity,
18493 task_content,
18494 owner_identity,
18495 )?;
18496 let component_receipts_digest = publication_action_receipts_digest_bytes(
18497 &publication_abi_bytes(&self.codebooks.words),
18498 &receipts,
18499 )?;
18500 if state.action_batch.component_receipts_digest != component_receipts_digest {
18501 self.poisoned = true;
18502 return Err(SemanticTransitionError::ObservationMismatch);
18503 }
18504 let batch_receipt = SemanticCompletedStepWitnessMaterial {
18505 identity: batch_root,
18506 bytes: publication_abi_bytes(&[state.action_batch]),
18507 };
18508
18509 let slot_zero_admission = completed_receipt_material(
18510 owner_identity,
18511 b"slot-zero-admission",
18512 0,
18513 &state.semantic_receipts[0],
18514 );
18515 let lane_admissions: [SemanticCompletedStepWitnessMaterial; 2] =
18516 std::array::from_fn(|lane| {
18517 completed_receipt_material(
18518 owner_identity,
18519 b"lane-admission",
18520 lane as u64,
18521 &state.semantic_receipts[3 + lane * 3],
18522 )
18523 });
18524 let hard_decode_receipts: [[SemanticCompletedStepWitnessMaterial; 2]; 2] =
18525 std::array::from_fn(|lane| {
18526 std::array::from_fn(|slot| {
18527 completed_receipt_material(
18528 owner_identity,
18529 b"hard-decode-receipt",
18530 (lane * 2 + slot) as u64,
18531 &state.semantic_receipts[1 + lane * 3 + slot],
18532 )
18533 })
18534 });
18535
18536 let mut components = Vec::new();
18537 components
18538 .try_reserve_exact(COMPONENT_COUNT)
18539 .map_err(|error| runtime_error("completed action component reservation", error))?;
18540 for (ordinal, (&component, &receipt)) in
18541 self.codebooks.components.iter().zip(&receipts).enumerate()
18542 {
18543 let begin = component.offset as usize;
18544 let end = begin
18545 .checked_add(component.cardinality as usize)
18546 .filter(|&end| end <= final_masks.len())
18547 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18548 let final_mask = &final_masks[begin..end];
18549 let active_set = &active_sets[begin..end];
18550 let pwl_cell = pwl_cells[ordinal];
18551 let selected_score_vjp = selected_score_vjps[ordinal];
18552 let block = (COMPONENT_COUNT as u64)
18553 .checked_mul(state.proposal)
18554 .and_then(|block| block.checked_add(ordinal as u64))
18555 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18556 let packed = (state.stream_serial << 8) | state.family_id as u64;
18557 let expected_counter = [
18558 block as u32,
18559 (block >> 32) as u32,
18560 packed as u32,
18561 (packed >> 32) as u32,
18562 ];
18563 if receipt.ordinal as usize != ordinal
18564 || receipt.ordinal != component.ordinal
18565 || receipt.lane != component.lane
18566 || receipt.slot != component.slot
18567 || receipt.field != component.field
18568 || receipt.kind != component.kind
18569 || receipt.proposal != state.proposal
18570 || receipt.catalogue_generation != catalogue.generation
18571 || receipt.catalogue_digest != catalogue.digest
18572 || receipt.admission_binding != state.binding_digest
18573 || receipt.choice >= component.cardinality
18574 || receipt.legal_count == 0
18575 || receipt.active_count == 0
18576 || receipt.selected_rank >= receipt.legal_count
18577 || final_mask.iter().map(|&value| value as u32).sum::<u32>() != receipt.legal_count
18578 || active_set.iter().map(|&value| value as u32).sum::<u32>() != receipt.active_count
18579 || final_mask[receipt.choice as usize] != 1
18580 || active_set[receipt.choice as usize] != 1
18581 || receipt.cdf_start >= receipt.cdf_end
18582 || receipt.cdf_end > 1 << 63
18583 || receipt.mass != receipt.cdf_end - receipt.cdf_start
18584 || receipt.p == [0; 3]
18585 || receipt.q == [0; 3]
18586 || receipt.factor_denominator == [0; 3]
18587 || receipt.key != [state.catalogue_generation as u32, state.model_generation]
18588 || receipt.counter != expected_counter
18589 || pwl_cell.abi != 1
18590 || pwl_cell.ordinal != ordinal as u64
18591 || pwl_cell.cardinality != u64::from(component.cardinality)
18592 || pwl_cell.legal_count != u64::from(receipt.legal_count)
18593 || pwl_cell.active_count != u64::from(receipt.active_count)
18594 || pwl_cell.selected_rank != u64::from(receipt.selected_rank)
18595 || pwl_cell.singleton != u64::from(receipt.legal_count == 1)
18596 || pwl_cell.maximum_bits >> 32 != 0
18597 || !f32::from_bits(pwl_cell.maximum_bits as u32).is_finite()
18598 || pwl_cell.selected_probability != receipt.p
18599 || pwl_cell.probability_denominator != receipt.q
18600 || selected_score_vjp.abi != 1
18601 || selected_score_vjp.ordinal != ordinal as u64
18602 || selected_score_vjp.choice != u64::from(receipt.choice)
18603 || selected_score_vjp.active_count != u64::from(receipt.active_count)
18604 || selected_score_vjp.selected_active != 1
18605 || selected_score_vjp.singleton != u64::from(receipt.legal_count == 1)
18606 || selected_score_vjp.probability_numerator != receipt.p
18607 || selected_score_vjp.probability_denominator != receipt.q
18608 {
18609 self.poisoned = true;
18610 return Err(SemanticTransitionError::ObservationMismatch);
18611 }
18612
18613 let mut final_mask_bytes = Vec::new();
18614 material_u64(&mut final_mask_bytes, component.cardinality as u64);
18615 final_mask_bytes.extend_from_slice(final_mask);
18616 let final_mask_material = completed_action_child_material(
18617 owner_identity,
18618 b"final-mask",
18619 ordinal as u64,
18620 &final_mask_bytes,
18621 );
18622 let mut active_set_bytes = Vec::new();
18623 material_u64(&mut active_set_bytes, component.cardinality as u64);
18624 active_set_bytes.extend_from_slice(active_set);
18625 let active_set_material = completed_action_child_material(
18626 owner_identity,
18627 b"active-set",
18628 ordinal as u64,
18629 &active_set_bytes,
18630 );
18631 let mut receipt_bytes = Vec::new();
18632 encode_completed_component_receipt(&mut receipt_bytes, receipt);
18633 let component_receipt = completed_action_child_material(
18634 owner_identity,
18635 b"component-receipt",
18636 ordinal as u64,
18637 &receipt_bytes,
18638 );
18639 let pwl_cell = completed_action_child_material(
18640 owner_identity,
18641 b"pwl-cell",
18642 ordinal as u64,
18643 &publication_abi_bytes(&[pwl_cell]),
18644 );
18645
18646 let null = if component.is_text() {
18647 receipt.choice == TEXT_NULL as u32
18648 } else {
18649 component.field != 0
18650 && receipt.choice == 0
18651 && receipt.legal_count == 1
18652 && receipt.active_count == 1
18653 };
18654 let vjp = completed_action_child_material(
18655 owner_identity,
18656 b"vjp",
18657 ordinal as u64,
18658 &publication_abi_bytes(&[selected_score_vjp]),
18659 );
18660 let hard_decode_receipt = (!component.is_text()).then(|| {
18661 hard_decode_receipts[component.lane as usize - 1][component.slot as usize].clone()
18662 });
18663 components.push(SemanticCompletedActionComponentMaterial {
18664 ordinal: receipt.ordinal,
18665 null,
18666 choice: receipt.choice,
18667 legal_count: receipt.legal_count,
18668 active_count: receipt.active_count,
18669 probability_numerator: receipt.p,
18670 probability_denominator: receipt.q,
18671 importance_denominator: receipt.factor_denominator,
18672 cumulative_mass_below: receipt.cumulative_mass_below,
18673 cdf_start: receipt.cdf_start,
18674 cdf_end: receipt.cdf_end,
18675 mass: receipt.mass,
18676 selected_rank: receipt.selected_rank,
18677 draw: receipt.draw,
18678 key: receipt.key,
18679 counter: receipt.counter,
18680 final_mask: final_mask_material,
18681 pwl_cell,
18682 active_set: active_set_material,
18683 vjp,
18684 component_receipt,
18685 hard_decode_receipt,
18686 });
18687 }
18688
18689 let lanes = std::array::from_fn(|lane| {
18690 let text_actions = (0..32)
18691 .filter_map(|slot| {
18692 let receipt = receipts[lane * 68 + slot];
18693 (receipt.choice != TEXT_NULL as u32).then_some((slot as u32, receipt.choice))
18694 })
18695 .collect();
18696 let mut edit_actions = [[0; 18]; 2];
18697 for slot in 0..2 {
18698 for field in 0..18 {
18699 edit_actions[slot][field] = receipts[lane * 68 + 32 + slot * 18 + field].choice;
18700 }
18701 }
18702 SemanticCompletedActionLaneMaterial {
18703 text_actions,
18704 edit_actions,
18705 admitted: state.task_evaluation.lane_refusal[lane] == 0,
18706 refusal_reason: match state.task_evaluation.lane_refusal[lane] {
18707 0 => None,
18708 1 => Some(SemanticTaskRefusal::Scope.canonical_kind()),
18709 2 => Some(SemanticTaskRefusal::HardConstraint.canonical_kind()),
18710 3 => Some(SemanticTaskRefusal::FactCapacity.canonical_kind()),
18711 4 => Some(SemanticTaskRefusal::FuelExhausted.canonical_kind()),
18712 _ => unreachable!("validated lane refusal code"),
18713 },
18714 admission: lane_admissions[lane].clone(),
18715 hard_decode_receipts: hard_decode_receipts[lane].clone(),
18716 }
18717 });
18718
18719 let admission = self
18720 .graph
18721 .admission()
18722 .ok_or(SemanticTransitionError::ObservationMismatch)?;
18723 let task_program = self
18724 .task
18725 .as_ref()
18726 .and_then(|(task, _)| task.spec().program.editable_program())
18727 .cloned();
18728 if let Some(program) = task_program.as_ref() {
18729 let edits = std::array::from_fn(|lane| lanes[lane].edit_actions);
18730 if let Err(error) = validate_program_query_receipts(
18731 program,
18732 task_identity,
18733 &self.codebooks,
18734 &state,
18735 &edits,
18736 ) {
18737 self.poisoned = true;
18738 return Err(error);
18739 }
18740 }
18741 let mut theory_deltas = Vec::new();
18742 for (lane, lane_material) in lanes.iter().enumerate() {
18743 for slot in 0..2 {
18744 let begin = lane * 68 + 32 + slot * 18;
18745 let projected = completed_theory_delta_for_slot(
18746 &self.codebooks,
18747 admission,
18748 task_program.as_ref(),
18749 task_identity,
18750 owner_identity,
18751 parent_semantic_digest,
18752 lane,
18753 slot,
18754 &lane_material.edit_actions[slot],
18755 (slot == 1).then_some(&lane_material.edit_actions[0]),
18756 &state.semantic_receipts[1 + lane * 3 + slot],
18757 &state.semantic_receipts[3 + lane * 3],
18758 &receipts[begin..begin + 18],
18759 state.task_evaluation.lane_refusal[lane],
18760 );
18761 match projected {
18762 Ok(Some(delta)) => theory_deltas.push(delta),
18763 Ok(None) => {}
18764 Err(error) => {
18765 self.poisoned = true;
18766 return Err(error);
18767 }
18768 }
18769 }
18770 }
18771
18772 let base_truth = completed_task_truths(state.task_evaluation.facts[0])?;
18773 let lane_outcomes =
18774 std::array::from_fn(|lane| match state.task_evaluation.lane_refusal[lane] {
18775 0 => SemanticCompletedLaneOutcomeMaterial::Executed(
18776 completed_task_truths(state.task_evaluation.facts[lane + 1])
18777 .expect("validated executed task truth"),
18778 ),
18779 1 => SemanticCompletedLaneOutcomeMaterial::Refused(SemanticTaskRefusal::Scope),
18780 2 => SemanticCompletedLaneOutcomeMaterial::Refused(
18781 SemanticTaskRefusal::HardConstraint,
18782 ),
18783 3 => {
18784 SemanticCompletedLaneOutcomeMaterial::Refused(SemanticTaskRefusal::FactCapacity)
18785 }
18786 4 => SemanticCompletedLaneOutcomeMaterial::Refused(
18787 SemanticTaskRefusal::FuelExhausted,
18788 ),
18789 _ => unreachable!("validated lane refusal code"),
18790 });
18791 let mut ground_bytes = Vec::new();
18792 ground_bytes.extend_from_slice(b"XLOG-COMPLETED-TASK-GROUND\0");
18793 material_u64(&mut ground_bytes, 3);
18794 let structural_cost = objective_law.structural_cost;
18795 ground_bytes.extend_from_slice(structural_cost.unit.as_bytes());
18796 material_u64(&mut ground_bytes, structural_cost.cap);
18797 ground_bytes.extend_from_slice(task_identity.as_bytes());
18798 for identity in [
18799 task_content.query,
18800 task_content.theory_program,
18801 task_content.result,
18802 ] {
18803 ground_bytes.extend_from_slice(identity.as_bytes());
18804 }
18805 for identity in [
18806 goal.semantic_root,
18807 goal.authority_root,
18808 goal.mandatory_links_root,
18809 goal.constraints_root,
18810 ] {
18811 ground_bytes.extend_from_slice(identity.as_bytes());
18812 }
18813 material_u64(&mut ground_bytes, goal.mandatory_link_count);
18814 material_u64(&mut ground_bytes, goal.constraint_count);
18815 material_u64(&mut ground_bytes, priority_levels.len() as u64);
18816 for level in &priority_levels {
18817 material_u64(&mut ground_bytes, level.goals.len() as u64);
18818 for goal in &level.goals {
18819 for value in [
18820 u64::from(goal.query),
18821 u64::from(goal.target_truth),
18822 u64::from(goal.weight),
18823 ] {
18824 material_u64(&mut ground_bytes, value);
18825 }
18826 }
18827 }
18828 encode_publication_identity(&mut ground_bytes, binding.0);
18829 for truth in expected_truth {
18830 material_u64(&mut ground_bytes, truth as u64);
18831 }
18832 for facts in state.task_evaluation.facts {
18833 encode_completed_task_facts(&mut ground_bytes, facts);
18834 }
18835 material_u64(&mut ground_bytes, state.task_evaluation.query_count);
18836 for refusal in state.task_evaluation.lane_refusal {
18837 material_u64(&mut ground_bytes, refusal);
18838 }
18839 for work in state.work {
18840 for value in [
18841 work.edit_commands,
18842 work.added_supports,
18843 work.defined_truth_changes,
18844 ] {
18845 material_u64(&mut ground_bytes, value);
18846 }
18847 }
18848 ground_bytes.extend_from_slice(batch_root.as_bytes());
18849 let task_ground = SemanticCompletedTaskGroundMaterial {
18850 witness: completed_action_child_material(
18851 owner_identity,
18852 b"task-ground",
18853 0,
18854 &ground_bytes,
18855 ),
18856 scoring_law: completed_action_child_material(
18857 owner_identity,
18858 b"task-scoring-law",
18859 0,
18860 &scoring.completed_law_bytes(task_identity, editable_program)?,
18861 ),
18862 scoring,
18863 return_bound: objective_law.return_bound,
18864 structural_cost,
18865 task_identity,
18866 content: task_content,
18867 goal,
18868 priority_levels,
18869 base: binding.0,
18870 expected_truth,
18871 facts: state.task_evaluation.facts,
18872 base_truth,
18873 lane_outcomes,
18874 };
18875
18876 let base_solves = state.task_evaluation.facts[0].eligible == 1
18877 && state.task_evaluation.facts[0].p == 1
18878 && state.task_evaluation.facts[0].correct == [1; 3];
18879 let decisive_lane = (0..2).find(|&lane| {
18880 let facts = state.task_evaluation.facts[lane + 1];
18881 state.task_evaluation.lane_refusal[lane] == 0
18882 && state.semantic_receipts[3 + lane * 3][0] == 0
18883 && state.work[lane].added_supports > 0
18884 && !base_solves
18885 && facts.eligible == 1
18886 && facts.p == 1
18887 && facts.correct == [1; 3]
18888 });
18889 let edit_solution = decisive_lane.map(|lane| {
18890 let component_begin = lane * 68 + 32;
18891 let component_end = lane * 68 + 68;
18892 let mut solution_bytes = Vec::new();
18893 solution_bytes.extend_from_slice(b"XLOG-COMPLETED-EDIT-SOLUTION\0");
18894 material_u64(&mut solution_bytes, 1);
18895 bind_completed_material(&mut solution_bytes, &task_ground.witness);
18896 solution_bytes.extend_from_slice(batch_root.as_bytes());
18897 material_u64(&mut solution_bytes, (lane + 1) as u64);
18898 material_u64(&mut solution_bytes, component_begin as u64);
18899 material_u64(&mut solution_bytes, component_end as u64);
18900 for value in [
18901 state.work[lane].edit_commands,
18902 state.work[lane].added_supports,
18903 state.work[lane].defined_truth_changes,
18904 ] {
18905 material_u64(&mut solution_bytes, value);
18906 }
18907 bind_completed_material(&mut solution_bytes, &lanes[lane].admission);
18908 for receipt in &lanes[lane].hard_decode_receipts {
18909 bind_completed_material(&mut solution_bytes, receipt);
18910 }
18911 for component in &components[lane * 68..(lane + 1) * 68] {
18912 for material in [
18913 &component.component_receipt,
18914 &component.final_mask,
18915 &component.pwl_cell,
18916 &component.active_set,
18917 &component.vjp,
18918 ] {
18919 bind_completed_material(&mut solution_bytes, material);
18920 }
18921 }
18922 SemanticCompletedEditSolutionMaterial {
18923 witness: completed_action_child_material(
18924 owner_identity,
18925 b"edit-solution",
18926 lane as u64,
18927 &solution_bytes,
18928 ),
18929 lane: (lane + 1) as u64,
18930 component_begin: component_begin as u64,
18931 component_end: component_end as u64,
18932 structural_delta: state.work[lane],
18933 resulting_state_receipt: lanes[lane].admission.clone(),
18934 }
18935 });
18936
18937 let mut attempt_bytes = Vec::new();
18938 material_u64(&mut attempt_bytes, result.attempt.abi);
18939 material_u64(&mut attempt_bytes, result.attempt.transition_kind);
18940 attempt_bytes.extend_from_slice(result.attempt.instance.as_bytes());
18941 material_u64(&mut attempt_bytes, result.attempt.base_word);
18942 material_u64(&mut attempt_bytes, result.attempt.next_word);
18943 for digest in [
18944 result.attempt.logical_digest,
18945 result.attempt.action_receipts_digest,
18946 result.attempt.semantic_receipts_digest,
18947 result.attempt.coverage_digest,
18948 result.attempt.replay_head_digest,
18949 result.attempt.intent_head_digest,
18950 result.attempt.acknowledgement_head_digest,
18951 result.attempt.previous_attempt_digest,
18952 result.attempt.receipt_digest,
18953 ] {
18954 attempt_bytes.extend_from_slice(digest.as_bytes());
18955 }
18956 let mut attempt_receipt =
18957 completed_action_child_material(owner_identity, b"attempt-receipt", 0, &attempt_bytes);
18958 attempt_receipt.identity = result.attempt.receipt_digest;
18959 let estimator_bound = if state.actor_eligible == 1 {
18960 self.prepared_completed_estimator_bound(
18961 step,
18962 bank,
18963 &parent_header,
18964 &task_ground.scoring_law,
18965 &batch_receipt,
18966 owner_identity,
18967 )?
18968 } else {
18969 None
18970 };
18971 let projection = SemanticCompletedActionProjectionMaterial {
18972 owner,
18973 initial_prefill,
18974 pre_action_checkpoint: self
18975 .checked_prepared_step(step, false)?
18976 .prepared
18977 .as_ref()
18978 .expect("checked prepared owner")
18979 .replay_custody
18980 .as_ref()
18981 .ok_or(SemanticTransitionError::ObservationMismatch)?
18982 .checkpoint_child
18983 .clone(),
18984 world_root: Some(world_root),
18985 schema_generation,
18986 action_law: SemanticActionCatalogue::current().completed_material(),
18987 edit_codebook: self.codebooks.completed_material(),
18988 roster: self.codebooks.completed_roster_material(),
18989 estimator_bound,
18990 predecessor_semantic_root_digest: parent_semantic_digest,
18991 predecessor: binding.0,
18992 successor,
18993 proposal: state.proposal,
18994 stream_serial: state.stream_serial,
18995 family_id: state.family_id as u64,
18996 action_law_generation: state.catalogue_generation,
18997 model_generation: state.model_generation as u64,
18998 winner: state.task_evaluation.winner,
18999 actor_eligible: state.actor_eligible == 1,
19000 total_return_bits: state.task_evaluation.return_value as u64,
19001 batch_root,
19002 batch_receipt,
19003 result: task_result,
19004 action_rng_base: completed_rng_material(
19005 owner_identity,
19006 0,
19007 state.model_generation as u64,
19008 state.stream_serial,
19009 state.family_id as u64,
19010 state.proposal,
19011 ),
19012 action_rng_successor: completed_rng_material(
19013 owner_identity,
19014 1,
19015 state.model_generation as u64,
19016 state.stream_serial,
19017 state.family_id as u64,
19018 state.next_proposal,
19019 ),
19020 base_logical_state: completed_logical_state_material(owner_identity, 0, binding.0),
19021 successor_logical_state: completed_logical_state_material(owner_identity, 1, successor),
19022 slot_zero_admission,
19023 lanes,
19024 theory_deltas,
19025 components,
19026 task_ground,
19027 edit_solution,
19028 attempt_receipt,
19029 };
19030 if self.prepared_model_binding(step, consumer_streams)? != binding {
19031 self.poisoned = true;
19032 return Err(SemanticTransitionError::ObservationMismatch);
19033 }
19034 Ok(projection)
19035 }
19036
19037 #[cfg(feature = "semantic-policy")]
19038 fn prepared_completed_estimator_bound(
19039 &mut self,
19040 step: &SemanticPreparedStep,
19041 bank: usize,
19042 parent: &PublicationHeader,
19043 scoring_law: &SemanticCompletedStepWitnessMaterial,
19044 batch_receipt: &SemanticCompletedStepWitnessMaterial,
19045 owner_identity: Identity256,
19046 ) -> Result<Option<SemanticCompletedStepWitnessMaterial>, SemanticTransitionError> {
19047 let tape_index = self.completed_prepared_policy_tape(step)?;
19048 let (original, storage, profile) = {
19049 let owner = self.checked_prepared_step(step, false)?;
19050 let inputs = owner.inputs.as_ref().expect("checked original inputs");
19051 let policy = &self.policy_tapes[tape_index].policy;
19052 let Some(profile) =
19053 inputs.views[bank].get(&(SemanticStateRole::RuntimeContract as u64, 0))
19054 else {
19055 return Err(SemanticTransitionError::ObservationMismatch);
19056 };
19057 (
19058 Arc::clone(&policy.text_binding),
19059 Arc::clone(&inputs.storage),
19060 profile.clone(),
19061 )
19062 };
19063 let Some(snapshot) = original.numerical_block_snapshot.as_ref() else {
19064 return Ok(None);
19065 };
19066 let contract = original
19067 .model_contract
19068 .as_ref()
19069 .ok_or(SemanticTransitionError::ObservationMismatch)?;
19070 let contract = self.publication_read(contract.clone())?;
19071 let layout = storage.contract_value.model_contract_layout;
19072 let roster = model_physical_parameter_roster(&contract, layout)?
19073 .ok_or(SemanticTransitionError::ObservationMismatch)?;
19074 let domain = self
19075 .task_training_domain()
19076 .ok_or(SemanticTransitionError::ObservationMismatch)?
19077 .identity();
19078 let bounds = self.publication_read(snapshot.view())?;
19079 if original.physical_blocks != roster.len() as u64
19080 || storage.physical_parameter_roster.as_ref() != Some(&roster)
19081 || roster.len().checked_mul(6) != Some(bounds.len())
19082 || u64::from_le_bytes(
19083 contract[layout.generation_offset as usize..layout.generation_offset as usize + 8]
19084 .try_into()
19085 .map_err(|_| SemanticTransitionError::ObservationMismatch)?,
19086 ) != parent.model_generation
19087 {
19088 self.poisoned = true;
19089 return Err(SemanticTransitionError::ObservationMismatch);
19090 }
19091 let profile = self.publication_read(profile)?;
19095 let mut bytes = b"XLOG-ESTIMATOR-BOUND\0".to_vec();
19096 material_u64(&mut bytes, 1);
19097 material_u64(&mut bytes, 1); material_u64(&mut bytes, 100);
19099 material_u64(&mut bytes, bank as u64);
19100 encode_publication_identity(
19101 &mut bytes,
19102 SemanticPublishedIdentity {
19103 instance: parent.instance,
19104 word: parent.publication_word,
19105 logical_digest: parent.logical_digest,
19106 state_digest: parent.state_digest,
19107 },
19108 );
19109 material_u64(&mut bytes, parent.model_generation);
19110 bytes.extend_from_slice(parent.model_geometry_digest.as_bytes());
19111 bytes.extend_from_slice(parent.model_numerical_digest.as_bytes());
19112 bytes.extend_from_slice(domain.as_bytes());
19113 bind_completed_material(&mut bytes, scoring_law);
19114 bind_completed_material(&mut bytes, batch_receipt);
19115 for offset in [layout.schema_digest_offset, layout.identity_offset] {
19116 bytes.extend_from_slice(&contract[offset as usize..offset as usize + 32]);
19117 }
19118 for offset in [
19119 layout.schema_begin,
19120 layout.schema_bytes,
19121 layout.schema_digest_offset,
19122 layout.generation_offset,
19123 layout.numerical_digest_offset,
19124 layout.identity_offset,
19125 ] {
19126 material_u64(&mut bytes, offset);
19127 }
19128 for material in [&contract, &profile] {
19129 material_u64(&mut bytes, material.len() as u64);
19130 bytes.extend_from_slice(material);
19131 }
19132 material_u64(&mut bytes, roster.len() as u64);
19133 for (name, block) in roster.iter().zip(bounds.as_chunks::<6>().0) {
19134 material_u64(&mut bytes, name.len() as u64);
19135 bytes.extend_from_slice(name.as_bytes());
19136 for value in block {
19137 material_u64(&mut bytes, value.to_bits());
19138 }
19139 }
19140 Ok(Some(completed_action_child_material(
19141 owner_identity,
19142 b"estimator-bound",
19143 0,
19144 &bytes,
19145 )))
19146 }
19147
19148 #[cfg(feature = "semantic-policy")]
19149 fn prepared_completed_numerical_material(
19150 &mut self,
19151 step: &SemanticPreparedStep,
19152 consumer_streams: &[u64],
19153 ) -> Result<SemanticCompletedStepWitnessMaterial, SemanticTransitionError> {
19154 let binding = self.prepared_model_binding(step, consumer_streams)?;
19155 let work = self.prepared_completed_step_witnesses(step, consumer_streams)?;
19156 let action = self.prepared_completed_action_witnesses(step, consumer_streams)?;
19157 let launches = self
19158 .captured
19159 .as_ref()
19160 .ok_or(SemanticTransitionError::ObservationMismatch)?
19161 .captured_launch_bindings();
19162 if launches.is_empty()
19163 || launches
19164 .iter()
19165 .any(|launch| launch.artifact_sha256.is_none())
19166 {
19167 self.poisoned = true;
19168 return Err(SemanticTransitionError::ObservationMismatch);
19169 }
19170 let mut graph = Vec::new();
19171 graph.extend_from_slice(b"XLOG-CAPTURED-CUDA-LAUNCH-BINDINGS\0");
19172 material_u64(&mut graph, 1);
19173 material_u64(&mut graph, launches.len() as u64);
19174 for (ordinal, launch) in launches.iter().enumerate() {
19175 material_u64(&mut graph, ordinal as u64);
19176 material_u64(&mut graph, launch.module_name.len() as u64);
19177 graph.extend_from_slice(launch.module_name.as_bytes());
19178 material_u64(&mut graph, launch.artifact_name.len() as u64);
19179 graph.extend_from_slice(launch.artifact_name.as_bytes());
19180 graph.extend_from_slice(
19181 launch
19182 .artifact_sha256
19183 .as_ref()
19184 .expect("checked captured artifact identity"),
19185 );
19186 material_u64(&mut graph, launch.function_name.len() as u64);
19187 graph.extend_from_slice(launch.function_name.as_bytes());
19188 for dimension in [launch.grid_dim.0, launch.grid_dim.1, launch.grid_dim.2] {
19189 material_u64(&mut graph, dimension as u64);
19190 }
19191 for dimension in [launch.block_dim.0, launch.block_dim.1, launch.block_dim.2] {
19192 material_u64(&mut graph, dimension as u64);
19193 }
19194 material_u64(&mut graph, launch.shared_mem_bytes as u64);
19195 material_u64(&mut graph, launch.parameter_count);
19196 material_u64(&mut graph, u64::from(launch.cooperative));
19197 }
19198
19199 let successor = binding
19200 .1
19201 .ok_or(SemanticTransitionError::ObservationMismatch)?;
19202 let mut owner_binding = Vec::new();
19203 owner_binding.extend_from_slice(b"xlog.completed-numerical-realization-owner.v2\0");
19204 encode_publication_identity(&mut owner_binding, binding.0);
19205 encode_publication_identity(&mut owner_binding, successor);
19206 owner_binding.extend_from_slice(work.identity.as_bytes());
19207 owner_binding.extend_from_slice(action.identity.as_bytes());
19208 let mut graph_hash = Sha256::new();
19209 graph_hash.update(&graph);
19210 owner_binding.extend_from_slice(&graph_hash.finalize());
19211 material_u64(&mut owner_binding, step.token);
19212 let mut owner_hash = Sha256::new();
19213 owner_hash.update(&owner_binding);
19214 let identity = Identity256::from_bytes(owner_hash.finalize().into());
19215
19216 let mut bytes = Vec::new();
19217 bytes.extend_from_slice(b"XLOG-COMPLETED-NUMERICAL-REALIZATION\0");
19218 material_u64(&mut bytes, 2);
19219 material_u64(&mut bytes, graph.len() as u64);
19220 bytes.extend_from_slice(&graph);
19221 material_u64(&mut bytes, work.bytes.len() as u64);
19222 bytes.extend_from_slice(&work.bytes);
19223 material_u64(&mut bytes, action.bytes.len() as u64);
19224 bytes.extend_from_slice(&action.bytes);
19225 if self.prepared_model_binding(step, consumer_streams)? != binding {
19226 self.poisoned = true;
19227 return Err(SemanticTransitionError::ObservationMismatch);
19228 }
19229 Ok(SemanticCompletedStepWitnessMaterial { identity, bytes })
19230 }
19231
19232 #[cfg(feature = "semantic-policy")]
19233 fn prepared_completed_logits_material(
19234 &mut self,
19235 step: &SemanticPreparedStep,
19236 consumer_streams: &[u64],
19237 ) -> Result<SemanticCompletedStepWitnessMaterial, SemanticTransitionError> {
19238 let binding = self.prepared_model_binding(step, consumer_streams)?;
19239 if self.completed_prepared_transition_kind(step)? != SemanticTransitionKind::Proposal {
19240 return Err(publication_input_error(
19241 "completed logits require an original Proposal",
19242 ));
19243 }
19244 let result_view = self.steps[&step.token]
19245 .prepared
19246 .as_ref()
19247 .expect("checked completed step")
19248 .result
19249 .view();
19250 let result = self.publication_read(result_view)?[0];
19251 let tape_index = self.completed_prepared_policy_tape(step)?;
19252 let (scores_view, layout) = {
19253 let policy = &self.policy_tapes[tape_index].policy;
19254 (policy.retained_scores.view(), policy.layout.clone())
19255 };
19256 let scores = self.publication_read(scores_view)?;
19257 if result.refusal != 0
19258 || result.advanced != 1
19259 || scores.len() != layout.retained_score_cells()
19260 || scores.iter().any(|value| !value.is_finite())
19261 {
19262 self.poisoned = true;
19263 return Err(SemanticTransitionError::ObservationMismatch);
19264 }
19265
19266 let successor = binding
19267 .1
19268 .ok_or(SemanticTransitionError::ObservationMismatch)?;
19269 let mut owner_binding = Vec::new();
19270 owner_binding.extend_from_slice(b"xlog.completed-logits-owner.v1\0");
19271 encode_publication_identity(&mut owner_binding, binding.0);
19272 encode_publication_identity(&mut owner_binding, successor);
19273 material_u64(&mut owner_binding, step.token);
19274 let mut owner_hash = Sha256::new();
19275 owner_hash.update(&owner_binding);
19276 let identity = Identity256::from_bytes(owner_hash.finalize().into());
19277
19278 let mut bytes = Vec::new();
19279 bytes.extend_from_slice(b"XLOG-COMPLETED-EDIT-LOGITS\0");
19280 material_u64(&mut bytes, 1);
19281 material_u64(&mut bytes, (4 * layout.fields.len()) as u64);
19282 let stride = layout.retained_score_stride();
19283 let mut next_offset = 0usize;
19284 let field_offsets = layout
19285 .fields
19286 .iter()
19287 .map(|field| {
19288 let offset = next_offset;
19289 next_offset += field.cardinality;
19290 offset
19291 })
19292 .collect::<Vec<_>>();
19293 for lane in 0..2usize {
19294 for slot in 0..2usize {
19295 for (field, field_layout) in layout.fields.iter().enumerate() {
19296 let ordinal = lane * 68 + 32 + slot * 18 + field;
19297 let offset = (lane * 2 + slot) * stride + field_offsets[field];
19298 material_u64(&mut bytes, ordinal as u64);
19299 material_u64(&mut bytes, lane as u64);
19300 material_u64(&mut bytes, slot as u64);
19301 material_u64(&mut bytes, field as u64);
19302 material_u64(&mut bytes, field_layout.cardinality as u64);
19303 for score in &scores[offset..offset + field_layout.cardinality] {
19304 bytes.extend_from_slice(&score.to_bits().to_le_bytes());
19305 }
19306 }
19307 }
19308 }
19309 if self.prepared_model_binding(step, consumer_streams)? != binding {
19310 self.poisoned = true;
19311 return Err(SemanticTransitionError::ObservationMismatch);
19312 }
19313 Ok(SemanticCompletedStepWitnessMaterial { identity, bytes })
19314 }
19315
19316 #[cfg(feature = "semantic-policy")]
19317 fn prepared_completed_random_material(
19318 &mut self,
19319 step: &SemanticPreparedStep,
19320 consumer_streams: &[u64],
19321 ) -> Result<SemanticCompletedStepWitnessMaterial, SemanticTransitionError> {
19322 let binding = self.prepared_model_binding(step, consumer_streams)?;
19323 let (header_view, result_view) = {
19324 let owner = self.checked_prepared_step(step, false)?;
19325 let inputs = owner
19326 .inputs
19327 .as_ref()
19328 .ok_or(SemanticTransitionError::ObservationMismatch)?;
19329 let prepared = owner.prepared.as_ref().expect("checked prepared owner");
19330 (inputs.header.view(), prepared.result.view())
19331 };
19332 let header = self.publication_read(header_view)?[0];
19333 let result = self.publication_read(result_view)?[0];
19334 let tape_index = self.completed_prepared_policy_tape(step)?;
19335 let receipt_view = self.policy_tapes[tape_index].receipts.view();
19336 let receipts = self.publication_read(receipt_view)?;
19337 if result.refusal != 0
19338 || result.advanced != 1
19339 || receipts.len() != COMPONENT_COUNT
19340 || receipts
19341 .iter()
19342 .any(|receipt| receipt.proposal != header.proposal)
19343 {
19344 self.poisoned = true;
19345 return Err(SemanticTransitionError::ObservationMismatch);
19346 }
19347
19348 let mut owner_binding = Vec::new();
19349 owner_binding.extend_from_slice(b"xlog.completed-random-state-owner.v1\0");
19350 encode_publication_identity(&mut owner_binding, binding.0);
19351 material_u64(&mut owner_binding, step.token);
19352 let mut owner_hash = Sha256::new();
19353 owner_hash.update(&owner_binding);
19354 let identity = Identity256::from_bytes(owner_hash.finalize().into());
19355
19356 let mut bytes = Vec::new();
19357 bytes.extend_from_slice(b"XLOG-COMPLETED-RANDOM-STATE\0");
19358 material_u64(&mut bytes, 1);
19359 material_u64(&mut bytes, header.model_generation);
19360 material_u64(&mut bytes, header.stream_serial);
19361 material_u64(&mut bytes, header.family_id);
19362 material_u64(&mut bytes, header.proposal);
19363 material_u64(&mut bytes, header.training_cursor);
19364 for value in header.training_rng {
19365 material_u64(&mut bytes, value);
19366 }
19367 material_u64(&mut bytes, receipts.len() as u64);
19368 for receipt in receipts {
19369 material_u64(&mut bytes, receipt.ordinal as u64);
19370 material_u64(&mut bytes, receipt.draw);
19371 for value in receipt.key {
19372 material_u64(&mut bytes, value as u64);
19373 }
19374 for value in receipt.counter {
19375 material_u64(&mut bytes, value as u64);
19376 }
19377 for value in receipt.random_words {
19378 material_u64(&mut bytes, value as u64);
19379 }
19380 }
19381 if self.prepared_model_binding(step, consumer_streams)? != binding {
19382 self.poisoned = true;
19383 return Err(SemanticTransitionError::ObservationMismatch);
19384 }
19385 Ok(SemanticCompletedStepWitnessMaterial { identity, bytes })
19386 }
19387
19388 #[cfg(feature = "semantic-policy")]
19389 pub fn prepared_completed_model_carrier(
19390 &mut self,
19391 step: &SemanticPreparedStep,
19392 consumer_streams: &[u64],
19393 ) -> Result<Option<SemanticCompletedModelCarrierMaterial>, SemanticTransitionError> {
19394 let binding = self.prepared_model_binding(step, consumer_streams)?;
19395 if self.completed_prepared_transition_kind(step)? != SemanticTransitionKind::Proposal
19396 || binding.1.is_none()
19397 {
19398 return Ok(None);
19399 }
19400 Ok(Some(SemanticCompletedModelCarrierMaterial {
19401 numerical_realization: self
19402 .prepared_completed_numerical_material(step, consumer_streams)?,
19403 logits: self.prepared_completed_logits_material(step, consumer_streams)?,
19404 random_state: self.prepared_completed_random_material(step, consumer_streams)?,
19405 }))
19406 }
19407
19408 pub fn begin_prepared_segment(
19411 &mut self,
19412 resources: Vec<Arc<dyn Send + Sync>>,
19413 ) -> Result<(SemanticPreparedSegmentCapture, Arc<CudaStream>), SemanticTransitionError> {
19414 self.ensure_quiescent()?;
19415 let build = self
19416 .prepared_segment
19417 .as_ref()
19418 .ok_or(SemanticTransitionError::NotBound)?;
19419 if build.capturing || build.finished {
19420 return Err(publication_input_error(
19421 "prepared segment construction already began",
19422 ));
19423 }
19424 let external_floor = build.cold_capacity.external_floor()?;
19425 if build
19426 .cold_reservation
19427 .as_ref()
19428 .is_none_or(|reservation| reservation.remaining_bytes() != external_floor)
19429 || build.tokens.iter().any(|token| {
19430 self.steps
19431 .get(token)
19432 .and_then(|step| step.prepared.as_ref())
19433 .is_none_or(|prepared| {
19434 prepared.digests.is_none() || prepared.model_work.is_none()
19435 })
19436 })
19437 {
19438 return Err(publication_input_error(
19439 "prepared segment lacks its complete frozen native cold allocation roster",
19440 ));
19441 }
19442 self.prepared_resources = resources.clone();
19445 let builder = crate::cuda_graph::ConditionalCudaGraphSequenceBuilder::new_retaining(
19446 &self.stream,
19447 resources,
19448 )
19449 .map_err(|error| runtime_error("bounded segment capture", error))?;
19450 let scope = Arc::clone(&build.scope);
19451 self.prepared_segment
19452 .as_mut()
19453 .expect("checked build")
19454 .capturing = true;
19455 self.graph.enter_transition();
19456 Ok((
19457 SemanticPreparedSegmentCapture { builder, scope },
19458 Arc::clone(&self.stream),
19459 ))
19460 }
19461
19462 fn check_prepared_content_stream(
19463 &self,
19464 step: &SemanticPreparedStep,
19465 consumer_stream: u64,
19466 ) -> Result<(), SemanticTransitionError> {
19467 self.checked_prepared_step(step, true)?;
19468 if dlpack_consumer_stream(consumer_stream)? != self.stream.cu_stream() {
19469 return Err(publication_input_error(
19470 "recorded content must use its original native capture stream",
19471 ));
19472 }
19473 if !self.steps[&step.token]
19474 .prepared
19475 .as_ref()
19476 .expect("prepared owner")
19477 .inputs_recorded
19478 {
19479 return Err(publication_input_error(
19480 "original step inputs must precede recorded content",
19481 ));
19482 }
19483 Ok(())
19484 }
19485
19486 pub fn bind_prepared_model_content(
19489 &mut self,
19490 step: &SemanticPreparedStep,
19491 bank: usize,
19492 tensors: Vec<SemanticTensorInput>,
19493 consumer_stream: u64,
19494 ) -> Result<SemanticTensorContentWitness, SemanticTransitionError> {
19495 self.check_prepared_cold(step)?;
19496 dlpack_consumer_stream(consumer_stream)?;
19497 if bank > 1 {
19498 return Err(publication_input_error(
19499 "prepared model content bank must be zero or one",
19500 ));
19501 }
19502 if self.steps[&step.token].content.iter().any(|content| {
19503 matches!(
19504 &content.seals,
19505 TensorContentSeals::Model(seals)
19506 if seals.prepared.as_ref().is_some_and(|prepared| prepared.bank == bank)
19507 )
19508 }) {
19509 return Err(publication_input_error(
19510 "prepared model content binds once per original branch bank",
19511 ));
19512 }
19513 let storage = Arc::clone(self.publication.as_ref().expect("prepared publication"));
19514 let original = prepare_semantic_tensors(&self.provider, tensors)?;
19515 let directory = &storage.bank_templates[bank];
19516 let indices = model_content_ranges(
19517 directory,
19518 &storage.layouts,
19519 original.iter().map(|tensor| {
19520 (
19521 tensor.layout,
19522 tensor.logical_begin,
19523 tensor.logical_end,
19524 tensor.source.as_ref().map_or(0, DeviceMemoryView::len),
19525 )
19526 }),
19527 )?;
19528 let plan = model_content_copy_plan(
19529 directory,
19530 &indices,
19531 &storage
19532 .allocations
19533 .iter()
19534 .map(TrackedCudaSlice::len)
19535 .collect::<Vec<_>>(),
19536 )?;
19537 let values = original
19538 .iter()
19539 .flat_map(|tensor| [tensor.layout.role, tensor.layout.index])
19540 .collect::<Vec<_>>();
19541 let provider = Arc::clone(&self.provider);
19542 let allocated = (|| {
19543 let reservation = self
19544 .prepared_segment
19545 .as_mut()
19546 .expect("checked prepared segment")
19547 .cold_reservation
19548 .as_mut()
19549 .ok_or(SemanticTransitionError::ObservationMismatch)?;
19550 let seals = ModelContentSeals::allocate_reserved(&provider, &plan, reservation)?;
19551 let roster = reservation
19552 .alloc::<u64>(values.len())
19553 .map_err(|error| runtime_error("prepared model roster allocation", error))?;
19554 Ok::<_, SemanticTransitionError>((seals, roster))
19555 })();
19556 let (mut seals, roster) = match allocated {
19557 Ok(allocated) => allocated,
19558 Err(error) => {
19559 self.poisoned = true;
19560 return Err(error);
19561 }
19562 };
19563 #[cfg(feature = "semantic-policy")]
19564 let execute = self
19565 .provider
19566 .device()
19567 .inner()
19568 .get_func(
19569 "xlog_semantic_transition",
19570 "semantic_publication_model_seals",
19571 )
19572 .ok_or_else(|| {
19573 runtime_error("kernel lookup", "original model seal snapshot unavailable")
19574 })?;
19575 #[cfg(feature = "semantic-policy")]
19576 let reader = self.steps[&step.token]
19577 .prepared
19578 .as_ref()
19579 .expect("prepared lease")
19580 .reader
19581 .view();
19582 seals.prepared = Some(PreparedModelContentSeals {
19583 bank,
19584 #[cfg(feature = "semantic-policy")]
19585 storage,
19586 #[cfg(feature = "semantic-policy")]
19587 reader,
19588 roster,
19589 #[cfg(feature = "semantic-policy")]
19590 execute,
19591 });
19592 let owner = self.steps.get_mut(&step.token).expect("checked fixed step");
19593 owner.consumer_streams.insert(consumer_stream);
19594 let index = owner.content.len();
19595 owner.content.push(TensorContentBuffers {
19596 tensors: original,
19597 seals: TensorContentSeals::Model(seals),
19598 verification_inputs: Vec::new(),
19599 });
19600 let handle = SemanticTensorContentWitness {
19601 issuer: Arc::clone(&self.publication_issuer),
19602 reader_token: step.token,
19603 index,
19604 _witness: Arc::clone(&owner.content_witnesses),
19605 };
19606 let TensorContentSeals::Model(seals) = &owner.content[index].seals else {
19607 unreachable!("installed original model seals")
19608 };
19609 if let Err(error) = upload_publication(
19610 &self.provider,
19611 &values,
19612 &seals
19613 .prepared
19614 .as_ref()
19615 .expect("installed original roster")
19616 .roster,
19617 ) {
19618 self.poisoned = true;
19619 return Err(error);
19620 }
19621 Ok(handle)
19622 }
19623
19624 pub fn bind_prepared_gradient_delivery(
19628 &mut self,
19629 step: &SemanticPreparedStep,
19630 bank: usize,
19631 tensors: Vec<SemanticTensorInput>,
19632 consumer_stream: u64,
19633 ) -> Result<SemanticGradientDeliveryBinding, SemanticTransitionError> {
19634 self.bind_gradient_delivery(step, bank, tensors, consumer_stream, None)
19635 }
19636
19637 #[cfg(feature = "semantic-policy")]
19638 #[expect(
19639 clippy::too_many_arguments,
19640 reason = "gradient delivery retains the destination bank, original source reader and exact member invocation"
19641 )]
19642 pub fn bind_imported_group_gradient_delivery(
19643 &mut self,
19644 step: &SemanticPreparedStep,
19645 bank: usize,
19646 source: &SemanticTransitionSession,
19647 source_lease: &SemanticPublishedLease,
19648 invocation: SemanticRngBinding,
19649 member_ordinal: u64,
19650 member_row: &SemanticTrainingViewRow,
19651 tensors: Vec<SemanticTensorInput>,
19652 consumer_stream: u64,
19653 ) -> Result<SemanticGradientDeliveryBinding, SemanticTransitionError> {
19654 self.check_prepared_cold(step)?;
19655 if bank > 1 {
19656 return Err(publication_input_error(
19657 "group gradient delivery requires bank zero or one",
19658 ));
19659 }
19660 source.checked_reader(source_lease)?;
19661 if std::ptr::eq(self, source)
19662 || self.provider.device().ordinal() != source.provider.device().ordinal()
19663 || source.policy_tapes.iter().all(|tape| {
19664 tape.invocation != invocation
19665 || tape.refusal.is_some()
19666 || tape.prepared_bank.is_some()
19667 || tape.policy.text_binding._witness.reader_token != source_lease.token
19668 })
19669 {
19670 return Err(publication_input_error(
19671 "group gradient delivery requires the original published policy on a distinct same-device Session",
19672 ));
19673 }
19674 let prepared = self.steps[&step.token]
19675 .prepared
19676 .as_ref()
19677 .expect("checked prepared step");
19678 if prepared.group_gradient_members[bank].contains(&member_ordinal) {
19679 return Err(publication_input_error(
19680 "original replay already owns this Update bank's physical gradient delivery",
19681 ));
19682 }
19683 let training = prepared.training_view.as_ref().ok_or_else(|| {
19684 publication_input_error(
19685 "group gradient delivery requires the frozen Update training view",
19686 )
19687 })?;
19688 if training
19689 .actor_group_member_index(member_ordinal, member_row)
19690 .is_err()
19691 && training
19692 .edit_group_member_index(member_ordinal, member_row)?
19693 .is_none()
19694 {
19695 return Err(publication_input_error(
19696 "original replay is absent from the frozen actor and edit groups",
19697 ));
19698 }
19699 let model = source.steps[&source_lease.token]
19700 .content
19701 .iter()
19702 .filter(|content| matches!(&content.seals, TensorContentSeals::Model(_)))
19703 .collect::<Vec<_>>();
19704 let [model] = model.as_slice() else {
19705 return Err(publication_input_error(
19706 "original replay has no unique authenticated physical model roster",
19707 ));
19708 };
19709 let binding = self.bind_gradient_delivery(
19710 step,
19711 bank,
19712 tensors,
19713 consumer_stream,
19714 Some(&model.tensors),
19715 )?;
19716 self.steps
19717 .get_mut(&step.token)
19718 .expect("checked prepared step")
19719 .prepared
19720 .as_mut()
19721 .expect("checked prepared owner")
19722 .group_gradient_members[bank]
19723 .insert(member_ordinal);
19724 Ok(binding)
19725 }
19726
19727 fn bind_gradient_delivery(
19728 &mut self,
19729 step: &SemanticPreparedStep,
19730 bank: usize,
19731 tensors: Vec<SemanticTensorInput>,
19732 consumer_stream: u64,
19733 foreign_model: Option<&[PreparedSemanticTensor]>,
19734 ) -> Result<SemanticGradientDeliveryBinding, SemanticTransitionError> {
19735 self.check_prepared_cold(step)?;
19736 dlpack_consumer_stream(consumer_stream)?;
19737 if bank > 1 || tensors.is_empty() {
19738 return Err(publication_input_error(
19739 "gradient delivery requires one prepared bank and a nonempty physical roster",
19740 ));
19741 }
19742 let imported = prepare_semantic_tensors(&self.provider, tensors)?;
19743 let inputs = self.steps[&step.token]
19744 .inputs
19745 .as_ref()
19746 .expect("fixed input owner");
19747 for tensor in &imported {
19748 let authentic = if let Some(model) =
19749 foreign_model.filter(|_| (18..=20).contains(&tensor.layout.role))
19750 {
19751 model
19752 .iter()
19753 .any(|original| same_tensor_content_owner(original, tensor))
19754 } else {
19755 inputs.owns_bank_model_tensor(bank, tensor)?
19756 };
19757 if !authentic {
19758 return Err(publication_input_error(
19759 "gradient delivery input differs from its authenticated model or prepared bank tensor",
19760 ));
19761 }
19762 }
19763 if let Some(model) = foreign_model {
19764 let expected = model
19765 .iter()
19766 .filter(|tensor| (18..=20).contains(&tensor.layout.role))
19767 .map(|tensor| (tensor.layout.role, tensor.layout.index))
19768 .collect::<BTreeSet<_>>();
19769 let actual_rows = imported
19770 .iter()
19771 .filter(|tensor| (18..=20).contains(&tensor.layout.role));
19772 let actual = actual_rows
19773 .clone()
19774 .map(|tensor| (tensor.layout.role, tensor.layout.index))
19775 .collect::<BTreeSet<_>>();
19776 if actual != expected || actual_rows.count() != actual.len() {
19777 return Err(publication_input_error(
19778 "group gradient delivery requires every original physical model leaf exactly once",
19779 ));
19780 }
19781 }
19782 for role in [
19783 SemanticStateRole::Gradients as u64,
19784 SemanticStateRole::GradientAccumulation as u64,
19785 ] {
19786 let expected = inputs
19787 .plans
19788 .iter()
19789 .filter(|input| input.role == role)
19790 .map(|input| (input.role, input.index))
19791 .collect::<BTreeSet<_>>();
19792 let actual_rows = imported.iter().filter(|tensor| tensor.layout.role == role);
19793 let actual = actual_rows
19794 .clone()
19795 .map(|tensor| (tensor.layout.role, tensor.layout.index))
19796 .collect::<BTreeSet<_>>();
19797 if actual != expected || actual_rows.count() != actual.len() {
19798 return Err(publication_input_error(
19799 "gradient delivery requires every canonical gradient and presence input exactly once",
19800 ));
19801 }
19802 }
19803 let is_phase_mask = |layout: &SemanticTensorLayout| {
19804 layout.role == SemanticStateRole::TrainingSchedule as u64
19805 && layout.element_bytes == 1
19806 && layout.scalar_type == 8
19807 && layout.rank == 1
19808 && layout.logical_axis == u64::MAX
19809 && layout.dimensions == [3, 0, 0, 0]
19810 && layout.strides_bytes == [1, 0, 0, 0]
19811 };
19812 let expected_phase_masks = inputs
19813 .plans
19814 .iter()
19815 .filter(|input| is_phase_mask(&input.layout))
19816 .map(|input| (input.role, input.index))
19817 .collect::<BTreeSet<_>>();
19818 let actual_phase_mask_rows = imported
19819 .iter()
19820 .filter(|tensor| is_phase_mask(&tensor.layout));
19821 let actual_phase_masks = actual_phase_mask_rows
19822 .clone()
19823 .map(|tensor| (tensor.layout.role, tensor.layout.index))
19824 .collect::<BTreeSet<_>>();
19825 if actual_phase_masks != expected_phase_masks
19826 || actual_phase_mask_rows.count() != actual_phase_masks.len()
19827 {
19828 return Err(publication_input_error(
19829 "gradient delivery requires every canonical phase mask exactly once",
19830 ));
19831 }
19832 self.steps
19833 .get_mut(&step.token)
19834 .expect("checked gradient-delivery step")
19835 .consumer_streams
19836 .insert(consumer_stream);
19837 Ok(SemanticGradientDeliveryBinding { _tensors: imported })
19838 }
19839
19840 pub fn capture_prepared_tensor_content(
19844 &mut self,
19845 step: &SemanticPreparedStep,
19846 tensors: Vec<SemanticTensorInput>,
19847 consumer_stream: u64,
19848 ) -> Result<SemanticTensorContentWitness, SemanticTransitionError> {
19849 self.check_prepared_content_stream(step, consumer_stream)?;
19850 if tensors.is_empty() {
19851 return Err(publication_input_error(
19852 "original content requires an actual tensor roster",
19853 ));
19854 }
19855 let original = prepare_semantic_tensors(&self.provider, tensors)?;
19856 let owner = self.steps.get_mut(&step.token).expect("checked fixed step");
19859 let index = owner.content.len();
19860 owner.content.push(TensorContentBuffers {
19861 tensors: original,
19862 seals: TensorContentSeals::Captured(Vec::new()),
19863 verification_inputs: Vec::new(),
19864 });
19865 let result = (|| {
19866 let owner = &self.steps[&step.token];
19867 let original = &owner.content[index].tensors;
19868 validate_content_coordinates(
19869 original
19870 .iter()
19871 .map(|tensor| (tensor.layout.role, tensor.layout.index)),
19872 )?;
19873 let mut digests = Vec::with_capacity(original.len());
19874 let prepared = owner.prepared.as_ref().expect("prepared content owner");
19875 let mut next = prepared.next_digest;
19876 for tensor in original {
19877 let mut native = owner.feedback_origin_digest(tensor)?;
19878 if native.is_none() {
19879 let inputs = owner.inputs.as_ref().expect("fixed step inputs");
19880 if inputs.owns_tensor(tensor)? {
19881 native = Some(CapturedTensorDigest::Publication(Arc::clone(inputs)));
19882 }
19883 }
19884 if let Some(native) = native {
19885 digests.push(native);
19886 continue;
19887 }
19888 for (&token, other) in &self.steps {
19889 if token == step.token {
19890 continue;
19891 }
19892 let other_input = match &other.inputs {
19893 Some(inputs) => inputs.owns_tensor(tensor)?,
19894 None => false,
19895 };
19896 if other.feedback_origin_digest(tensor)?.is_some() || other_input {
19897 return Err(publication_input_error(
19898 "original content belongs to another native prepared step",
19899 ));
19900 }
19901 }
19902 if tensor.native_allocation.is_some() {
19903 return Err(publication_input_error("native allocation origin has no original content producer in this prepared step"));
19904 }
19905 tensor_content_range(
19906 &tensor.layout,
19907 tensor.logical_begin,
19908 tensor.logical_end,
19909 tensor.source.as_ref().map_or(0, DeviceMemoryView::len),
19910 )?;
19911 let cells = prepared
19912 .digests
19913 .as_ref()
19914 .filter(|cells| next < cells.len() / 4)
19915 .ok_or_else(|| {
19916 publication_input_error(
19917 "original tensor roster exceeds its cold native content reservation",
19918 )
19919 })?;
19920 let offset = next * 4;
19921 next += 1;
19922 digests.push(CapturedTensorDigest::Tensor {
19923 cells: Arc::clone(cells),
19924 offset,
19925 producer_sealed: false,
19926 });
19927 }
19928 let owner = self.steps.get_mut(&step.token).expect("checked fixed step");
19929 owner
19930 .prepared
19931 .as_mut()
19932 .expect("prepared content owner")
19933 .next_digest = next;
19934 owner.content[index].seals = TensorContentSeals::Captured(digests);
19935 let handle = SemanticTensorContentWitness {
19936 issuer: Arc::clone(&self.publication_issuer),
19937 reader_token: step.token,
19938 index,
19939 _witness: Arc::clone(&owner.content_witnesses),
19940 };
19941 self.record_prepared_tensor_content(step, &handle, false)?;
19942 Ok(handle)
19943 })();
19944 if result.is_err() {
19945 self.poisoned = true;
19946 }
19947 result
19948 }
19949
19950 fn checked_prepared_content_witness(
19951 &self,
19952 step: &SemanticPreparedStep,
19953 witness: &SemanticTensorContentWitness,
19954 ) -> Result<(), SemanticTransitionError> {
19955 let owner = self.checked_prepared_step(step, false)?;
19956 if witness.reader_token != step.token
19957 || !Arc::ptr_eq(&witness.issuer, &self.publication_issuer)
19958 || !Arc::ptr_eq(&witness._witness, &owner.content_witnesses)
19959 || witness.index >= owner.content.len()
19960 {
19961 return Err(publication_input_error(
19962 "original content witness belongs to another native prepared step",
19963 ));
19964 }
19965 Ok(())
19966 }
19967
19968 pub fn record_prepared_tensor_content(
19969 &mut self,
19970 step: &SemanticPreparedStep,
19971 witness: &SemanticTensorContentWitness,
19972 verify: bool,
19973 ) -> Result<(), SemanticTransitionError> {
19974 self.checked_prepared_step(step, true)?;
19975 self.checked_prepared_content_witness(step, witness)?;
19976 let owner = &self.steps[&step.token];
19977 let execute = &owner
19978 .prepared
19979 .as_ref()
19980 .expect("prepared content owner")
19981 .witness;
19982 owner.content[witness.index].enqueue(&self.domain, &mut self.poisoned, execute, verify)
19983 }
19984
19985 pub fn bind_prepared_continuation(
19991 &mut self,
19992 step: &SemanticPreparedStep,
19993 bank: usize,
19994 continuation: SemanticContinuationInput,
19995 witness: &SemanticTensorContentWitness,
19996 model_content_witness: Option<&SemanticTensorContentWitness>,
19997 consumer_stream: u64,
19998 ) -> Result<(), SemanticTransitionError> {
19999 self.check_prepared_content_stream(step, consumer_stream)?;
20000 self.checked_prepared_content_witness(step, witness)?;
20001 if bank > 1 {
20002 return Err(publication_input_error(
20003 "prepared continuation bank must be zero or one",
20004 ));
20005 }
20006 if self.steps[&step.token]
20007 .prepared
20008 .as_ref()
20009 .expect("prepared owner")
20010 .branches[bank]
20011 .continuation
20012 .is_some()
20013 {
20014 return Err(publication_input_error(
20015 "original prepared continuation binds once",
20016 ));
20017 }
20018 if !matches!(
20019 self.steps[&step.token].content[witness.index].seals,
20020 TensorContentSeals::Captured(_)
20021 ) {
20022 return Err(publication_input_error(
20023 "continuation requires its original transient producer witness",
20024 ));
20025 }
20026 let storage = Arc::clone(self.publication.as_ref().expect("prepared publication"));
20027 let tensor_count = continuation.tensors.len();
20028 let capacity = storage
20029 .contract_value
20030 .feedback_capacity
20031 .checked_add(32)
20032 .ok_or(SemanticTransitionError::GenerationExhausted)?;
20033 let kind = self.prepared_transition_kind(step)?;
20034 let (physical_blocks, model_schema_digest, model_identity) =
20035 storage.continuation_block_contract(kind, &continuation, true)?;
20036 let model_contract = match (physical_blocks, model_content_witness) {
20037 (None, None) => None,
20038 (Some(_), Some(model_witness)) => {
20039 self.checked_prepared_content_witness(step, model_witness)?;
20040 let owner = &self.steps[&step.token];
20041 let TensorContentSeals::Model(seals) = &owner.content[model_witness.index].seals else {
20042 return Err(publication_input_error(
20043 "prepared block bounds require their original model-content witness",
20044 ));
20045 };
20046 let prepared = owner.prepared.as_ref().expect("prepared model owner");
20047 if seals.prepared.as_ref().is_none_or(|source| source.bank != bank)
20048 || prepared.model_content_recorded & (1 << bank) == 0
20049 {
20050 return Err(publication_input_error(
20051 "prepared block bounds require the same bank's recorded model-content guard",
20052 ));
20053 }
20054 Some(seals.contract.view())
20058 }
20059 _ => return Err(publication_input_error(
20060 "prepared proposal blocks and their model-content witness must be supplied together",
20061 )),
20062 };
20063 let service_layouts =
20064 continuation_service_layouts(tensor_count, capacity, physical_blocks)?;
20065 let SemanticContinuationInput {
20066 mut tensors,
20067 authority_decisions,
20068 text_rows,
20069 text_row_count,
20070 selected_text,
20071 active_rows,
20072 active_row_count,
20073 numerical_admissibility,
20074 numerical_blocks,
20075 model_schema_digest: _,
20076 model_identity: _,
20077 } = continuation;
20078 if authority_decisions.is_empty() {
20079 return Err(publication_input_error(
20080 "continuation requires its original authority snapshot geometry",
20081 ));
20082 }
20083 let mut services = vec![
20084 text_rows,
20085 text_row_count,
20086 selected_text,
20087 active_rows,
20088 active_row_count,
20089 numerical_admissibility,
20090 ];
20091 services.extend(numerical_blocks);
20092 tensors.extend(
20093 services
20094 .into_iter()
20095 .zip(service_layouts)
20096 .map(|(tensor, layout)| SemanticTensorInput {
20097 tensor,
20098 layout,
20099 logical_begin: 0,
20100 logical_end: 0,
20101 native_allocation: None,
20102 }),
20103 );
20104 self.verify_prepared_tensor_content(step, witness, tensors, consumer_stream)?;
20105 let numerical_block_snapshot = if physical_blocks.is_some() {
20106 let original =
20107 self.steps[&step.token].content[witness.index].tensors[tensor_count + 6].clone();
20108 let snapshot = Arc::clone(
20109 self.steps[&step.token]
20110 .prepared
20111 .as_ref()
20112 .expect("prepared owner")
20113 .branches[bank]
20114 .numerical_block_snapshot
20115 .as_ref()
20116 .ok_or_else(|| {
20117 publication_input_error(
20118 "prepared block bounds lack their reserved native slot",
20119 )
20120 })?,
20121 );
20122 enqueue_numerical_block_snapshot(
20123 &self.domain,
20124 &mut self.poisoned,
20125 &original,
20126 &snapshot,
20127 )?;
20128 Some(snapshot)
20129 } else {
20130 None
20131 };
20132 let owner = &self.steps[&step.token];
20133 let original = &owner.content[witness.index].tensors;
20134 let services = original[tensor_count..].to_vec();
20135 if services.len() != 6 + usize::from(physical_blocks.is_some()) {
20136 return Err(publication_input_error(
20137 "continuation witness has the wrong original service roster",
20138 ));
20139 }
20140 let binding = Arc::new(TextBindingStorage {
20141 inputs: services,
20142 numerical_block_snapshot,
20143 model_contract,
20144 physical_blocks: physical_blocks.unwrap_or(0) as u64,
20145 model_schema_digest,
20146 model_identity,
20147 _witness: witness.clone(),
20148 _model_content_witness: model_content_witness.cloned(),
20149 consumer_stream,
20150 parent: TextBindingParent::Prepared(Arc::clone(
20151 owner.inputs.as_ref().expect("fixed inputs"),
20152 )),
20153 });
20154 let kind = self
20155 .prepared_segment
20156 .as_ref()
20157 .expect("prepared scope")
20158 .requested_kind(step, &self.publication_issuer)?;
20159 let (uploads, layouts) = prepare_continuation_payloads(
20160 &storage,
20161 &original[..tensor_count],
20162 &authority_decisions,
20163 kind,
20164 )?;
20165 let training_selection = match (
20166 kind,
20167 owner
20168 .prepared
20169 .as_ref()
20170 .expect("prepared selection owner")
20171 .training_view
20172 .as_ref(),
20173 ) {
20174 (SemanticTransitionKind::Update, Some(view)) => Some(view.selection()),
20175 (SemanticTransitionKind::Update, None) => {
20176 return Err(publication_input_error(
20177 "prepared update continuation has no native training selection",
20178 ));
20179 }
20180 (_, None) => None,
20181 (_, Some(_)) => {
20182 return Err(publication_input_error(
20183 "non-update continuation owns an unexpected training selection",
20184 ));
20185 }
20186 };
20187 let training_selection_pointer = training_selection
20188 .as_ref()
20189 .map_or(0, |selection| *selection.device_ptr());
20190 let model_update = owner
20191 .prepared
20192 .as_ref()
20193 .expect("prepared model update owner")
20194 .branches[bank]
20195 .model_update
20196 .as_ref()
20197 .map(PreparedModelUpdate::descriptor)
20198 .unwrap_or_default();
20199 let continuation = PreparedContinuation::prepare(
20200 &self.provider,
20201 storage,
20202 owner
20203 .prepared
20204 .as_ref()
20205 .expect("prepared lease")
20206 .reader
20207 .view(),
20208 Arc::clone(&binding),
20209 binding.continuation_inputs(
20210 kind,
20211 authority_decisions.len() as u64,
20212 training_selection_pointer,
20213 model_update,
20214 ),
20215 training_selection,
20216 &uploads,
20217 &layouts,
20218 )?;
20219 self.steps
20220 .get_mut(&step.token)
20221 .expect("checked prepared step")
20222 .prepared
20223 .as_mut()
20224 .expect("prepared owner")
20225 .branches[bank]
20226 .continuation = Some(continuation);
20227 #[cfg(feature = "semantic-policy")]
20228 self.attach_prepared_policy_continuation(step, bank)?;
20229 Ok(())
20230 }
20231
20232 pub fn record_prepared_model_forward(
20240 &mut self,
20241 step: &SemanticPreparedStep,
20242 bank: usize,
20243 role: usize,
20244 logits: SemanticTensorInput,
20245 consumer_stream: u64,
20246 ) -> Result<SemanticModelForwardWitness, SemanticTransitionError> {
20247 self.check_prepared_content_stream(step, consumer_stream)?;
20248 if bank > 1 || role > 1 {
20249 return Err(publication_input_error(
20250 "prepared model forward bank and role must be zero or one",
20251 ));
20252 }
20253 if self.prepared_transition_kind(step)? != SemanticTransitionKind::Update {
20254 return Err(publication_input_error(
20255 "model forward receipts belong only to a prepared update",
20256 ));
20257 }
20258 let content = self.capture_prepared_tensor_content(step, vec![logits], consumer_stream)?;
20259 let storage = Arc::clone(self.publication.as_ref().expect("prepared publication"));
20260 let owner = self
20261 .steps
20262 .get_mut(&step.token)
20263 .expect("checked update step");
20264 let prepared = owner.prepared.as_mut().expect("prepared update owner");
20265 if prepared
20266 .model_work
20267 .as_ref()
20268 .is_none_or(|work| work.capture_bank != Some(bank))
20269 {
20270 return Err(publication_input_error(
20271 "model forward receipt requires the active producer bank capture",
20272 ));
20273 }
20274 let training_view = prepared.training_view.as_ref().ok_or_else(|| {
20275 publication_input_error("prepared update has no native training view")
20276 })?;
20277 let work_sequence = prepared
20278 .model_work
20279 .as_ref()
20280 .expect("active model work checked above")
20281 .next_slot()
20282 .map_err(publication_input_error)?;
20283 if work_sequence == 0 {
20284 return Err(publication_input_error(
20285 "model forward receipt requires recorded producer work before the logits occurrence",
20286 ));
20287 }
20288 let tensor = owner.content[content.index]
20289 .tensors
20290 .first()
20291 .ok_or(SemanticTransitionError::ObservationMismatch)?
20292 .clone();
20293 let layout = tensor.layout;
20294 let row_count = training_view.roster_rows().len() as u64;
20295 let capacity = training_view.capacity() as u64;
20296 if !matches!(
20297 (layout.scalar_type, layout.element_bytes),
20298 (4, 2) | (5, 2) | (6, 4)
20299 ) || layout.role != 0
20300 || layout.index != role as u64
20301 || layout.rank != 3
20302 || layout.logical_axis != u64::MAX
20303 || layout.dimensions[0] != row_count
20304 || layout.dimensions[1] != capacity
20305 || layout.dimensions[2] == 0
20306 || layout.dimensions[3] != 0
20307 || layout.strides_bytes[2] != layout.element_bytes
20308 || layout.strides_bytes[1]
20309 != layout.dimensions[2]
20310 .checked_mul(layout.element_bytes)
20311 .unwrap_or(0)
20312 || layout.strides_bytes[0]
20313 != layout.dimensions[1]
20314 .checked_mul(layout.strides_bytes[1])
20315 .unwrap_or(0)
20316 || layout.strides_bytes[3] != 0
20317 || tensor.logical_begin != 0
20318 || tensor.logical_end != 0
20319 {
20320 return Err(publication_input_error(
20321 "model forward logits must be aligned contiguous F16/BF16/F32 [rows,capacity,vocabulary] with its explicit role",
20322 ));
20323 }
20324 let TensorContentSeals::Captured(digests) = &owner.content[content.index].seals else {
20325 return Err(SemanticTransitionError::ObservationMismatch);
20326 };
20327 let (logits_digest, digest_cells) = captured_tensor_digest_pointer(digests, 0)?;
20328 let update = prepared.branches[bank]
20329 .model_update
20330 .as_mut()
20331 .ok_or_else(|| publication_input_error("prepared branch has no model update"))?;
20332 if update.forward_recorded != role as u8 {
20333 return Err(publication_input_error(
20334 "model forwards must be recorded exactly once in baseline then candidate order",
20335 ));
20336 }
20337 update.forward_recorded += 1;
20338 let receipt = update.forward_receipts.device_ptr_value()
20339 + (role * size_of::<ModelForwardReceipt>()) as u64;
20340 let inputs = ModelForwardReceiptInputs {
20341 control: storage.control.device_ptr_value(),
20342 lease: prepared.reader.device_ptr_value(),
20343 candidate_seals: update.forward_seals.device_ptr_value(),
20344 candidate_seal_count: update.forward_seals.len() as u64,
20345 role: role as u64,
20346 work_sequence: work_sequence as u64,
20347 logits: tensor.data,
20348 scalar_type: layout.scalar_type,
20349 row_count,
20350 capacity,
20351 vocabulary: layout.dimensions[2],
20352 row_stride_bytes: layout.strides_bytes[0],
20353 position_stride_bytes: layout.strides_bytes[1],
20354 vocabulary_stride_bytes: layout.strides_bytes[2],
20355 logits_digest,
20356 receipt,
20357 };
20358 let mut recorder = self.domain.new_strict_recorder();
20359 storage.record(&mut recorder);
20360 recorder.read(&prepared.reader);
20361 recorder.read(&update.forward_seals);
20362 recorder.read(digest_cells.as_ref());
20363 recorder.write(&update.forward_receipts);
20364 let result = enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
20365 unsafe {
20368 update.forward_receipt.clone().launch_in(
20369 enqueue,
20370 LaunchConfig {
20371 grid_dim: (1, 1, 1),
20372 block_dim: (1, 1, 1),
20373 shared_mem_bytes: 0,
20374 },
20375 (inputs,),
20376 )
20377 }
20378 .map_err(|error| XlogError::Kernel(error.to_string()))
20379 });
20380 if result.is_err() {
20381 self.poisoned = true;
20382 }
20383 result?;
20384 Ok(SemanticModelForwardWitness {
20385 issuer: Arc::clone(&self.publication_issuer),
20386 reader_token: step.token,
20387 bank,
20388 role,
20389 content,
20390 })
20391 }
20392
20393 #[expect(
20394 clippy::too_many_arguments,
20395 reason = "the native update handoff binds model geometry, numerical validity and canary evidence"
20396 )]
20397 pub fn bind_prepared_update_output(
20398 &mut self,
20399 step: &SemanticPreparedStep,
20400 bank: usize,
20401 mut model_memory: SemanticModelMemory,
20402 mut tensors: Vec<SemanticTensorInput>,
20403 admissibility: SemanticTensorInput,
20404 slab_backing: SemanticTensorInput,
20405 baseline_forward: &SemanticModelForwardWitness,
20406 candidate_forward: &SemanticModelForwardWitness,
20407 witness: &SemanticTensorContentWitness,
20408 consumer_stream: u64,
20409 ) -> Result<(), SemanticTransitionError> {
20410 self.check_prepared_content_stream(step, consumer_stream)?;
20411 self.checked_prepared_content_witness(step, witness)?;
20412 if bank > 1 {
20413 return Err(publication_input_error(
20414 "prepared model update bank must be zero or one",
20415 ));
20416 }
20417 for (role, forward) in [(0, baseline_forward), (1, candidate_forward)] {
20418 if !Arc::ptr_eq(&forward.issuer, &self.publication_issuer)
20419 || forward.reader_token != step.token
20420 || forward.bank != bank
20421 || forward.role != role
20422 {
20423 return Err(publication_input_error(
20424 "model update requires exact producer-issued baseline and candidate forward witnesses",
20425 ));
20426 }
20427 }
20428 if self.prepared_transition_kind(step)? != SemanticTransitionKind::Update {
20429 return Err(publication_input_error(
20430 "model update output belongs only to a prepared update",
20431 ));
20432 }
20433 if self.steps[&step.token]
20434 .prepared
20435 .as_ref()
20436 .expect("prepared update owner")
20437 .branches[bank]
20438 .model_update
20439 .as_ref()
20440 .is_none_or(|update| update.output.is_some())
20441 {
20442 return Err(publication_input_error(
20443 "prepared update output binds exactly once",
20444 ));
20445 }
20446 if !matches!(
20447 self.steps[&step.token].content[witness.index].seals,
20448 TensorContentSeals::Captured(_)
20449 ) {
20450 return Err(publication_input_error(
20451 "model update output requires its original transient producer witness",
20452 ));
20453 }
20454 let allocation_count = model_memory.allocations.len();
20455 if allocation_count == 0 {
20456 return Err(publication_input_error(
20457 "model update output requires complete backing allocations",
20458 ));
20459 }
20460 let tensor_count = tensors.len();
20461 model_memory.allocations.append(&mut tensors);
20462 model_memory.allocations.push(admissibility);
20463 self.verify_prepared_tensor_content(
20464 step,
20465 witness,
20466 model_memory.allocations,
20467 consumer_stream,
20468 )?;
20469 let storage = Arc::clone(self.publication.as_ref().expect("prepared publication"));
20470 let outputs = self.steps[&step.token].content[witness.index]
20471 .tensors
20472 .clone();
20473 let (allocations, outputs) = outputs.split_at(allocation_count);
20474 let (tensors, update_metadata) = outputs.split_at(tensor_count);
20475 let [admissibility] = update_metadata else {
20476 return Err(publication_input_error(
20477 "model update output requires numerical admissibility",
20478 ));
20479 };
20480 let forward_tensor = |forward: &SemanticModelForwardWitness| {
20481 self.steps[&step.token].content[forward.content.index]
20482 .tensors
20483 .first()
20484 .cloned()
20485 .ok_or(SemanticTransitionError::ObservationMismatch)
20486 };
20487 let baseline_logits = forward_tensor(baseline_forward)?;
20488 let candidate_logits = forward_tensor(candidate_forward)?;
20489 let allocation_index = u64::try_from(allocation_count)
20490 .map_err(|_| SemanticTransitionError::GenerationExhausted)?;
20491 if admissibility.layout
20492 != (SemanticTensorLayout {
20493 role: 0,
20494 index: allocation_index,
20495 element_bytes: 1,
20496 scalar_type: 8,
20497 rank: 1,
20498 logical_axis: u64::MAX,
20499 dimensions: [1, 0, 0, 0],
20500 strides_bytes: [1, 0, 0, 0],
20501 })
20502 || admissibility.logical_begin != 0
20503 || admissibility.logical_end != 0
20504 {
20505 return Err(publication_input_error(
20506 "model update numerical admissibility must be Bool8[1]",
20507 ));
20508 }
20509 let training_view = self.steps[&step.token]
20510 .prepared
20511 .as_ref()
20512 .expect("prepared update owner")
20513 .training_view
20514 .as_ref()
20515 .ok_or_else(|| {
20516 publication_input_error("prepared update has no native training view")
20517 })?;
20518 let row_count = training_view.roster_rows().len() as u64;
20519 let capacity = training_view.capacity() as u64;
20520 let layout_valid = |tensor: &PreparedSemanticTensor, index: u64| {
20521 let layout = tensor.layout;
20522 matches!(layout.scalar_type, 4..=6)
20523 && matches!(
20524 (layout.scalar_type, layout.element_bytes),
20525 (4, 2) | (5, 2) | (6, 4)
20526 )
20527 && layout.role == 0
20528 && layout.index == index
20529 && layout.rank == 3
20530 && layout.logical_axis == u64::MAX
20531 && layout.dimensions[0] == row_count
20532 && layout.dimensions[1] == capacity
20533 && layout.dimensions[2] > 0
20534 && layout.dimensions[3] == 0
20535 && layout.strides_bytes[2] == layout.element_bytes
20536 && layout.strides_bytes[1]
20537 == layout.dimensions[2]
20538 .checked_mul(layout.element_bytes)
20539 .unwrap_or(0)
20540 && layout.strides_bytes[0]
20541 == layout.dimensions[1]
20542 .checked_mul(layout.strides_bytes[1])
20543 .unwrap_or(0)
20544 && layout.strides_bytes[3] == 0
20545 && tensor.logical_begin == 0
20546 && tensor.logical_end == 0
20547 };
20548 if !layout_valid(&baseline_logits, 0)
20549 || !layout_valid(&candidate_logits, 1)
20550 || baseline_logits.layout.scalar_type != candidate_logits.layout.scalar_type
20551 || baseline_logits.layout.dimensions != candidate_logits.layout.dimensions
20552 || baseline_logits.layout.strides_bytes != candidate_logits.layout.strides_bytes
20553 {
20554 return Err(publication_input_error(
20555 "model update canary logits must be aligned contiguous F16/BF16/F32 [rows,capacity,vocabulary]",
20556 ));
20557 }
20558 let geometry = prepare_model_memory(
20559 allocations,
20560 model_memory.storages,
20561 model_memory.views,
20562 tensors,
20563 )?;
20564 let actual_layouts = tensors
20565 .iter()
20566 .map(|tensor| ((tensor.layout.role, tensor.layout.index), tensor.layout))
20567 .collect::<BTreeMap<_, _>>();
20568 let expected_layouts = storage
20569 .layouts
20570 .iter()
20571 .filter(|((role, _), _)| matches!(role, 18..=25))
20572 .map(|(key, layout)| (*key, *layout))
20573 .collect::<BTreeMap<_, _>>();
20574 if geometry != storage.model_memory || actual_layouts != expected_layouts {
20575 return Err(publication_input_error(
20576 "model update output differs from the acquired model memory contract",
20577 ));
20578 }
20579 let TensorContentSeals::Captured(digests) =
20580 &self.steps[&step.token].content[witness.index].seals
20581 else {
20582 return Err(SemanticTransitionError::ObservationMismatch);
20583 };
20584 let mut forward_seal_values = Vec::new();
20585 let mut digest_cells = Vec::new();
20586 for range in storage.bank_templates[0]
20587 .iter()
20588 .filter(|range| matches!(range.role, 18..=25))
20589 {
20590 let tensor_index = tensors
20591 .iter()
20592 .position(|tensor| {
20593 (tensor.layout.role, tensor.layout.index) == (range.role, range.index)
20594 })
20595 .ok_or(SemanticTransitionError::ObservationMismatch)?;
20596 let (allocation_index, _) = geometry.location(range.role, range.index)?;
20597 let (tensor_digest, tensor_cells) =
20598 captured_tensor_digest_pointer(digests, allocation_count + tensor_index)?;
20599 let (backing_digest, backing_cells) =
20600 captured_tensor_digest_pointer(digests, allocation_index)?;
20601 forward_seal_values.push(ModelForwardSealInput {
20602 role: range.role,
20603 index: range.index,
20604 tensor_digest,
20605 backing_digest,
20606 });
20607 digest_cells.push(tensor_cells);
20608 digest_cells.push(backing_cells);
20609 }
20610 let forward_digest = |forward: &SemanticModelForwardWitness| {
20611 let TensorContentSeals::Captured(digests) =
20612 &self.steps[&step.token].content[forward.content.index].seals
20613 else {
20614 return Err(SemanticTransitionError::ObservationMismatch);
20615 };
20616 captured_tensor_digest_pointer(digests, 0)
20617 };
20618 let (_, baseline_digest_cells) = forward_digest(baseline_forward)?;
20619 let (_, candidate_digest_cells) = forward_digest(candidate_forward)?;
20620 digest_cells.push(baseline_digest_cells);
20621 digest_cells.push(candidate_digest_cells);
20622 for allocation in allocations {
20623 let bytes = tensor_layout_bytes(&allocation.layout)?;
20624 if step_input_overlap(allocation.data, bytes, admissibility.data, 1)? {
20625 return Err(publication_input_error(
20626 "model update numerical admissibility aliases an output allocation",
20627 ));
20628 }
20629 let logits_bytes = tensor_layout_bytes(&baseline_logits.layout)?;
20630 if step_input_overlap(allocation.data, bytes, baseline_logits.data, logits_bytes)?
20631 || step_input_overlap(allocation.data, bytes, candidate_logits.data, logits_bytes)?
20632 {
20633 return Err(publication_input_error(
20634 "model update canary logits alias an output allocation",
20635 ));
20636 }
20637 for owned in &storage.allocations {
20638 if step_input_overlap(
20639 allocation.data,
20640 bytes,
20641 owned.device_ptr_value(),
20642 owned.len(),
20643 )? {
20644 return Err(publication_input_error(
20645 "model update output aliases native publication storage",
20646 ));
20647 }
20648 }
20649 }
20650 let logits_bytes = tensor_layout_bytes(&baseline_logits.layout)?;
20651 if step_input_overlap(admissibility.data, 1, baseline_logits.data, logits_bytes)?
20652 || step_input_overlap(admissibility.data, 1, candidate_logits.data, logits_bytes)?
20653 || step_input_overlap(
20654 baseline_logits.data,
20655 logits_bytes,
20656 candidate_logits.data,
20657 logits_bytes,
20658 )?
20659 {
20660 return Err(publication_input_error(
20661 "model update canary logits alias one another or numerical admissibility",
20662 ));
20663 }
20664 for owned in &storage.allocations {
20665 if step_input_overlap(
20666 baseline_logits.data,
20667 logits_bytes,
20668 owned.device_ptr_value(),
20669 owned.len(),
20670 )? || step_input_overlap(
20671 candidate_logits.data,
20672 logits_bytes,
20673 owned.device_ptr_value(),
20674 owned.len(),
20675 )? {
20676 return Err(publication_input_error(
20677 "model update canary logits alias native publication storage",
20678 ));
20679 }
20680 }
20681 let values = allocations
20682 .iter()
20683 .zip(&storage.model_slots)
20684 .zip(&geometry.allocation_bytes)
20685 .map(|((allocation, slots), &bytes)| ModelUpdateBinding {
20686 source: allocation.data,
20687 bytes,
20688 slots: [slots[0] as u64, slots[1] as u64],
20689 })
20690 .collect::<Vec<_>>();
20691 let retained_allocations = allocations.to_vec();
20692 let mut slab = prepare_semantic_tensors(&self.provider, vec![slab_backing])?;
20693 let slab = slab
20694 .pop()
20695 .ok_or(SemanticTransitionError::ObservationMismatch)?;
20696 if slab.layout.role != 0
20697 || slab.layout.index != 0
20698 || slab.layout.scalar_type != 1
20699 || slab.layout.element_bytes != 1
20700 || slab.layout.rank != 1
20701 || slab.layout.logical_axis != u64::MAX
20702 || slab.layout.dimensions[0] == 0
20703 || slab.layout.dimensions[1..] != [0, 0, 0]
20704 || slab.layout.strides_bytes != [1, 0, 0, 0]
20705 || slab.logical_begin != 0
20706 || slab.logical_end != 0
20707 {
20708 return Err(publication_input_error(
20709 "update slab must be its original contiguous CUDA UInt8 allocation",
20710 ));
20711 }
20712 #[cfg(feature = "semantic-policy")]
20713 let accounted_reserved_bytes = accounted_tensor_allocations(
20714 &outputs
20715 .iter()
20716 .chain([&baseline_logits, &candidate_logits])
20717 .collect::<Vec<_>>(),
20718 &slab,
20719 )?;
20720 #[cfg(feature = "semantic-policy")]
20721 let copy_bytes = values.iter().try_fold(0u64, |total, binding| {
20722 total
20723 .checked_add(binding.bytes)
20724 .ok_or(SemanticTransitionError::GenerationExhausted)
20725 })?;
20726 let prepared = self
20727 .steps
20728 .get_mut(&step.token)
20729 .expect("checked update step");
20730 let update = prepared
20731 .prepared
20732 .as_mut()
20733 .expect("prepared update owner")
20734 .branches[bank]
20735 .model_update
20736 .as_mut()
20737 .expect("prepared update binding allocation");
20738 if values.len() != update.bindings.len() {
20739 return Err(SemanticTransitionError::ObservationMismatch);
20740 }
20741 if forward_seal_values.len() != update.forward_seals.len() {
20742 return Err(SemanticTransitionError::ObservationMismatch);
20743 }
20744 if update.forward_recorded != 2 {
20745 return Err(publication_input_error(
20746 "model update output requires both producer-issued forward receipts",
20747 ));
20748 }
20749 update.output = Some(BoundModelUpdate {
20750 values,
20751 forward_seal_values,
20752 digest_cells,
20753 allocations: retained_allocations,
20754 admissibility: admissibility.clone(),
20755 baseline_logits,
20756 candidate_logits,
20757 _slab_backing: slab,
20758 #[cfg(feature = "semantic-policy")]
20759 accounted_reserved_bytes,
20760 #[cfg(feature = "semantic-policy")]
20761 copy_bytes,
20762 _witness: witness.clone(),
20763 _forward_witnesses: [baseline_forward.clone(), candidate_forward.clone()],
20764 });
20765 Ok(())
20766 }
20767
20768 pub fn verify_prepared_tensor_content(
20769 &mut self,
20770 step: &SemanticPreparedStep,
20771 witness: &SemanticTensorContentWitness,
20772 tensors: Vec<SemanticTensorInput>,
20773 consumer_stream: u64,
20774 ) -> Result<(), SemanticTransitionError> {
20775 self.checked_prepared_content_witness(step, witness)?;
20776 let build = self
20777 .prepared_segment
20778 .as_ref()
20779 .expect("checked prepared scope");
20780 let recorded = !build.finished;
20781 if recorded {
20782 self.check_prepared_content_stream(step, consumer_stream)?;
20783 } else if !build.completed
20784 || !self.steps[&step.token]
20785 .prepared
20786 .as_ref()
20787 .expect("prepared owner")
20788 .observed
20789 {
20790 return Err(publication_input_error(
20791 "retained content requires an actually completed prepared invocation",
20792 ));
20793 }
20794 let actual = prepare_semantic_tensors(&self.provider, tensors)?;
20795 let content = &mut self
20796 .steps
20797 .get_mut(&step.token)
20798 .expect("checked fixed step")
20799 .content[witness.index];
20800 let start = content.verification_inputs.len();
20801 content.verification_inputs.extend(actual);
20802 let actual = &content.verification_inputs[start..];
20803 if content.tensors.len() != actual.len()
20804 || content
20805 .tensors
20806 .iter()
20807 .zip(actual)
20808 .any(|(expected, actual)| !same_tensor_content_owner(expected, actual))
20809 {
20810 self.poisoned = true;
20811 return Err(publication_input_error("content verification requires the exact original tensor owners, layout and interval"));
20812 }
20813 if recorded {
20814 self.record_prepared_tensor_content(step, witness, true)
20815 } else {
20816 self.enqueue_content_witness(witness, consumer_stream, true)
20817 }
20818 }
20819
20820 pub fn record_prepared_step_admission(
20821 &mut self,
20822 step: &SemanticPreparedStep,
20823 conditional_handle: u64,
20824 ) -> Result<(), SemanticTransitionError> {
20825 self.checked_prepared_step(step, false)?;
20826 if conditional_handle == 0
20827 || !self
20828 .prepared_segment
20829 .as_ref()
20830 .expect("checked build")
20831 .capturing
20832 {
20833 return Err(publication_input_error(
20834 "step admission requires the actual conditional capture handle",
20835 ));
20836 }
20837 let requested_kind = self
20838 .prepared_segment
20839 .as_mut()
20840 .expect("checked build")
20841 .enter(step, &self.publication_issuer)?;
20842 let storage = self.publication.as_ref().expect("prepared publication");
20843 let prepared = self.steps[&step.token]
20844 .prepared
20845 .as_ref()
20846 .expect("prepared lease owner");
20847 let build = self
20848 .prepared_segment
20849 .as_ref()
20850 .expect("checked prepared scope");
20851 let previous = build.next.checked_sub(1).map(|index| {
20852 &self.steps[&build.tokens[index]]
20853 .prepared
20854 .as_ref()
20855 .expect("previous prepared step")
20856 .result
20857 });
20858 let mut recorder = self.domain.new_strict_recorder();
20859 storage.record(&mut recorder);
20860 recorder.write(&prepared.reader);
20861 if let Some(previous) = previous {
20862 recorder.read(previous);
20863 }
20864 let arguments = (
20865 storage.control.device_ptr_value(),
20866 prepared.reader.device_ptr_value(),
20867 requested_kind.code(),
20868 conditional_handle,
20869 previous.map_or(0, TrackedCudaSlice::device_ptr_value),
20870 );
20871 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
20872 unsafe {
20875 prepared.admit.clone().launch_in(
20876 enqueue,
20877 LaunchConfig {
20878 grid_dim: (1, 1, 1),
20879 block_dim: (1, 1, 1),
20880 shared_mem_bytes: 0,
20881 },
20882 arguments,
20883 )
20884 }
20885 .map_err(|error| XlogError::Kernel(error.to_string()))
20886 })
20887 }
20888
20889 pub fn record_prepared_step_inputs(
20890 &mut self,
20891 step: &SemanticPreparedStep,
20892 ) -> Result<(), SemanticTransitionError> {
20893 self.checked_prepared_step(step, true)?;
20894 if self.steps[&step.token]
20895 .prepared
20896 .as_ref()
20897 .expect("prepared owner")
20898 .inputs_recorded
20899 {
20900 return Err(publication_input_error(
20901 "prepared input producer records exactly once",
20902 ));
20903 }
20904 let keys = self.prepared_range_keys(step)?;
20907 self.guard_prepared_content(step, &keys, self.stream.cu_stream() as usize as u64)?;
20908 let owner = &self.steps[&step.token];
20909 let descriptor = self.descriptor();
20910 owner
20911 .inputs
20912 .as_ref()
20913 .expect("fixed input owner")
20914 .enqueue(&self.domain, &mut self.poisoned)?;
20915 if let Some(custody) = &owner
20916 .prepared
20917 .as_ref()
20918 .expect("prepared owner")
20919 .replay_custody
20920 {
20921 custody.enqueue_parent(
20922 &self.domain,
20923 &mut self.poisoned,
20924 self.publication.as_ref().expect("prepared publication"),
20925 &owner.prepared.as_ref().expect("prepared owner").reader,
20926 &self.graph,
20927 )?;
20928 }
20929 owner.feedback[0].enqueue(
20930 &self.domain,
20931 &mut self.poisoned,
20932 &self.graph,
20933 self.publication.as_ref().expect("prepared publication"),
20934 &self
20935 .task
20936 .as_ref()
20937 .ok_or(SemanticTransitionError::InvalidTaskBank)?
20938 .1,
20939 &owner.prepared.as_ref().expect("prepared lease").reader,
20940 descriptor,
20941 )?;
20942 let selection = if let Some(selected) = owner
20943 .prepared
20944 .as_ref()
20945 .expect("prepared selection owner")
20946 .training_view
20947 .as_ref()
20948 {
20949 let selected_view = owner
20950 .inputs
20951 .as_ref()
20952 .expect("fixed input owner")
20953 .views
20954 .first()
20955 .expect("two publication input banks")
20956 .get(&(SemanticStateRole::TrainingView as u64, 0))
20957 .cloned()
20958 .ok_or_else(|| {
20959 publication_input_error("prepared update has no acquired training-view input")
20960 })?;
20961 let coordinates = owner
20962 .inputs
20963 .as_ref()
20964 .expect("fixed input owner")
20965 .training_coordinates_view()?;
20966 selected.enqueue_device_selection(selected_view, coordinates)
20967 } else {
20968 Ok(())
20969 };
20970 if selection.is_err() {
20971 self.poisoned = true;
20972 return selection;
20973 }
20974 self.steps
20975 .get_mut(&step.token)
20976 .expect("checked step")
20977 .prepared
20978 .as_mut()
20979 .expect("prepared owner")
20980 .inputs_recorded = true;
20981 Ok(())
20982 }
20983
20984 fn record_prepared_step_kind_gate(
20985 &mut self,
20986 step: &SemanticPreparedStep,
20987 expected_kind: SemanticTransitionKind,
20988 conditional_handle: u64,
20989 ) -> Result<(), SemanticTransitionError> {
20990 self.checked_prepared_step(step, true)?;
20991 if conditional_handle == 0 {
20992 return Err(publication_input_error(
20993 "prepared kind gate requires the actual conditional capture handle",
20994 ));
20995 }
20996 let prepared = self.steps[&step.token]
20997 .prepared
20998 .as_ref()
20999 .expect("prepared lease owner");
21000 let mut recorder = self.domain.new_strict_recorder();
21001 recorder.read(&prepared.reader);
21002 let arguments = (
21003 prepared.reader.device_ptr_value(),
21004 expected_kind.code(),
21005 conditional_handle,
21006 );
21007 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
21008 unsafe {
21011 prepared.kind_gate.clone().launch_in(
21012 enqueue,
21013 LaunchConfig {
21014 grid_dim: (1, 1, 1),
21015 block_dim: (1, 1, 1),
21016 shared_mem_bytes: 0,
21017 },
21018 arguments,
21019 )
21020 }
21021 .map_err(|error| XlogError::Kernel(error.to_string()))
21022 })
21023 }
21024
21025 pub fn record_prepared_step_requested_bank_gate(
21026 &mut self,
21027 step: &SemanticPreparedStep,
21028 bank: usize,
21029 conditional_handle: u64,
21030 ) -> Result<(), SemanticTransitionError> {
21031 let expected = self.prepared_transition_kind(step)?;
21032 self.checked_prepared_step(step, true)?;
21033 if bank > 1 || conditional_handle == 0 {
21034 return Err(publication_input_error(
21035 "prepared bank gate requires bank zero or one and the actual conditional capture handle",
21036 ));
21037 }
21038 let prepared = self.steps[&step.token]
21039 .prepared
21040 .as_ref()
21041 .expect("prepared lease owner");
21042 let mut recorder = self.domain.new_strict_recorder();
21043 recorder.read(&prepared.reader);
21044 let arguments = (
21045 prepared.reader.device_ptr_value(),
21046 expected.code(),
21047 bank as u64,
21048 conditional_handle,
21049 );
21050 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
21051 unsafe {
21054 prepared.kind_bank_gate.clone().launch_in(
21055 enqueue,
21056 LaunchConfig {
21057 grid_dim: (1, 1, 1),
21058 block_dim: (1, 1, 1),
21059 shared_mem_bytes: 0,
21060 },
21061 arguments,
21062 )
21063 }
21064 .map_err(|error| XlogError::Kernel(error.to_string()))
21065 })
21066 }
21067
21068 #[cfg(feature = "semantic-policy")]
21069 pub fn begin_prepared_step_bank_capture(
21070 &mut self,
21071 step: &SemanticPreparedStep,
21072 bank: usize,
21073 ) -> Result<(), SemanticTransitionError> {
21074 self.check_prepared_content_stream(step, self.stream.cu_stream() as u64)?;
21075 let prepared = self
21076 .steps
21077 .get_mut(&step.token)
21078 .expect("checked prepared bank step")
21079 .prepared
21080 .as_mut()
21081 .expect("prepared bank owner");
21082 let recorded = prepared.transition_recorded;
21083 let result = prepared
21084 .model_work
21085 .as_mut()
21086 .ok_or_else(|| publication_input_error("prepared bank requires original model work"))
21087 .and_then(|work| {
21088 work.begin_capture(bank, recorded)
21089 .map_err(publication_input_error)
21090 });
21091 if result.is_err() {
21092 self.poisoned = true;
21093 }
21094 result
21095 }
21096
21097 #[cfg(feature = "semantic-policy")]
21098 pub fn record_prepared_bank_model_content(
21101 &mut self,
21102 step: &SemanticPreparedStep,
21103 bank: usize,
21104 ) -> Result<(), SemanticTransitionError> {
21105 self.check_prepared_content_stream(step, self.stream.cu_stream() as u64)?;
21106 if bank > 1 {
21107 return Err(publication_input_error(
21108 "prepared model content bank must be zero or one",
21109 ));
21110 }
21111 let owner = &self.steps[&step.token];
21112 let prepared = owner
21113 .prepared
21114 .as_ref()
21115 .expect("prepared model content owner");
21116 if prepared.model_content_recorded & (1 << bank) != 0 {
21117 return Err(publication_input_error(
21118 "prepared model content records once per bank branch",
21119 ));
21120 }
21121 let indices = owner
21122 .content
21123 .iter()
21124 .enumerate()
21125 .filter_map(|(index, content)| match &content.seals {
21126 TensorContentSeals::Model(seals)
21127 if seals
21128 .prepared
21129 .as_ref()
21130 .is_some_and(|source| source.bank == bank) =>
21131 {
21132 Some(index)
21133 }
21134 _ => None,
21135 })
21136 .collect::<Vec<_>>();
21137 if indices.is_empty() {
21138 return Err(publication_input_error(
21139 "prepared branch has no original admitted model content",
21140 ));
21141 }
21142 for index in indices {
21143 let TensorContentSeals::Model(seals) = &self.steps[&step.token].content[index].seals
21144 else {
21145 return Err(SemanticTransitionError::ObservationMismatch);
21146 };
21147 seals.snapshot_prepared(&self.domain, &mut self.poisoned)?;
21148 let witness = SemanticTensorContentWitness {
21149 issuer: Arc::clone(&self.publication_issuer),
21150 reader_token: step.token,
21151 index,
21152 _witness: Arc::clone(&self.steps[&step.token].content_witnesses),
21153 };
21154 self.record_prepared_tensor_content(step, &witness, true)?;
21155 }
21156 self.steps
21157 .get_mut(&step.token)
21158 .expect("prepared model content owner")
21159 .prepared
21160 .as_mut()
21161 .expect("prepared model content storage")
21162 .model_content_recorded |= 1 << bank;
21163 Ok(())
21164 }
21165
21166 pub fn record_prepared_step_drain_gate(
21167 &mut self,
21168 step: &SemanticPreparedStep,
21169 conditional_handle: u64,
21170 ) -> Result<(), SemanticTransitionError> {
21171 self.record_prepared_step_kind_gate(step, SemanticTransitionKind::Drain, conditional_handle)
21172 }
21173
21174 pub fn record_prepared_step_active_gate(
21175 &mut self,
21176 step: &SemanticPreparedStep,
21177 conditional_handle: u64,
21178 ) -> Result<(), SemanticTransitionError> {
21179 self.checked_prepared_step(step, true)?;
21180 if conditional_handle == 0 {
21181 return Err(publication_input_error(
21182 "prepared release gate requires the actual conditional capture handle",
21183 ));
21184 }
21185 let prepared = self.steps[&step.token]
21186 .prepared
21187 .as_ref()
21188 .expect("prepared lease owner");
21189 let mut recorder = self.domain.new_strict_recorder();
21190 recorder.read(&prepared.reader);
21191 let arguments = (prepared.reader.device_ptr_value(), conditional_handle);
21192 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
21193 unsafe {
21196 prepared.active_gate.clone().launch_in(
21197 enqueue,
21198 LaunchConfig {
21199 grid_dim: (1, 1, 1),
21200 block_dim: (1, 1, 1),
21201 shared_mem_bytes: 0,
21202 },
21203 arguments,
21204 )
21205 }
21206 .map_err(|error| XlogError::Kernel(error.to_string()))
21207 })
21208 }
21209
21210 pub fn guard_prepared_content(
21211 &mut self,
21212 step: &SemanticPreparedStep,
21213 keys: &[(SemanticStateRole, u64)],
21214 consumer_stream: u64,
21215 ) -> Result<(), SemanticTransitionError> {
21216 self.checked_prepared_step(step, true)?;
21217 if dlpack_consumer_stream(consumer_stream)? != self.stream.cu_stream() || keys.is_empty() {
21218 return Err(publication_input_error(
21219 "prepared content guard requires original ranges on the native capture stream",
21220 ));
21221 }
21222 let storage = self.publication.as_ref().expect("prepared publication");
21223 let owner = &self.steps[&step.token];
21224 let prepared = owner.prepared.as_ref().expect("prepared lease");
21225 let mut distinct = BTreeSet::new();
21226 for &(role, index) in keys {
21227 if !distinct.insert((role as u64, index))
21228 || !storage.bank_templates[0]
21229 .iter()
21230 .any(|range| (range.role, range.index) == (role as u64, index))
21231 {
21232 return Err(publication_input_error(
21233 "prepared guard names duplicate or undeclared original ranges",
21234 ));
21235 }
21236 let layout = if is_tensor_role(role as u64) {
21237 *storage
21238 .layouts
21239 .get(&(role as u64, index))
21240 .ok_or(SemanticTransitionError::ObservationMismatch)?
21241 } else {
21242 SemanticTensorLayout::default()
21243 };
21244 storage.enqueue_content_guard(
21245 &self.domain,
21246 &mut self.poisoned,
21247 prepared.reader.view(),
21248 &prepared.content_guard,
21249 role as u64,
21250 index,
21251 layout,
21252 )?;
21253 }
21254 if prepared.inputs_recorded {
21255 owner
21256 .inputs
21257 .as_ref()
21258 .expect("fixed input owner")
21259 .verify(&self.domain, &mut self.poisoned)?;
21260 owner.feedback[0].content.enqueue(
21261 &self.domain,
21262 &mut self.poisoned,
21263 &prepared.witness,
21264 true,
21265 )?;
21266 }
21267 Ok(())
21268 }
21269
21270 pub fn record_prepared_step_release(
21271 &mut self,
21272 step: &SemanticPreparedStep,
21273 ) -> Result<(), SemanticTransitionError> {
21274 self.checked_prepared_step(step, true)?;
21275 let storage = self.publication.as_ref().expect("prepared publication");
21276 let prepared = self.steps[&step.token]
21277 .prepared
21278 .as_ref()
21279 .expect("prepared lease");
21280 if prepared.transition_recorded != PREPARED_TRANSITION_BANKS || !prepared.drain_recorded {
21281 return Err(publication_input_error(
21282 "release must follow this prepared step's complete native transition and drain branches",
21283 ));
21284 }
21285 let mut recorder = self.domain.new_strict_recorder();
21286 storage.record(&mut recorder);
21287 recorder.read_write(&prepared.reader);
21288 recorder.read(
21289 &self.steps[&step.token]
21290 .inputs
21291 .as_ref()
21292 .expect("fixed input owner")
21293 .header,
21294 );
21295 recorder.write(&prepared.result);
21296 if let Some(origin) = &prepared.training_origin {
21297 recorder.write(origin);
21298 }
21299 let arguments = (
21300 storage.control.device_ptr_value(),
21301 prepared.reader.device_ptr_value(),
21302 );
21303 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
21304 unsafe {
21307 prepared.result_kernel.clone().launch_in(
21308 enqueue,
21309 LaunchConfig {
21310 grid_dim: (1, 1, 1),
21311 block_dim: (1, 1, 1),
21312 shared_mem_bytes: 0,
21313 },
21314 (
21315 storage.control.device_ptr_value(),
21316 prepared.reader.device_ptr_value(),
21317 prepared.result.device_ptr_value(),
21318 self.steps[&step.token]
21319 .inputs
21320 .as_ref()
21321 .expect("fixed input owner")
21322 .header
21323 .device_ptr_value(),
21324 prepared
21325 .training_origin
21326 .as_ref()
21327 .map_or(0, |origin| *origin.device_ptr()),
21328 ),
21329 )
21330 }
21331 .map_err(|error| XlogError::Kernel(error.to_string()))?;
21332 unsafe {
21335 prepared.release.clone().launch_in(
21336 enqueue,
21337 LaunchConfig {
21338 grid_dim: (1, 1, 1),
21339 block_dim: (1, 1, 1),
21340 shared_mem_bytes: 0,
21341 },
21342 arguments,
21343 )
21344 }
21345 .map_err(|error| XlogError::Kernel(error.to_string()))
21346 })?;
21347 self.prepared_segment
21348 .as_mut()
21349 .expect("checked build")
21350 .leave(step, &self.publication_issuer)
21351 }
21352
21353 pub fn finish_prepared_segment(
21354 &mut self,
21355 executable: &mut Option<SemanticPreparedExecutable>,
21356 ) -> Result<(), SemanticTransitionError> {
21357 self.ensure_quiescent()?;
21358 let build = self
21359 .prepared_segment
21360 .as_mut()
21361 .ok_or(SemanticTransitionError::NotBound)?;
21362 if self.captured.is_some()
21363 || executable
21364 .as_ref()
21365 .is_none_or(|executable| !Arc::ptr_eq(&executable.scope, &build.scope))
21366 {
21367 return Err(publication_input_error(
21368 "executable differs from the original native segment construction",
21369 ));
21370 }
21371 #[cfg(feature = "semantic-policy")]
21372 for token in &build.tokens {
21373 let prepared = self.steps[token]
21374 .prepared
21375 .as_ref()
21376 .expect("original prepared owner");
21377 if prepared
21378 .training_view
21379 .as_ref()
21380 .is_some_and(|view| view.actor_group_member_count() > 1)
21381 && prepared.group_critic_recorded != 0b11
21382 {
21383 return Err(publication_input_error(
21384 "multi-member Update requires the complete frozen group critic in both banks",
21385 ));
21386 }
21387 if (0..2).any(|bank| {
21388 prepared.group_imported_vjp_members[bank] != prepared.group_gradient_members[bank]
21389 }) {
21390 return Err(publication_input_error(
21391 "every imported group VJP requires its original physical gradient delivery in the same bank",
21392 ));
21393 }
21394 }
21395 build.finish()?;
21396 for token in &build.tokens {
21399 let prepared = self.steps[token]
21400 .prepared
21401 .as_ref()
21402 .expect("original prepared owner");
21403 let work = prepared.model_work.as_ref().ok_or_else(|| {
21404 publication_input_error("prepared body has no frozen original model work")
21405 })?;
21406 if work.recording.frozen_bound().is_none() {
21407 return Err(publication_input_error(
21408 "original model work was not frozen by its transition",
21409 ));
21410 }
21411 if let Some(custody) = &prepared.replay_custody {
21412 work.recording
21413 .frozen_bound()
21414 .expect("checked frozen original work")
21415 .checked_add(custody.copy_work_bound()?)
21416 .ok_or(SemanticTransitionError::GenerationExhausted)?;
21417 }
21418 let mut destination = work.device.view().slice(..work.recording.events().len());
21419 self.provider
21420 .htod_launch_metadata_sync_copy_into(work.recording.events(), &mut destination)
21421 .map_err(|error| runtime_error("original model work cold upload", error))?;
21422 for branch in &prepared.branches {
21423 if let Some(update) = &branch.model_update {
21424 let output = update.output.as_ref().ok_or_else(|| {
21425 publication_input_error(
21426 "prepared update has no branch-owned model output binding",
21427 )
21428 })?;
21429 let mut destination = update.bindings.view();
21430 self.provider
21431 .htod_launch_metadata_sync_copy_into(&output.values, &mut destination)
21432 .map_err(|error| {
21433 runtime_error("model update binding cold upload", error)
21434 })?;
21435 let mut forward_seals = update.forward_seals.view();
21436 self.provider
21437 .htod_launch_metadata_sync_copy_into(
21438 &output.forward_seal_values,
21439 &mut forward_seals,
21440 )
21441 .map_err(|error| runtime_error("model forward seal cold upload", error))?;
21442 }
21443 }
21444 }
21445 executable
21446 .as_ref()
21447 .expect("checked authentic executable")
21448 .graph
21449 .upload_cold(&self.stream)
21450 .map_err(|error| runtime_error("prepared graph cold upload", error))?;
21451 self.captured = Some(
21454 executable
21455 .take()
21456 .expect("checked authentic executable")
21457 .graph,
21458 );
21459 Ok(())
21460 }
21461
21462 pub fn take_prepared_executable_for_retirement(
21466 &mut self,
21467 ) -> Result<Option<CapturedCudaGraph>, SemanticTransitionError> {
21468 if self
21469 .prepared_segment
21470 .as_ref()
21471 .is_none_or(|build| !build.completed)
21472 {
21473 return Err(publication_input_error(
21474 "prepared executable retirement requires known actual completion",
21475 ));
21476 }
21477 Ok(self.captured.take())
21478 }
21479
21480 pub fn take_prepared_resources_for_retirement(
21483 &mut self,
21484 ) -> Result<Vec<Arc<dyn Send + Sync>>, SemanticTransitionError> {
21485 let build = self
21486 .prepared_segment
21487 .as_ref()
21488 .ok_or(SemanticTransitionError::NotBound)?;
21489 if !build.completed
21490 || self.captured.is_some()
21491 || build
21492 .tokens
21493 .iter()
21494 .any(|token| self.steps.contains_key(token))
21495 {
21496 return Err(publication_input_error(
21497 "original prepared resources still own an executable or retained step",
21498 ));
21499 }
21500 let resources = std::mem::take(&mut self.prepared_resources);
21501 self.prepared_segment = None;
21502 Ok(resources)
21503 }
21504
21505 #[cfg(feature = "semantic-policy")]
21506 fn prepared_segment_recorder(&self) -> Result<LaunchRecorder, SemanticTransitionError> {
21507 let build = self
21508 .prepared_segment
21509 .as_ref()
21510 .ok_or(SemanticTransitionError::NotBound)?;
21511 let mut recorder = self.kernel_recorder();
21514 self.publication
21515 .as_ref()
21516 .ok_or(SemanticTransitionError::NotBound)?
21517 .record(&mut recorder);
21518 for token in &build.tokens {
21519 let owner = self
21520 .steps
21521 .get(token)
21522 .ok_or(SemanticTransitionError::ObservationMismatch)?;
21523 let prepared = owner
21524 .prepared
21525 .as_ref()
21526 .ok_or(SemanticTransitionError::ObservationMismatch)?;
21527 recorder.read_write(&prepared.reader);
21528 recorder.write(&prepared.result);
21529 if let Some(custody) = &prepared.replay_custody {
21530 custody.record(&mut recorder);
21531 }
21532 if let Some(work) = &prepared.model_work {
21533 recorder.read(&work.device);
21534 recorder.read_write(&work.actual);
21535 }
21536 if let Some(digests) = &prepared.digests {
21537 recorder.read_write(digests.as_ref());
21538 }
21539 let inputs = owner
21540 .inputs
21541 .as_ref()
21542 .ok_or(SemanticTransitionError::ObservationMismatch)?;
21543 for bindings in &inputs.bindings {
21544 recorder.read(bindings);
21545 }
21546 recorder.write(&inputs.header);
21547 recorder.write(&inputs.source);
21548 recorder.write(&inputs.ranges);
21549 recorder.write(&inputs.metadata_digests);
21550 for allocation in &inputs.private {
21551 recorder.write(allocation);
21552 }
21553 for bank in &inputs.views {
21554 for view in bank.values() {
21555 recorder.read_write(view);
21556 }
21557 }
21558 for feedback in &owner.feedback {
21559 recorder.write(&feedback.status);
21560 }
21561 for content in owner
21562 .content
21563 .iter()
21564 .chain(owner.feedback.iter().map(|feedback| &feedback.content))
21565 {
21566 for tensor in content.tensors.iter().chain(&content.verification_inputs) {
21567 if let Some(source) = &tensor.source {
21568 recorder.read_write(source);
21569 }
21570 }
21571 match &content.seals {
21572 TensorContentSeals::Captured(digests) => {
21573 for digest in digests {
21574 if let CapturedTensorDigest::Tensor { cells, .. } = digest {
21575 recorder.read_write(cells.as_ref());
21576 }
21577 }
21578 }
21579 TensorContentSeals::Model(model) => {
21580 recorder.read_write(&model.ranges);
21581 recorder.read_write(&model.contract);
21582 if let Some(source) = &model.prepared {
21583 recorder.read(&source.roster);
21584 recorder.read(&source.reader);
21585 }
21586 }
21587 }
21588 }
21589 for branch in &prepared.branches {
21590 if let Some(continuation) = &branch.continuation {
21591 continuation.text_binding.record(&mut recorder);
21592 for tensor in &continuation.sources {
21593 if let Some(source) = &tensor.source {
21594 recorder.read(source);
21595 }
21596 }
21597 }
21598 if let Some(update) = &branch.model_update {
21599 update.record(&mut recorder);
21600 }
21601 #[cfg(feature = "semantic-policy")]
21602 {
21603 recorder.write(&branch.state);
21604 recorder.write(
21605 branch
21606 .support
21607 .as_ref()
21608 .ok_or(SemanticTransitionError::ObservationMismatch)?,
21609 );
21610 recorder.write(
21611 branch
21612 .receipts
21613 .as_ref()
21614 .ok_or(SemanticTransitionError::ObservationMismatch)?,
21615 );
21616 if let Some(policy) = &branch.policy {
21617 policy.numerical.record(&mut recorder);
21618 for buffer in [
21619 &policy.parameters,
21620 &policy.hidden,
21621 &policy.scores,
21622 &policy.retained_scores,
21623 &policy.recurrent,
21624 &policy.text_logits,
21625 ] {
21626 recorder.read_write(buffer);
21627 }
21628 policy.text_binding.record(&mut recorder);
21629 } else {
21630 recorder.read(
21631 &branch
21632 .policy_buffers
21633 .as_ref()
21634 .ok_or(SemanticTransitionError::NotBound)?
21635 .text_logits,
21636 );
21637 }
21638 for tensor in &branch.policy_sources {
21639 if let Some(source) = &tensor.source {
21640 recorder.read(source);
21641 }
21642 }
21643 }
21644 }
21645 }
21646 Ok(recorder)
21647 }
21648
21649 pub fn begin_initial_prefill(
21653 &mut self,
21654 layout: SemanticInitialSourceLayout,
21655 model_generation: u64,
21656 ) -> Result<SemanticInitialPrefillLease, SemanticTransitionError> {
21657 self.ensure_rebindable()?;
21658 if self.publication.is_some() || self.initial_prefill.is_some() {
21659 return Err(publication_input_error(
21660 "initial prefill requires one unpublished imported task",
21661 ));
21662 }
21663 let task_identity = self
21664 .task_evaluation_identity()
21665 .ok_or(SemanticTransitionError::NotBound)?;
21666 if model_generation == 0 || layout.prefill_tokens.is_empty() {
21667 return Err(publication_input_error(
21668 "initial prefill requires a model generation and nonempty committed prefix",
21669 ));
21670 }
21671 if layout.prefill_tokens.len() != layout.prefix.len()
21672 || layout.prefix.iter().enumerate().any(|(position, row)| {
21673 row.token != layout.prefill_tokens[position]
21674 || row.logical_position != position as u64
21675 || row.kind != 1
21676 || row.provenance != 1
21677 || row.valid != 1
21678 || row.committed != 1
21679 })
21680 {
21681 return Err(publication_input_error(
21682 "initial prefill layout differs from the admitted ordered prefix",
21683 ));
21684 }
21685 let expected_tokens = allocate_publication(&self.provider, layout.prefill_tokens.len())?;
21686 let scope = Arc::new(());
21687 self.initial_prefill = Some(InitialPrefillStage {
21688 scope: Arc::clone(&scope),
21689 task_identity,
21690 task_epoch: self.task_epoch,
21691 model_generation,
21692 layout,
21693 expected_tokens,
21694 input: None,
21695 model_content: None,
21696 output_content: None,
21697 captured_content: Vec::new(),
21698 consumer_stream: None,
21699 });
21700 let stage = self
21701 .initial_prefill
21702 .as_mut()
21703 .expect("stage installed before upload");
21704 if let Err(error) = self
21705 .provider
21706 .htod_sync_copy_into_tracked(&stage.layout.prefill_tokens, &mut stage.expected_tokens)
21707 {
21708 self.poisoned = true;
21709 return Err(runtime_error("initial prefill token upload", error));
21710 }
21711 Ok(SemanticInitialPrefillLease {
21712 issuer: Arc::clone(&self.publication_issuer),
21713 scope,
21714 })
21715 }
21716
21717 pub fn record_initial_prefill_input(
21721 &mut self,
21722 lease: &SemanticInitialPrefillLease,
21723 input: SemanticTensorInput,
21724 consumer_stream: u64,
21725 ) -> Result<(), SemanticTransitionError> {
21726 self.ensure_quiescent()?;
21727 dlpack_consumer_stream(consumer_stream)?;
21728 let stage = self
21729 .initial_prefill
21730 .as_ref()
21731 .ok_or(SemanticTransitionError::NotBound)?;
21732 if !Arc::ptr_eq(&self.publication_issuer, &lease.issuer)
21733 || !Arc::ptr_eq(&stage.scope, &lease.scope)
21734 || self.publication.is_some()
21735 || stage.task_epoch != self.task_epoch
21736 || self.task_evaluation_identity() != Some(stage.task_identity)
21737 || stage.model_content.is_none()
21738 || stage.consumer_stream != Some(consumer_stream)
21739 || stage.input.is_some()
21740 {
21741 return Err(publication_input_error(
21742 "initial prefill input belongs to another or already-used task stage",
21743 ));
21744 }
21745 validate_initial_prefill_input_layout(
21746 &input.layout,
21747 stage.layout.prefill_tokens.len() as u64,
21748 )?;
21749 if input.logical_begin != 0 || input.logical_end != stage.layout.prefill_tokens.len() as u64
21750 {
21751 return Err(publication_input_error(
21752 "initial prefill input interval differs from the admitted prefix",
21753 ));
21754 }
21755 let mut prepared = prepare_semantic_tensors(&self.provider, vec![input])?;
21756 let input = prepared.pop().expect("one checked prefill input");
21757 let actual_ptr = input.data;
21758 self.initial_prefill.as_mut().expect("checked stage").input = Some(input);
21759 self.initial_prefill
21760 .as_mut()
21761 .expect("checked stage")
21762 .consumer_stream = Some(consumer_stream);
21763 let result = (|| {
21764 self.order_tensor_producer_inputs(consumer_stream)?;
21765 let stage = self
21766 .initial_prefill
21767 .as_ref()
21768 .expect("retained prefill stage");
21769 let execute = self
21770 .provider
21771 .device()
21772 .inner()
21773 .get_func(
21774 "xlog_semantic_transition",
21775 "semantic_initial_prefill_input_guard",
21776 )
21777 .ok_or_else(|| {
21778 runtime_error("kernel lookup", "initial prefill input guard unavailable")
21779 })?;
21780 let mut recorder = self.domain.new_strict_recorder();
21781 recorder.read(&stage.expected_tokens);
21782 recorder.read(
21783 stage
21784 .input
21785 .as_ref()
21786 .expect("retained prefill input")
21787 .source
21788 .as_ref()
21789 .ok_or_else(|| {
21790 publication_input_error(
21791 "initial prefill input has no original device storage",
21792 )
21793 })?,
21794 );
21795 let arguments = (
21796 stage.expected_tokens.device_ptr_value(),
21797 actual_ptr,
21798 stage.layout.prefill_tokens.len() as u64,
21799 );
21800 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
21801 unsafe {
21804 execute.launch_in(
21805 enqueue,
21806 LaunchConfig {
21807 grid_dim: (1, 1, 1),
21808 block_dim: (1, 1, 1),
21809 shared_mem_bytes: 0,
21810 },
21811 arguments,
21812 )
21813 }
21814 .map_err(|error| XlogError::Kernel(error.to_string()))
21815 })?;
21816 self.stream
21817 .synchronize()
21818 .map_err(|error| runtime_error("initial prefill input verification", error))?;
21819 self.order_content_consumers(consumer_stream)
21820 })();
21821 if result.is_err() {
21822 self.poisoned = true;
21823 }
21824 result
21825 }
21826
21827 pub fn bind_initial_prefill_model_content(
21831 &mut self,
21832 lease: &SemanticInitialPrefillLease,
21833 tensors: Vec<SemanticTensorInput>,
21834 consumer_stream: u64,
21835 ) -> Result<SemanticInitialPrefillContentWitness, SemanticTransitionError> {
21836 self.capture_initial_prefill_roster(
21837 lease,
21838 tensors,
21839 consumer_stream,
21840 InitialPrefillCaptureKind::Model,
21841 )?
21842 .ok_or(SemanticTransitionError::ObservationMismatch)
21843 }
21844
21845 pub fn capture_initial_prefill_tensor_content(
21849 &mut self,
21850 lease: &SemanticInitialPrefillLease,
21851 tensors: Vec<SemanticTensorInput>,
21852 consumer_stream: u64,
21853 ) -> Result<SemanticInitialPrefillContentWitness, SemanticTransitionError> {
21854 self.capture_initial_prefill_roster(
21855 lease,
21856 tensors,
21857 consumer_stream,
21858 InitialPrefillCaptureKind::Captured,
21859 )?
21860 .ok_or(SemanticTransitionError::ObservationMismatch)
21861 }
21862
21863 pub fn record_initial_prefill_outputs(
21867 &mut self,
21868 lease: &SemanticInitialPrefillLease,
21869 tensors: Vec<SemanticTensorInput>,
21870 consumer_stream: u64,
21871 ) -> Result<(), SemanticTransitionError> {
21872 self.capture_initial_prefill_roster(
21873 lease,
21874 tensors,
21875 consumer_stream,
21876 InitialPrefillCaptureKind::Outputs,
21877 )?;
21878 Ok(())
21879 }
21880
21881 fn capture_initial_prefill_roster(
21882 &mut self,
21883 lease: &SemanticInitialPrefillLease,
21884 tensors: Vec<SemanticTensorInput>,
21885 consumer_stream: u64,
21886 kind: InitialPrefillCaptureKind,
21887 ) -> Result<Option<SemanticInitialPrefillContentWitness>, SemanticTransitionError> {
21888 self.ensure_quiescent()?;
21889 dlpack_consumer_stream(consumer_stream)?;
21890 let stage = self
21891 .initial_prefill
21892 .as_ref()
21893 .ok_or(SemanticTransitionError::NotBound)?;
21894 if !Arc::ptr_eq(&self.publication_issuer, &lease.issuer)
21895 || !Arc::ptr_eq(&stage.scope, &lease.scope)
21896 || self.publication.is_some()
21897 || stage.task_epoch != self.task_epoch
21898 || self.task_evaluation_identity() != Some(stage.task_identity)
21899 || stage
21900 .consumer_stream
21901 .is_some_and(|stream| stream != consumer_stream)
21902 || match kind {
21903 InitialPrefillCaptureKind::Model => {
21904 stage.model_content.is_some() || stage.input.is_some()
21905 }
21906 InitialPrefillCaptureKind::Outputs => {
21907 stage.model_content.is_none()
21908 || stage.input.is_none()
21909 || stage.output_content.is_some()
21910 }
21911 InitialPrefillCaptureKind::Captured => {
21912 stage.model_content.is_none() || stage.output_content.is_some()
21913 }
21914 }
21915 {
21916 return Err(publication_input_error(
21917 "initial prefill roster belongs to another stage, stream or forward order",
21918 ));
21919 }
21920 if tensors.is_empty()
21921 || tensors.iter().any(|tensor| match kind {
21922 InitialPrefillCaptureKind::Model => !matches!(tensor.layout.role, 0 | 18..=25),
21923 InitialPrefillCaptureKind::Outputs => !matches!(tensor.layout.role, 4..=13),
21924 InitialPrefillCaptureKind::Captured => false,
21925 })
21926 {
21927 return Err(publication_input_error(
21928 "initial prefill model or output roster has missing or foreign tensor roles",
21929 ));
21930 }
21931 let prepared = prepare_semantic_tensors(&self.provider, tensors)?;
21932 let stage = self
21933 .initial_prefill
21934 .as_mut()
21935 .expect("checked prefill stage");
21936 let content = TensorContentBuffers {
21937 tensors: prepared,
21938 seals: TensorContentSeals::Captured(Vec::new()),
21939 verification_inputs: Vec::new(),
21940 };
21941 let slot = match kind {
21942 InitialPrefillCaptureKind::Model => {
21943 stage.model_content = Some(content);
21944 Some(InitialPrefillContentSlot::Model)
21945 }
21946 InitialPrefillCaptureKind::Outputs => {
21947 stage.output_content = Some(content);
21948 None
21949 }
21950 InitialPrefillCaptureKind::Captured => {
21951 let index = stage.captured_content.len();
21952 stage.captured_content.push(content);
21953 Some(InitialPrefillContentSlot::Captured(index))
21954 }
21955 };
21956 stage.consumer_stream = Some(consumer_stream);
21957 let witness = slot.map(|slot| SemanticInitialPrefillContentWitness {
21958 issuer: Arc::clone(&self.publication_issuer),
21959 scope: Arc::clone(&stage.scope),
21960 task_identity: stage.task_identity,
21961 task_epoch: stage.task_epoch,
21962 model_generation: stage.model_generation,
21963 slot,
21964 });
21965 let result = (|| {
21966 self.order_tensor_producer_inputs(consumer_stream)?;
21967 let stage = self
21968 .initial_prefill
21969 .as_ref()
21970 .expect("retained prefill stage");
21971 let content = match kind {
21972 InitialPrefillCaptureKind::Model => stage
21973 .model_content
21974 .as_ref()
21975 .expect("retained model content"),
21976 InitialPrefillCaptureKind::Outputs => stage
21977 .output_content
21978 .as_ref()
21979 .expect("retained output content"),
21980 InitialPrefillCaptureKind::Captured => stage
21981 .captured_content
21982 .last()
21983 .expect("retained transient content"),
21984 };
21985 let private_prefix = if matches!(kind, InitialPrefillCaptureKind::Model) {
21988 content
21989 .tensors
21990 .iter()
21991 .filter(|tensor| tensor.layout.role != 0)
21992 .count()
21993 } else {
21994 0
21995 };
21996 validate_content_coordinates_after(
21997 content
21998 .tensors
21999 .iter()
22000 .map(|tensor| (tensor.layout.role, tensor.layout.index)),
22001 private_prefix,
22002 )?;
22003 let digests = content
22004 .tensors
22005 .iter()
22006 .map(|tensor| {
22007 tensor_content_range(
22008 &tensor.layout,
22009 tensor.logical_begin,
22010 tensor.logical_end,
22011 tensor.source.as_ref().map_or(0, DeviceMemoryView::len),
22012 )?;
22013 Ok(CapturedTensorDigest::Tensor {
22014 cells: Arc::new(allocate_publication(&self.provider, 4)?),
22015 offset: 0,
22016 producer_sealed: false,
22017 })
22018 })
22019 .collect::<Result<Vec<_>, SemanticTransitionError>>()?;
22020 let stage = self
22021 .initial_prefill
22022 .as_mut()
22023 .expect("retained prefill stage");
22024 let content = match kind {
22025 InitialPrefillCaptureKind::Model => stage
22026 .model_content
22027 .as_mut()
22028 .expect("retained model content"),
22029 InitialPrefillCaptureKind::Outputs => stage
22030 .output_content
22031 .as_mut()
22032 .expect("retained output content"),
22033 InitialPrefillCaptureKind::Captured => stage
22034 .captured_content
22035 .last_mut()
22036 .expect("retained transient content"),
22037 };
22038 content.seals = TensorContentSeals::Captured(digests);
22039 let stage = self
22040 .initial_prefill
22041 .as_ref()
22042 .expect("retained prefill stage");
22043 let content = match kind {
22044 InitialPrefillCaptureKind::Model => stage
22045 .model_content
22046 .as_ref()
22047 .expect("retained model content"),
22048 InitialPrefillCaptureKind::Outputs => stage
22049 .output_content
22050 .as_ref()
22051 .expect("retained output content"),
22052 InitialPrefillCaptureKind::Captured => stage
22053 .captured_content
22054 .last()
22055 .expect("retained transient content"),
22056 };
22057 let execute = self
22058 .provider
22059 .device()
22060 .inner()
22061 .get_func(
22062 "xlog_semantic_transition",
22063 "semantic_tensor_content_witness",
22064 )
22065 .ok_or_else(|| {
22066 runtime_error("kernel lookup", "tensor content witness unavailable")
22067 })?;
22068 content.enqueue(&self.domain, &mut self.poisoned, &execute, false)?;
22069 self.order_content_consumers(consumer_stream)
22070 })();
22071 if result.is_err() {
22072 self.poisoned = true;
22073 }
22074 result.map(|()| witness)
22075 }
22076
22077 pub fn verify_initial_prefill_tensor_content(
22080 &mut self,
22081 lease: &SemanticInitialPrefillLease,
22082 witness: &SemanticInitialPrefillContentWitness,
22083 tensors: Vec<SemanticTensorInput>,
22084 consumer_stream: u64,
22085 ) -> Result<(), SemanticTransitionError> {
22086 let mut handoff = RetainedTensorAdmission {
22087 inputs: Some(tensors),
22088 stream: Arc::clone(self.provider.device().inner().stream()),
22089 ready: false,
22090 };
22091 if self.is_poisoned() {
22092 return Err(SemanticTransitionError::Poisoned);
22093 }
22094 dlpack_consumer_stream(consumer_stream)?;
22095 let (scope, task_identity, task_epoch, model_generation, captured_count) =
22096 if let Some(stage) = self.initial_prefill.as_ref() {
22097 (
22098 &stage.scope,
22099 stage.task_identity,
22100 stage.task_epoch,
22101 stage.model_generation,
22102 stage.captured_content.len(),
22103 )
22104 } else if let Some(retained) = self.retained_initial_prefill.as_ref() {
22105 (
22106 &retained.scope,
22107 retained.task_identity,
22108 retained.task_epoch,
22109 retained.model_generation,
22110 retained.captured.len(),
22111 )
22112 } else {
22113 return Err(SemanticTransitionError::NotBound);
22114 };
22115 if !Arc::ptr_eq(&self.publication_issuer, &lease.issuer)
22116 || !Arc::ptr_eq(scope, &lease.scope)
22117 || self.task_epoch != task_epoch
22118 || self.task_evaluation_identity() != Some(task_identity)
22119 || !witness.matches(
22120 &self.publication_issuer,
22121 scope,
22122 task_identity,
22123 task_epoch,
22124 model_generation,
22125 captured_count,
22126 )
22127 {
22128 return Err(publication_input_error(
22129 "initial prefill content witness belongs to another task, stream or stage",
22130 ));
22131 }
22132 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
22133 .map_err(|error| runtime_error("prefill content stream admission", error))?;
22134 let prepared = prepare_semantic_tensors(
22135 &self.provider,
22136 handoff
22137 .inputs
22138 .take()
22139 .expect("retained original prefill verification inputs"),
22140 )?;
22141 let content = if let Some(stage) = self.initial_prefill.as_mut() {
22142 match witness.slot {
22143 InitialPrefillContentSlot::Model => stage.model_content.as_mut(),
22144 InitialPrefillContentSlot::Captured(index) => stage.captured_content.get_mut(index),
22145 }
22146 } else {
22147 self.retained_initial_prefill
22148 .as_mut()
22149 .and_then(|retained| match witness.slot {
22150 InitialPrefillContentSlot::Model => Some(&mut retained.model),
22151 InitialPrefillContentSlot::Captured(index) => retained.captured.get_mut(index),
22152 })
22153 }
22154 .ok_or(SemanticTransitionError::ObservationMismatch)?;
22155 let offset = content.verification_inputs.len();
22156 content.verification_inputs.extend(prepared);
22157 let actual = &content.verification_inputs[offset..];
22158 if actual.len() != content.tensors.len()
22159 || content
22160 .tensors
22161 .iter()
22162 .zip(actual)
22163 .any(|(expected, actual)| !same_tensor_content_owner(expected, actual))
22164 {
22165 return Err(publication_input_error(
22166 "prefill content verification requires the original storage, layout and interval",
22167 ));
22168 }
22169 let result = (|| {
22170 self.order_tensor_producer_inputs(consumer_stream)?;
22171 let content = if let Some(stage) = self.initial_prefill.as_ref() {
22172 match witness.slot {
22173 InitialPrefillContentSlot::Model => stage.model_content.as_ref(),
22174 InitialPrefillContentSlot::Captured(index) => stage.captured_content.get(index),
22175 }
22176 } else {
22177 self.retained_initial_prefill
22178 .as_ref()
22179 .and_then(|retained| match witness.slot {
22180 InitialPrefillContentSlot::Model => Some(&retained.model),
22181 InitialPrefillContentSlot::Captured(index) => retained.captured.get(index),
22182 })
22183 }
22184 .ok_or(SemanticTransitionError::ObservationMismatch)?;
22185 let execute = self
22186 .provider
22187 .device()
22188 .inner()
22189 .get_func(
22190 "xlog_semantic_transition",
22191 "semantic_tensor_content_witness",
22192 )
22193 .ok_or_else(|| {
22194 runtime_error("kernel lookup", "tensor content witness unavailable")
22195 })?;
22196 content.enqueue(&self.domain, &mut self.poisoned, &execute, true)?;
22197 self.order_content_consumers(consumer_stream)
22198 })();
22199 if result.is_err() {
22200 self.poisoned = true;
22201 }
22202 result
22203 }
22204
22205 fn verify_initial_prefill_parent(
22206 &mut self,
22207 parent: &SemanticParentBinding,
22208 tensors: &[PreparedSemanticTensor],
22209 allocations: &[PreparedSemanticTensor],
22210 ) -> Result<(), SemanticTransitionError> {
22211 if parent.prefix.is_empty() {
22212 if self.initial_prefill.is_some() {
22213 return Err(publication_input_error(
22214 "an initial prefill stage cannot be bound to an empty prefix",
22215 ));
22216 }
22217 return Ok(());
22218 }
22219 let stage = self.initial_prefill.as_ref().ok_or_else(|| {
22220 publication_input_error(
22221 "nonempty initial prefix requires its original model prefill stage",
22222 )
22223 })?;
22224 let model = stage.model_content.as_ref().ok_or_else(|| {
22225 publication_input_error("initial prefill has no original model-content witness")
22226 })?;
22227 let outputs = stage.output_content.as_ref().ok_or_else(|| {
22228 publication_input_error("initial prefill has no original model-output witness")
22229 })?;
22230 let model_inputs = tensors
22231 .iter()
22232 .filter(|tensor| matches!(tensor.layout.role, 18..=25))
22233 .chain(allocations);
22234 let output_inputs = tensors
22235 .iter()
22236 .filter(|tensor| matches!(tensor.layout.role, 4..=13));
22237 if self.publication.is_some()
22238 || stage.task_epoch != self.task_epoch
22239 || self.task_evaluation_identity() != Some(stage.task_identity)
22240 || stage.task_epoch != parent.authority_generation
22241 || stage.model_generation != parent.model_generation
22242 || stage.input.is_none()
22243 || stage.consumer_stream.is_none()
22244 || stage.layout.ring_head != parent.ring_head
22245 || !same_initial_source_rows(&stage.layout.source, &parent.source)
22246 || !same_initial_source_rows(&stage.layout.prefix, &parent.prefix)
22247 || parent.provenance_records != stage.layout.provenance_records
22248 || parent
22249 .records
22250 .iter()
22251 .filter(|record| record.role == SemanticStateRole::TokenProvenanceRecords)
22252 .count()
22253 != 1
22254 || !parent.records.iter().any(|record| {
22255 record.role == SemanticStateRole::TokenProvenanceRecords
22256 && record.index == 0
22257 && record.bytes == stage.layout.provenance_bytes
22258 && record.capacity_bytes == stage.layout.provenance_capacity_bytes
22259 })
22260 || model.tensors.len() != model_inputs.clone().count()
22261 || !model
22262 .tensors
22263 .iter()
22264 .zip(model_inputs)
22265 .all(|(expected, actual)| same_tensor_content_owner(expected, actual))
22266 || outputs.tensors.len() != output_inputs.clone().count()
22267 || !outputs
22268 .tensors
22269 .iter()
22270 .zip(output_inputs)
22271 .all(|(expected, actual)| same_tensor_content_owner(expected, actual))
22272 {
22273 return Err(publication_input_error(
22274 "initial parent changed its admitted source, model or original prefill outputs",
22275 ));
22276 }
22277 let stream = stage.consumer_stream.expect("checked prefill stream");
22278 let result = (|| {
22279 self.order_tensor_producer_inputs(stream)?;
22280 let stage = self
22281 .initial_prefill
22282 .as_ref()
22283 .expect("retained prefill stage");
22284 let execute = self
22285 .provider
22286 .device()
22287 .inner()
22288 .get_func(
22289 "xlog_semantic_transition",
22290 "semantic_tensor_content_witness",
22291 )
22292 .ok_or_else(|| {
22293 runtime_error("kernel lookup", "tensor content witness unavailable")
22294 })?;
22295 stage
22296 .model_content
22297 .as_ref()
22298 .expect("checked model content")
22299 .enqueue(&self.domain, &mut self.poisoned, &execute, true)?;
22300 stage
22301 .output_content
22302 .as_ref()
22303 .expect("checked output content")
22304 .enqueue(&self.domain, &mut self.poisoned, &execute, true)?;
22305 self.order_content_consumers(stream)
22306 })();
22307 if result.is_err() {
22308 self.poisoned = true;
22309 }
22310 result
22311 }
22312
22313 pub fn bind_parent(
22316 &mut self,
22317 mut parent: SemanticParentBinding,
22318 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
22319 let tensor_count = parent.tensors.len();
22322 let mut producers = std::mem::take(&mut parent.tensors);
22323 producers.append(&mut parent.model_memory.allocations);
22324 let producers = complete_tensor_handoff(&self.provider, producers)?;
22325 let mut tensors = prepare_semantic_tensors(&self.provider, producers)?;
22326 let allocations = tensors.split_off(tensor_count);
22327 let model_memory = prepare_model_memory(
22328 &allocations,
22329 std::mem::take(&mut parent.model_memory.storages),
22330 std::mem::take(&mut parent.model_memory.views),
22331 &tensors,
22332 )?;
22333 self.verify_initial_prefill_parent(&parent, &tensors, &allocations)?;
22334 self.ensure_rebindable_with_prefill()?;
22335 if self.publication.is_some() {
22336 return Err(publication_input_error(
22337 "this Session already owns a canonical publication instance",
22338 ));
22339 }
22340 let task_identity = self
22341 .task_evaluation_identity()
22342 .ok_or(SemanticTransitionError::NotBound)?;
22343 #[cfg(feature = "semantic-policy")]
22344 let task_content = self
22345 .task
22346 .as_ref()
22347 .ok_or(SemanticTransitionError::NotBound)?
22348 .0
22349 .content_identity();
22350 if parent.authority_generation != self.task_epoch {
22351 return Err(publication_input_error(
22352 "parent authority generation differs from the retained task import",
22353 ));
22354 }
22355 if parent.recovered_instance.is_some()
22356 || parent.records.iter().any(|record| {
22357 matches!(
22358 record.role,
22359 SemanticStateRole::IntentEntries
22360 | SemanticStateRole::IntentPayload
22361 | SemanticStateRole::Acknowledgements
22362 )
22363 })
22364 {
22365 return Err(publication_input_error("fresh parent initialization cannot replace recovered history or accept private intent records"));
22366 }
22367 parent.records.extend(initial_intent_records(
22368 &parent.intent_effect,
22369 parent.intent_entry_capacity,
22370 parent.intent_payload_capacity_bytes,
22371 parent.final_intent_payload_bytes,
22372 )?);
22373 parent.records.push(initial_acknowledgement_record(
22374 parent.intent_entry_capacity,
22375 parent.acknowledgement_payload_capacity_bytes,
22376 parent.intent_payload_capacity_bytes,
22377 parent.intent_effect.len(),
22378 )?);
22379 validate_parent_records(&parent, &tensors)?;
22380 let mut layouts = BTreeMap::new();
22381 let mut plans = Vec::new();
22382 for tensor in tensors {
22383 let layout = if matches!(tensor.layout.role, 18..=25) {
22384 tensor.layout
22385 } else if matches!(tensor.layout.role, 4 | 5) {
22386 prefix_capacity_layout(tensor.layout, parent.prefix_capacity)?
22387 } else {
22388 canonical_tensor_layout(tensor.layout)?
22389 };
22390 let bytes = tensor_layout_bytes(&layout)?;
22391 if bytes == 0 && !empty_model_tensor_layout(&layout) {
22392 return Err(publication_input_error(
22393 "non-active tensor destination has no owned extent",
22394 ));
22395 }
22396 layouts.insert((layout.role, layout.index), layout);
22397 let capacity = if matches!(layout.role, 18..=25) {
22398 let (allocation, offset) = model_memory.location(layout.role, layout.index)?;
22399 model_memory.allocation_bytes[allocation] as usize - offset
22400 } else {
22401 bytes
22402 };
22403 plans.push(PublicationAllocationPlan {
22404 role: layout.role,
22405 index: layout.index,
22406 capacity,
22407 length: bytes,
22408 logical_begin: tensor.logical_begin,
22409 logical_end: tensor.logical_end,
22410 payload: if matches!(layout.role, 18..=25) {
22411 PublicationPayload::Uncomputed
22412 } else {
22413 PublicationPayload::Tensor(tensor)
22414 },
22415 });
22416 }
22417 for layout in &parent.active_layouts {
22418 let layout = canonical_tensor_layout(*layout)?;
22419 let bytes = tensor_layout_bytes(&layout)?;
22420 layouts.insert((layout.role, layout.index), layout);
22421 plans.push(PublicationAllocationPlan {
22422 role: layout.role,
22423 index: layout.index,
22424 capacity: bytes,
22425 length: 0,
22426 logical_begin: 0,
22427 logical_end: 0,
22428 payload: PublicationPayload::Uncomputed,
22429 });
22430 }
22431 for record in &parent.records {
22432 plans.push(PublicationAllocationPlan {
22433 role: record.role as u64,
22434 index: record.index,
22435 capacity: record.capacity_bytes,
22436 length: record.bytes.len(),
22437 logical_begin: 0,
22438 logical_end: if record.role == SemanticStateRole::TokenProvenanceRecords {
22439 parent.provenance_records
22440 } else {
22441 0
22442 },
22443 payload: PublicationPayload::Metadata(record.bytes.clone()),
22444 });
22445 }
22446 let statements = self.feedback_statement_bytes()?.map(<[u8]>::to_vec);
22447 let layout_rows: Vec<_> = layouts.values().copied().collect();
22448 let prefix_capacity = usize::try_from(parent.prefix_capacity)
22449 .ok()
22450 .and_then(|n| n.checked_mul(size_of::<SemanticTextSlot>()))
22451 .ok_or_else(|| publication_input_error("prefix source capacity overflow"))?;
22452 let feedback_capacity = usize::try_from(parent.feedback_capacity)
22453 .ok()
22454 .and_then(|n| n.checked_mul(size_of::<RawFeedbackRecord>()))
22455 .ok_or_else(|| publication_input_error("feedback capacity overflow"))?;
22456 for (role, index, bytes, capacity, end) in [
22457 (
22458 1,
22459 0,
22460 publication_abi_bytes(&parent.prefix),
22461 prefix_capacity,
22462 parent.prefix.len() as u64,
22463 ),
22464 (3, 0, vec![0; 32], 32, 0),
22467 (
22468 14,
22469 0,
22470 vec![0; size_of::<CompletionCoverage>()],
22471 size_of::<CompletionCoverage>(),
22472 0,
22473 ),
22474 (15, 0, vec![0; feedback_capacity], feedback_capacity, 0),
22475 (16, 0, statements[0].clone(), statements[0].len(), 0),
22476 (16, 1, statements[1].clone(), statements[1].len(), 0),
22477 (16, 2, statements[2].clone(), statements[2].len(), 0),
22478 (
22479 33,
22480 0,
22481 vec![0; size_of::<AttemptReceipt>()],
22482 size_of::<AttemptReceipt>(),
22483 0,
22484 ),
22485 (
22486 47,
22487 0,
22488 include_bytes!("semantic_action_catalogue_v1.def").to_vec(),
22489 include_bytes!("semantic_action_catalogue_v1.def").len(),
22490 0,
22491 ),
22492 (
22493 48,
22494 0,
22495 publication_abi_bytes(&self.codebooks.words),
22496 self.codebooks.words.len() * 8,
22497 0,
22498 ),
22499 (
22500 55,
22501 0,
22502 tensor_table_bytes(&layout_rows, false, &[])?,
22503 tensor_table_capacity(layout_rows.len(), 32 + parent.feedback_capacity)?,
22504 0,
22505 ),
22506 ] {
22507 plans.push(PublicationAllocationPlan {
22508 role,
22509 index,
22510 capacity,
22511 length: bytes.len(),
22512 logical_begin: 0,
22513 logical_end: end,
22514 payload: PublicationPayload::Metadata(bytes),
22515 });
22516 }
22517 let mut instance = [0u8; 32];
22518 getrandom::fill(&mut instance)
22519 .map_err(|error| runtime_error("publication instance entropy", error))?;
22520 let instance = Identity256::from_bytes(instance);
22521 let contract = PublicationContract {
22522 abi: 1,
22523 range_capacity: plans.len() as u64 + 1,
22524 prefix_capacity: parent.prefix_capacity,
22525 window_capacity: 32,
22526 feedback_capacity: parent.feedback_capacity,
22527 max_position: parent.max_position,
22528 pad_token: parent.pad_token,
22529 terminal_token_count: parent.terminal_tokens.len() as u64,
22530 final_intent_payload_bytes: parent.final_intent_payload_bytes,
22531 model_generation: parent.model_generation,
22532 policy_generation: parent.policy_generation,
22533 authority_generation: parent.authority_generation,
22534 semantic_owner: self.graph.transition_arena()[1],
22535 task_identity,
22536 topology_identity: parent.topology_identity,
22537 table_identity: parent.table_identity,
22538 model_contract_layout: parent.model_contract_layout,
22539 role_count: 55,
22540 ..PublicationContract::default()
22541 };
22542 let runtime = initial_runtime_contract_record(
22543 contract,
22544 &parent.role_counts,
22545 &parent.terminal_tokens,
22546 &layouts,
22547 plans
22548 .iter()
22549 .map(|plan| (plan.role, plan.index, plan.capacity))
22550 .collect(),
22551 &parent.model_numerical_mode,
22552 &model_memory,
22553 )?;
22554 plans.push(PublicationAllocationPlan {
22555 role: runtime.role as u64,
22556 index: runtime.index,
22557 capacity: runtime.capacity_bytes,
22558 length: runtime.bytes.len(),
22559 logical_begin: 0,
22560 logical_end: 0,
22561 payload: PublicationPayload::Metadata(runtime.bytes),
22562 });
22563 plans.sort_by_key(|plan| (plan.role, plan.index));
22564 let model_geometry_digest = model_memory.digest(&layouts)?;
22565 let model_payloads = allocations
22566 .into_iter()
22567 .map(PublicationPayload::Tensor)
22568 .collect::<Vec<_>>();
22569 let (storage, uploads) = PublicationStorage::allocate(
22570 &self.provider,
22571 &plans,
22572 layouts,
22573 model_memory,
22574 &model_payloads,
22575 contract,
22576 &parent.terminal_tokens,
22577 instance,
22578 )?;
22579 self.publication = Some(Arc::new(storage));
22582 self.publication_uploads = uploads;
22583 self.captured = None;
22584 let extents = self.base_snapshot.extents();
22585 let header = PublicationHeader {
22586 instance,
22587 ring_head: parent.ring_head,
22588 prefix_extent: parent.prefix.len() as u64,
22589 semantic_owner: self.graph.transition_arena()[1],
22590 semantic_slot: u64::from(self.root.slot()),
22591 semantic_generation: self.root.generation(),
22592 semantic_digest: Identity256::from_bytes(*self.base_snapshot.digest().as_bytes()),
22593 semantic_extents: [
22594 u64::from(extents.statements()),
22595 u64::from(extents.supports()),
22596 u64::from(extents.versions()),
22597 ],
22598 model_generation: parent.model_generation,
22599 neural_generation: parent.neural_generation,
22600 cache_generation: parent.cache_generation,
22601 authority_generation: parent.authority_generation,
22602 fuel: parent.fuel,
22603 proposal: u64::from(parent.rng.proposal),
22604 stream_serial: parent.rng.stream_serial,
22605 family_id: u64::from(parent.rng.family_id),
22606 training_cursor: parent.training_cursor,
22607 training_rng: parent.training_rng,
22608 range_count: contract.range_capacity,
22609 model_geometry_digest,
22610 ..PublicationHeader::default()
22611 };
22612 let state = DeviceState {
22613 model_generation: parent.rng.model_generation,
22614 family_id: u32::from(parent.rng.family_id),
22615 stream_serial: parent.rng.stream_serial,
22616 next_proposal: u64::from(parent.rng.proposal),
22617 catalogue_generation: self.binding().generation,
22618 catalogue_digest: Identity256::from_bytes(CATALOGUE_DIGEST),
22619 binding_digest: self.binding().digest,
22620 ..DeviceState::default()
22621 };
22622 let bank = PublicationBank {
22623 header,
22624 source: parent.source,
22625 state,
22626 receipts: [SemanticTransitionReceipt::default(); COMPONENT_COUNT],
22627 };
22628 let result = self.initialize_publication(
22629 bank,
22630 &parent.terminal_tokens,
22631 &parent.role_counts,
22632 parent.rng,
22633 1,
22634 None,
22635 );
22636 if let Ok(_predecessor) = &result {
22637 #[cfg(feature = "semantic-policy")]
22638 let predecessor = *_predecessor;
22639 self.retained_initial_prefill =
22643 self.initial_prefill
22644 .take()
22645 .map(|mut stage| RetainedInitialPrefillContent {
22646 scope: stage.scope,
22647 task_identity: stage.task_identity,
22648 task_epoch: stage.task_epoch,
22649 model_generation: stage.model_generation,
22650 model: stage.model_content.take().expect("verified model content"),
22651 #[cfg(feature = "semantic-policy")]
22652 output: stage
22653 .output_content
22654 .take()
22655 .expect("verified output content"),
22656 #[cfg(feature = "semantic-policy")]
22657 record: InitialPrefillRecord {
22658 predecessor,
22659 semantic_root: header.semantic_digest,
22660 task_identity,
22661 task_epoch: stage.task_epoch,
22662 task_content,
22663 model_generation: stage.model_generation,
22664 tokens: stage.layout.prefill_tokens,
22665 mapping: stage.layout.prefill_mapping,
22666 },
22667 captured: stage.captured_content,
22668 });
22669 } else {
22670 self.poisoned = true;
22671 }
22672 result
22673 }
22674
22675 pub fn restore_state_material(
22680 &mut self,
22681 bytes: &[u8],
22682 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
22683 self.restore_state_material_inner(bytes, None)
22684 }
22685
22686 pub fn restore_learning_phase_material(
22691 &mut self,
22692 bytes: &[u8],
22693 transition: &SemanticLearningPhaseTransition,
22694 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
22695 self.restore_state_material_inner(bytes, Some(transition))
22696 }
22697
22698 fn restore_state_material_inner(
22699 &mut self,
22700 bytes: &[u8],
22701 transition: Option<&SemanticLearningPhaseTransition>,
22702 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
22703 self.ensure_rebindable()?;
22704 if self.publication.is_some() || self.captured.is_some() || self.task.is_none() {
22705 return Err(publication_input_error(
22706 "state restoration requires a fresh uncaptured task-bound Session",
22707 ));
22708 }
22709 let mut material = PublicationMaterial::decode(bytes)?;
22710 let header = material.bank.header;
22711 let mut rng = header.rng_binding()?;
22712 let mut fold = None;
22713 if let Some(transition) = transition {
22714 let (record, absorption) = transition.apply(&mut material)?;
22715 material.learning_phases.push(record);
22716 fold = absorption;
22717 }
22718 if fold.is_some() {
22719 let generation = header
22720 .model_generation
22721 .checked_add(1)
22722 .filter(|n| *n <= u64::from(u32::MAX))
22723 .ok_or(SemanticTransitionError::GenerationExhausted)?;
22724 material.bank.header.model_generation = generation;
22725 material.bank.header.neural_generation = header
22726 .neural_generation
22727 .checked_add(1)
22728 .ok_or(SemanticTransitionError::GenerationExhausted)?;
22729 material.bank.state.model_generation = generation as u32;
22730 rng.model_generation = generation as u32;
22731 }
22732 if header.authority_generation == 0 {
22733 return Err(publication_input_error(
22734 "restored RNG or task generation exceeds its native domain",
22735 ));
22736 }
22737 for (index, statement) in self.feedback_statement_bytes()?.iter().enumerate() {
22740 let saved = material
22741 .ranges
22742 .iter()
22743 .find(|item| item.range.role == 16 && item.range.index == index as u64)
22744 .ok_or(SemanticTransitionError::ObservationMismatch)?;
22745 if saved.bytes != *statement {
22746 return Err(publication_input_error(
22747 "restored feedback statement differs from the actual admitted task",
22748 ));
22749 }
22750 }
22751 let result = (|| {
22752 let root = self
22753 .graph
22754 .restore_root(&material.graph)
22755 .map_err(SemanticTransitionError::Semantic)?;
22756 let snapshot = self
22757 .graph
22758 .snapshot(crate::SemanticView::Root(root))
22759 .map_err(SemanticTransitionError::Semantic)?;
22760 let admission = self
22761 .graph
22762 .admission()
22763 .ok_or(SemanticTransitionError::NotBound)?;
22764 let codebooks = ActionCodebooks::derive(
22765 admission,
22766 self.graph.transition_arena()[1],
22767 self.task
22768 .as_ref()
22769 .and_then(|(task, _)| task.spec.program.editable_program()),
22770 )?;
22771 if codebooks.input_cells != self.codebooks.input_cells
22772 || codebooks.words.len() != self.device_codebooks.len()
22773 {
22774 return Err(publication_input_error(
22775 "restored action catalogue changes its allocated shape",
22776 ));
22777 }
22778 let (task, device) = self
22779 .task
22780 .as_mut()
22781 .ok_or(SemanticTransitionError::NotBound)?;
22782 task.admission_identity = admission.identity();
22783 if task.identity() != material.contract.task_identity {
22784 return Err(publication_input_error(
22785 "restored native task differs from its original complete admission",
22786 ));
22787 }
22788 let words = task.words(self.graph.transition_arena()[1]);
22789 self.provider
22790 .htod_sync_copy_into_tracked(&words, device)
22791 .map_err(|error| runtime_error("restored task owner upload", error))?;
22792 let codebook = material
22793 .ranges
22794 .iter_mut()
22795 .find(|item| item.range.role == 48)
22796 .ok_or(SemanticTransitionError::ObservationMismatch)?;
22797 codebook.bytes = relocate_publication_codebooks(&codebook.bytes, &codebooks.words)?;
22798 self.codebooks = codebooks;
22799 self.upload_cold_codebooks()?;
22800 self.root = root;
22801 self.base_snapshot = snapshot;
22802 self.task_epoch = header.authority_generation;
22803 self.learning_phases = material.learning_phases;
22804 let mut instance = [0; 32];
22805 getrandom::fill(&mut instance)
22806 .map_err(|error| runtime_error("restored instance entropy", error))?;
22807 let instance = Identity256::from_bytes(instance);
22808 if instance == header.instance {
22809 return Err(publication_input_error(
22810 "restoration must create a fresh instance",
22811 ));
22812 }
22813 let mut contract = material.contract;
22814 contract.semantic_owner = self.graph.transition_arena()[1];
22815 let plans: Vec<_> = material
22816 .ranges
22817 .into_iter()
22818 .map(|item| PublicationAllocationPlan {
22819 role: item.range.role,
22820 index: item.range.index,
22821 capacity: item.capacity,
22822 length: item.bytes.len(),
22823 logical_begin: item.range.logical_begin,
22824 logical_end: item.range.logical_end,
22825 payload: if matches!(item.range.role, 18..=25) {
22826 PublicationPayload::Uncomputed
22827 } else {
22828 PublicationPayload::Metadata(item.bytes)
22829 },
22830 })
22831 .collect();
22832 let model_payloads = material
22833 .model_allocations
22834 .into_iter()
22835 .map(PublicationPayload::Metadata)
22836 .collect::<Vec<_>>();
22837 let (storage, uploads) = PublicationStorage::allocate(
22838 &self.provider,
22839 &plans,
22840 material.layouts,
22841 material.model_memory,
22842 &model_payloads,
22843 contract,
22844 &material.terminals,
22845 instance,
22846 )?;
22847 material.bank.header.abi = 0;
22848 material.bank.header.instance = instance;
22849 material.bank.header.recovered_instance = header.instance;
22850 material.bank.header.sealed_epoch = 0;
22851 material.bank.header.base_word = 0;
22852 material.bank.header.publication_word = 0;
22853 material.bank.header.semantic_owner = contract.semantic_owner;
22854 material.bank.header.semantic_slot = u64::from(root.slot());
22855 material.bank.header.semantic_generation = root.generation();
22856 material.bank.header.neural_bank = 0;
22857 self.publication = Some(Arc::new(storage));
22861 self.publication_uploads = uploads;
22862 let restored = self.initialize_publication(
22863 material.bank,
22864 &material.terminals,
22865 &material.role_counts,
22866 rng,
22867 if fold.is_some() {
22868 7
22869 } else if transition.is_some() {
22870 5
22871 } else {
22872 4
22873 },
22874 fold.as_ref(),
22875 )?;
22876 if transition.is_none()
22877 && (restored.logical_digest != header.logical_digest
22878 || restored.state_digest != header.state_digest)
22879 {
22880 return Err(SemanticTransitionError::ObservationMismatch);
22881 }
22882 Ok(restored)
22883 })();
22884 if result.is_err() {
22885 self.poisoned = true;
22886 }
22887 result
22888 }
22889
22890 pub fn learning_phase_history(&self) -> &[SemanticLearningPhaseRecord] {
22893 &self.learning_phases
22894 }
22895
22896 pub fn rebind_restored_training_arena(
22901 &mut self,
22902 source: &[u8],
22903 witness: SemanticTaskGoalWitness,
22904 rows: Vec<SemanticTrainingViewRow>,
22905 objective: SemanticTrainingObjective,
22906 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
22907 self.ensure_quiescent()?;
22908 if self.poisoned
22909 || self.captured.is_some()
22910 || !self.readers.is_empty()
22911 || self.training_views.is_some()
22912 || self.task.is_none()
22913 || self.publication.is_none()
22914 {
22915 return Err(publication_input_error(
22916 "training arena transfer requires one private restored publication",
22917 ));
22918 }
22919 self.task_objective_law()
22920 .ok_or(SemanticTransitionError::NotBound)?
22921 .require_objective(&objective)?;
22922 let result = (|| {
22923 let mut material = PublicationMaterial::decode(source)?;
22924 material.require_successful_recompute()?;
22925 let original = material.bank.header;
22926 let restored = self.read_publication_header(0)?;
22927 if restored.recovered_instance != original.instance
22928 || restored.instance == original.instance
22929 || restored.publication_word != 0
22930 || restored.logical_digest != original.logical_digest
22931 || restored.state_digest != original.state_digest
22932 || self.task_epoch != original.authority_generation
22933 {
22934 return Err(publication_input_error(
22935 "training arena source is not the exact private cold restoration",
22936 ));
22937 }
22938 let (task, _) = self
22939 .task
22940 .as_ref()
22941 .ok_or(SemanticTransitionError::NotBound)?;
22942 let old_witness = task.goal_witness.ok_or(SemanticTransitionError::NotBound)?;
22943 if task.identity() != material.contract.task_identity
22944 || witness.semantic_root != old_witness.semantic_root
22945 || witness.mandatory_link_count == 0
22946 || witness.constraint_count == 0
22947 || witness
22948 .authority_root
22949 .as_bytes()
22950 .iter()
22951 .all(|byte| *byte == 0)
22952 || witness
22953 .mandatory_links_root
22954 .as_bytes()
22955 .iter()
22956 .all(|byte| *byte == 0)
22957 || witness
22958 .constraints_root
22959 .as_bytes()
22960 .iter()
22961 .all(|byte| *byte == 0)
22962 {
22963 return Err(publication_input_error(
22964 "training arena transfer changed the original task content or semantic goal",
22965 ));
22966 }
22967 let next_epoch = self
22968 .task_epoch
22969 .checked_add(1)
22970 .ok_or(SemanticTransitionError::GenerationExhausted)?;
22971 let model_mode = material.model_numerical_mode()?.to_vec();
22972 let (task, device) = self
22973 .task
22974 .as_mut()
22975 .ok_or(SemanticTransitionError::NotBound)?;
22976 task.goal_witness = Some(witness);
22977 let task_identity = task.identity();
22978 if task_identity == material.contract.task_identity {
22979 return Err(publication_input_error(
22980 "training arena transfer requires a new current authority binding",
22981 ));
22982 }
22983 let words = task.words(self.graph.transition_arena()[1]);
22984 self.provider
22985 .htod_sync_copy_into_tracked(&words, device)
22986 .map_err(|error| runtime_error("training arena task owner upload", error))?;
22987 self.training_views = Some(SemanticTrainingViewArena::allocate(
22988 &self.provider,
22989 &self.domain,
22990 rows,
22991 objective,
22992 task.spec.training_domain.as_ref().ok_or_else(|| {
22993 publication_input_error(
22994 "training arena transfer requires the original pre-action input domain",
22995 )
22996 })?,
22997 task_identity,
22998 task.content().0,
22999 task.content().1,
23000 )?);
23001 material.contract.task_identity = task_identity;
23002 material.contract.authority_generation = next_epoch;
23003 material.contract.semantic_owner = self.graph.transition_arena()[1];
23004 let capacities = material
23005 .ranges
23006 .iter()
23007 .filter(|item| item.range.role != 43)
23008 .map(|item| (item.range.role, item.range.index, item.capacity))
23009 .collect();
23010 let runtime = initial_runtime_contract_record(
23011 material.contract,
23012 &material.role_counts,
23013 &material.terminals,
23014 &material.layouts,
23015 capacities,
23016 &model_mode,
23017 &material.model_memory,
23018 )?;
23019 let runtime_range = material
23020 .ranges
23021 .iter_mut()
23022 .find(|item| item.range.role == 43 && item.range.index == 0)
23023 .ok_or(SemanticTransitionError::ObservationMismatch)?;
23024 if runtime.bytes.len() > runtime_range.capacity {
23025 return Err(publication_input_error(
23026 "training arena runtime contract exceeds its retained allocation",
23027 ));
23028 }
23029 runtime_range.bytes = runtime.bytes;
23030 let plans = material
23031 .ranges
23032 .into_iter()
23033 .map(|item| PublicationAllocationPlan {
23034 role: item.range.role,
23035 index: item.range.index,
23036 capacity: item.capacity,
23037 length: item.bytes.len(),
23038 logical_begin: item.range.logical_begin,
23039 logical_end: item.range.logical_end,
23040 payload: if matches!(item.range.role, 18..=25) {
23041 PublicationPayload::Uncomputed
23042 } else {
23043 PublicationPayload::Metadata(item.bytes)
23044 },
23045 })
23046 .collect::<Vec<_>>();
23047 let model_payloads = material
23048 .model_allocations
23049 .into_iter()
23050 .map(PublicationPayload::Metadata)
23051 .collect::<Vec<_>>();
23052 let mut instance = [0u8; 32];
23053 getrandom::fill(&mut instance)
23054 .map_err(|error| runtime_error("training arena instance entropy", error))?;
23055 let instance = Identity256::from_bytes(instance);
23056 if instance == original.instance || instance == restored.instance {
23057 return Err(publication_input_error(
23058 "training arena requires a fresh instance",
23059 ));
23060 }
23061 let (storage, uploads) = PublicationStorage::allocate(
23062 &self.provider,
23063 &plans,
23064 material.layouts,
23065 material.model_memory,
23066 &model_payloads,
23067 material.contract,
23068 &material.terminals,
23069 instance,
23070 )?;
23071 let mut bank = material.bank;
23072 bank.header.abi = 0;
23073 bank.header.instance = instance;
23074 bank.header.recovered_instance = original.instance;
23075 bank.header.sealed_epoch = 0;
23076 bank.header.base_word = 0;
23077 bank.header.publication_word = 0;
23078 bank.header.semantic_owner = material.contract.semantic_owner;
23079 bank.header.semantic_slot = u64::from(self.root.slot());
23080 bank.header.semantic_generation = self.root.generation();
23081 bank.header.neural_bank = 0;
23082 bank.header.authority_generation = next_epoch;
23083 self.publication = Some(Arc::new(storage));
23084 self.publication_uploads = uploads;
23085 self.task_epoch = next_epoch;
23086 let published = self.initialize_publication(
23087 bank,
23088 &material.terminals,
23089 &material.role_counts,
23090 original.rng_binding()?,
23091 5,
23092 None,
23093 )?;
23094 if published.logical_digest == original.logical_digest
23095 || published.state_digest == original.state_digest
23096 {
23097 return Err(SemanticTransitionError::ObservationMismatch);
23098 }
23099 Ok(published)
23100 })();
23101 if result.is_err() {
23102 self.poisoned = true;
23103 }
23104 result
23105 }
23106
23107 pub fn verify_restored_state_material(
23111 &mut self,
23112 lease: &SemanticPublishedLease,
23113 bytes: &[u8],
23114 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
23115 let expected = PublicationMaterial::decode(bytes)?;
23116 let actual = PublicationMaterial::decode(&self.published_state_material(lease)?)?;
23117 if expected.learning_phases != actual.learning_phases {
23118 return Err(publication_input_error(
23119 "checkpoint restore changed retained learning-phase history",
23120 ));
23121 }
23122 let expected = expected.bank.header;
23123 let header = actual.bank.header;
23124 if header.instance == expected.instance
23125 || header.recovered_instance != expected.instance
23126 || header.publication_word != 0
23127 || header.logical_digest != expected.logical_digest
23128 || header.state_digest != expected.state_digest
23129 {
23130 return Err(publication_input_error(
23131 "checkpoint restore no longer owns the exact fresh recovered publication",
23132 ));
23133 }
23134 self.published_identity(lease)
23135 }
23136
23137 pub fn checkpoint_initial_prefill_material(
23141 &mut self,
23142 lease: &SemanticPublishedLease,
23143 ) -> Result<(Vec<u8>, bool), SemanticTransitionError> {
23144 self.ensure_quiescent()?;
23145 self.checked_reader(lease)?;
23146 #[cfg(feature = "semantic-policy")]
23147 if let Some(record) = self
23148 .retained_initial_prefill
23149 .as_ref()
23150 .map(|retained| retained.record.clone())
23151 {
23152 let content = self
23153 .original_initial_prefill_content(
23154 record.predecessor,
23155 record.semantic_root,
23156 record.tokens.len() as u64,
23157 record.model_generation,
23158 record.task_identity,
23159 record.task_content,
23160 )?
23161 .ok_or(SemanticTransitionError::ObservationMismatch)?;
23162 if let Some(saved) = &self.checkpoint_initial_prefill {
23163 if saved.original != record.predecessor || saved.content != content {
23164 self.poisoned = true;
23165 return Err(SemanticTransitionError::ObservationMismatch);
23166 }
23167 } else {
23168 self.checkpoint_initial_prefill = Some(CheckpointInitialPrefill {
23169 original: record.predecessor,
23170 content,
23171 recovery_referent: None,
23172 });
23173 }
23174 }
23175 Ok((
23176 CheckpointInitialPrefill::encode_section(self.checkpoint_initial_prefill.as_ref())?,
23177 self.checkpoint_initial_prefill.is_some(),
23178 ))
23179 }
23180
23181 pub fn verify_checkpoint_initial_prefill_source(
23182 section: &[u8],
23183 native: &[u8],
23184 task_identity: Identity256,
23185 task_epoch: u64,
23186 task_content: SemanticTaskContentIdentity,
23187 require_original_publication: bool,
23188 ) -> Result<bool, SemanticTransitionError> {
23189 let Some(prefill) = CheckpointInitialPrefill::decode_section(section)? else {
23190 return Ok(false);
23191 };
23192 let material = PublicationMaterial::decode(native)?;
23193 let header = material.bank.header;
23194 let original = SemanticPublishedIdentity {
23195 instance: header.instance,
23196 word: header.publication_word,
23197 logical_digest: header.logical_digest,
23198 state_digest: header.state_digest,
23199 };
23200 if material.contract.task_identity != task_identity
23201 || prefill.original.word != 0
23202 || (require_original_publication && prefill.original != original)
23203 {
23204 return Err(publication_input_error(
23205 "checkpoint initial prefill names another original publication or task",
23206 ));
23207 }
23208 if prefill.original == original {
23209 prefill.verify_content(
23210 header.semantic_digest,
23211 header.model_generation,
23212 task_identity,
23213 task_epoch,
23214 task_content,
23215 header.prefix_extent,
23216 )?;
23217 } else {
23218 prefill.verify_recorded_content(task_identity, task_epoch, task_content)?;
23219 }
23220 Ok(true)
23221 }
23222
23223 pub fn bind_restored_checkpoint_initial_prefill(
23226 &mut self,
23227 lease: &SemanticPublishedLease,
23228 native: &[u8],
23229 section: &[u8],
23230 referent: &[u8],
23231 ) -> Result<(), SemanticTransitionError> {
23232 if self.checkpoint_initial_prefill.is_some() || referent.is_empty() {
23233 return Err(publication_input_error(
23234 "restored initial prefill is already bound or has no source reference",
23235 ));
23236 }
23237 self.verify_restored_state_material(lease, native)?;
23238 let original_header = PublicationMaterial::decode(native)?.bank.header;
23239 let original = SemanticPublishedIdentity {
23240 instance: original_header.instance,
23241 word: original_header.publication_word,
23242 logical_digest: original_header.logical_digest,
23243 state_digest: original_header.state_digest,
23244 };
23245 let mut prefill = CheckpointInitialPrefill::decode_section(section)?.ok_or_else(|| {
23246 publication_input_error("pre-action checkpoint has no original initial prefill")
23247 })?;
23248 let task_identity = self
23249 .task_evaluation_identity()
23250 .ok_or(SemanticTransitionError::NotBound)?;
23251 let (task_content, _) = self
23252 .task_content()
23253 .ok_or(SemanticTransitionError::NotBound)?;
23254 if prefill.original != original {
23255 return Err(publication_input_error(
23256 "checkpoint prefill names another original publication",
23257 ));
23258 }
23259 prefill.verify_content(
23260 original_header.semantic_digest,
23261 original_header.model_generation,
23262 task_identity,
23263 self.task_epoch,
23264 task_content,
23265 original_header.prefix_extent,
23266 )?;
23267 prefill.recovery_referent = Some(referent.to_vec());
23268 self.checkpoint_initial_prefill = Some(prefill);
23269 Ok(())
23270 }
23271
23272 fn initialize_publication(
23273 &mut self,
23274 bank: PublicationBank,
23275 terminal_tokens: &[u64],
23276 role_counts: &[u64; 55],
23277 rng: SemanticRngBinding,
23278 operation: u64,
23279 fold: Option<&learning_phase::LearningFoldPlan>,
23280 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
23281 let storage = Arc::clone(
23282 self.publication
23283 .as_ref()
23284 .expect("installed publication owner"),
23285 );
23286 let mut recorder = self.domain.new_strict_recorder();
23287 storage.record(&mut recorder);
23288 for (_, payload) in &self.publication_uploads {
23289 if let PublicationPayload::Tensor(tensor) = payload {
23290 if let Some(source) = &tensor.source {
23291 recorder.read(source);
23292 }
23293 }
23294 }
23295 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
23296 for allocation in &storage.allocations {
23297 if allocation.is_empty() {
23300 continue;
23301 }
23302 unsafe {
23305 sys::cuMemsetD8Async(
23306 allocation.device_ptr_value(),
23307 0,
23308 allocation.len(),
23309 enqueue.stream().cu_stream(),
23310 )
23311 }
23312 .result()
23313 .map_err(|error| XlogError::Kernel(error.to_string()))?;
23314 }
23315 for (slot, payload) in &self.publication_uploads {
23316 if let PublicationPayload::Tensor(tensor) = payload {
23317 if let Some(source) = &tensor.source {
23318 let destination = &storage.allocations[*slot];
23319 let layout = if tensor.layout.role == 0 {
23320 &tensor.layout
23321 } else {
23322 &storage.layouts[&(tensor.layout.role, tensor.layout.index)]
23323 };
23324 for (source_offset, destination_offset, bytes) in
23325 tensor_copy_plan(&tensor.layout, layout)
23326 .map_err(|error| XlogError::Kernel(error.to_string()))?
23327 {
23328 unsafe {
23329 sys::cuMemcpyDtoDAsync_v2(
23330 destination.device_ptr_value() + destination_offset,
23331 *source.device_ptr() + source_offset,
23332 bytes,
23333 enqueue.stream().cu_stream(),
23334 )
23335 }
23336 .result()
23337 .map_err(|error| XlogError::Kernel(error.to_string()))?;
23338 }
23339 }
23340 }
23341 }
23342 Ok::<(), XlogError>(())
23343 })?;
23344 wait_on_stream(
23345 &self.stream,
23346 &mut self.poisoned,
23347 &mut self.stream_waits,
23348 "cold publication tensor snapshot",
23349 CudaStream::synchronize,
23350 )?;
23351 for (slot, payload) in &self.publication_uploads {
23352 if let PublicationPayload::Metadata(bytes) = payload {
23353 if !bytes.is_empty() {
23354 let mut destination = storage.allocations[*slot].view().slice(..bytes.len());
23355 self.provider
23356 .htod_launch_metadata_sync_copy_into(bytes, &mut destination)
23357 .map_err(|error| runtime_error("cold publication record upload", error))?;
23358 }
23359 }
23360 }
23361 if let Some(fold) = fold {
23362 self.apply_learning_fold(fold)?;
23363 }
23364 upload_publication(&self.provider, &[bank], &storage.banks[0])?;
23365 upload_publication(&self.provider, &[bank], &storage.banks[1])?;
23366 for bank in 0..2 {
23367 upload_publication(
23368 &self.provider,
23369 &storage.bank_templates[bank],
23370 &storage.directories[bank],
23371 )?;
23372 }
23373 let entries: Vec<_> = storage
23374 .allocations
23375 .iter()
23376 .map(|allocation| PublicationStorageEntry {
23377 pointer: allocation.device_ptr_value(),
23378 bytes: allocation.len() as u64,
23379 generation: 1,
23380 })
23381 .collect();
23382 upload_publication(&self.provider, &entries, &storage.storage)?;
23383 upload_publication(&self.provider, &[storage.contract_value], &storage.contract)?;
23384 upload_publication(&self.provider, terminal_tokens, &storage.terminals)?;
23385 let counts: Vec<_> = role_counts
23386 .iter()
23387 .enumerate()
23388 .map(|(index, &count)| PublicationRoleCount {
23389 role: index as u64 + 1,
23390 count,
23391 })
23392 .collect();
23393 upload_publication(&self.provider, &counts, &storage.role_counts)?;
23394 upload_publication(
23395 &self.provider,
23396 &[PendingContinuation {
23397 abi: 1,
23398 ranges: storage.continuation_directory.device_ptr_value(),
23399 range_count: storage.continuation_templates.len() as u64,
23400 ..PendingContinuation::default()
23401 }],
23402 &storage.continuation,
23403 )?;
23404 upload_publication(
23405 &self.provider,
23406 &storage.continuation_templates,
23407 &storage.continuation_directory,
23408 )?;
23409 upload_publication(
23410 &self.provider,
23411 &[PublicationControl {
23412 abi: 1,
23413 instance: storage.instance,
23414 banks: storage.banks.each_ref().map(|bank| bank.device_ptr_value()),
23415 directories: storage
23416 .directories
23417 .each_ref()
23418 .map(|directory| directory.device_ptr_value()),
23419 storage: storage.storage.device_ptr_value(),
23420 storage_count: storage.allocations.len() as u64,
23421 contract: storage.contract.device_ptr_value(),
23422 continuation: storage.continuation.device_ptr_value(),
23423 ..PublicationControl::default()
23424 }],
23425 &storage.control,
23426 )?;
23427 self.upload_rng_state(self.binding(), rng)?;
23428 self.publication_command(operation, None)?;
23429 let control = self.publication_read(storage.control.view())?[0];
23430 if control.refusal != 0 {
23431 return Err(SemanticTransitionError::PublicationRefused {
23432 status: control.refusal,
23433 });
23434 }
23435 let header = self.read_publication_header(0)?;
23436 if header.abi != 1
23437 || header.instance != storage.instance
23438 || header.publication_word != 0
23439 || control.word != 0
23440 || header.model_geometry_digest != bank.header.model_geometry_digest
23441 || (operation == 4
23442 && header.model_numerical_digest != bank.header.model_numerical_digest)
23443 {
23444 return Err(SemanticTransitionError::ObservationMismatch);
23445 }
23446 self.publication_uploads.clear();
23447 self.rng = Some(rng);
23448 self.next_proposal = u64::from(rng.proposal);
23449 Ok(SemanticPublishedIdentity {
23450 instance: header.instance,
23451 word: header.publication_word,
23452 logical_digest: header.logical_digest,
23453 state_digest: header.state_digest,
23454 })
23455 }
23456
23457 fn publication_command(
23458 &mut self,
23459 operation: u64,
23460 token: Option<u64>,
23461 ) -> Result<(), SemanticTransitionError> {
23462 let storage = self
23463 .publication
23464 .as_ref()
23465 .ok_or(SemanticTransitionError::NotBound)?;
23466 let mut descriptor = self.descriptor();
23467 descriptor.publication = PublicationCommand {
23468 control: storage.control.device_ptr_value(),
23469 operation,
23470 lease: token.map_or(0, |token| self.readers[&token].device.device_ptr_value()),
23471 };
23472 let mut recorder = self.kernel_recorder();
23473 if let Some(token) = token {
23474 recorder.read_write(&self.readers[&token].device);
23475 }
23476 let execute = self.execute.clone();
23477 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |stream| {
23478 unsafe {
23481 execute.launch_in(
23482 stream,
23483 LaunchConfig {
23484 grid_dim: (1, 1, 1),
23485 block_dim: (256, 1, 1),
23486 shared_mem_bytes: 0,
23487 },
23488 (descriptor,),
23489 )
23490 }
23491 .map_err(|error| XlogError::Kernel(error.to_string()))
23492 })?;
23493 wait_on_stream(
23494 &self.stream,
23495 &mut self.poisoned,
23496 &mut self.stream_waits,
23497 "publication command completion",
23498 CudaStream::synchronize,
23499 )
23500 }
23501
23502 fn publication_read<T: DeviceRepr + Copy>(
23503 &mut self,
23504 source: DeviceMemoryView<T>,
23505 ) -> Result<Vec<T>, SemanticTransitionError> {
23506 let bytes = source
23507 .len()
23508 .checked_mul(size_of::<T>())
23509 .ok_or_else(|| publication_input_error("publication metadata read overflow"))?;
23510 let mut pinned = crate::device::PinnedHostBuffer::new(&self.stream, bytes)
23511 .map_err(|error| runtime_error("publication metadata staging", error))?;
23512 let mut recorder = self.domain.new_strict_recorder();
23513 recorder.read(&source);
23514 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |stream| {
23515 unsafe {
23518 pinned.enqueue(stream.stream(), |destination| {
23519 sys::cuMemcpyDtoHAsync_v2(
23520 destination.cast(),
23521 *source.device_ptr(),
23522 bytes,
23523 stream.stream().cu_stream(),
23524 )
23525 .result()
23526 })
23527 }
23528 .map_err(|error| XlogError::Kernel(error.to_string()))
23529 })?;
23530 wait_on_stream(
23531 &self.stream,
23532 &mut self.poisoned,
23533 &mut self.stream_waits,
23534 "publication metadata read completion",
23535 CudaStream::synchronize,
23536 )?;
23537 let result = unsafe { pinned.read_vec::<T>(source.len()) }
23539 .map_err(|error| runtime_error("publication metadata read", error))?;
23540 self.provider
23541 .record_final_observation_transfer(bytes as u64);
23542 Ok(result)
23543 }
23544
23545 fn read_publication_header(
23546 &mut self,
23547 bank: usize,
23548 ) -> Result<PublicationHeader, SemanticTransitionError> {
23549 let storage = Arc::clone(
23550 self.publication
23551 .as_ref()
23552 .ok_or(SemanticTransitionError::NotBound)?,
23553 );
23554 let view = unsafe {
23557 storage.banks[bank]
23558 .view()
23559 .cast::<u8>()
23560 .expect("byte-aligned bank ABI")
23561 .slice(..size_of::<PublicationHeader>())
23562 .cast::<PublicationHeader>()
23563 .expect("aligned fixed header ABI")
23564 };
23565 Ok(self.publication_read(view)?[0])
23566 }
23567
23568 pub fn acquire(&mut self) -> Result<SemanticPublishedLease, SemanticTransitionError> {
23569 if self.pending {
23570 let proposal = u32::try_from(self.next_proposal)
23571 .map_err(|_| SemanticTransitionError::GenerationExhausted)?;
23572 self.observe(proposal)?.into_published()?;
23575 }
23576 self.ensure_quiescent()?;
23577 let storage = Arc::clone(
23578 self.publication
23579 .as_ref()
23580 .ok_or(SemanticTransitionError::NotBound)?,
23581 );
23582 let token = self
23583 .next_reader
23584 .checked_add(1)
23585 .ok_or(SemanticTransitionError::GenerationExhausted)?;
23586 self.next_reader = token;
23587 let device = allocate_publication(&self.provider, 1)?;
23588 self.steps.insert(token, StepContentStorage::new());
23589 self.readers.insert(
23590 token,
23591 PublishedReader {
23592 device,
23593 aliases: Arc::new(()),
23594 consumer_streams: BTreeSet::new(),
23595 },
23596 );
23597 if let Err(error) = upload_publication(
23599 &self.provider,
23600 &[PublicationLease::default()],
23601 &self.readers[&token].device,
23602 ) {
23603 self.poisoned = true;
23604 return Err(error);
23605 }
23606 self.publication_command(2, Some(token))?;
23607 let lease = self.publication_read(self.readers[&token].device.view())?[0];
23608 if lease.status != 0 {
23609 self.readers.remove(&token);
23610 self.steps.remove(&token);
23611 return Err(SemanticTransitionError::PublicationRefused {
23612 status: lease.status,
23613 });
23614 }
23615 if lease.abi != 1
23616 || lease.active != 1
23617 || lease.instance != storage.instance
23618 || lease.bank > 1
23619 || lease.bank != (lease.word & 1)
23620 || lease.epoch != lease.word >> 1
23621 {
23622 self.poisoned = true;
23623 return Err(SemanticTransitionError::ObservationMismatch);
23624 }
23625 let header = self.read_publication_header(lease.bank as usize)?;
23626 let directory = self.publication_read(storage.directories[lease.bank as usize].view())?;
23627 let source_view = unsafe {
23630 storage.banks[lease.bank as usize]
23631 .view()
23632 .cast::<u8>()
23633 .expect("byte-aligned bank ABI")
23634 .slice(
23635 size_of::<PublicationHeader>()
23636 ..size_of::<PublicationHeader>() + 32 * size_of::<SemanticTextSlot>(),
23637 )
23638 .cast::<SemanticTextSlot>()
23639 .expect("aligned fixed source ABI")
23640 };
23641 let source: [SemanticTextSlot; 32] = self
23642 .publication_read(source_view)?
23643 .try_into()
23644 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
23645 if header.abi != 1
23646 || header.instance != lease.instance
23647 || header.publication_word != lease.word
23648 || header.sealed_epoch != lease.epoch
23649 || header.range_count as usize != directory.len()
23650 {
23651 self.poisoned = true;
23652 return Err(SemanticTransitionError::ObservationMismatch);
23653 }
23654 let identity = SemanticPublishedIdentity {
23655 instance: lease.instance,
23656 word: lease.word,
23657 logical_digest: header.logical_digest,
23658 state_digest: header.state_digest,
23659 };
23660 self.steps
23661 .get_mut(&token)
23662 .expect("installed acquisition step")
23663 .identity = Some(identity);
23664 Ok(SemanticPublishedLease {
23665 issuer: Arc::clone(&self.publication_issuer),
23666 token,
23667 identity,
23668 header,
23669 source,
23670 directory,
23671 active: true,
23672 })
23673 }
23674
23675 fn checked_reader(
23676 &self,
23677 lease: &SemanticPublishedLease,
23678 ) -> Result<&PublishedReader, SemanticTransitionError> {
23679 self.ensure_quiescent()?;
23680 if !lease.active || !Arc::ptr_eq(&lease.issuer, &self.publication_issuer) {
23681 return Err(publication_input_error(
23682 "lease is released or belongs to a different Session",
23683 ));
23684 }
23685 self.readers
23686 .get(&lease.token)
23687 .ok_or_else(|| publication_input_error("lease has no live native reader owner"))
23688 }
23689
23690 fn checked_step(
23691 &self,
23692 lease: &SemanticPublishedLease,
23693 ) -> Result<&StepContentStorage, SemanticTransitionError> {
23694 self.ensure_quiescent()?;
23695 if !Arc::ptr_eq(&lease.issuer, &self.publication_issuer) {
23696 return Err(publication_input_error(
23697 "retained step belongs to a different Session",
23698 ));
23699 }
23700 let step = self
23701 .steps
23702 .get(&lease.token)
23703 .ok_or_else(|| publication_input_error("original step has been fully released"))?;
23704 if step.identity != Some(lease.identity)
23705 || lease.active != self.readers.contains_key(&lease.token)
23706 {
23707 return Err(publication_input_error(
23708 "retained step differs from its original acquired identity",
23709 ));
23710 }
23711 Ok(step)
23712 }
23713
23714 pub fn retained_step_identity(
23717 &self,
23718 lease: &SemanticPublishedLease,
23719 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
23720 self.checked_step(lease)?;
23721 Ok(lease.identity)
23722 }
23723
23724 pub fn require_retired_publication(
23728 &self,
23729 lease: &SemanticPublishedLease,
23730 ) -> Result<(), SemanticTransitionError> {
23731 self.ensure_quiescent()?;
23732 #[cfg(feature = "semantic-policy")]
23733 self.require_closed_evaluations()?;
23734 if self.is_poisoned() {
23735 return Err(SemanticTransitionError::Poisoned);
23736 }
23737 if !Arc::ptr_eq(&lease.issuer, &self.publication_issuer)
23738 || lease.active
23739 || !self.readers.is_empty()
23740 || !self.steps.is_empty()
23741 || self.captured.is_some()
23742 || self.prepared_segment.is_some()
23743 || !self.prepared_resources.is_empty()
23744 {
23745 return Err(publication_input_error(
23746 "private publication requires known full retirement of its original consumers",
23747 ));
23748 }
23749 Ok(())
23750 }
23751
23752 pub fn published_identity(
23753 &self,
23754 lease: &SemanticPublishedLease,
23755 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
23756 self.checked_reader(lease)?;
23757 Ok(lease.identity)
23758 }
23759
23760 pub fn current_recompute_state_material(
23764 &mut self,
23765 lease: &SemanticPublishedLease,
23766 ) -> Result<Vec<u8>, SemanticTransitionError> {
23767 self.checked_reader(lease)?;
23768 let storage = Arc::clone(
23769 self.publication
23770 .as_ref()
23771 .ok_or(SemanticTransitionError::NotBound)?,
23772 );
23773 let control = self.publication_read(storage.control.view())?[0];
23774 if control.abi != 1
23775 || control.instance != lease.identity.instance
23776 || control.word != lease.identity.word
23777 {
23778 return Err(publication_input_error(
23779 "selected recompute is no longer the current publication",
23780 ));
23781 }
23782 let material = self.published_state_material(lease)?;
23783 PublicationMaterial::decode(&material)?.require_successful_recompute()?;
23784 Ok(material)
23785 }
23786
23787 pub fn published_range_keys(
23791 &self,
23792 lease: &SemanticPublishedLease,
23793 ) -> Result<Vec<(SemanticStateRole, u64)>, SemanticTransitionError> {
23794 self.checked_reader(lease)?;
23795 lease
23796 .directory
23797 .iter()
23798 .map(|range| {
23799 SemanticStateRole::from_code(range.role)
23800 .map(|role| (role, range.index))
23801 .ok_or(SemanticTransitionError::ObservationMismatch)
23802 })
23803 .collect()
23804 }
23805
23806 fn order_content_inputs(
23811 &mut self,
23812 lease: &SemanticPublishedLease,
23813 consumer_stream: u64,
23814 ) -> Result<(), SemanticTransitionError> {
23815 self.readers
23816 .get_mut(&lease.token)
23817 .expect("validated publication reader")
23818 .consumer_streams
23819 .insert(consumer_stream);
23820 self.order_step_content_inputs(lease.token, consumer_stream)
23821 }
23822
23823 fn order_step_content_inputs(
23824 &mut self,
23825 reader_token: u64,
23826 consumer_stream: u64,
23827 ) -> Result<(), SemanticTransitionError> {
23828 self.steps
23829 .get_mut(&reader_token)
23830 .expect("validated content step")
23831 .consumer_streams
23832 .insert(consumer_stream);
23833 self.order_tensor_producer_inputs(consumer_stream)
23834 }
23835
23836 fn order_tensor_producer_inputs(
23837 &mut self,
23838 consumer_stream: u64,
23839 ) -> Result<(), SemanticTransitionError> {
23840 let consumer = dlpack_consumer_stream(consumer_stream)?;
23841 self.stream
23842 .context()
23843 .bind_to_thread()
23844 .map_err(|e| runtime_error("content context binding", e))?;
23845 for source in [std::ptr::null_mut(), consumer] {
23846 let event = self
23847 .stream
23848 .context()
23849 .new_event(None)
23850 .map_err(|e| runtime_error("content producer event", e))?;
23851 self.release_events.push(event);
23852 let event = self.release_events.last().expect("retained content event");
23853 unsafe { cudarc::driver::result::event::record(event.cu_event(), source) }
23857 .map_err(|e| runtime_error("content producer event record", e))?;
23858 self.stream
23859 .wait(event)
23860 .map_err(|e| runtime_error("content producer event join", e))?;
23861 }
23862 Ok(())
23863 }
23864
23865 fn order_content_consumers(
23866 &mut self,
23867 consumer_stream: u64,
23868 ) -> Result<(), SemanticTransitionError> {
23869 let event = self
23870 .stream
23871 .context()
23872 .new_event(None)
23873 .map_err(|e| runtime_error("content guard event", e))?;
23874 self.release_events.push(event);
23875 let event = self
23876 .release_events
23877 .last()
23878 .expect("retained content guard event");
23879 unsafe {
23883 cudarc::driver::result::event::record(event.cu_event(), self.stream.cu_stream())
23884 .map_err(|e| runtime_error("content guard event record", e))?;
23885 sys::cuStreamWaitEvent(
23886 dlpack_consumer_stream(consumer_stream)?,
23887 event.cu_event(),
23888 0,
23889 )
23890 .result()
23891 .map_err(|e| runtime_error("content guard consumer join", e))?;
23892 }
23893 Ok(())
23894 }
23895
23896 pub fn guard_published_content(
23903 &mut self,
23904 lease: &SemanticPublishedLease,
23905 keys: &[(SemanticStateRole, u64)],
23906 consumer_stream: u64,
23907 ) -> Result<(), SemanticTransitionError> {
23908 self.checked_reader(lease)?;
23909 dlpack_consumer_stream(consumer_stream)?;
23910 let storage = Arc::clone(
23911 self.publication
23912 .as_ref()
23913 .ok_or(SemanticTransitionError::NotBound)?,
23914 );
23915 let inputs = if keys
23916 .iter()
23917 .any(|(role, _)| matches!(*role as u64, 1 | 3..=13))
23918 {
23919 self.steps[&lease.token].inputs.as_ref().map(Arc::clone)
23920 } else {
23921 None
23922 };
23923 let directory = &storage.directories[(lease.identity.word & 1) as usize];
23924 let mut distinct = BTreeSet::new();
23925 let mut ranges = Vec::with_capacity(keys.len());
23926 if keys.is_empty() {
23927 return Err(publication_input_error(
23928 "content guard requires actual publication ranges",
23929 ));
23930 }
23931 for &(role, index) in keys {
23932 let key = (role as u64, index);
23933 if !distinct.insert(key) {
23934 return Err(publication_input_error(
23935 "content guard has duplicate publication ranges",
23936 ));
23937 }
23938 let (range_index, &range) = lease
23939 .directory
23940 .iter()
23941 .enumerate()
23942 .find(|(_, range)| (range.role, range.index) == key)
23943 .ok_or_else(|| {
23944 publication_input_error("content guard names an absent publication range")
23945 })?;
23946 if range_index >= directory.len() {
23947 return Err(SemanticTransitionError::ObservationMismatch);
23948 }
23949 let allocation = storage
23950 .allocations
23951 .get(range.storage_slot as usize)
23952 .ok_or(SemanticTransitionError::ObservationMismatch)?;
23953 if range.generation != 1
23954 || range
23955 .offset_bytes
23956 .checked_add(range.length_bytes)
23957 .is_none_or(|end| end > allocation.len() as u64)
23958 {
23959 return Err(SemanticTransitionError::ObservationMismatch);
23960 }
23961 let layout = if is_tensor_role(role as u64) {
23962 *storage
23963 .layouts
23964 .get(&key)
23965 .ok_or(SemanticTransitionError::ObservationMismatch)?
23966 } else {
23967 SemanticTensorLayout::default()
23968 };
23969 ranges.push((role as u64, index, layout));
23974 }
23975 let execute = self
23976 .provider
23977 .device()
23978 .inner()
23979 .get_func(
23980 "xlog_semantic_transition",
23981 "semantic_publication_content_guard",
23982 )
23983 .ok_or_else(|| {
23984 runtime_error("kernel lookup", "publication content guard unavailable")
23985 })?;
23986 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
23987 .map_err(|e| runtime_error("content guard stream admission", e))?;
23988 let result = (|| {
23989 self.order_content_inputs(lease, consumer_stream)?;
23990 if let Some(inputs) = &inputs {
23991 self.steps
23994 .get_mut(&lease.token)
23995 .expect("validated input step")
23996 .consumer_streams
23997 .insert(consumer_stream);
23998 inputs.verify(&self.domain, &mut self.poisoned)?;
23999 }
24000 for (role, index, layout) in ranges {
24001 let reader = self
24002 .readers
24003 .get(&lease.token)
24004 .expect("validated native reader");
24005 storage.enqueue_content_guard(
24006 &self.domain,
24007 &mut self.poisoned,
24008 reader.device.view(),
24009 &execute,
24010 role,
24011 index,
24012 layout,
24013 )?;
24014 }
24015 self.order_content_consumers(consumer_stream)
24016 })();
24017 if result.is_err() {
24018 self.poisoned = true;
24019 }
24020 result
24021 }
24022
24023 pub fn capture_tensor_content(
24031 &mut self,
24032 lease: &SemanticPublishedLease,
24033 tensors: Vec<SemanticTensorInput>,
24034 consumer_stream: u64,
24035 ) -> Result<SemanticTensorContentWitness, SemanticTransitionError> {
24036 self.bind_tensor_content(lease, tensors, consumer_stream, false)
24037 }
24038
24039 pub fn bind_model_content(
24044 &mut self,
24045 lease: &SemanticPublishedLease,
24046 tensors: Vec<SemanticTensorInput>,
24047 consumer_stream: u64,
24048 ) -> Result<SemanticTensorContentWitness, SemanticTransitionError> {
24049 self.bind_tensor_content(lease, tensors, consumer_stream, true)
24050 }
24051
24052 fn bind_tensor_content(
24053 &mut self,
24054 lease: &SemanticPublishedLease,
24055 tensors: Vec<SemanticTensorInput>,
24056 consumer_stream: u64,
24057 model: bool,
24058 ) -> Result<SemanticTensorContentWitness, SemanticTransitionError> {
24059 let empty = tensors.is_empty();
24060 let mut handoff = RetainedTensorAdmission {
24061 inputs: Some(tensors),
24062 stream: Arc::clone(self.provider.device().inner().stream()),
24063 ready: false,
24064 };
24065 self.checked_reader(lease)?;
24066 dlpack_consumer_stream(consumer_stream)?;
24067 if empty {
24068 return Err(publication_input_error(
24069 "content witness requires an actual tensor roster",
24070 ));
24071 }
24072 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
24073 .map_err(|e| runtime_error("content binding stream admission", e))?;
24074 if !self
24075 .provider
24076 .device()
24077 .inner()
24078 .stream()
24079 .context()
24080 .has_async_alloc()
24081 {
24082 return Err(publication_input_error(
24083 "device content capture requires stream-ordered CUDA allocation support",
24084 ));
24085 }
24086 self.steps
24089 .get_mut(&lease.token)
24090 .expect("validated content step")
24091 .consumer_streams
24092 .insert(consumer_stream);
24093 let tensors = prepare_semantic_tensors(
24094 &self.provider,
24095 handoff
24096 .inputs
24097 .take()
24098 .expect("retained original content inputs"),
24099 )?;
24100 let reader = self
24101 .steps
24102 .get_mut(&lease.token)
24103 .expect("validated content step");
24104 let index = reader.content.len();
24105 reader.content.push(TensorContentBuffers {
24106 tensors,
24107 seals: TensorContentSeals::Captured(Vec::new()),
24108 verification_inputs: Vec::new(),
24109 });
24110 let reader = &self.steps[&lease.token];
24111 let content = &reader.content[index];
24112 validate_content_coordinates(
24113 content
24114 .tensors
24115 .iter()
24116 .map(|tensor| (tensor.layout.role, tensor.layout.index)),
24117 )?;
24118 let mut native_origins = Vec::with_capacity(content.tensors.len());
24119 for tensor in &content.tensors {
24120 let mut original = None;
24121 if !model {
24122 if let Some(inputs) = &reader.inputs {
24126 if inputs.owns_tensor(tensor)? {
24127 original = Some(Arc::clone(inputs));
24128 }
24129 }
24130 if original.is_none() {
24131 for (&token, owner) in &self.steps {
24132 if token == lease.token {
24133 continue;
24134 }
24135 if let Some(inputs) = &owner.inputs {
24136 if inputs.owns_tensor(tensor)? {
24137 return Err(publication_input_error(
24138 "native step content belongs to another acquired reader",
24139 ));
24140 }
24141 }
24142 }
24143 }
24144 }
24145 if original.is_none() {
24146 tensor_content_range(
24147 &tensor.layout,
24148 tensor.logical_begin,
24149 tensor.logical_end,
24150 tensor.source.as_ref().map_or(0, DeviceMemoryView::len),
24151 )?;
24152 }
24153 native_origins.push(original);
24154 }
24155 let model_plan = if model {
24156 let storage = self
24157 .publication
24158 .as_ref()
24159 .ok_or(SemanticTransitionError::NotBound)?;
24160 let ranges = model_content_ranges(
24161 &lease.directory,
24162 &storage.layouts,
24163 content.tensors.iter().map(|tensor| {
24164 (
24165 tensor.layout,
24166 tensor.logical_begin,
24167 tensor.logical_end,
24168 tensor.source.as_ref().map_or(0, DeviceMemoryView::len),
24169 )
24170 }),
24171 )?;
24172 Some(model_content_copy_plan(
24173 &lease.directory,
24174 &ranges,
24175 &storage
24176 .allocations
24177 .iter()
24178 .map(TrackedCudaSlice::len)
24179 .collect::<Vec<_>>(),
24180 )?)
24181 } else {
24182 None
24183 };
24184 let seals = if let Some(plan) = &model_plan {
24185 TensorContentSeals::Model(ModelContentSeals::allocate(&self.provider, plan)?)
24186 } else {
24187 let mut digests = Vec::with_capacity(content.tensors.len());
24188 for (tensor, native) in content.tensors.iter().zip(native_origins) {
24189 if let Some(inputs) = native {
24190 digests.push(CapturedTensorDigest::Publication(inputs));
24191 continue;
24192 }
24193 let mut origin = None;
24194 for (&token, owner) in &self.steps {
24195 if let Some(digest) = owner.feedback_origin_digest(tensor)? {
24196 if token != lease.token {
24197 return Err(publication_input_error(
24198 "native feedback content belongs to another acquired reader",
24199 ));
24200 }
24201 origin = Some(digest);
24202 break;
24203 }
24204 }
24205 digests.push(match origin {
24206 Some(original) => original,
24207 None => {
24208 if tensor.native_allocation.is_some() {
24209 return Err(publication_input_error("native allocation origin has no original content producer in this acquired reader"));
24210 }
24211 CapturedTensorDigest::Tensor {
24212 cells: Arc::new(allocate_publication(&self.provider, 4)?), offset: 0, producer_sealed: false,
24213 }
24214 }
24215 });
24216 }
24217 TensorContentSeals::Captured(digests)
24218 };
24219 let handle = SemanticTensorContentWitness {
24220 issuer: Arc::clone(&self.publication_issuer),
24221 reader_token: lease.token,
24222 index,
24223 _witness: Arc::clone(&reader.content_witnesses),
24224 };
24225 self.steps
24226 .get_mut(&lease.token)
24227 .expect("validated content step")
24228 .content[index]
24229 .seals = seals;
24230 if let Some(plan) = model_plan {
24231 self.guard_published_content(
24235 lease,
24236 &[(SemanticStateRole::ModelContract, 0)],
24237 consumer_stream,
24238 )?;
24239 let storage = self
24240 .publication
24241 .as_ref()
24242 .ok_or(SemanticTransitionError::NotBound)?;
24243 let TensorContentSeals::Model(model) = &self.steps[&lease.token].content[index].seals
24244 else {
24245 return Err(SemanticTransitionError::ObservationMismatch);
24246 };
24247 model.snapshot(
24248 &self.domain,
24249 &mut self.poisoned,
24250 &storage.directories[(lease.identity.word & 1) as usize],
24251 &storage.allocations[plan.contract_storage_slot],
24252 &plan,
24253 )?;
24254 }
24255 self.enqueue_tensor_content(lease, &handle, consumer_stream, model)?;
24256 Ok(handle)
24257 }
24258
24259 pub fn verify_tensor_content(
24264 &mut self,
24265 lease: &SemanticPublishedLease,
24266 witness: &SemanticTensorContentWitness,
24267 tensors: Vec<SemanticTensorInput>,
24268 consumer_stream: u64,
24269 ) -> Result<(), SemanticTransitionError> {
24270 let mut handoff = RetainedTensorAdmission {
24271 inputs: Some(tensors),
24272 stream: Arc::clone(self.provider.device().inner().stream()),
24273 ready: false,
24274 };
24275 self.checked_content_witness(lease, witness)?;
24276 dlpack_consumer_stream(consumer_stream)?;
24277 self.steps
24278 .get_mut(&lease.token)
24279 .expect("validated witness step")
24280 .consumer_streams
24281 .insert(consumer_stream);
24282 let tensors = prepare_semantic_tensors(
24283 &self.provider,
24284 handoff
24285 .inputs
24286 .take()
24287 .expect("retained original verification inputs"),
24288 )?;
24289 let content = &mut self
24290 .steps
24291 .get_mut(&lease.token)
24292 .expect("validated witness step")
24293 .content[witness.index];
24294 let offset = content.verification_inputs.len();
24295 content.verification_inputs.extend(tensors);
24296 let actual = &content.verification_inputs[offset..];
24297 if actual.len() != content.tensors.len()
24298 || content
24299 .tensors
24300 .iter()
24301 .zip(actual)
24302 .any(|(expected, actual)| !same_tensor_content_owner(expected, actual))
24303 {
24304 return Err(publication_input_error("content verification must use the exact original tensor storage, layout and interval"));
24305 }
24306 self.enqueue_tensor_content(lease, witness, consumer_stream, true)
24307 }
24308
24309 fn checked_content_witness(
24310 &self,
24311 lease: &SemanticPublishedLease,
24312 witness: &SemanticTensorContentWitness,
24313 ) -> Result<(), SemanticTransitionError> {
24314 let reader = self.checked_step(lease)?;
24315 if !Arc::ptr_eq(&self.publication_issuer, &witness.issuer)
24316 || witness.reader_token != lease.token
24317 || !Arc::ptr_eq(&reader.content_witnesses, &witness._witness)
24318 || witness.index >= reader.content.len()
24319 {
24320 return Err(publication_input_error(
24321 "content witness belongs to another parent or Session",
24322 ));
24323 }
24324 Ok(())
24325 }
24326
24327 fn enqueue_tensor_content(
24328 &mut self,
24329 lease: &SemanticPublishedLease,
24330 witness: &SemanticTensorContentWitness,
24331 consumer_stream: u64,
24332 verify: bool,
24333 ) -> Result<(), SemanticTransitionError> {
24334 self.checked_content_witness(lease, witness)?;
24335 lease.model_context_header()?;
24336 self.enqueue_content_witness(witness, consumer_stream, verify)
24340 }
24341
24342 fn guard_continuation_content(
24345 &mut self,
24346 binding: &TextBindingStorage,
24347 ) -> Result<(), SemanticTransitionError> {
24348 let witness = &binding._witness;
24349 let reader = self.steps.get(&witness.reader_token).ok_or_else(|| {
24350 publication_input_error("original continuation step has been released")
24351 })?;
24352 let original_parent = match &binding.parent {
24353 TextBindingParent::Published { .. } => reader.identity.is_some(),
24354 TextBindingParent::Prepared(inputs) => {
24355 reader
24356 .inputs
24357 .as_ref()
24358 .is_some_and(|original| Arc::ptr_eq(original, inputs))
24359 && reader
24360 .prepared
24361 .as_ref()
24362 .is_some_and(|prepared| prepared.observed)
24363 && self
24364 .prepared_segment
24365 .as_ref()
24366 .is_some_and(|build| build.completed)
24367 }
24368 };
24369 if !Arc::ptr_eq(&self.publication_issuer, &witness.issuer)
24370 || !original_parent
24371 || !Arc::ptr_eq(&reader.content_witnesses, &witness._witness)
24372 || reader
24373 .content
24374 .get(witness.index)
24375 .is_none_or(|content| !matches!(content.seals, TensorContentSeals::Captured(_)))
24376 {
24377 return Err(publication_input_error(
24378 "continuation no longer owns its original captured content",
24379 ));
24380 }
24381 self.enqueue_content_witness(witness, binding.consumer_stream, true)
24382 }
24383
24384 fn enqueue_content_witness(
24385 &mut self,
24386 witness: &SemanticTensorContentWitness,
24387 consumer_stream: u64,
24388 verify: bool,
24389 ) -> Result<(), SemanticTransitionError> {
24390 let execute = self
24391 .provider
24392 .device()
24393 .inner()
24394 .get_func(
24395 "xlog_semantic_transition",
24396 "semantic_tensor_content_witness",
24397 )
24398 .ok_or_else(|| runtime_error("kernel lookup", "tensor content witness unavailable"))?;
24399 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
24400 .map_err(|e| runtime_error("tensor content stream admission", e))?;
24401 let result = (|| {
24402 self.order_step_content_inputs(witness.reader_token, consumer_stream)?;
24403 let step_owner = &self.steps[&witness.reader_token];
24404 let retained = self
24405 .prepared_segment
24406 .as_ref()
24407 .is_some_and(|build| build.completed)
24408 && step_owner
24409 .prepared
24410 .as_ref()
24411 .is_some_and(|prepared| prepared.observed);
24412 let custody = if retained {
24413 let bank = self.prepared_completed_parent_bank(witness.reader_token)?;
24414 let content = &self.steps[&witness.reader_token].content[witness.index];
24415 if matches!(&content.seals, TensorContentSeals::Model(seals)
24416 if seals.prepared.as_ref().is_none_or(|source| source.bank != bank))
24417 {
24418 return Err(publication_input_error(
24419 "completed model witness requires its original executed branch bank",
24420 ));
24421 }
24422 self.steps[&witness.reader_token]
24423 .prepared
24424 .as_ref()
24425 .expect("checked prepared owner")
24426 .replay_custody
24427 .as_ref()
24428 } else {
24429 None
24430 };
24431 let content = &self.steps[&witness.reader_token].content[witness.index];
24432 content.enqueue_with_custody(
24433 &self.domain,
24434 &mut self.poisoned,
24435 &execute,
24436 verify,
24437 custody,
24438 retained,
24439 )?;
24440 self.order_content_consumers(consumer_stream)
24441 })();
24442 if result.is_err() {
24443 self.poisoned = true;
24444 }
24445 result
24446 }
24447
24448 fn ensure_step_inputs(
24449 &mut self,
24450 lease: &SemanticPublishedLease,
24451 ) -> Result<Arc<PreparedStepInputs>, SemanticTransitionError> {
24452 self.checked_reader(lease)?;
24453 self.checked_step(lease)?;
24454 lease.model_context_header()?;
24455 if let Some(inputs) = &self.steps[&lease.token].inputs {
24456 return Ok(Arc::clone(inputs));
24457 }
24458 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
24459 .map_err(|error| runtime_error("step input preparation stream admission", error))?;
24460 let storage = Arc::clone(
24461 self.publication
24462 .as_ref()
24463 .ok_or(SemanticTransitionError::NotBound)?,
24464 );
24465 let inputs = Arc::new(PreparedStepInputs::allocate(
24466 &self.provider,
24467 storage,
24468 self.readers[&lease.token].device.view(),
24469 )?);
24470 self.steps
24473 .get_mut(&lease.token)
24474 .expect("validated input step")
24475 .inputs = Some(Arc::clone(&inputs));
24476 let result = inputs
24477 .initialize(&self.provider)
24478 .and_then(|()| inputs.enqueue(&self.domain, &mut self.poisoned));
24479 if let Err(error) = result {
24480 self.poisoned = true;
24481 return Err(error);
24482 }
24483 Ok(inputs)
24484 }
24485
24486 pub fn published_source(
24488 &mut self,
24489 lease: &SemanticPublishedLease,
24490 consumer_stream: u64,
24491 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
24492 self.export_publication_bank_field(lease, PublicationBankField::Source, consumer_stream)
24493 }
24494
24495 pub fn published_terminal(
24500 &mut self,
24501 lease: &SemanticPublishedLease,
24502 consumer_stream: u64,
24503 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
24504 self.export_publication_bank_field(lease, PublicationBankField::Terminal, consumer_stream)
24505 }
24506
24507 pub fn published_model_context(
24511 &mut self,
24512 lease: &SemanticPublishedLease,
24513 consumer_stream: u64,
24514 ) -> Result<SemanticModelContext, SemanticTransitionError> {
24515 dlpack_consumer_stream(consumer_stream)?;
24516 self.checked_reader(lease)?;
24517 let header = lease.model_context_header()?;
24518 let contract = self
24519 .publication
24520 .as_ref()
24521 .ok_or(SemanticTransitionError::NotBound)?
24522 .contract_value;
24523 let prefix_range = lease
24524 .directory
24525 .iter()
24526 .find(|range| {
24527 range.role == SemanticStateRole::PrefixIdentity as u64 && range.index == 0
24528 })
24529 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24530 if prefix_range.length_bytes != 32 {
24531 return Err(SemanticTransitionError::ObservationMismatch);
24532 }
24533 let prefix_identity =
24534 self.published_record(lease, SemanticStateRole::PrefixIdentity, 0, consumer_stream)?;
24535 let prefix_extent = self.export_publication_bank_field(
24536 lease,
24537 PublicationBankField::PrefixExtent,
24538 consumer_stream,
24539 )?;
24540 let ring_head = self.export_publication_bank_field(
24541 lease,
24542 PublicationBankField::RingHead,
24543 consumer_stream,
24544 )?;
24545 let source = self.published_source(lease, consumer_stream)?;
24546 Ok(SemanticModelContext {
24547 parent: lease.identity,
24548 descriptor_digest: header.descriptor_digest,
24549 numerical_state: (header.model_geometry_digest, header.model_numerical_digest),
24550 semantic_root: (
24551 header.semantic_owner,
24552 header.semantic_slot,
24553 header.semantic_generation,
24554 header.semantic_digest,
24555 header.semantic_extents,
24556 ),
24557 prefix: (prefix_identity, prefix_extent),
24558 ring_head,
24559 source,
24560 generations: (
24561 header.model_generation,
24562 header.neural_bank,
24563 header.neural_generation,
24564 header.cache_generation,
24565 header.authority_generation,
24566 ),
24567 topology_identity: contract.topology_identity,
24568 table_identity: contract.table_identity,
24569 capacities: (
24570 contract.prefix_capacity,
24571 contract.feedback_capacity,
24572 contract.max_position,
24573 ),
24574 })
24575 }
24576
24577 pub fn published_resident_model_memory(
24583 &mut self,
24584 lease: &SemanticPublishedLease,
24585 consumer_stream: u64,
24586 ) -> Result<SemanticResidentModelMemory, SemanticTransitionError> {
24587 dlpack_consumer_stream(consumer_stream)?;
24588 self.checked_reader(lease)?;
24589 let header = lease.model_context_header()?;
24590 let storage = Arc::clone(
24591 self.publication
24592 .as_ref()
24593 .ok_or(SemanticTransitionError::NotBound)?,
24594 );
24595 storage.model_memory.validate(&storage.layouts)?;
24596 if storage.model_slots.len() != storage.model_memory.allocation_bytes.len() {
24597 return Err(SemanticTransitionError::ObservationMismatch);
24598 }
24599 let keys = lease
24600 .directory
24601 .iter()
24602 .filter(|range| matches!(range.role, 18..=25))
24603 .map(|range| {
24604 SemanticStateRole::from_code(range.role)
24605 .map(|role| (role, range.index))
24606 .ok_or(SemanticTransitionError::ObservationMismatch)
24607 })
24608 .collect::<Result<Vec<_>, _>>()?;
24609 if keys.len() != storage.model_memory.views.len() {
24610 return Err(publication_input_error(
24611 "resident model memory requires the complete selected model roster",
24612 ));
24613 }
24614 self.guard_published_content(lease, &keys, consumer_stream)?;
24615
24616 let mut allocations = Vec::with_capacity(storage.model_slots.len());
24617 for (allocation_index, (&bytes, slots)) in storage
24618 .model_memory
24619 .allocation_bytes
24620 .iter()
24621 .zip(&storage.model_slots)
24622 .enumerate()
24623 {
24624 let mut selected_slot = None;
24625 for range in lease
24626 .directory
24627 .iter()
24628 .filter(|range| matches!(range.role, 18..=25))
24629 {
24630 let (owner, _) = storage.model_memory.location(range.role, range.index)?;
24631 if owner == allocation_index
24632 && selected_slot
24633 .replace(range.storage_slot as usize)
24634 .is_some_and(|prior| prior != range.storage_slot as usize)
24635 {
24636 return Err(SemanticTransitionError::ObservationMismatch);
24637 }
24638 }
24639 let slot = selected_slot.unwrap_or(slots[(lease.identity.word & 1) as usize]);
24640 if !slots.contains(&slot) {
24641 return Err(SemanticTransitionError::ObservationMismatch);
24642 }
24643 let allocation = storage
24644 .allocations
24645 .get(slot)
24646 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24647 if allocation.len() as u64 != bytes {
24648 return Err(SemanticTransitionError::ObservationMismatch);
24649 }
24650 let view = allocation.view();
24651 let provenance = view.allocation_provenance().ok_or_else(|| {
24652 publication_input_error("resident model backing has no native allocation owner")
24653 })?;
24654 let extent =
24655 i64::try_from(bytes).map_err(|_| SemanticTransitionError::ObservationMismatch)?;
24656 let tensor = self.export_reader_view(
24657 lease,
24658 view,
24659 vec![extent],
24660 vec![1],
24661 (1, 8),
24662 consumer_stream,
24663 )?;
24664 allocations.push((provenance, tensor));
24665 }
24666 let views = storage
24667 .model_memory
24668 .views
24669 .iter()
24670 .cloned()
24671 .map(|view| {
24672 let layout = storage
24673 .layouts
24674 .get(&(view.role, view.index))
24675 .copied()
24676 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24677 Ok((view, layout))
24678 })
24679 .collect::<Result<Vec<_>, SemanticTransitionError>>()?;
24680 Ok(SemanticResidentModelMemory {
24681 parent: lease.identity,
24682 generations: (
24683 header.model_generation,
24684 header.neural_bank,
24685 header.neural_generation,
24686 ),
24687 numerical_state: (header.model_geometry_digest, header.model_numerical_digest),
24688 allocations,
24689 storages: storage.model_memory.storages.clone(),
24690 views,
24691 })
24692 }
24693
24694 pub fn published_prefix(
24703 &mut self,
24704 lease: &SemanticPublishedLease,
24705 consumer_stream: u64,
24706 ) -> Result<(SemanticPublishedIdentity, DlpackManagedTensor), SemanticTransitionError> {
24707 self.checked_reader(lease)?;
24708 let range = *lease
24709 .directory
24710 .iter()
24711 .find(|range| range.role == SemanticStateRole::PrefixSource as u64 && range.index == 0)
24712 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24713 if range.logical_end != lease.header.prefix_extent {
24714 return Err(SemanticTransitionError::ObservationMismatch);
24715 }
24716 let capacity = self
24717 .publication
24718 .as_ref()
24719 .ok_or(SemanticTransitionError::NotBound)?
24720 .contract_value
24721 .prefix_capacity;
24722 let layout = committed_prefix_layout(&range, capacity)?;
24723 let tensor = self.export_publication_range(lease, range, layout, consumer_stream)?;
24724 Ok((lease.identity, tensor))
24725 }
24726
24727 pub fn continuation_rng(
24730 &self,
24731 lease: &SemanticPublishedLease,
24732 ) -> Result<SemanticRngBinding, SemanticTransitionError> {
24733 self.checked_reader(lease)?;
24734 if self.continuation_base != Some(lease.identity.word)
24735 || self
24736 .admitted_transition
24737 .is_none_or(|(token, word, _)| token != lease.token || word != lease.identity.word)
24738 {
24739 return Err(publication_input_error(
24740 "execution requires this exact acquired reader's admitted continuation",
24741 ));
24742 }
24743 lease.header.rng_binding()
24744 }
24745
24746 #[cfg(feature = "semantic-policy")]
24749 pub fn admitted_policy_rng(
24750 &self,
24751 lease: &SemanticPublishedLease,
24752 ) -> Result<SemanticRngBinding, SemanticTransitionError> {
24753 self.checked_reader(lease)?;
24754 if self.admitted_transition
24755 != Some((
24756 lease.token,
24757 lease.identity.word,
24758 SemanticTransitionKind::Proposal,
24759 ))
24760 {
24761 return Err(publication_input_error(
24762 "policy snapshot requires this exact acquired reader's admitted proposal",
24763 ));
24764 }
24765 lease.header.rng_binding()
24766 }
24767
24768 fn read_published_control_record(
24769 &mut self,
24770 lease: &SemanticPublishedLease,
24771 role: u64,
24772 ) -> Result<PublicationMaterialRange, SemanticTransitionError> {
24773 self.checked_reader(lease)?;
24774 let range = *lease
24775 .directory
24776 .iter()
24777 .find(|range| range.role == role && range.index == 0)
24778 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24779 let storage = Arc::clone(
24780 self.publication
24781 .as_ref()
24782 .ok_or(SemanticTransitionError::NotBound)?,
24783 );
24784 let allocation = storage
24785 .allocations
24786 .get(range.storage_slot as usize)
24787 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24788 let begin = usize::try_from(range.offset_bytes)
24789 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
24790 let end = usize::try_from(range.length_bytes)
24791 .ok()
24792 .and_then(|length| begin.checked_add(length))
24793 .filter(|&end| end <= allocation.len())
24794 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24795 let bytes = self.publication_read(allocation.view().slice(begin..end))?;
24796 let material = PublicationMaterialRange {
24797 range,
24798 capacity: allocation.len() - begin,
24799 bytes,
24800 };
24801 if material.original_record_digest() != range.digest {
24802 return Err(SemanticTransitionError::ObservationMismatch);
24803 }
24804 Ok(material)
24805 }
24806
24807 pub fn acknowledge_delivery(
24811 &mut self,
24812 lease: &SemanticPublishedLease,
24813 receipt: &[u8],
24814 recipient_id: Identity256,
24815 verification_key: &[u8; 32],
24816 expected_effect: &[u8],
24817 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
24818 self.checked_reader(lease)?;
24819 if self.pending || self.admitted_transition.is_some() || self.continuation_base.is_some() {
24820 return Err(publication_input_error(
24821 "delivery acknowledgement cannot overlap a transition",
24822 ));
24823 }
24824 if lease.header.terminal != 2
24825 || receipt.len() < 169
24826 || verification_key.iter().all(|&byte| byte == 0)
24827 {
24828 return Err(publication_input_error(
24829 "delivery acknowledgement requires a FINAL parent and trusted receipt",
24830 ));
24831 }
24832 let entries = self.read_published_control_record(lease, 30)?;
24833 let payload = self.read_published_control_record(lease, 31)?;
24834 let acknowledgements = self.read_published_control_record(lease, 32)?;
24835 let intents = output_intents_from_ranges(&entries, &payload)?;
24836 let acknowledged =
24837 acknowledgement_receipts(&acknowledgements.bytes, acknowledgements.capacity)?;
24838 let stable_identity =
24839 Identity256::from_bytes(receipt[25..57].try_into().expect("checked receipt extent"));
24840 let intent = intents
24841 .iter()
24842 .find(|intent| intent.stable_identity == stable_identity)
24843 .ok_or_else(|| {
24844 publication_input_error("delivery receipt has no native FINAL intent")
24845 })?;
24846 if expected_effect.is_empty() || intent.effect.as_slice() != expected_effect {
24847 return Err(publication_input_error(
24848 "native FINAL effect differs from the bound receiver",
24849 ));
24850 }
24851 let receipt_digest =
24852 verify_delivery_receipt(receipt, intent, recipient_id, verification_key)?;
24853 let storage = Arc::clone(
24854 self.publication
24855 .as_ref()
24856 .ok_or(SemanticTransitionError::NotBound)?,
24857 );
24858 let current = self.publication_read(storage.control.view())?[0];
24859 if current.instance != lease.identity.instance || current.word != lease.identity.word {
24860 return Err(publication_input_error(
24861 "delivery acknowledgement requires the current acquired FINAL parent",
24862 ));
24863 }
24864 if let Some((_, previous)) = acknowledged
24865 .iter()
24866 .find(|(identity, _)| *identity == stable_identity)
24867 {
24868 if previous == receipt {
24869 return Ok(lease.identity);
24870 }
24871 return Err(publication_input_error(
24872 "native intent was acknowledged with a different receipt",
24873 ));
24874 }
24875 if lease.header.fuel == 0 {
24876 return Err(publication_input_error(
24877 "FINAL parent has no reserved acknowledgement fuel",
24878 ));
24879 }
24880 let receipt_device = allocate_publication::<u8>(&self.provider, receipt.len())?;
24881 upload_publication(&self.provider, receipt, &receipt_device)?;
24882 let input_device = allocate_publication::<PublicationDeliveryInput>(&self.provider, 1)?;
24883 upload_publication(
24884 &self.provider,
24885 &[PublicationDeliveryInput {
24886 lease: self.readers[&lease.token].device.device_ptr_value(),
24887 receipt: receipt_device.device_ptr_value(),
24888 receipt_len: receipt.len() as u64,
24889 recipient_id,
24890 receipt_digest,
24891 }],
24892 &input_device,
24893 )?;
24894 let mut descriptor = self.descriptor();
24895 descriptor.publication = PublicationCommand {
24896 control: storage.control.device_ptr_value(),
24897 lease: input_device.device_ptr_value(),
24898 operation: 6,
24899 };
24900 let mut recorder = self.kernel_recorder();
24901 recorder.read(&receipt_device);
24902 recorder.read(&input_device);
24903 recorder.read(&self.readers[&lease.token].device);
24904 let execute = self.execute.clone();
24905 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |stream| {
24906 unsafe {
24909 execute.launch_in(
24910 stream,
24911 LaunchConfig {
24912 grid_dim: (1, 1, 1),
24913 block_dim: (256, 1, 1),
24914 shared_mem_bytes: 0,
24915 },
24916 (descriptor,),
24917 )
24918 }
24919 .map_err(|error| XlogError::Kernel(error.to_string()))
24920 })?;
24921 wait_on_stream(
24922 &self.stream,
24923 &mut self.poisoned,
24924 &mut self.stream_waits,
24925 "delivery acknowledgement publication",
24926 CudaStream::synchronize,
24927 )?;
24928 let control = self.publication_read(storage.control.view())?[0];
24929 if control.refusal != 0 {
24930 return Err(SemanticTransitionError::PublicationRefused {
24931 status: control.refusal,
24932 });
24933 }
24934 let header = self.read_publication_header((control.word & 1) as usize)?;
24935 let expected_word = ((lease.identity.word >> 1) + 1) << 1 | ((lease.identity.word & 1) ^ 1);
24936 if control.word != expected_word
24937 || header.publication_word != control.word
24938 || header.terminal != 2
24939 || header.fuel + 1 != lease.header.fuel
24940 || header.instance != lease.identity.instance
24941 {
24942 self.poisoned = true;
24943 return Err(SemanticTransitionError::ObservationMismatch);
24944 }
24945 Ok(SemanticPublishedIdentity {
24946 instance: header.instance,
24947 word: header.publication_word,
24948 logical_digest: header.logical_digest,
24949 state_digest: header.state_digest,
24950 })
24951 }
24952
24953 pub fn admit_external_activation(
24956 &mut self,
24957 lease: &SemanticPublishedLease,
24958 ) -> Result<(), SemanticTransitionError> {
24959 self.checked_reader(lease)?;
24960 if lease.header.terminal != 2 {
24961 return Err(publication_input_error(
24962 "external activation requires a genuinely published FINAL parent",
24963 ));
24964 }
24965 if lease.header.fuel == 0 {
24966 return Err(publication_input_error(
24967 "FINAL parent has no reserved fuel for durable delivery acknowledgement",
24968 ));
24969 }
24970 let storage = Arc::clone(
24971 self.publication
24972 .as_ref()
24973 .ok_or(SemanticTransitionError::NotBound)?,
24974 );
24975 let range = lease
24976 .directory
24977 .iter()
24978 .find(|range| range.role == 30)
24979 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24980 let payload = lease
24981 .directory
24982 .iter()
24983 .find(|range| range.role == 31)
24984 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24985 let owner = storage
24986 .allocations
24987 .get(range.storage_slot as usize)
24988 .ok_or(SemanticTransitionError::ObservationMismatch)?;
24989 if range.offset_bytes != 0
24990 || range.length_bytes < size_of::<IntentQueueHeader>() as u64
24991 || range.length_bytes > owner.len() as u64
24992 {
24993 return Err(SemanticTransitionError::ObservationMismatch);
24994 }
24995 let header_view = unsafe {
24998 owner
24999 .view()
25000 .slice(..size_of::<IntentQueueHeader>())
25001 .cast::<IntentQueueHeader>()
25002 }
25003 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25004 let header = self.publication_read(header_view)?[0];
25005 if header.abi != 1
25006 || header.count == 0
25007 || header.count > header.capacity
25008 || header
25009 .count
25010 .checked_mul(size_of::<IntentEntry>() as u64)
25011 .and_then(|n| n.checked_add(size_of::<IntentQueueHeader>() as u64))
25012 != Some(range.length_bytes)
25013 || header.payload_used_bytes != payload.length_bytes
25014 || header.payload_used_bytes > header.payload_capacity_bytes
25015 || header.effect_length_bytes == 0
25016 || header
25017 .effect_offset_bytes
25018 .checked_add(header.effect_length_bytes)
25019 .is_none_or(|n| n > header.payload_used_bytes)
25020 {
25021 return Err(publication_input_error(
25022 "FINAL bank has no complete native terminal intent queue",
25023 ));
25024 }
25025 let begin =
25026 size_of::<IntentQueueHeader>() + (header.count as usize - 1) * size_of::<IntentEntry>();
25027 let entry_view = unsafe {
25029 owner
25030 .view()
25031 .slice(begin..begin + size_of::<IntentEntry>())
25032 .cast::<IntentEntry>()
25033 }
25034 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25035 let entry = self.publication_read(entry_view)?[0];
25036 if entry.audit_instance != lease.identity.instance
25037 || entry.audit_epoch != lease.identity.word >> 1
25038 || entry.result_logical != lease.identity.logical_digest
25039 || entry.chain != header.chain_head
25040 || entry.payload_len < 8
25041 || entry
25042 .payload_offset
25043 .checked_add(entry.payload_len)
25044 .is_none_or(|n| n > header.payload_used_bytes)
25045 || entry.stable_identity == Identity256::default()
25046 || entry.effect_digest == Identity256::default()
25047 {
25048 return Err(publication_input_error(
25049 "terminal intent is not the actual final effect of this acquired publication",
25050 ));
25051 }
25052 let current = self.publication_read(storage.control.view())?[0];
25053 if current.instance != lease.identity.instance || current.word != lease.identity.word {
25054 return Err(publication_input_error(
25055 "external activation requires the current acquired FINAL parent",
25056 ));
25057 }
25058 let entries = self.read_published_control_record(lease, 30)?;
25059 let payload = self.read_published_control_record(lease, 31)?;
25060 let acknowledgements = self.read_published_control_record(lease, 32)?;
25061 let intents = output_intents_from_ranges(&entries, &payload)?;
25062 let acknowledged =
25063 acknowledgement_receipts(&acknowledgements.bytes, acknowledgements.capacity)?;
25064 if intents.iter().all(|intent| {
25065 acknowledged
25066 .iter()
25067 .any(|(identity, _)| *identity == intent.stable_identity)
25068 }) {
25069 return Err(publication_input_error(
25070 "FINAL publication has no unacknowledged delivery intent",
25071 ));
25072 }
25073 Ok(())
25074 }
25075
25076 pub fn published_tensor(
25080 &mut self,
25081 lease: &SemanticPublishedLease,
25082 role: SemanticStateRole,
25083 index: u64,
25084 consumer_stream: u64,
25085 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
25086 let (range, layout) = self.published_tensor_layout(lease, role, index)?;
25087 if matches!(role as u64, 18..=25 | 51..=54) {
25088 self.guard_published_content(lease, &[(role, index)], consumer_stream)?;
25089 }
25090 self.export_publication_range(lease, range, layout, consumer_stream)
25091 }
25092
25093 pub fn select_training_view(
25098 &mut self,
25099 lease: &SemanticPublishedLease,
25100 ) -> Result<SemanticSelectedTrainingView, SemanticTransitionError> {
25101 self.checked_reader(lease)?;
25102 let arena = Arc::clone(
25103 self.training_views
25104 .as_ref()
25105 .ok_or(SemanticTransitionError::NotBound)?,
25106 );
25107 let range = *lease
25108 .directory
25109 .iter()
25110 .find(|range| range.role == SemanticStateRole::TrainingView as u64 && range.index == 0)
25111 .ok_or_else(|| publication_input_error("acquired training-view range is absent"))?;
25112 let storage = Arc::clone(
25113 self.publication
25114 .as_ref()
25115 .ok_or(SemanticTransitionError::NotBound)?,
25116 );
25117 let allocation = storage
25118 .allocations
25119 .get(
25120 usize::try_from(range.storage_slot)
25121 .map_err(|_| SemanticTransitionError::ObservationMismatch)?,
25122 )
25123 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25124 let begin = usize::try_from(range.offset_bytes)
25125 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
25126 let length = usize::try_from(range.length_bytes)
25127 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
25128 let end = begin
25129 .checked_add(length)
25130 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25131 let selected = allocation
25132 .view()
25133 .try_slice(begin..end)
25134 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25135 let result = arena.enqueue_selection(
25136 selected,
25137 lease.header.training_cursor,
25138 lease.header.training_rng,
25139 self.training_origins.clone(),
25140 );
25141 if matches!(
25142 &result,
25143 Err(SemanticTransitionError::Runtime {
25144 operation: "training-view device selection" | "training-view launch commit",
25145 ..
25146 })
25147 ) {
25148 self.poisoned = true;
25149 }
25150 result
25151 }
25152
25153 pub fn published_tensor_allocation(
25157 &mut self,
25158 lease: &SemanticPublishedLease,
25159 role: SemanticStateRole,
25160 index: u64,
25161 consumer_stream: u64,
25162 ) -> Result<(DeviceAllocationProvenance, DlpackManagedTensor), SemanticTransitionError> {
25163 dlpack_consumer_stream(consumer_stream)?;
25164 let (range, layout) = self.published_tensor_layout(lease, role, index)?;
25165 if matches!(role as u64, 18..=25 | 51..=54) {
25166 self.guard_published_content(lease, &[(role, index)], consumer_stream)?;
25167 }
25168 let view = self.publication_tensor_view(lease, range, layout)?;
25169 let provenance = view.allocation_provenance().ok_or_else(|| {
25170 publication_input_error("published tensor has no complete native allocation owner")
25171 })?;
25172 let allocation = view
25173 .allocation_view()
25174 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25175 let bytes = i64::try_from(allocation.len())
25176 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
25177 let tensor = self.export_publication_tensor_view(
25178 lease,
25179 range.role,
25180 allocation,
25181 vec![bytes],
25182 vec![1],
25183 (1, 8),
25184 consumer_stream,
25185 )?;
25186 Ok((provenance, tensor))
25187 }
25188
25189 fn published_tensor_layout(
25190 &self,
25191 lease: &SemanticPublishedLease,
25192 role: SemanticStateRole,
25193 index: u64,
25194 ) -> Result<(PublicationRange, SemanticTensorLayout), SemanticTransitionError> {
25195 self.checked_reader(lease)?;
25196 let storage = self
25197 .publication
25198 .as_ref()
25199 .ok_or(SemanticTransitionError::NotBound)?;
25200 let layout = *storage
25201 .layouts
25202 .get(&(role as u64, index))
25203 .ok_or_else(|| publication_input_error("acquired role has no model tensor layout"))?;
25204 let range = *lease
25205 .directory
25206 .iter()
25207 .find(|range| range.role == role as u64 && range.index == index)
25208 .ok_or_else(|| publication_input_error("acquired tensor range is absent"))?;
25209 Ok((range, layout))
25210 }
25211
25212 pub fn published_active_rows(
25215 &mut self,
25216 lease: &SemanticPublishedLease,
25217 ) -> Result<SemanticActiveRows, SemanticTransitionError> {
25218 self.checked_reader(lease)?;
25219 let bytes = self.read_published_record_bytes(lease, SemanticStateRole::TensorLayout)?;
25220 let (_, layouts, active) = decode_tensor_table(&bytes)?;
25221 let storage = self
25222 .publication
25223 .as_ref()
25224 .ok_or(SemanticTransitionError::NotBound)?;
25225 if layouts != storage.layouts.values().copied().collect::<Vec<_>>()
25226 || active.rows.len() as u64 > 32 + storage.contract_value.feedback_capacity
25227 || lease
25228 .directory
25229 .iter()
25230 .filter(|range| matches!(range.role, 51..=54))
25231 .any(|range| {
25232 range.logical_begin != 0
25233 || range.logical_end != active.rows.len() as u64
25234 || (active.rows.is_empty() != (range.length_bytes == 0))
25235 })
25236 {
25237 return Err(SemanticTransitionError::ObservationMismatch);
25238 }
25239 Ok(active)
25240 }
25241
25242 pub fn published_model_numerical_mode(
25247 &mut self,
25248 lease: &SemanticPublishedLease,
25249 ) -> Result<Vec<u8>, SemanticTransitionError> {
25250 self.ensure_quiescent()?;
25251 let streams = self
25252 .checked_reader(lease)?
25253 .consumer_streams
25254 .iter()
25255 .chain(&self.checked_step(lease)?.consumer_streams)
25256 .copied()
25257 .collect::<BTreeSet<_>>()
25258 .into_iter()
25259 .collect::<Vec<_>>();
25260 self.complete_step_consumers(lease, &streams)?;
25261 let record = self.read_published_material_range(lease, 43, 0)?;
25262 if record.original_record_digest() != record.range.digest {
25263 return Err(SemanticTransitionError::ObservationMismatch);
25264 }
25265 let table =
25266 self.read_published_material_range(lease, SemanticStateRole::TensorLayout as u64, 0)?;
25267 let storage = Arc::clone(
25268 self.publication
25269 .as_ref()
25270 .ok_or(SemanticTransitionError::NotBound)?,
25271 );
25272 let contract = self.publication_read(storage.contract.view())?[0];
25273 if publication_abi_bytes(&[contract]) != publication_abi_bytes(&[storage.contract_value]) {
25274 return Err(SemanticTransitionError::ObservationMismatch);
25275 }
25276 let counts = self.publication_read(storage.role_counts.view())?;
25277 let mut role_counts = [0; 55];
25278 for (index, count) in counts.iter().enumerate() {
25279 if count.role != index as u64 + 1 {
25280 return Err(SemanticTransitionError::ObservationMismatch);
25281 }
25282 role_counts[index] = count.count;
25283 }
25284 let terminals = self.publication_read(storage.terminals.view())?;
25285 let capacities = lease
25286 .directory
25287 .iter()
25288 .map(|range| {
25289 let allocation = usize::try_from(range.storage_slot)
25290 .ok()
25291 .and_then(|slot| storage.allocations.get(slot))
25292 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25293 let capacity = usize::try_from(range.offset_bytes)
25294 .ok()
25295 .and_then(|offset| allocation.len().checked_sub(offset))
25296 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25297 Ok((range.role, range.index, capacity))
25298 })
25299 .collect::<Result<Vec<_>, SemanticTransitionError>>()?;
25300 Ok(verified_runtime_model_mode(
25301 &record.bytes,
25302 contract,
25303 &role_counts,
25304 &terminals,
25305 &storage.layouts,
25306 &capacities,
25307 &table,
25308 &storage.model_memory,
25309 )?
25310 .to_vec())
25311 }
25312
25313 pub fn published_state_material(
25317 &mut self,
25318 lease: &SemanticPublishedLease,
25319 ) -> Result<Vec<u8>, SemanticTransitionError> {
25320 self.ensure_quiescent()?;
25321 self.checked_reader(lease)?;
25322 let storage = Arc::clone(
25323 self.publication
25324 .as_ref()
25325 .ok_or(SemanticTransitionError::NotBound)?,
25326 );
25327 let bank = self.read_published_bank(lease)?;
25328 let graph = self
25329 .graph
25330 .export_transition_root_parts(
25331 bank.header.semantic_owner,
25332 bank.header.semantic_slot,
25333 bank.header.semantic_generation,
25334 )
25335 .map_err(SemanticTransitionError::Semantic)?;
25336 let counts = self.publication_read(storage.role_counts.view())?;
25337 let mut role_counts = [0; 55];
25338 for (index, count) in counts.iter().enumerate() {
25339 if count.role != index as u64 + 1 {
25340 return Err(SemanticTransitionError::ObservationMismatch);
25341 }
25342 role_counts[index] = count.count;
25343 }
25344 let terminals = if storage.terminals.is_empty() {
25345 Vec::new()
25346 } else {
25347 self.publication_read(storage.terminals.view())?
25348 };
25349 let mut ranges = Vec::with_capacity(lease.directory.len());
25350 let mut model_allocations = Vec::with_capacity(storage.model_slots.len());
25351 for (allocation_index, slots) in storage.model_slots.iter().enumerate() {
25352 let mut selected_slot = None;
25353 for range in lease
25354 .directory
25355 .iter()
25356 .filter(|range| matches!(range.role, 18..=25))
25357 {
25358 let (owner, _) = storage.model_memory.location(range.role, range.index)?;
25359 if owner == allocation_index
25360 && selected_slot
25361 .replace(range.storage_slot as usize)
25362 .is_some_and(|prior| prior != range.storage_slot as usize)
25363 {
25364 return Err(SemanticTransitionError::ObservationMismatch);
25365 }
25366 }
25367 let slot = selected_slot.unwrap_or(slots[(lease.identity.word & 1) as usize]);
25368 if !slots.contains(&slot) {
25369 return Err(SemanticTransitionError::ObservationMismatch);
25370 }
25371 let allocation = &storage.allocations[slot];
25372 model_allocations.push(if allocation.is_empty() {
25373 Vec::new()
25374 } else {
25375 self.publication_read(allocation.view())?
25376 });
25377 }
25378 for range in &lease.directory {
25379 if matches!(range.role, 18..=25) {
25380 let (allocation, offset) =
25381 storage.model_memory.location(range.role, range.index)?;
25382 let end = usize::try_from(range.length_bytes)
25383 .ok()
25384 .and_then(|bytes| offset.checked_add(bytes))
25385 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25386 let bytes = model_allocations[allocation]
25387 .get(offset..end)
25388 .ok_or(SemanticTransitionError::ObservationMismatch)?
25389 .to_vec();
25390 ranges.push(PublicationMaterialRange {
25391 range: *range,
25392 capacity: model_allocations[allocation].len() - offset,
25393 bytes,
25394 });
25395 } else {
25396 ranges.push(self.read_published_material_range(lease, range.role, range.index)?);
25397 }
25398 }
25399 let mut contract = storage.contract_value;
25400 contract.terminal_tokens = 0;
25403 contract.role_counts = 0;
25404 contract.semantic_owner = 0;
25405 PublicationMaterial {
25406 bank,
25407 contract,
25408 role_counts,
25409 terminals,
25410 layouts: storage.layouts.clone(),
25411 model_memory: storage.model_memory.clone(),
25412 model_allocations,
25413 ranges,
25414 graph,
25415 learning_phases: self.learning_phases.clone(),
25416 }
25417 .encode()
25418 }
25419
25420 pub fn published_replay_evidence(
25426 &mut self,
25427 predecessor: &SemanticPublishedLease,
25428 successor: &SemanticPublishedLease,
25429 ) -> Result<Vec<u8>, SemanticTransitionError> {
25430 self.guard_replay_publications(predecessor, successor)?;
25431 let predecessor =
25432 PublicationMaterial::decode(&self.published_state_material(predecessor)?)?;
25433 self.read_replay_evidence(&predecessor, successor)?.encode()
25434 }
25435
25436 pub fn published_replay_provenance(
25443 &mut self,
25444 predecessor: &SemanticPublishedLease,
25445 successor: &SemanticPublishedLease,
25446 ) -> Result<Vec<u8>, SemanticTransitionError> {
25447 self.guard_replay_publications(predecessor, successor)?;
25448 let identity = predecessor.identity;
25449 let predecessor =
25450 PublicationMaterial::decode(&self.published_state_material(predecessor)?)?;
25451 self.read_replay_evidence(&predecessor, successor)?;
25452 let authority = predecessor
25453 .ranges
25454 .iter()
25455 .find(|item| item.range.role == 38 && item.range.index == 0)
25456 .ok_or(SemanticTransitionError::ObservationMismatch)?
25457 .clone();
25458 let decision = self.read_published_material_range(successor, 39, 0)?;
25459 let provenance = PublicationReplayProvenance {
25460 predecessor: identity,
25461 authority,
25462 decision,
25463 };
25464 provenance.validate(&predecessor)?;
25465 provenance.encode()
25466 }
25467
25468 pub fn restore_replay_material(
25471 &mut self,
25472 material: &SemanticReplayMaterial,
25473 ) -> Result<SemanticPublishedIdentity, SemanticTransitionError> {
25474 self.restore_state_material(&material.predecessor.encode()?)
25475 }
25476
25477 pub fn verify_replay_publication(
25486 &mut self,
25487 material: &SemanticReplayMaterial,
25488 predecessor: &SemanticPublishedLease,
25489 successor: &SemanticPublishedLease,
25490 ) -> Result<(), SemanticTransitionError> {
25491 self.guard_replay_publications(predecessor, successor)?;
25492 let actual_predecessor =
25495 PublicationMaterial::decode(&self.published_state_material(predecessor)?)?;
25496 let header = actual_predecessor.bank.header;
25497 let expected = material.predecessor_identity();
25498 if header.instance == expected.instance
25499 || header.recovered_instance != expected.instance
25500 || header.publication_word != 0
25501 || header.logical_digest != expected.logical_digest
25502 || header.state_digest != expected.state_digest
25503 {
25504 return Err(publication_input_error(
25505 "replay comparison requires the freshly restored complete predecessor",
25506 ));
25507 }
25508 let actual = self.read_replay_evidence(&actual_predecessor, successor)?;
25509 if actual.successor.logical_digest != material.evidence.successor.logical_digest
25510 || actual.successor.state_digest != material.evidence.successor.state_digest
25511 {
25512 return Err(publication_input_error(
25513 "genuine replay successor differs from the expected complete native state",
25514 ));
25515 }
25516 for (actual, expected) in actual.ranges.iter().zip(&material.evidence.ranges) {
25517 if actual.logical_record_digest()? != expected.logical_record_digest()? {
25518 return Err(publication_input_error(
25519 "genuine replay differs from the expected normalized publication records",
25520 ));
25521 }
25522 }
25523 Ok(())
25524 }
25525
25526 fn guard_replay_publications(
25530 &mut self,
25531 predecessor: &SemanticPublishedLease,
25532 successor: &SemanticPublishedLease,
25533 ) -> Result<(), SemanticTransitionError> {
25534 for lease in [predecessor, successor] {
25535 let streams = self
25536 .checked_reader(lease)?
25537 .consumer_streams
25538 .iter()
25539 .chain(&self.checked_step(lease)?.consumer_streams)
25540 .copied()
25541 .collect::<BTreeSet<_>>()
25542 .into_iter()
25543 .collect::<Vec<_>>();
25544 self.complete_step_consumers(lease, &streams)?;
25545 }
25546 let predecessor_ranges = self.published_range_keys(predecessor)?;
25547 let successor_ranges = self.published_range_keys(successor)?;
25548 self.guard_published_content(predecessor, &predecessor_ranges, 1)?;
25549 self.guard_published_content(successor, &successor_ranges, 1)
25550 }
25551
25552 fn read_replay_evidence(
25553 &mut self,
25554 predecessor: &PublicationMaterial,
25555 successor: &SemanticPublishedLease,
25556 ) -> Result<PublicationReplayEvidence, SemanticTransitionError> {
25557 let bank = self.read_published_bank(successor)?;
25558 let mut ranges = Vec::with_capacity(REPLAY_EVIDENCE_ROLES.len());
25559 for role in REPLAY_EVIDENCE_ROLES {
25560 ranges.push(self.read_published_material_range(successor, role, 0)?);
25561 }
25562 let evidence = PublicationReplayEvidence {
25563 successor: successor.identity,
25564 ranges,
25565 };
25566 let coverage = self.read_published_material_range(successor, 14, 0)?;
25567 let codebook = self.read_published_material_range(successor, 48, 0)?;
25568 evidence.validate_observed(predecessor, &bank, &coverage, &codebook)?;
25569 Ok(evidence)
25570 }
25571
25572 fn read_published_bank(
25573 &mut self,
25574 lease: &SemanticPublishedLease,
25575 ) -> Result<PublicationBank, SemanticTransitionError> {
25576 self.checked_reader(lease)?;
25577 let storage = Arc::clone(
25578 self.publication
25579 .as_ref()
25580 .ok_or(SemanticTransitionError::NotBound)?,
25581 );
25582 let bank =
25583 self.publication_read(storage.banks[(lease.identity.word & 1) as usize].view())?[0];
25584 if publication_abi_bytes(&[bank.header]) != publication_abi_bytes(&[lease.header])
25585 || publication_abi_bytes(&bank.source) != publication_abi_bytes(&lease.source)
25586 {
25587 return Err(SemanticTransitionError::ObservationMismatch);
25588 }
25589 Ok(bank)
25590 }
25591
25592 fn read_published_material_range(
25593 &mut self,
25594 lease: &SemanticPublishedLease,
25595 role: u64,
25596 index: u64,
25597 ) -> Result<PublicationMaterialRange, SemanticTransitionError> {
25598 self.checked_reader(lease)?;
25599 let storage = Arc::clone(
25600 self.publication
25601 .as_ref()
25602 .ok_or(SemanticTransitionError::NotBound)?,
25603 );
25604 let range = lease
25605 .directory
25606 .iter()
25607 .find(|range| (range.role, range.index) == (role, index))
25608 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25609 let owner = storage
25610 .allocations
25611 .get(
25612 usize::try_from(range.storage_slot)
25613 .map_err(|_| SemanticTransitionError::ObservationMismatch)?,
25614 )
25615 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25616 let begin = usize::try_from(range.offset_bytes)
25617 .map_err(|_| SemanticTransitionError::ObservationMismatch)?;
25618 let end = usize::try_from(range.length_bytes)
25619 .ok()
25620 .and_then(|n| begin.checked_add(n))
25621 .filter(|&end| end <= owner.len())
25622 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25623 if range.generation != 1 {
25624 return Err(SemanticTransitionError::ObservationMismatch);
25625 }
25626 let bytes = if begin == end {
25627 Vec::new()
25628 } else {
25629 self.publication_read(owner.view().slice(begin..end))?
25630 };
25631 Ok(PublicationMaterialRange {
25632 range: *range,
25633 capacity: owner.len() - begin,
25634 bytes,
25635 })
25636 }
25637
25638 fn read_published_record_bytes(
25639 &mut self,
25640 lease: &SemanticPublishedLease,
25641 role: SemanticStateRole,
25642 ) -> Result<Vec<u8>, SemanticTransitionError> {
25643 Ok(self
25644 .read_published_material_range(lease, role as u64, 0)?
25645 .bytes)
25646 }
25647
25648 pub fn published_record(
25651 &mut self,
25652 lease: &SemanticPublishedLease,
25653 role: SemanticStateRole,
25654 index: u64,
25655 consumer_stream: u64,
25656 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
25657 self.checked_reader(lease)?;
25658 if is_tensor_role(role as u64) {
25659 return Err(publication_input_error(
25660 "tensor roles require their exact model layout export",
25661 ));
25662 }
25663 let range = *lease
25664 .directory
25665 .iter()
25666 .find(|range| range.role == role as u64 && range.index == index)
25667 .ok_or_else(|| publication_input_error("acquired record range is absent"))?;
25668 self.export_publication_range(
25669 lease,
25670 range,
25671 publication_record_layout(&range),
25672 consumer_stream,
25673 )
25674 }
25675
25676 pub fn published_feedback(
25683 &mut self,
25684 lease: &SemanticPublishedLease,
25685 consumer_stream: u64,
25686 ) -> Result<SemanticFeedback, SemanticTransitionError> {
25687 self.checked_reader(lease)?;
25688 dlpack_consumer_stream(consumer_stream)?;
25689 if self
25690 .admitted_transition
25691 .is_none_or(|(token, word, _)| token != lease.token || word != lease.identity.word)
25692 {
25693 return Err(publication_input_error(
25694 "feedback encoding requires this acquired parent's admitted segment",
25695 ));
25696 }
25697 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
25701 .map_err(|error| runtime_error("feedback stream admission", error))?;
25702 let schema = SemanticFeedbackSchema::new(self.feedback_statement_bytes()?)?;
25703 let storage = Arc::clone(
25704 self.publication
25705 .as_ref()
25706 .ok_or(SemanticTransitionError::NotBound)?,
25707 );
25708 let descriptor = self.descriptor();
25709 let buffers = FeedbackBuffers::allocate(
25710 &self.provider,
25711 schema,
25712 storage.contract_value.feedback_capacity,
25713 descriptor.arena[4],
25714 )?;
25715 let schema = buffers.schema.clone();
25716 let slots = buffers.slots;
25717 let support_capacity = buffers.support_capacity;
25718 let offset_cells = buffers.support_offsets.len();
25719 let reader = self
25723 .steps
25724 .get_mut(&lease.token)
25725 .expect("validated feedback step");
25726 let output_index = reader.feedback.len();
25727 reader.feedback.push(buffers);
25728 let result = (|| {
25729 let reader = self
25730 .readers
25731 .get(&lease.token)
25732 .expect("validated native reader");
25733 let buffers = &self.steps[&lease.token].feedback[output_index];
25734 buffers.enqueue(
25735 &self.domain,
25736 &mut self.poisoned,
25737 &self.graph,
25738 &storage,
25739 &self
25740 .task
25741 .as_ref()
25742 .ok_or(SemanticTransitionError::InvalidTaskBank)?
25743 .1,
25744 &reader.device,
25745 descriptor,
25746 )?;
25747 let features = unsafe { buffers.features.view().cast::<u8>() }
25750 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25751 let device_validity = buffers.validity.view();
25752 let queries = buffers.query_receipts.view();
25753 let originals = buffers.original_statements.view();
25754 let offsets = buffers.support_offsets.view();
25755 let support_rows = buffers.supports.view();
25756 let features = self.export_step_view(
25757 lease,
25758 features,
25759 vec![slots as i64, schema.feature_width as i64],
25760 vec![schema.feature_width as i64, 1],
25761 (2, 32),
25762 consumer_stream,
25763 )?;
25764 let device_validity = self.export_step_view(
25765 lease,
25766 device_validity,
25767 vec![slots as i64],
25768 vec![1],
25769 (6, 8),
25770 consumer_stream,
25771 )?;
25772 let mut export_words =
25773 |view: DeviceMemoryView<u64>, shape: Vec<i64>, strides: Vec<i64>| {
25774 let bytes = unsafe { view.cast::<u8>() }
25777 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25778 self.export_step_view(lease, bytes, shape, strides, (1, 64), consumer_stream)
25779 };
25780 let query_receipts = export_words(queries, vec![slots as i64, 42], vec![42, 1])?;
25781 let original_statements = export_words(originals, vec![slots as i64], vec![1])?;
25782 let support_offsets = export_words(offsets, vec![offset_cells as i64], vec![1])?;
25783 let supports =
25784 export_words(support_rows, vec![support_capacity as i64, 12], vec![12, 1])?;
25785 Ok(SemanticFeedback {
25786 parent: lease.identity,
25787 schema,
25788 features,
25789 device_validity,
25790 query_receipts,
25791 original_statements,
25792 support_offsets,
25793 supports,
25794 })
25795 })();
25796 if result.is_err() {
25797 self.poisoned = true;
25798 }
25799 result
25800 }
25801
25802 fn publication_tensor_view(
25803 &mut self,
25804 lease: &SemanticPublishedLease,
25805 range: PublicationRange,
25806 layout: SemanticTensorLayout,
25807 ) -> Result<DeviceMemoryView<u8>, SemanticTransitionError> {
25808 self.checked_reader(lease)?;
25809 let view = if matches!(range.role, 1 | 3..=13 | 18..=25) {
25810 let inputs = self.ensure_step_inputs(lease)?;
25811 let view = inputs
25812 .views
25813 .get((lease.header.publication_word & 1) as usize)
25814 .expect("two publication input banks")
25815 .get(&(range.role, range.index))
25816 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25817 let local = PublicationRange {
25818 offset_bytes: 0,
25819 ..range
25820 };
25821 view.slice(publication_export_span(&local, &layout, view.len())?)
25822 } else {
25823 let storage = Arc::clone(
25824 self.publication
25825 .as_ref()
25826 .ok_or(SemanticTransitionError::NotBound)?,
25827 );
25828 let allocation = storage
25829 .allocations
25830 .get(range.storage_slot as usize)
25831 .ok_or(SemanticTransitionError::ObservationMismatch)?;
25832 allocation
25833 .view()
25834 .slice(publication_export_span(&range, &layout, allocation.len())?)
25835 };
25836 Ok(view)
25837 }
25838
25839 fn export_publication_range(
25840 &mut self,
25841 lease: &SemanticPublishedLease,
25842 range: PublicationRange,
25843 layout: SemanticTensorLayout,
25844 consumer_stream: u64,
25845 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
25846 dlpack_consumer_stream(consumer_stream)?;
25847 let view = self.publication_tensor_view(lease, range, layout)?;
25848 let shape = layout.dimensions[..layout.rank as usize]
25849 .iter()
25850 .map(|&n| {
25851 i64::try_from(n)
25852 .map_err(|_| publication_input_error("DLPack shape exceeds signed extent"))
25853 })
25854 .collect::<Result<Vec<_>, _>>()?;
25855 let strides = layout.strides_bytes[..layout.rank as usize]
25856 .iter()
25857 .map(|&n| {
25858 i64::try_from(n / layout.element_bytes)
25859 .map_err(|_| publication_input_error("DLPack stride exceeds signed extent"))
25860 })
25861 .collect::<Result<Vec<_>, _>>()?;
25862 let dtype = match layout.scalar_type {
25863 1 => (1, 8),
25864 2 => (1, 32),
25865 3 => (1, 64),
25866 4 => (2, 16),
25867 5 => (4, 16),
25868 6 => (2, 32),
25869 7 => (0, 64),
25870 8 => (6, 8),
25871 9 => (2, 64),
25872 _ => return Err(SemanticTransitionError::ObservationMismatch),
25873 };
25874 self.export_publication_tensor_view(
25875 lease,
25876 range.role,
25877 view,
25878 shape,
25879 strides,
25880 dtype,
25881 consumer_stream,
25882 )
25883 }
25884
25885 #[expect(
25886 clippy::too_many_arguments,
25887 reason = "publication export keeps authenticated role and DLPack geometry explicit"
25888 )]
25889 fn export_publication_tensor_view(
25890 &mut self,
25891 lease: &SemanticPublishedLease,
25892 role: u64,
25893 view: DeviceMemoryView<u8>,
25894 shape: Vec<i64>,
25895 strides: Vec<i64>,
25896 dtype: (u8, u8),
25897 consumer_stream: u64,
25898 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
25899 if matches!(role, 3 | 6..=13 | 18..=25) {
25900 self.export_step_view(lease, view, shape, strides, dtype, consumer_stream)
25901 } else {
25902 self.export_reader_view(lease, view, shape, strides, dtype, consumer_stream)
25903 }
25904 }
25905
25906 fn export_publication_bank_field(
25907 &mut self,
25908 lease: &SemanticPublishedLease,
25909 field: PublicationBankField,
25910 consumer_stream: u64,
25911 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
25912 dlpack_consumer_stream(consumer_stream)?;
25913 let inputs = self.ensure_step_inputs(lease)?;
25914 let (_, shape, strides) = field.layout();
25915 self.export_step_view(
25916 lease,
25917 inputs.field_view(field)?,
25918 shape,
25919 strides,
25920 (1, 64),
25921 consumer_stream,
25922 )
25923 }
25924
25925 fn export_reader_view(
25926 &mut self,
25927 lease: &SemanticPublishedLease,
25928 view: DeviceMemoryView<u8>,
25929 shape: Vec<i64>,
25930 strides: Vec<i64>,
25931 dtype: (u8, u8),
25932 consumer_stream: u64,
25933 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
25934 dlpack_consumer_stream(consumer_stream)?;
25935 let guard = Arc::clone(&self.checked_reader(lease)?.aliases);
25936 self.readers
25937 .get_mut(&lease.token)
25938 .expect("validated native reader")
25939 .consumer_streams
25940 .insert(consumer_stream);
25941 self.export_owned_view(view, shape, strides, dtype, guard, consumer_stream)
25942 }
25943
25944 fn export_step_view(
25945 &mut self,
25946 lease: &SemanticPublishedLease,
25947 view: DeviceMemoryView<u8>,
25948 shape: Vec<i64>,
25949 strides: Vec<i64>,
25950 dtype: (u8, u8),
25951 consumer_stream: u64,
25952 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
25953 dlpack_consumer_stream(consumer_stream)?;
25954 let guard = Arc::clone(&self.checked_step(lease)?.aliases);
25955 self.steps
25956 .get_mut(&lease.token)
25957 .expect("validated output step")
25958 .consumer_streams
25959 .insert(consumer_stream);
25960 self.export_owned_view(view, shape, strides, dtype, guard, consumer_stream)
25961 }
25962
25963 fn export_owned_view(
25964 &mut self,
25965 view: DeviceMemoryView<u8>,
25966 shape: Vec<i64>,
25967 strides: Vec<i64>,
25968 dtype: (u8, u8),
25969 guard: Arc<()>,
25970 consumer_stream: u64,
25971 ) -> Result<DlpackManagedTensor, SemanticTransitionError> {
25972 let storage = Arc::clone(
25973 self.publication
25974 .as_ref()
25975 .ok_or(SemanticTransitionError::NotBound)?,
25976 );
25977 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
25978 .map_err(|error| runtime_error("owned export stream admission", error))?;
25979 if let Err(error) = self.order_content_consumers(consumer_stream) {
25982 self.poisoned = true;
25983 return Err(error);
25984 }
25985 Ok(export_owned_allocation(
25986 view,
25987 shape,
25988 strides,
25989 dtype,
25990 self.provider.device().ordinal() as i32,
25991 guard,
25992 storage,
25993 None,
25994 None,
25995 ))
25996 }
25997
25998 fn complete_step_consumers(
26001 &mut self,
26002 lease: &SemanticPublishedLease,
26003 consumer_streams: &[u64],
26004 ) -> Result<(), SemanticTransitionError> {
26005 self.checked_step(lease)?;
26006 self.complete_step_consumers_by_token(lease.token, consumer_streams)
26007 }
26008
26009 fn complete_step_consumers_by_token(
26010 &mut self,
26011 token: u64,
26012 consumer_streams: &[u64],
26013 ) -> Result<(), SemanticTransitionError> {
26014 let streams = self.step_consumer_streams(token, consumer_streams)?;
26015 let result = (|| {
26016 self.stream
26017 .context()
26018 .bind_to_thread()
26019 .map_err(|error| runtime_error("release context binding", error))?;
26020 for stream in streams {
26021 let event = self
26022 .stream
26023 .context()
26024 .new_event(None)
26025 .map_err(|error| runtime_error("consumer completion event", error))?;
26026 self.release_events.push(event);
26027 let event = self.release_events.last().expect("retained consumer event");
26028 unsafe {
26031 cudarc::driver::result::event::record(
26032 event.cu_event(),
26033 dlpack_consumer_stream(stream)?,
26034 )
26035 }
26036 .map_err(|error| runtime_error("consumer final event record", error))?;
26037 self.stream
26038 .wait(event)
26039 .map_err(|error| runtime_error("consumer final event join", error))?;
26040 }
26041 wait_on_stream(
26042 &self.stream,
26043 &mut self.poisoned,
26044 &mut self.stream_waits,
26045 "published reader consumer completion",
26046 CudaStream::synchronize,
26047 )?;
26048 Ok(())
26049 })();
26050 if result.is_err() {
26051 self.poisoned = true;
26052 } else {
26053 self.release_events.clear();
26057 }
26058 result
26059 }
26060
26061 fn step_consumer_streams(
26062 &self,
26063 token: u64,
26064 consumer_streams: &[u64],
26065 ) -> Result<BTreeSet<u64>, SemanticTransitionError> {
26066 let step = self
26067 .steps
26068 .get(&token)
26069 .ok_or_else(|| publication_input_error("original step has been fully released"))?;
26070 let mut streams = consumer_streams.iter().copied().collect::<BTreeSet<_>>();
26071 if !step.consumer_streams.is_subset(&streams)
26072 || self
26073 .readers
26074 .get(&token)
26075 .is_some_and(|reader| !reader.consumer_streams.is_subset(&streams))
26076 {
26077 return Err(publication_input_error(
26078 "release omits a consumer stream that received a published alias",
26079 ));
26080 }
26081 for &stream in &streams {
26082 dlpack_consumer_stream(stream)?;
26083 }
26084 if !step.content.is_empty() {
26087 streams.insert(1);
26088 }
26089 Ok(streams)
26090 }
26091
26092 pub fn quiesce_published_reader(
26097 &mut self,
26098 lease: &SemanticPublishedLease,
26099 consumer_streams: &[u64],
26100 ) -> Result<(), SemanticTransitionError> {
26101 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
26102 .map_err(|error| runtime_error("reader quiescence stream admission", error))?;
26103 self.checked_reader(lease)?;
26104 self.quiesce_step_content(lease, consumer_streams)
26105 }
26106
26107 fn quiesce_step_content(
26108 &mut self,
26109 lease: &SemanticPublishedLease,
26110 consumer_streams: &[u64],
26111 ) -> Result<(), SemanticTransitionError> {
26112 let step = self.checked_step(lease)?;
26113 if Arc::strong_count(&step.content_witnesses) != 1 {
26114 return Err(publication_input_error(
26115 "content witnesses still retain this step",
26116 ));
26117 }
26118 if step.content.is_empty()
26119 && (Arc::strong_count(&step.aliases) != 1
26120 || self
26121 .readers
26122 .get(&lease.token)
26123 .is_some_and(|reader| Arc::strong_count(&reader.aliases) != 1))
26124 {
26125 return Err(publication_input_error(
26126 "published tensor aliases still retain this reader",
26127 ));
26128 }
26129 self.complete_step_consumers(lease, consumer_streams)?;
26130 let step = self
26134 .steps
26135 .get_mut(&lease.token)
26136 .expect("completed content step");
26137 step.content.clear();
26138 if Arc::strong_count(&step.aliases) != 1 {
26139 return Err(publication_input_error(
26140 "output aliases still retain this step",
26141 ));
26142 }
26143 if self
26144 .readers
26145 .get(&lease.token)
26146 .is_some_and(|reader| Arc::strong_count(&reader.aliases) != 1)
26147 {
26148 return Err(publication_input_error(
26149 "published tensor aliases still retain this reader",
26150 ));
26151 }
26152 Ok(())
26153 }
26154
26155 pub fn release_published_reader(
26159 &mut self,
26160 lease: &mut SemanticPublishedLease,
26161 consumer_streams: &[u64],
26162 ) -> Result<(), SemanticTransitionError> {
26163 #[cfg(feature = "semantic-policy")]
26164 self.require_closed_evaluations()?;
26165 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
26168 .map_err(|error| runtime_error("reader retirement stream admission", error))?;
26169 self.checked_step(lease)?;
26170 let reader = self.checked_reader(lease)?;
26171 if Arc::strong_count(&reader.aliases) != 1
26172 || self
26173 .admitted_transition
26174 .is_some_and(|(token, _, _)| token == lease.token)
26175 {
26176 return Err(publication_input_error(
26177 "publication reader still owns aliases or an admitted transition",
26178 ));
26179 }
26180 self.complete_step_consumers(lease, consumer_streams)?;
26181 self.retire_published_reader(lease)
26182 }
26183
26184 fn retire_published_reader(
26185 &mut self,
26186 lease: &mut SemanticPublishedLease,
26187 ) -> Result<(), SemanticTransitionError> {
26188 let reader = self.checked_reader(lease)?;
26189 if Arc::strong_count(&reader.aliases) != 1
26190 || (self
26191 .admitted_transition
26192 .is_some_and(|(token, _, _)| token == lease.token)
26193 && (self.continuation_base.is_some() || self.text_binding.is_some()))
26194 {
26195 return Err(publication_input_error(
26196 "publication reader still owns aliases or an unfinished transition",
26197 ));
26198 }
26199 let result = (|| {
26200 self.publication_command(3, Some(lease.token))?;
26201 let result = self.publication_read(self.readers[&lease.token].device.view())?[0];
26202 if result.status != 0
26203 || result.active != 0
26204 || result.instance != lease.identity.instance
26205 || result.word != lease.identity.word
26206 {
26207 return Err(SemanticTransitionError::PublicationRefused {
26208 status: result.status,
26209 });
26210 }
26211 Ok(())
26212 })();
26213 if result.is_err() {
26214 self.poisoned = true;
26215 return result;
26216 }
26217 lease.active = false;
26218 self.readers.remove(&lease.token);
26219 if self
26220 .admitted_transition
26221 .is_some_and(|(token, _, _)| token == lease.token)
26222 {
26223 self.admitted_transition = None;
26224 }
26225 Ok(())
26226 }
26227
26228 pub fn release(
26233 &mut self,
26234 lease: &mut SemanticPublishedLease,
26235 consumer_streams: &[u64],
26236 ) -> Result<(), SemanticTransitionError> {
26237 #[cfg(feature = "semantic-policy")]
26238 self.require_closed_evaluations()?;
26239 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
26240 .map_err(|error| runtime_error("step retirement stream admission", error))?;
26241 self.quiesce_step_content(lease, consumer_streams)?;
26242 if lease.active {
26243 self.retire_published_reader(lease)?;
26244 }
26245 self.steps.remove(&lease.token);
26246 self.release_events.clear();
26247 Ok(())
26248 }
26249
26250 pub fn release_prepared_step(
26254 &mut self,
26255 step: &SemanticPreparedStep,
26256 consumer_streams: &[u64],
26257 ) -> Result<(), SemanticTransitionError> {
26258 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
26259 .map_err(|error| runtime_error("prepared step retirement stream admission", error))?;
26260 self.quiesce_prepared_step(step, consumer_streams)?;
26261 let owner = self
26262 .steps
26263 .get_mut(&step.token)
26264 .expect("completed prepared step");
26265 let prepared = owner.prepared.as_mut().expect("prepared owner");
26266 for branch in &mut prepared.branches {
26269 branch.continuation = None;
26270 #[cfg(feature = "semantic-policy")]
26271 {
26272 branch.policy_witness = None;
26273 branch.policy = None;
26274 branch.policy_sources.clear();
26275 }
26276 }
26277 if Arc::strong_count(&owner.content_witnesses) != 1 {
26278 return Err(publication_input_error(
26279 "content witnesses still retain this prepared step",
26280 ));
26281 }
26282 owner.content.clear();
26283 if Arc::strong_count(&owner.aliases) != 1 {
26284 return Err(publication_input_error(
26285 "output aliases still retain this prepared step",
26286 ));
26287 }
26288 self.steps.remove(&step.token);
26289 Ok(())
26290 }
26291
26292 pub fn quiesce_prepared_step(
26295 &mut self,
26296 step: &SemanticPreparedStep,
26297 consumer_streams: &[u64],
26298 ) -> Result<(), SemanticTransitionError> {
26299 self.checked_prepared_step(step, false)?;
26300 if !self
26301 .prepared_segment
26302 .as_ref()
26303 .expect("checked prepared scope")
26304 .completed
26305 {
26306 return Err(publication_input_error(
26307 "prepared step cannot retire before actual segment completion",
26308 ));
26309 }
26310 #[cfg(feature = "semantic-policy")]
26311 if self
26312 .policy_tapes
26313 .iter()
26314 .any(|tape| tape.policy.text_binding._witness.reader_token == step.token)
26315 {
26316 return Err(SemanticTransitionError::UnconsumedPolicyTape);
26317 }
26318 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
26319 .map_err(|error| runtime_error("prepared step quiescence stream admission", error))?;
26320 self.complete_step_consumers_by_token(step.token, consumer_streams)
26321 }
26322
26323 pub fn admit_transition(
26324 &mut self,
26325 lease: &SemanticPublishedLease,
26326 kind: SemanticTransitionKind,
26327 ) -> Result<(), SemanticTransitionError> {
26328 #[cfg(feature = "semantic-policy")]
26329 self.require_closed_evaluations()?;
26330 self.checked_reader(lease)?;
26331 if kind == SemanticTransitionKind::Update {
26332 return Err(publication_input_error(
26333 "updates require a prepared step with native training and pending-output owners",
26334 ));
26335 }
26336 if self.admitted_transition.is_some() || self.continuation_base.is_some() {
26337 return Err(publication_input_error(
26338 "an admitted transition already owns the pending invocation",
26339 ));
26340 }
26341 let control = Arc::clone(
26342 self.publication
26343 .as_ref()
26344 .ok_or(SemanticTransitionError::NotBound)?,
26345 );
26346 let current = self.publication_read(control.control.view())?[0];
26347 if current.instance != lease.identity.instance || current.word != lease.identity.word {
26348 return Err(publication_input_error(
26349 "transition requires the current acquired parent, not an older retained reader",
26350 ));
26351 }
26352 if lease.header.terminal == 2 {
26353 return Err(publication_input_error(
26354 "final publication admits reads, not another transition",
26355 ));
26356 }
26357 let reserve = if matches!(
26358 kind,
26359 SemanticTransitionKind::Proposal | SemanticTransitionKind::Drain
26360 ) {
26361 2
26362 } else {
26363 1
26364 };
26365 if lease.header.fuel < reserve {
26366 return Err(publication_input_error(
26367 "acquired publication has insufficient transition fuel",
26368 ));
26369 }
26370 if (lease.header.terminal == 1) != (kind == SemanticTransitionKind::Drain) {
26371 return Err(SemanticTransitionError::PublicationRefused { status: 4 });
26372 }
26373 self.admitted_transition = Some((lease.token, lease.identity.word, kind));
26374 Ok(())
26375 }
26376
26377 pub fn bind_continuation(
26381 &mut self,
26382 lease: &SemanticPublishedLease,
26383 continuation: SemanticContinuationInput,
26384 witness: &SemanticTensorContentWitness,
26385 consumer_stream: u64,
26386 ) -> Result<(), SemanticTransitionError> {
26387 let mut handoff = RetainedTensorAdmission {
26388 inputs: Some(vec![continuation]),
26389 stream: Arc::clone(self.provider.device().inner().stream()),
26390 ready: false,
26391 };
26392 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
26393 .map_err(|error| runtime_error("continuation stream admission", error))?;
26394 self.checked_reader(lease)?;
26395 self.ensure_rebindable()?;
26396 self.checked_content_witness(lease, witness)?;
26397 dlpack_consumer_stream(consumer_stream)?;
26398 let (_, base_word, kind) = self
26399 .admitted_transition
26400 .filter(|(token, word, _)| *token == lease.token && *word == lease.identity.word)
26401 .ok_or_else(|| {
26402 publication_input_error(
26403 "continuation has no admitted invocation for this exact acquired reader",
26404 )
26405 })?;
26406 if self.continuation_base.is_some() {
26407 return Err(publication_input_error(
26408 "an unconsumed continuation already owns the pending bank",
26409 ));
26410 }
26411 if !matches!(
26412 self.steps[&lease.token].content[witness.index].seals,
26413 TensorContentSeals::Captured(_)
26414 ) {
26415 return Err(publication_input_error(
26416 "continuation requires its original transient producer witness",
26417 ));
26418 }
26419 let storage = Arc::clone(
26420 self.publication
26421 .as_ref()
26422 .ok_or(SemanticTransitionError::NotBound)?,
26423 );
26424 let continuation = handoff
26425 .inputs
26426 .as_ref()
26427 .expect("retained continuation")
26428 .first()
26429 .expect("one continuation");
26430 let tensor_count = continuation.tensors.len();
26431 let active_capacity = storage
26432 .contract_value
26433 .feedback_capacity
26434 .checked_add(32)
26435 .ok_or_else(|| publication_input_error("continuation active capacity overflow"))?;
26436 let (physical_blocks, model_schema_digest, model_identity) =
26437 storage.continuation_block_contract(kind, continuation, false)?;
26438 let service_layouts =
26439 continuation_service_layouts(tensor_count, active_capacity, physical_blocks)?;
26440 if continuation.authority_decisions.is_empty() {
26441 return Err(publication_input_error(
26442 "continuation lacks its actual fresh authority decision snapshot",
26443 ));
26444 }
26445 let continuation = handoff
26446 .inputs
26447 .take()
26448 .expect("retained continuation")
26449 .pop()
26450 .expect("one continuation");
26451 let SemanticContinuationInput {
26452 mut tensors,
26453 authority_decisions,
26454 text_rows,
26455 text_row_count,
26456 selected_text,
26457 active_rows,
26458 active_row_count,
26459 numerical_admissibility,
26460 numerical_blocks,
26461 model_schema_digest: _,
26462 model_identity: _,
26463 } = continuation;
26464 let mut services = vec![
26465 text_rows,
26466 text_row_count,
26467 selected_text,
26468 active_rows,
26469 active_row_count,
26470 numerical_admissibility,
26471 ];
26472 services.extend(numerical_blocks);
26473 tensors.extend(
26474 services
26475 .into_iter()
26476 .zip(service_layouts)
26477 .map(|(tensor, layout)| SemanticTensorInput {
26478 layout,
26479 logical_begin: 0,
26480 logical_end: 0,
26481 tensor,
26482 native_allocation: None,
26483 }),
26484 );
26485 self.verify_tensor_content(lease, witness, tensors, consumer_stream)?;
26488 let numerical_block_snapshot = if let Some(blocks) = physical_blocks {
26489 let original =
26490 self.steps[&lease.token].content[witness.index].tensors[tensor_count + 6].clone();
26491 let cells = blocks
26492 .checked_mul(6)
26493 .ok_or(SemanticTransitionError::GenerationExhausted)?;
26494 let snapshot = Arc::new(allocate_publication::<f64>(&self.provider, cells)?);
26495 enqueue_numerical_block_snapshot(
26496 &self.domain,
26497 &mut self.poisoned,
26498 &original,
26499 &snapshot,
26500 )?;
26501 Some(snapshot)
26502 } else {
26503 None
26504 };
26505 let original = &self.steps[&lease.token].content[witness.index].tensors;
26506 let services = original[tensor_count..].to_vec();
26507 if services.len() != 6 + usize::from(physical_blocks.is_some()) {
26508 return Err(publication_input_error(
26509 "continuation witness has the wrong original service roster",
26510 ));
26511 }
26512 let text_binding = Arc::new(TextBindingStorage {
26513 inputs: services,
26514 numerical_block_snapshot,
26515 model_contract: None,
26516 physical_blocks: physical_blocks.unwrap_or(0) as u64,
26517 model_schema_digest,
26518 model_identity,
26519 _witness: witness.clone(),
26520 _model_content_witness: None,
26521 consumer_stream,
26522 parent: TextBindingParent::Published {
26523 bank: (lease.identity.word & 1) as usize,
26524 header: lease.header,
26525 },
26526 });
26527 let authority_bytes = authority_decisions.len() as u64;
26528 let (uploads, pending_layouts) = prepare_continuation_payloads(
26529 &storage,
26530 &original[..tensor_count],
26531 &authority_decisions,
26532 kind,
26533 )?;
26534 let prepared = PreparedContinuation::prepare(
26535 &self.provider,
26536 Arc::clone(&storage),
26537 self.checked_reader(lease)?.device.view(),
26538 Arc::clone(&text_binding),
26539 text_binding.continuation_inputs(
26540 kind,
26541 authority_bytes,
26542 0,
26543 ModelUpdateContinuationInputs::default(),
26544 ),
26545 None,
26546 &uploads,
26547 &pending_layouts,
26548 )?;
26549 self.publication_uploads = uploads;
26553 self.text_binding = Some(Arc::clone(&text_binding));
26554 let result = (|| {
26555 for (slot, payload) in &self.publication_uploads {
26556 if let PublicationPayload::Metadata(bytes) = payload {
26557 if !bytes.is_empty() {
26558 let mut destination =
26559 storage.allocations[*slot].view().slice(..bytes.len());
26560 self.provider
26561 .htod_launch_metadata_sync_copy_into(bytes, &mut destination)
26562 .map_err(|error| {
26563 runtime_error("continuation fresh authority upload", error)
26564 })?;
26565 }
26566 }
26567 }
26568 prepared.enqueue(&self.domain, &mut self.poisoned)
26569 })();
26570 if let Err(error) = result {
26571 self.poisoned = true;
26572 return Err(error);
26573 }
26574 if let Err(error) = self.order_content_consumers(consumer_stream) {
26575 self.poisoned = true;
26576 return Err(error);
26577 }
26578 self.publication_uploads.clear();
26579 self.continuation_base = Some(base_word);
26580 #[cfg(feature = "semantic-policy")]
26581 if kind == SemanticTransitionKind::Proposal {
26582 self.attach_policy_continuation()?;
26583 }
26584 if kind != SemanticTransitionKind::Proposal {
26585 let rng = self.continuation_rng(lease)?;
26586 self.captured = None;
26587 self.rng = Some(rng);
26588 self.next_proposal = u64::from(rng.proposal);
26589 }
26590 Ok(())
26591 }
26592
26593 pub fn policy_layout(&self) -> Result<SemanticPolicyLayout, SemanticTransitionError> {
26594 self.ensure_quiescent()?;
26595 SemanticPolicyLayout::from_components(&self.codebooks.components)
26596 }
26597
26598 pub fn policy_support_layout(
26602 &self,
26603 ) -> Result<(Vec<std::ops::Range<usize>>, usize), SemanticTransitionError> {
26604 self.ensure_quiescent()?;
26605 Ok(self.codebooks.support_layout())
26606 }
26607
26608 pub fn new(
26609 provider: &Arc<CudaKernelProvider>,
26610 domain: &ResidentExecutionDomain,
26611 ) -> Result<Self, SemanticTransitionError> {
26612 let mut graph = provider
26613 .allocate_semantic_hypergraph(
26614 domain,
26615 SemanticHypergraphCapacities::try_new(3, 4, 4, 4)
26616 .map_err(SemanticTransitionError::Semantic)?,
26617 )
26618 .map_err(SemanticTransitionError::Semantic)?;
26619 let base = graph.empty_root();
26620 graph
26621 .admit_records(
26622 base,
26623 SemanticAdmissionRecords {
26624 predicates: vec![],
26625 records: vec![],
26626 supports: vec![],
26627 },
26628 SemanticAdmissionLimits {
26629 max_records: 0,
26630 max_terms: 0,
26631 max_references: 0,
26632 max_utf8_bytes: 0,
26633 },
26634 )
26635 .map_err(SemanticTransitionError::Semantic)?;
26636 Self::from_hypergraph(graph)
26637 }
26638
26639 pub fn from_hypergraph(graph: SemanticHypergraph) -> Result<Self, SemanticTransitionError> {
26642 Self::from_hypergraph_with_program(graph, None)
26643 }
26644
26645 pub fn from_hypergraph_with_program(
26648 graph: SemanticHypergraph,
26649 program: Option<&crate::SemanticProgramAdmission>,
26650 ) -> Result<Self, SemanticTransitionError> {
26651 let (provider, domain) = graph
26652 .transition_owner()
26653 .map_err(SemanticTransitionError::Semantic)?;
26654 validate_execution_domain(&provider, &domain)
26655 .map_err(|e| runtime_error("domain validation", e))?;
26656 let execute = provider
26657 .device()
26658 .inner()
26659 .get_func("xlog_semantic_transition", "semantic_transition_execute")
26660 .ok_or_else(|| {
26661 runtime_error("kernel lookup", "semantic transition kernel unavailable")
26662 })?;
26663 let admission = graph
26664 .admission()
26665 .expect("transition owner validated admission");
26666 let root = admission.base();
26667 let base_snapshot = *admission.base_snapshot();
26668 let codebooks = ActionCodebooks::derive(admission, graph.transition_arena()[1], program)?;
26669 let bytes = codebooks.input_cells * (size_of::<f32>() + size_of::<u8>())
26670 + SCRATCH_BYTES
26671 + OBSERVATION_BYTES
26672 + codebooks.words.len() * 8
26673 + COMPONENT_COUNT * size_of::<SemanticComponent>();
26674 let mut reservation = provider
26675 .memory()
26676 .reserve_bytes(bytes as u64)
26677 .map_err(|e| runtime_error("reservation", e))?;
26678 let logits = reservation
26679 .alloc::<f32>(codebooks.input_cells)
26680 .map_err(|e| runtime_error("logits allocation", e))?;
26681 let support = reservation
26682 .alloc::<u8>(codebooks.input_cells)
26683 .map_err(|e| runtime_error("support allocation", e))?;
26684 let scratch = reservation
26685 .alloc::<u64>(SCRATCH_BYTES / 8)
26686 .map_err(|e| runtime_error("scratch allocation", e))?;
26687 let receipts = reservation
26688 .alloc::<SemanticTransitionReceipt>(COMPONENT_COUNT)
26689 .map_err(|e| runtime_error("receipt allocation", e))?;
26690 let state = reservation
26691 .alloc::<DeviceState>(1)
26692 .map_err(|e| runtime_error("state allocation", e))?;
26693 let device_codebooks = reservation
26694 .alloc::<u64>(codebooks.words.len())
26695 .map_err(|e| runtime_error("codebook allocation", e))?;
26696 let device_components = reservation
26697 .alloc::<SemanticComponent>(COMPONENT_COUNT)
26698 .map_err(|e| runtime_error("component allocation", e))?;
26699 debug_assert_eq!(reservation.remaining_bytes(), 0);
26700 let stream = provider
26701 .memory()
26702 .runtime()
26703 .and_then(|r| r.stream_pool().resolve(domain.stream_id()))
26704 .ok_or_else(|| runtime_error("stream resolution", "owned stream is unavailable"))?;
26705 let mut session = Self {
26706 captured: None,
26707 provider,
26708 domain: domain.clone(),
26709 stream: stream.clone(),
26710 graph: std::mem::ManuallyDrop::new(graph),
26711 root,
26712 base_snapshot,
26713 codebooks,
26714 device_codebooks,
26715 device_components,
26716 task: None,
26717 cold_content: None,
26718 initial_prefill: None,
26719 retained_initial_prefill: None,
26720 checkpoint_initial_prefill: None,
26721 training_views: None,
26722 training_origins: None,
26723 task_epoch: 0,
26724 task_observed: false,
26725 publication: None,
26726 learning_phases: Vec::new(),
26727 publication_uploads: Vec::new(),
26728 publication_issuer: Arc::new(()),
26729 readers: BTreeMap::new(),
26730 steps: BTreeMap::new(),
26731 next_reader: 0,
26732 prepared_segment: None,
26733 prepared_resources: Vec::new(),
26734 continuation_base: None,
26735 text_binding: None,
26736 admitted_transition: None,
26737 release_events: Vec::new(),
26738 logits,
26739 support,
26740 scratch,
26741 receipts,
26742 state,
26743 pinned: PinnedObservation::new(stream.clone())?,
26744 execute,
26745 #[cfg(feature = "semantic-policy")]
26746 policy: None,
26747 #[cfg(feature = "semantic-policy")]
26748 pending_policy: None,
26749 #[cfg(feature = "semantic-policy")]
26750 policy_tapes: Vec::new(),
26751 rng: None,
26752 next_proposal: 0,
26753 pending: false,
26754 poisoned: false,
26755 stream_waits: 0,
26756 };
26757 session.validate_ranges()?;
26758 session.upload_cold_codebooks()?;
26759 Ok(session)
26760 }
26761
26762 pub fn is_poisoned(&self) -> bool {
26763 self.poisoned || self.graph.ensure_not_poisoned().is_err()
26764 }
26765
26766 pub fn abort(&mut self) {
26774 self.poisoned = true;
26775 }
26776
26777 pub fn join_observed_cold_release(&mut self) -> Result<(), SemanticTransitionError> {
26781 if self.is_poisoned()
26782 || self.cold_content.is_none()
26783 || self.task.is_some()
26784 || self.task_epoch != 0
26785 || self.task_observed
26786 || self.publication.is_some()
26787 || self.captured.is_some()
26788 || !self.readers.is_empty()
26789 || !self.steps.is_empty()
26790 || self.prepared_segment.is_some()
26791 || self.initial_prefill.is_some()
26792 || self.retained_initial_prefill.is_some()
26793 || self.checkpoint_initial_prefill.is_some()
26794 {
26795 return Err(publication_input_error(
26796 "cold release requires the observed, unpublished fresh task",
26797 ));
26798 }
26799 let result = self
26800 .stream
26801 .context()
26802 .bind_to_thread()
26803 .and_then(|_| self.stream.context().synchronize());
26804 if let Err(error) = result {
26805 self.poisoned = true;
26806 return Err(runtime_error("fresh cold observer completion", error));
26807 }
26808 Ok(())
26809 }
26810
26811 pub fn finish_observed_cold_release(self) -> Result<(), SemanticTransitionError> {
26814 let memory = Arc::clone(self.provider.memory());
26815 drop(self);
26816 memory
26817 .reap_pending_deallocations()
26818 .map_err(|error| runtime_error("fresh cold allocation retirement", error))?;
26819 if memory.allocated_bytes() != 0
26820 || memory
26821 .runtime()
26822 .is_some_and(|runtime| runtime.bytes_outstanding() != 0)
26823 {
26824 return Err(publication_input_error(
26825 "fresh cold allocation owners remain after retirement",
26826 ));
26827 }
26828 Ok(())
26829 }
26830
26831 pub fn task_observation_roots(
26836 &mut self,
26837 spec: &SemanticTaskEvaluationSpec,
26838 replay: Option<&SemanticReplayMaterial>,
26839 ) -> Result<SemanticTaskObservationRoots, SemanticTransitionError> {
26840 self.ensure_rebindable()?;
26841 if self.publication.is_some() || self.captured.is_some() {
26842 return Err(publication_input_error(
26843 "task observation roots require a cold unpublished Session",
26844 ));
26845 }
26846 let admission = self
26847 .graph
26848 .admission()
26849 .ok_or(SemanticTransitionError::NotBound)?;
26850 spec.validate_records(admission.records())?;
26851 if let Some(replay) = replay {
26852 return replay
26853 .predecessor
26854 .graph
26855 .task_observation_roots(admission, spec.statement_records)
26856 .map_err(SemanticTransitionError::Semantic);
26857 }
26858 let material = self
26859 .graph
26860 .export_transition_root(self.root)
26861 .map_err(SemanticTransitionError::Semantic)?;
26862 let admission = self
26863 .graph
26864 .admission()
26865 .ok_or(SemanticTransitionError::NotBound)?;
26866 material
26867 .task_observation_roots(admission, spec.statement_records)
26868 .map_err(SemanticTransitionError::Semantic)
26869 }
26870
26871 pub fn bind_task_evaluation(
26875 &mut self,
26876 spec: SemanticTaskEvaluationSpec,
26877 ) -> Result<Identity256, SemanticTransitionError> {
26878 self.ensure_rebindable()?;
26879 if self.publication.is_some() {
26880 return Err(publication_input_error(
26881 "task data is immutable after its canonical parent is initialized",
26882 ));
26883 }
26884 let admission = self
26885 .graph
26886 .admission()
26887 .ok_or(SemanticTransitionError::NotBound)?;
26888 let next_epoch = self
26889 .task_epoch
26890 .checked_add(1)
26891 .ok_or(SemanticTransitionError::GenerationExhausted)?;
26892 spec.validate_records(admission.records())?;
26893 if spec
26894 .program
26895 .editable_program()
26896 .map(ActionCodebooks::program_binding)
26897 != self.codebooks.program_binding
26898 {
26899 return Err(publication_input_error(
26900 "task editable program differs from the cold action grammar",
26901 ));
26902 }
26903 let observation = spec
26904 .program
26905 .observe(Arc::clone(&self.provider))
26906 .inspect_err(|_error| {
26907 self.poisoned = true;
26908 })?;
26909 let binding = TaskEvaluationBinding::bind(admission, spec, observation)?;
26910 if self
26911 .cold_content
26912 .is_some_and(|expected| binding.content() != expected)
26913 {
26914 self.poisoned = true;
26915 return Err(publication_input_error(
26916 "final task content differs from the executed cold admission",
26917 ));
26918 }
26919 #[cfg(feature = "semantic-policy")]
26920 {
26921 let material = self
26922 .graph
26923 .export_transition_root(self.root)
26924 .map_err(SemanticTransitionError::Semantic)?;
26925 if material.digest != *self.base_snapshot.digest().as_bytes() {
26926 self.poisoned = true;
26927 return Err(SemanticTransitionError::ObservationMismatch);
26928 }
26929 }
26930 let words = binding.words(self.graph.transition_arena()[1]);
26931 let mut reservation = self
26932 .provider
26933 .memory()
26934 .reserve_bytes((words.len() * size_of::<u64>()) as u64)
26935 .map_err(|error| runtime_error("private task reservation", error))?;
26936 let device = reservation
26937 .alloc::<u64>(words.len())
26938 .map_err(|error| runtime_error("private task allocation", error))?;
26939 self.captured = None;
26942 let identity = binding.identity();
26943 self.task = Some((binding, device));
26944 let (_, device) = self.task.as_mut().expect("private task installed above");
26945 self.provider
26946 .htod_sync_copy_into_tracked(&words, device)
26947 .map_err(|error| {
26948 self.poisoned = true;
26949 runtime_error("private task upload", error)
26950 })?;
26951 let mut recorder = self.domain.new_strict_recorder();
26952 recorder.read_write(device);
26953 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |_| {
26954 Ok::<(), XlogError>(())
26955 })?;
26956 wait_on_stream(
26957 &self.stream,
26958 &mut self.poisoned,
26959 &mut self.stream_waits,
26960 "private task adoption wait",
26961 CudaStream::synchronize,
26962 )?;
26963 self.validate_ranges()?;
26964 self.task_epoch = next_epoch;
26965 Ok(identity)
26966 }
26967
26968 pub fn observe_cold_task_content(
26972 &mut self,
26973 statement_records: [u32; 3],
26974 allowed_support_records: &[u32],
26975 program: &dyn SemanticTaskProgram,
26976 ) -> Result<(SemanticTaskContentIdentity, [crate::SemanticTruth; 3]), SemanticTransitionError>
26977 {
26978 self.ensure_rebindable()?;
26979 if self.publication.is_some() || self.task.is_some() || self.cold_content.is_some() {
26980 return Err(publication_input_error(
26981 "cold task content can be observed only once before final import",
26982 ));
26983 }
26984 let admission = self
26985 .graph
26986 .admission()
26987 .ok_or(SemanticTransitionError::NotBound)?;
26988 if program
26989 .editable_program()
26990 .map(ActionCodebooks::program_binding)
26991 != self.codebooks.program_binding
26992 {
26993 return Err(publication_input_error(
26994 "cold task observer differs from the admitted edit grammar",
26995 ));
26996 }
26997 let observation = program
26998 .observe(Arc::clone(&self.provider))
26999 .inspect_err(|_| self.poisoned = true)?;
27000 let content = TaskEvaluationBinding::cold_content(
27001 admission,
27002 statement_records,
27003 allowed_support_records,
27004 program.editable_program(),
27005 observation,
27006 )
27007 .inspect_err(|_| self.poisoned = true)?;
27008 self.cold_content = Some(content);
27009 Ok(content)
27010 }
27011
27012 pub fn bind_task_goal_witness(
27015 &mut self,
27016 witness: SemanticTaskGoalWitness,
27017 ) -> Result<Identity256, SemanticTransitionError> {
27018 self.ensure_rebindable()?;
27019 if self.publication.is_some() || self.captured.is_some() {
27020 return Err(publication_input_error(
27021 "goal authority is immutable after publication or capture",
27022 ));
27023 }
27024 if witness.mandatory_link_count == 0
27025 || witness.constraint_count == 0
27026 || witness
27027 .semantic_root
27028 .as_bytes()
27029 .iter()
27030 .all(|byte| *byte == 0)
27031 || witness
27032 .authority_root
27033 .as_bytes()
27034 .iter()
27035 .all(|byte| *byte == 0)
27036 || witness
27037 .mandatory_links_root
27038 .as_bytes()
27039 .iter()
27040 .all(|byte| *byte == 0)
27041 || witness
27042 .constraints_root
27043 .as_bytes()
27044 .iter()
27045 .all(|byte| *byte == 0)
27046 {
27047 return Err(publication_input_error(
27048 "goal authority requires nonempty independently validated roots and closures",
27049 ));
27050 }
27051 let next_epoch = self
27052 .task_epoch
27053 .checked_add(1)
27054 .ok_or(SemanticTransitionError::GenerationExhausted)?;
27055 let (binding, device) = self.task.as_mut().ok_or_else(|| {
27056 publication_input_error("goal authority requires a bound native task evaluation")
27057 })?;
27058 if binding.goal_witness.is_some() {
27059 return Err(publication_input_error(
27060 "goal authority can be bound only once",
27061 ));
27062 }
27063 binding.goal_witness = Some(witness);
27064 let identity = binding.identity();
27065 let words = binding.words(self.graph.transition_arena()[1]);
27066 self.provider
27067 .htod_sync_copy_into_tracked(&words, device)
27068 .map_err(|error| {
27069 self.poisoned = true;
27070 runtime_error("private goal-authority upload", error)
27071 })?;
27072 let mut recorder = self.domain.new_strict_recorder();
27073 recorder.read_write(device);
27074 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |_| {
27075 Ok::<(), XlogError>(())
27076 })?;
27077 wait_on_stream(
27078 &self.stream,
27079 &mut self.poisoned,
27080 &mut self.stream_waits,
27081 "private goal-authority adoption wait",
27082 CudaStream::synchronize,
27083 )?;
27084 self.validate_ranges()?;
27085 self.task_epoch = next_epoch;
27086 Ok(identity)
27087 }
27088
27089 pub fn task_evaluation_identity(&self) -> Option<Identity256> {
27091 self.task.as_ref().map(|(binding, _)| binding.identity())
27092 }
27093
27094 pub fn task_content(&self) -> Option<(SemanticTaskContentIdentity, [crate::SemanticTruth; 3])> {
27097 self.task.as_ref().map(|(binding, _)| binding.content())
27098 }
27099
27100 pub fn task_scoring_law_identity(
27102 &self,
27103 ) -> Result<Option<Identity256>, SemanticTransitionError> {
27104 Ok(self.task.as_ref().map(|(binding, _)| {
27105 checkpoint_scoring_law_identity(
27106 binding.spec.scoring,
27107 binding.content_identity(),
27108 binding.objective_law,
27109 binding.spec.training_domain.as_ref(),
27110 )
27111 }))
27112 }
27113
27114 pub fn task_objective_law(&self) -> Option<SemanticTaskObjectiveLaw> {
27117 self.task.as_ref().map(|(binding, _)| binding.objective_law)
27118 }
27119
27120 pub fn task_training_domain(&self) -> Option<&SemanticTrainingDomain> {
27122 self.task
27123 .as_ref()
27124 .and_then(|(binding, _)| binding.spec.training_domain.as_ref())
27125 }
27126
27127 #[cfg(feature = "semantic-policy")]
27131 pub fn policy_numerical_domains(
27132 &mut self,
27133 parent: &SemanticPublishedLease,
27134 consumer_stream: u64,
27135 ) -> Result<[DlpackManagedTensor; 3], SemanticTransitionError> {
27136 self.checked_reader(parent)?;
27137 dlpack_consumer_stream(consumer_stream)?;
27138 if self.captured.is_some() {
27139 return Err(publication_input_error(
27140 "uniform domains must precede policy capture",
27141 ));
27142 }
27143 let pending = self.pending_policy.as_ref().ok_or_else(|| {
27144 publication_input_error("uniform domains require the nine original policy snapshots")
27145 })?;
27146 if pending
27147 .witness
27148 .as_ref()
27149 .is_none_or(|(witness, _)| witness.reader_token != parent.token)
27150 {
27151 return Err(publication_input_error(
27152 "uniform domains belong to another acquired parent",
27153 ));
27154 }
27155 let publication = Arc::clone(
27156 self.publication
27157 .as_ref()
27158 .ok_or(SemanticTransitionError::NotBound)?,
27159 );
27160 let tensors = export_policy_uniform_domains(
27161 &pending.buffers,
27162 self.codebooks.input_cells,
27163 self.provider.device().ordinal() as i32,
27164 Arc::clone(&self.steps[&parent.token].aliases),
27165 publication,
27166 )?;
27167 self.steps
27168 .get_mut(&parent.token)
27169 .expect("checked original parent")
27170 .consumer_streams
27171 .insert(consumer_stream);
27172 self.order_content_consumers(consumer_stream)?;
27173 Ok(tensors)
27174 }
27175
27176 #[cfg(feature = "semantic-policy")]
27179 pub fn prepared_policy_numerical_domains(
27180 &mut self,
27181 step: &SemanticPreparedStep,
27182 bank: usize,
27183 consumer_stream: u64,
27184 ) -> Result<[DlpackManagedTensor; 3], SemanticTransitionError> {
27185 self.check_prepared_content_stream(step, consumer_stream)?;
27186 if bank > 1 {
27187 return Err(publication_input_error(
27188 "prepared policy bank must be zero or one",
27189 ));
27190 }
27191 let original = &self.steps[&step.token];
27192 let prepared = original.prepared.as_ref().expect("checked prepared owner");
27193 if prepared.transition_recorded & (1 << bank) != 0 {
27194 return Err(publication_input_error(
27195 "uniform domains must precede policy submission",
27196 ));
27197 }
27198 let branch = &prepared.branches[bank];
27199 if branch.policy_sources.len() != 9 {
27200 return Err(publication_input_error(
27201 "uniform domains require the nine original policy snapshots",
27202 ));
27203 }
27204 let buffers = branch
27205 .policy_buffers
27206 .as_ref()
27207 .or_else(|| branch.policy.as_ref().map(|policy| &policy.buffers))
27208 .ok_or_else(|| publication_input_error("original uniform policy bank is absent"))?;
27209 let tensors = export_policy_uniform_domains(
27210 buffers,
27211 self.codebooks.input_cells,
27212 self.provider.device().ordinal() as i32,
27213 Arc::clone(&original.aliases),
27214 Arc::clone(
27215 self.publication
27216 .as_ref()
27217 .ok_or(SemanticTransitionError::NotBound)?,
27218 ),
27219 )?;
27220 self.steps
27221 .get_mut(&step.token)
27222 .expect("checked original step")
27223 .consumer_streams
27224 .insert(consumer_stream);
27225 self.order_content_consumers(consumer_stream)?;
27226 Ok(tensors)
27227 }
27228
27229 pub fn task_semantic_goal_root(&self) -> Option<Identity256> {
27232 self.task
27233 .as_ref()
27234 .and_then(|(binding, _)| binding.goal_witness.map(|goal| goal.semantic_root))
27235 }
27236
27237 pub fn task_priority_levels(&self) -> Option<&[SemanticTaskPriorityLevel]> {
27240 self.task
27241 .as_ref()
27242 .map(|(binding, _)| binding.priority_levels())
27243 }
27244
27245 pub fn bind_training_view_arena(
27248 &mut self,
27249 rows: Vec<SemanticTrainingViewRow>,
27250 objective: SemanticTrainingObjective,
27251 ) -> Result<(), SemanticTransitionError> {
27252 self.ensure_rebindable()?;
27253 if self.publication.is_some() || self.training_views.is_some() || self.task.is_none() {
27254 return Err(publication_input_error(
27255 "training-view arena requires one cold task binding and cannot be replaced",
27256 ));
27257 }
27258 self.task_objective_law()
27259 .expect("checked cold task binding")
27260 .require_objective(&objective)?;
27261 let task_identity = self
27262 .task
27263 .as_ref()
27264 .expect("checked cold task binding")
27265 .0
27266 .identity();
27267 let (task_content, expected_truth) = self
27268 .task
27269 .as_ref()
27270 .expect("checked cold task binding")
27271 .0
27272 .content();
27273 self.training_views = Some(SemanticTrainingViewArena::allocate(
27274 &self.provider,
27275 &self.domain,
27276 rows,
27277 objective,
27278 self.task_training_domain().ok_or_else(|| {
27279 publication_input_error(
27280 "training arena requires its original pre-action input domain",
27281 )
27282 })?,
27283 task_identity,
27284 task_content,
27285 expected_truth,
27286 )?);
27287 Ok(())
27288 }
27289
27290 pub fn task_evaluation_spec(
27294 &self,
27295 ) -> Result<&SemanticTaskEvaluationSpec, SemanticTransitionError> {
27296 self.ensure_quiescent()?;
27297 let (task, _) = self
27298 .task
27299 .as_ref()
27300 .ok_or(SemanticTransitionError::NotBound)?;
27301 Ok(task.spec())
27302 }
27303
27304 pub fn feedback_statement_bytes(&self) -> Result<[&[u8]; 3], SemanticTransitionError> {
27311 let selected = self.task_evaluation_spec()?.statement_records;
27312 let (task, _) = self
27313 .task
27314 .as_ref()
27315 .ok_or(SemanticTransitionError::NotBound)?;
27316 Ok(selected.map(|record| task.statement_bytes[&record].as_slice()))
27317 }
27318
27319 pub fn feedback_adapter_identity() -> Identity256 {
27322 let mut hash = Sha256::new();
27323 hash.update(b"xlog.native.flat-feedback-adapter.v1\0");
27324 hash.update(include_bytes!("semantic_transition.rs"));
27325 hash.update(include_bytes!("../kernels/semantic_transition.cu"));
27326 hash.update(include_bytes!("../kernels/semantic_feedback_encoding.cuh"));
27327 Identity256::from_bytes(hash.finalize().into())
27328 }
27329
27330 pub fn task_evaluation_epoch(&self) -> u64 {
27332 self.task_epoch
27333 }
27334
27335 pub fn binding(&self) -> SemanticCatalogueBinding {
27336 self.codebooks.binding
27337 }
27338 pub fn components(&self) -> &[SemanticComponent] {
27339 &self.codebooks.components
27340 }
27341 pub fn descriptor_meaning(
27342 &self,
27343 field: u32,
27344 category: u32,
27345 ) -> Option<&SemanticActionDescriptor> {
27346 let entries = match field {
27347 2 => &self.codebooks.targets,
27348 3..=10 => &self.codebooks.operands,
27349 11 => &self.codebooks.qualifiers,
27350 17 => &self.codebooks.leaves,
27351 _ => return None,
27352 };
27353 entries.get(category.checked_sub(1)? as usize)
27354 }
27355
27356 pub fn host_io_stats(&self) -> SemanticTransitionHostIoStats {
27357 let io = self.provider.host_transfer_stats();
27358 let metadata = self.provider.host_launch_metadata_transfer_stats();
27359 let observation = self.provider.final_observation_transfer_stats();
27360 SemanticTransitionHostIoStats {
27361 htod_bytes: io.htod_bytes,
27362 dtoh_bytes: io.dtoh_bytes,
27363 htod_calls: io.htod_calls,
27364 dtoh_calls: io.dtoh_calls,
27365 launch_metadata_bytes: metadata.htod_bytes,
27366 launch_metadata_calls: metadata.htod_calls,
27367 metadata_dtoh_calls: self.provider.untracked_metadata_dtoh_count(),
27368 observation_bytes: observation.dtoh_bytes,
27369 observation_calls: observation.dtoh_calls,
27370 session_stream_waits: self.stream_waits,
27371 }
27372 }
27373
27374 pub fn root_snapshot(&mut self) -> Result<SemanticRootSnapshot, SemanticTransitionError> {
27375 self.ensure_quiescent()?;
27376 Ok(self.base_snapshot)
27377 }
27378
27379 pub fn bind_inputs(
27384 &mut self,
27385 binding: SemanticCatalogueBinding,
27386 rng: SemanticRngBinding,
27387 inputs: &[SemanticComponentInput],
27388 ) -> Result<(), SemanticTransitionError> {
27389 self.ensure_rebindable()?;
27390 if binding != self.binding() {
27391 return Err(SemanticTransitionError::CatalogueMismatch);
27392 }
27393 validate_bound_inputs(&self.codebooks.components, rng, inputs)?;
27394 self.validate_ranges()?;
27395 let logits: Vec<f32> = inputs
27396 .iter()
27397 .flat_map(|r| r.logits.iter().copied())
27398 .collect();
27399 let support: Vec<u8> = inputs
27400 .iter()
27401 .flat_map(|r| r.product_support.iter().copied())
27402 .collect();
27403 #[cfg(feature = "semantic-policy")]
27404 if self.pending_policy.is_some() {
27405 return Err(publication_input_error(
27406 "original policy snapshots cannot be replaced by raw inputs",
27407 ));
27408 }
27409 #[cfg(feature = "semantic-policy")]
27410 if self.policy.is_some() {
27411 self.captured = None;
27412 self.policy = None;
27413 }
27414 let upload = (|| {
27417 self.provider
27418 .htod_sync_copy_into_tracked(&logits, &mut self.logits)?;
27419 self.provider
27420 .htod_sync_copy_into_tracked(&support, &mut self.support)?;
27421 Ok::<(), XlogError>(())
27422 })();
27423 upload.map_err(|e| {
27424 self.poisoned = true;
27425 runtime_error("input upload", e)
27426 })?;
27427 self.upload_rng_state(binding, rng)?;
27428 let mut recorder = self.domain.new_strict_recorder();
27429 recorder.read_write(&self.logits);
27430 recorder.read_write(&self.support);
27431 recorder.read_write(&self.state);
27432 recorder.write(&self.scratch);
27433 recorder.write(&self.receipts);
27434 recorder.read(&self.device_codebooks);
27435 recorder.read(&self.device_components);
27436 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |_| {
27439 Ok::<(), XlogError>(())
27440 })?;
27441 self.stream_waits += 1;
27442 self.stream.synchronize().map_err(|e| {
27443 self.poisoned = true;
27444 runtime_error("input adoption wait", e)
27445 })?;
27446 self.rng = Some(rng);
27447 self.next_proposal = u64::from(rng.proposal);
27448 Ok(())
27449 }
27450
27451 #[cfg(feature = "semantic-policy")]
27466 #[expect(
27467 clippy::too_many_arguments,
27468 reason = "all nine original policy operands share one snapshot"
27469 )]
27470 pub fn bind_policy(
27471 &mut self,
27472 binding: SemanticCatalogueBinding,
27473 rng: SemanticRngBinding,
27474 text_logits: &TrackedCudaSlice<f32>,
27475 product_support: &TrackedCudaSlice<u8>,
27476 parameters: &TrackedCudaSlice<f32>,
27477 component_baselines: &TrackedCudaSlice<f32>,
27478 numerical: [&TrackedCudaSlice<f64>; 5],
27479 ) -> Result<(), SemanticTransitionError> {
27480 self.bind_policy_views(
27481 binding,
27482 rng,
27483 text_logits.view(),
27484 product_support.view(),
27485 parameters.view(),
27486 component_baselines.view(),
27487 numerical.map(TrackedCudaSlice::view),
27488 None,
27489 )
27490 }
27491
27492 #[cfg(feature = "semantic-policy")]
27516 #[expect(
27517 clippy::too_many_arguments,
27518 reason = "the complete original witness and operand owners are explicit"
27519 )]
27520 pub fn bind_policy_dlpack(
27521 &mut self,
27522 lease: &SemanticPublishedLease,
27523 binding: SemanticCatalogueBinding,
27524 rng: SemanticRngBinding,
27525 text_logits: DlpackManagedTensor,
27526 product_support: DlpackManagedTensor,
27527 parameters: DlpackManagedTensor,
27528 component_baselines: DlpackManagedTensor,
27529 numerical: [DlpackManagedTensor; 5],
27530 witness: &SemanticTensorContentWitness,
27531 consumer_stream: u64,
27532 ) -> Result<(), SemanticTransitionError> {
27533 let mut handoff = RetainedTensorAdmission {
27536 inputs: Some(
27537 vec![
27538 text_logits,
27539 product_support,
27540 parameters,
27541 component_baselines,
27542 ]
27543 .into_iter()
27544 .chain(numerical)
27545 .collect(),
27546 ),
27547 stream: Arc::clone(self.provider.device().inner().stream()),
27548 ready: false,
27549 };
27550 self.ensure_rebindable()?;
27551 self.checked_reader(lease)?;
27552 self.checked_content_witness(lease, witness)?;
27553 if rng != self.admitted_policy_rng(lease)? {
27554 return Err(publication_input_error(
27555 "policy invocation differs from its actual acquired parent",
27556 ));
27557 }
27558 if binding != self.binding() {
27559 return Err(SemanticTransitionError::CatalogueMismatch);
27560 }
27561 if rng.stream_serial >= (1u64 << 56) {
27562 return Err(SemanticTransitionError::InvalidInput {
27563 detail: "policy stream namespace does not match the native catalogue".into(),
27564 });
27565 }
27566 let layout = self.policy_layout()?;
27567 let layouts =
27568 policy_numerical_producer_layouts(self.codebooks.input_cells, layout.parameter_cells)?;
27569 let inputs = handoff
27573 .inputs
27574 .take()
27575 .expect("retained policy producers")
27576 .into_iter()
27577 .zip(layouts)
27578 .map(|(tensor, layout)| SemanticTensorInput {
27579 layout,
27580 logical_begin: 0,
27581 logical_end: 0,
27582 tensor,
27583 native_allocation: None,
27584 })
27585 .collect();
27586 self.verify_tensor_content(lease, witness, inputs, consumer_stream)?;
27587 let original =
27588 policy_source_views(&self.steps[&lease.token].content[witness.index].tensors)?;
27589 self.bind_policy_views(
27590 binding,
27591 rng,
27592 original.text_logits,
27593 original.product_support,
27594 original.parameters,
27595 original.component_baselines,
27596 original.numerical,
27597 Some((witness.clone(), consumer_stream)),
27598 )
27599 }
27600
27601 #[cfg(feature = "semantic-policy")]
27602 fn allocate_policy_buffers(&self) -> Result<PolicyBuffers, SemanticTransitionError> {
27603 let layout = self.policy_layout()?;
27604 let mut reservation = self
27605 .provider
27606 .memory()
27607 .reserve_bytes(policy_buffer_bytes(&layout, self.codebooks.input_cells)? as u64)
27608 .map_err(|error| runtime_error("policy reservation", error))?;
27609 self.allocate_policy_buffers_reserved(&mut reservation)
27610 }
27611
27612 #[cfg(feature = "semantic-policy")]
27613 fn allocate_policy_buffers_reserved(
27614 &self,
27615 reservation: &mut GpuMemoryReservation,
27616 ) -> Result<PolicyBuffers, SemanticTransitionError> {
27617 let layout = self.policy_layout()?;
27618 let law = self.task_objective_law().ok_or_else(|| {
27619 publication_input_error("uniform policy domains require the original cold task law")
27620 })?;
27621 let text_cells = 32 * TEXT_CARDINALITY;
27622 let pwl_cells = reservation
27623 .alloc::<SemanticPolicyPwlCell>(COMPONENT_COUNT)
27624 .map_err(|error| runtime_error("retained PWL cell allocation", error))?;
27625 let selected_score_vjps = reservation
27626 .alloc::<SemanticPolicySelectedScoreVjp>(COMPONENT_COUNT)
27627 .map_err(|error| runtime_error("retained selected-score VJP allocation", error))?;
27628 let mut allocate_adjoints = || {
27629 let mut allocate_numerical = |cells: usize| {
27630 reservation
27631 .alloc::<f64>(cells)
27632 .map_err(|error| runtime_error("policy adjoint numerical allocation", error))
27633 };
27634 let numerical = Arc::new(PolicyAdjointNumerical {
27635 roots: [
27636 allocate_numerical(
27637 layout
27638 .parameter_cells
27639 .checked_mul(2)
27640 .ok_or(SemanticTransitionError::GenerationExhausted)?,
27641 )?,
27642 allocate_numerical(text_cells * 2)?,
27643 allocate_numerical(COMPONENT_COUNT * 2)?,
27644 allocate_numerical(
27645 layout
27646 .parameter_cells
27647 .checked_mul(8)
27648 .ok_or(SemanticTransitionError::GenerationExhausted)?,
27649 )?,
27650 allocate_numerical(text_cells * 8)?,
27651 allocate_numerical(COMPONENT_COUNT * 8)?,
27652 ],
27653 recurrent_errors: allocate_numerical(layout.recurrent_cells() * 8)?,
27654 score_errors: allocate_numerical(layout.score_cells() * 8)?,
27655 coefficient_errors: allocate_numerical(COMPONENT_COUNT * 8)?,
27656 root_cotangents: [
27657 allocate_numerical(
27658 layout
27659 .parameter_cells
27660 .checked_mul(8)
27661 .ok_or(SemanticTransitionError::GenerationExhausted)?,
27662 )?,
27663 allocate_numerical(text_cells * 8)?,
27664 allocate_numerical(COMPONENT_COUNT * 8)?,
27665 ],
27666 });
27667 Ok::<_, SemanticTransitionError>(PolicyAdjointBuffers {
27668 numerical,
27669 parameters: reservation
27670 .alloc::<f32>(layout.parameter_cells)
27671 .map_err(|error| runtime_error("parameter adjoint allocation", error))?,
27672 text_logits: reservation
27673 .alloc::<f32>(text_cells)
27674 .map_err(|error| runtime_error("text adjoint allocation", error))?,
27675 component_baselines: reservation
27676 .alloc::<f32>(COMPONENT_COUNT)
27677 .map_err(|error| runtime_error("baseline adjoint allocation", error))?,
27678 recurrent: reservation
27679 .alloc::<f32>(layout.recurrent_cells())
27680 .map_err(|error| runtime_error("recurrent adjoint allocation", error))?,
27681 scores: reservation
27682 .alloc::<f32>(layout.score_cells())
27683 .map_err(|error| runtime_error("score adjoint allocation", error))?,
27684 coefficients: reservation
27685 .alloc::<f64>(COMPONENT_COUNT)
27686 .map_err(|error| runtime_error("cotangent snapshot allocation", error))?,
27687 status: reservation
27688 .alloc::<u64>(1)
27689 .map_err(|error| runtime_error("policy backward status allocation", error))?,
27690 })
27691 };
27692 let adjoints = allocate_adjoints()?;
27693 let temporal_adjoints = Arc::new(allocate_adjoints()?);
27694 let mut allocate_uniform = |cells: usize| {
27695 reservation
27696 .alloc::<f64>(cells)
27697 .map_err(|error| runtime_error("uniform policy domain allocation", error))
27698 };
27699 let root_cells = [layout.parameter_cells, text_cells, COMPONENT_COUNT];
27700 let mut roots = Vec::with_capacity(3);
27701 let mut outputs = Vec::with_capacity(3);
27702 for cells in root_cells {
27703 let cells = cells
27704 .checked_mul(8)
27705 .ok_or(SemanticTransitionError::GenerationExhausted)?;
27706 outputs.push(allocate_uniform(cells)?);
27707 }
27708 for cells in [layout.parameter_cells, TEXT_CARDINALITY, COMPONENT_COUNT] {
27709 roots.push(allocate_uniform(
27710 cells
27711 .checked_mul(8)
27712 .ok_or(SemanticTransitionError::GenerationExhausted)?,
27713 )?);
27714 }
27715 let roots: [_; 3] = roots
27716 .try_into()
27717 .unwrap_or_else(|_| unreachable!("three policy roots"));
27718 let outputs: [_; 3] = outputs
27719 .try_into()
27720 .unwrap_or_else(|_| unreachable!("three policy outputs"));
27721 let scratch = [
27722 allocate_uniform(layout.recurrent_cells() * 4)?,
27723 allocate_uniform(128 * 4)?,
27724 allocate_uniform(layout.score_cells() * 4)?,
27725 allocate_uniform(layout.recurrent_cells() * 8)?,
27726 allocate_uniform(layout.score_cells() * 8)?,
27727 allocate_uniform(COMPONENT_COUNT * 8)?,
27728 ];
27729 let status = reservation
27730 .alloc::<u64>(1)
27731 .map_err(|error| runtime_error("uniform policy status allocation", error))?;
27732 let work = reservation
27733 .alloc::<u64>(11)
27734 .map_err(|error| runtime_error("uniform policy work allocation", error))?;
27735 let descriptor = reservation
27736 .alloc::<PolicyUniformDescriptor>(1)
27737 .map_err(|error| runtime_error("uniform policy descriptor allocation", error))?;
27738 let initial_descriptor = PolicyUniformDescriptor {
27739 outputs: outputs.each_ref().map(TrackedCudaSlice::device_ptr_value),
27740 roots: roots.each_ref().map(TrackedCudaSlice::device_ptr_value),
27741 recurrent: scratch[0].device_ptr_value(),
27742 hidden: scratch[1].device_ptr_value(),
27743 scores: scratch[2].device_ptr_value(),
27744 recurrent_cotangents: scratch[3].device_ptr_value(),
27745 score_cotangents: scratch[4].device_ptr_value(),
27746 score_roots: scratch[5].device_ptr_value(),
27747 status: status.device_ptr_value(),
27748 work: work.device_ptr_value(),
27749 training_rows: self
27750 .task_training_domain()
27751 .map_or(0, SemanticTrainingDomain::record_limit),
27752 return_bound: law.return_bound as u64,
27753 loss_coefficients: [3, 6, 7, 8].map(|index| f64::from(law.coefficients[index])),
27754 };
27755 let uniform = Arc::new(PolicyUniformBuffers {
27756 descriptor,
27757 initial_descriptor,
27758 roots,
27759 outputs,
27760 scratch,
27761 status,
27762 work,
27763 execute: self
27764 .provider
27765 .device()
27766 .inner()
27767 .get_func(
27768 "xlog_semantic_transition",
27769 "semantic_policy_uniform_domains",
27770 )
27771 .ok_or_else(|| {
27772 runtime_error("kernel lookup", "uniform policy domains unavailable")
27773 })?,
27774 });
27775 let mut allocate_numerical = |cells: usize| {
27776 reservation
27777 .alloc::<f64>(cells)
27778 .map_err(|error| runtime_error("policy numerical allocation", error))
27779 };
27780 let numerical = PolicyNumericalBuffers {
27781 uniform,
27782 parameter_errors: allocate_numerical(
27783 layout
27784 .parameter_cells
27785 .checked_mul(2)
27786 .ok_or(SemanticTransitionError::GenerationExhausted)?,
27787 )?,
27788 baseline_errors: allocate_numerical(COMPONENT_COUNT * 2)?,
27789 parameter_domains: allocate_numerical(
27790 layout
27791 .parameter_cells
27792 .checked_mul(4)
27793 .ok_or(SemanticTransitionError::GenerationExhausted)?,
27794 )?,
27795 text_domains: allocate_numerical(text_cells * 4)?,
27796 baseline_domains: allocate_numerical(COMPONENT_COUNT * 4)?,
27797 hidden_errors: allocate_numerical(128 * 3)?,
27798 score_errors: allocate_numerical(layout.score_cells() * 3)?,
27799 recurrent_errors: allocate_numerical(layout.recurrent_cells() * 3)?,
27800 parameter_envelopes: allocate_numerical(
27801 layout
27802 .parameter_cells
27803 .checked_mul(3)
27804 .ok_or(SemanticTransitionError::GenerationExhausted)?,
27805 )?,
27806 baseline_envelopes: allocate_numerical(COMPONENT_COUNT * 3)?,
27807 };
27808 Ok(PolicyBuffers {
27809 numerical,
27810 parameters: reservation
27811 .alloc::<f32>(layout.parameter_cells)
27812 .map_err(|error| runtime_error("policy parameter allocation", error))?,
27813 hidden: reservation
27814 .alloc::<f32>(128)
27815 .map_err(|error| runtime_error("policy hidden allocation", error))?,
27816 scores: reservation
27817 .alloc::<f32>(layout.score_cells())
27818 .map_err(|error| runtime_error("policy score allocation", error))?,
27819 retained_scores: reservation
27820 .alloc::<f32>(layout.retained_score_cells())
27821 .map_err(|error| runtime_error("retained policy score allocation", error))?,
27822 final_masks: reservation
27823 .alloc::<u8>(self.codebooks.input_cells)
27824 .map_err(|error| runtime_error("retained final mask allocation", error))?,
27825 active_sets: reservation
27826 .alloc::<u8>(self.codebooks.input_cells)
27827 .map_err(|error| runtime_error("retained active set allocation", error))?,
27828 pwl_cells,
27829 selected_score_vjps,
27830 recurrent: reservation
27831 .alloc::<f32>(layout.recurrent_cells())
27832 .map_err(|error| runtime_error("policy recurrent allocation", error))?,
27833 text_logits: reservation
27834 .alloc::<f32>(text_cells)
27835 .map_err(|error| runtime_error("original text snapshot allocation", error))?,
27836 component_baselines: reservation
27837 .alloc::<f32>(COMPONENT_COUNT)
27838 .map_err(|error| runtime_error("component baseline snapshot allocation", error))?,
27839 adjoints: Some(adjoints),
27840 temporal_adjoints,
27841 layout,
27842 })
27843 }
27844
27845 #[cfg(feature = "semantic-policy")]
27846 fn prepare_step_policy_storage(
27847 &self,
27848 reservation: &mut GpuMemoryReservation,
27849 ) -> Result<PreparedPolicyStorage, SemanticTransitionError> {
27850 let buffers = self.allocate_policy_buffers_reserved(reservation)?;
27851 let support = reservation
27852 .alloc(self.codebooks.input_cells)
27853 .map_err(|error| runtime_error("prepared support allocation", error))?;
27854 let receipts = reservation
27855 .alloc(COMPONENT_COUNT)
27856 .map_err(|error| runtime_error("prepared receipt allocation", error))?;
27857 let state = reservation
27858 .alloc(1)
27859 .map_err(|error| runtime_error("prepared state allocation", error))?;
27860 Ok((buffers, support, receipts, state))
27861 }
27862
27863 #[cfg(feature = "semantic-policy")]
27868 #[expect(
27869 clippy::too_many_arguments,
27870 reason = "prepared policy binding retains each typed producer and witness explicitly"
27871 )]
27872 pub fn bind_prepared_policy(
27873 &mut self,
27874 step: &SemanticPreparedStep,
27875 bank: usize,
27876 binding: SemanticCatalogueBinding,
27877 text_logits: DlpackManagedTensor,
27878 product_support: DlpackManagedTensor,
27879 parameters: DlpackManagedTensor,
27880 component_baselines: DlpackManagedTensor,
27881 numerical: [DlpackManagedTensor; 5],
27882 witness: &SemanticTensorContentWitness,
27883 consumer_stream: u64,
27884 ) -> Result<(), SemanticTransitionError> {
27885 self.check_prepared_content_stream(step, consumer_stream)?;
27886 if bank > 1 {
27887 return Err(publication_input_error(
27888 "prepared policy bank must be zero or one",
27889 ));
27890 }
27891 if self.prepared_transition_kind(step)? != SemanticTransitionKind::Proposal {
27892 return Err(publication_input_error(
27893 "only a proposal step binds a learned policy",
27894 ));
27895 }
27896 if binding != self.binding() {
27897 return Err(SemanticTransitionError::CatalogueMismatch);
27898 }
27899 let layouts = policy_numerical_producer_layouts(
27900 self.codebooks.input_cells,
27901 self.policy_layout()?.parameter_cells,
27902 )?;
27903 let tensors = [
27904 text_logits,
27905 product_support,
27906 parameters,
27907 component_baselines,
27908 ]
27909 .into_iter()
27910 .chain(numerical)
27911 .zip(layouts)
27912 .map(|(tensor, layout)| SemanticTensorInput {
27913 layout,
27914 logical_begin: 0,
27915 logical_end: 0,
27916 tensor,
27917 native_allocation: None,
27918 })
27919 .collect();
27920 self.verify_prepared_tensor_content(step, witness, tensors, consumer_stream)?;
27921 let sources = self.steps[&step.token].content[witness.index]
27922 .tensors
27923 .clone();
27924 let owner = self
27925 .steps
27926 .get_mut(&step.token)
27927 .expect("checked original step");
27928 let prepared = owner.prepared.as_mut().expect("prepared policy owner");
27929 let branch = &mut prepared.branches[bank];
27930 if branch.policy.is_some() || !branch.policy_sources.is_empty() {
27931 return Err(publication_input_error(
27932 "prepared policy already owns its original invocation",
27933 ));
27934 }
27935 if branch.policy_buffers.is_none() {
27936 return Err(publication_input_error(
27937 "prepared policy has no unused cold allocation",
27938 ));
27939 }
27940 branch.policy_sources = sources;
27941 branch.policy_witness = Some(witness.clone());
27942 let sources = policy_source_views(&branch.policy_sources)?;
27943 enqueue_policy_snapshots(
27944 &self.domain,
27945 &mut self.poisoned,
27946 branch
27947 .policy_buffers
27948 .as_ref()
27949 .expect("checked original cold policy bank"),
27950 branch.support.as_ref().expect("original support bank"),
27951 &sources,
27952 )?;
27953 enqueue_policy_uniform_domains(
27954 &self.domain,
27955 &mut self.poisoned,
27956 branch
27957 .policy_buffers
27958 .as_ref()
27959 .expect("original policy domain bank"),
27960 &self.device_components,
27961 branch.support.as_ref().expect("original support bank"),
27962 )?;
27963 self.attach_prepared_policy_continuation(step, bank)
27964 }
27965
27966 #[cfg(feature = "semantic-policy")]
27970 fn attach_prepared_policy_continuation(
27971 &mut self,
27972 step: &SemanticPreparedStep,
27973 bank: usize,
27974 ) -> Result<(), SemanticTransitionError> {
27975 let branch = &mut self
27976 .steps
27977 .get_mut(&step.token)
27978 .expect("checked original step")
27979 .prepared
27980 .as_mut()
27981 .expect("prepared policy owner")
27982 .branches[bank];
27983 if branch.policy.is_some() || branch.policy_sources.is_empty() {
27984 return Ok(());
27985 }
27986 let Some(continuation) = branch.continuation.as_ref() else {
27987 return Ok(());
27988 };
27989 let text_binding = Arc::clone(&continuation.text_binding);
27990 if text_binding._witness.reader_token != step.token {
27991 return Err(publication_input_error(
27992 "prepared policy and continuation belong to different original steps",
27993 ));
27994 }
27995 let buffers = branch.policy_buffers.take().ok_or_else(|| {
27996 publication_input_error("prepared policy has no unused cold allocation")
27997 })?;
27998 branch.policy = Some(PolicyStorage {
27999 buffers,
28000 text_binding,
28001 _policy_witness: branch.policy_witness.clone(),
28002 replacement: None,
28003 tape_live: false,
28004 temporal_vjp_recorded: BTreeSet::new(),
28005 });
28006 Ok(())
28007 }
28008
28009 #[cfg(feature = "semantic-policy")]
28012 pub fn enqueue_prepared_transition(
28013 &mut self,
28014 step: &SemanticPreparedStep,
28015 bank: usize,
28016 ) -> Result<(), SemanticTransitionError> {
28017 self.check_prepared_content_stream(step, self.stream.cu_stream() as u64)?;
28018 if bank > 1 {
28019 return Err(publication_input_error(
28020 "prepared transition bank must be zero or one",
28021 ));
28022 }
28023 let kind = self.prepared_transition_kind(step)?;
28024 let finish = self
28025 .steps
28026 .get_mut(&step.token)
28027 .expect("checked original step")
28028 .prepared
28029 .as_mut()
28030 .expect("prepared owner")
28031 .model_work
28032 .as_mut()
28033 .ok_or_else(|| {
28034 publication_input_error("prepared transition requires original model work")
28035 })
28036 .and_then(|work| work.finish_capture(bank).map_err(publication_input_error));
28037 if let Err(error) = finish {
28038 self.poisoned = true;
28039 return Err(error);
28040 }
28041 let owner = &self.steps[&step.token];
28042 let prepared = owner.prepared.as_ref().expect("prepared transition owner");
28043 let branch = &prepared.branches[bank];
28044 if prepared.transition_recorded & (1 << bank) != 0
28045 || prepared.model_content_recorded & (1 << bank) == 0
28046 || branch.continuation.is_none()
28047 || (kind == SemanticTransitionKind::Proposal && branch.policy.is_none())
28048 || (kind != SemanticTransitionKind::Proposal && branch.policy.is_some())
28049 || (kind == SemanticTransitionKind::Update
28050 && branch
28051 .model_update
28052 .as_ref()
28053 .is_none_or(|update| update.output.is_none()))
28054 {
28055 return Err(publication_input_error("prepared transition requires recorded branch model content, its unused original continuation, a policy only for proposals, and a bound model output for updates"));
28056 }
28057 let policy_witness = if kind == SemanticTransitionKind::Proposal {
28058 Some(branch.policy_witness.clone().ok_or_else(|| {
28059 publication_input_error("prepared transition has no original policy content")
28060 })?)
28061 } else {
28062 None
28063 };
28064 let continuation_witness = branch
28065 .continuation
28066 .as_ref()
28067 .expect("checked continuation")
28068 .text_binding
28069 ._witness
28070 .clone();
28071 if let Some(witness) = &policy_witness {
28072 self.record_prepared_tensor_content(step, witness, true)?;
28073 }
28074 self.record_prepared_tensor_content(step, &continuation_witness, true)?;
28075 let result = (|| {
28076 let prepared = self.steps[&step.token]
28077 .prepared
28078 .as_ref()
28079 .expect("retained original step");
28080 let branch = &prepared.branches[bank];
28081 branch
28082 .continuation
28083 .as_ref()
28084 .expect("checked original continuation")
28085 .enqueue(&self.domain, &mut self.poisoned)?;
28086 if let Some(update) = &branch.model_update {
28087 let training_view = prepared.training_view.as_ref().ok_or_else(|| {
28088 publication_input_error("prepared update has no native training view")
28089 })?;
28090 update.enqueue_copy(
28091 &self.domain,
28092 &mut self.poisoned,
28093 self.publication.as_ref().expect("prepared publication"),
28094 &prepared.reader,
28095 training_view,
28096 &self.task.as_ref().expect("prepared task binding").1,
28097 prepared
28098 .model_work
28099 .as_ref()
28100 .expect("prepared model work frozen above"),
28101 )?;
28102 }
28103 let io = self.prepared_kernel_io(step, bank)?;
28104 self.validate_ranges_with(&io)?;
28105 let descriptor = self.descriptor_with(&io);
28106 let recorder = self.kernel_recorder_with(&io);
28107 let execute = self.execute.clone();
28108 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
28109 unsafe {
28112 execute.launch_in(
28113 enqueue,
28114 LaunchConfig {
28115 grid_dim: (1, 1, 1),
28116 block_dim: (256, 1, 1),
28117 shared_mem_bytes: 0,
28118 },
28119 (descriptor,),
28120 )
28121 }
28122 .map_err(|error| XlogError::Kernel(error.to_string()))
28123 })
28124 })();
28125 if result.is_err() {
28126 self.poisoned = true;
28127 return result;
28128 }
28129 let prepared = self
28130 .steps
28131 .get_mut(&step.token)
28132 .expect("retained original step")
28133 .prepared
28134 .as_mut()
28135 .expect("retained original prepared step");
28136 prepared.transition_recorded |= 1 << bank;
28137 Ok(())
28138 }
28139
28140 #[cfg(feature = "semantic-policy")]
28143 pub fn enqueue_prepared_drain(
28144 &mut self,
28145 step: &SemanticPreparedStep,
28146 ) -> Result<(), SemanticTransitionError> {
28147 self.check_prepared_content_stream(step, self.stream.cu_stream() as u64)?;
28148 let prepared = self.steps[&step.token]
28149 .prepared
28150 .as_ref()
28151 .expect("prepared drain owner");
28152 if prepared.transition_recorded != PREPARED_TRANSITION_BANKS || prepared.drain_recorded {
28153 return Err(publication_input_error(
28154 "prepared drain requires its recorded requested branch and unused drain branch",
28155 ));
28156 }
28157 let publication = self.publication.as_ref().expect("prepared publication");
28158 let mut recorder = self.domain.new_strict_recorder();
28159 publication.record(&mut recorder);
28160 recorder.read(&prepared.reader);
28161 let arguments = (
28162 publication.control.device_ptr_value(),
28163 prepared.reader.device_ptr_value(),
28164 );
28165 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
28166 unsafe {
28169 prepared.drain_prepare.clone().launch_in(
28170 enqueue,
28171 LaunchConfig {
28172 grid_dim: (1, 1, 1),
28173 block_dim: (1, 1, 1),
28174 shared_mem_bytes: 0,
28175 },
28176 arguments,
28177 )
28178 }
28179 .map_err(|error| XlogError::Kernel(error.to_string()))
28180 })?;
28181 let io = self.prepared_drain_kernel_io(step)?;
28182 self.validate_ranges_with(&io)?;
28183 let descriptor = self.descriptor_with(&io);
28184 let recorder = self.kernel_recorder_with(&io);
28185 let execute = self.execute.clone();
28186 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
28187 unsafe {
28190 execute.launch_in(
28191 enqueue,
28192 LaunchConfig {
28193 grid_dim: (1, 1, 1),
28194 block_dim: (256, 1, 1),
28195 shared_mem_bytes: 0,
28196 },
28197 (descriptor,),
28198 )
28199 }
28200 .map_err(|error| XlogError::Kernel(error.to_string()))
28201 })?;
28202 self.steps
28203 .get_mut(&step.token)
28204 .expect("prepared drain owner")
28205 .prepared
28206 .as_mut()
28207 .expect("prepared drain storage")
28208 .drain_recorded = true;
28209 Ok(())
28210 }
28211
28212 #[cfg(feature = "semantic-policy")]
28215 fn take_prepared_policy_tape(
28216 &mut self,
28217 step: &SemanticPreparedStep,
28218 bank: usize,
28219 invocation: SemanticRngBinding,
28220 refusal: Option<SemanticTransitionRefusal>,
28221 ) -> Result<(), SemanticTransitionError> {
28222 if !Arc::ptr_eq(&step.issuer, &self.publication_issuer)
28223 || self
28224 .policy_tapes
28225 .iter()
28226 .any(|tape| tape.invocation == invocation)
28227 {
28228 return Err(publication_input_error(
28229 "observed prepared policy differs from its original Session or invocation",
28230 ));
28231 }
28232 let binding = self.binding();
28233 let prepared = self
28234 .steps
28235 .get_mut(&step.token)
28236 .and_then(|owner| owner.prepared.as_mut())
28237 .ok_or_else(|| {
28238 publication_input_error("observed prepared policy has no retained original step")
28239 })?;
28240 let transition_recorded = prepared.transition_recorded;
28241 let branch = prepared
28242 .branches
28243 .get_mut(bank)
28244 .ok_or(SemanticTransitionError::ObservationMismatch)?;
28245 if transition_recorded != PREPARED_TRANSITION_BANKS
28246 || branch.policy.is_none()
28247 || branch.support.is_none()
28248 || branch.receipts.is_none()
28249 {
28250 return Err(publication_input_error(
28251 "observed prepared policy was not recorded or has already retired",
28252 ));
28253 }
28254 branch
28257 .policy
28258 .as_mut()
28259 .expect("checked original policy")
28260 .tape_live = true;
28261 self.policy_tapes.push(PolicyTape {
28262 invocation,
28263 refusal,
28264 binding,
28265 policy: branch.policy.take().expect("checked original policy"),
28266 support: branch.support.take().expect("checked original support"),
28267 receipts: branch.receipts.take().expect("checked original receipts"),
28268 prepared_bank: Some(bank),
28269 origin_state: None,
28270 components: self.device_components.view(),
28271 codebooks: self.device_codebooks.view(),
28272 });
28273 Ok(())
28274 }
28275
28276 #[cfg(feature = "semantic-policy")]
28277 #[expect(
28278 clippy::too_many_arguments,
28279 reason = "one original policy snapshot carries all values and numerical owners"
28280 )]
28281 fn bind_policy_views(
28282 &mut self,
28283 binding: SemanticCatalogueBinding,
28284 rng: SemanticRngBinding,
28285 text_logits: DeviceMemoryView<f32>,
28286 product_support: DeviceMemoryView<u8>,
28287 parameters: DeviceMemoryView<f32>,
28288 component_baselines: DeviceMemoryView<f32>,
28289 numerical: [DeviceMemoryView<f64>; 5],
28290 policy_witness: Option<(SemanticTensorContentWitness, u64)>,
28291 ) -> Result<(), SemanticTransitionError> {
28292 self.ensure_rebindable()?;
28293 if binding != self.binding() {
28294 return Err(SemanticTransitionError::CatalogueMismatch);
28295 }
28296 let layout = self.policy_layout()?;
28297 if self.pending_policy.is_some() {
28298 return Err(publication_input_error(
28299 "policy already owns its original snapshots",
28300 ));
28301 }
28302 match (self.text_binding.as_ref(), policy_witness.as_ref()) {
28303 (Some(binding), _) if self.continuation_base.is_some() => {
28304 if rng != binding.published_parent()?.1.rng_binding()? {
28305 return Err(publication_input_error(
28306 "policy invocation differs from its actual acquired parent",
28307 ));
28308 }
28309 }
28310 (None, Some((witness, _)))
28311 if self.admitted_transition.is_some_and(|(token, _, kind)| {
28312 token == witness.reader_token && kind == SemanticTransitionKind::Proposal
28313 }) => {}
28314 _ => {
28315 return Err(publication_input_error(
28316 "policy snapshots require their original parent witness or continuation",
28317 ));
28318 }
28319 }
28320 let text_cells = 32 * TEXT_CARDINALITY;
28321 let support_cells = self.codebooks.input_cells;
28322 if self
28323 .admitted_transition
28324 .is_none_or(|(_, _, kind)| kind != SemanticTransitionKind::Proposal)
28325 || self.policy_tapes.iter().any(|tape| tape.invocation == rng)
28326 {
28327 return Err(publication_input_error(
28328 "policy binding requires a fresh admitted proposal invocation",
28329 ));
28330 }
28331 if rng.stream_serial >= (1u64 << 56)
28332 || text_logits.len() != text_cells
28333 || product_support.len() != support_cells
28334 || parameters.len() != layout.parameter_cells
28335 || component_baselines.len() != COMPONENT_COUNT
28336 {
28337 return Err(SemanticTransitionError::InvalidInput {
28338 detail:
28339 "policy input shape or stream namespace does not match the native catalogue"
28340 .into(),
28341 });
28342 }
28343 let policy = PendingPolicyStorage {
28344 witness: policy_witness,
28345 replacement: PolicyReplacement {
28349 support: allocate_publication(&self.provider, self.codebooks.input_cells)?,
28350 receipts: allocate_publication(&self.provider, COMPONENT_COUNT)?,
28351 state: allocate_publication(&self.provider, 1)?,
28352 },
28353 buffers: self.allocate_policy_buffers()?,
28354 invocation: rng,
28355 };
28356 self.captured = None;
28359 self.rng = None;
28360 self.pending_policy = Some(policy);
28361 let policy = self
28362 .pending_policy
28363 .as_ref()
28364 .expect("policy storage installed above");
28365 enqueue_policy_snapshots(
28366 &self.domain,
28367 &mut self.poisoned,
28368 &policy.buffers,
28369 &self.support,
28370 &PolicyProducerViews {
28371 text_logits,
28372 product_support,
28373 parameters,
28374 component_baselines,
28375 numerical,
28376 },
28377 )?;
28378 enqueue_policy_uniform_domains(
28379 &self.domain,
28380 &mut self.poisoned,
28381 &policy.buffers,
28382 &self.device_components,
28383 &self.support,
28384 )?;
28385 let consumer_stream = policy.witness.as_ref().map(|(_, stream)| *stream);
28386 if let Some(stream) = consumer_stream {
28387 if let Err(error) = self.order_content_consumers(stream) {
28388 self.poisoned = true;
28389 return Err(error);
28390 }
28391 }
28392 self.attach_policy_continuation()
28393 }
28394
28395 #[cfg(feature = "semantic-policy")]
28396 fn attach_policy_continuation(&mut self) -> Result<(), SemanticTransitionError> {
28397 let Some(snapshot) = self.pending_policy.as_ref() else {
28398 return Ok(());
28399 };
28400 let Some(original) = self
28401 .text_binding
28402 .as_ref()
28403 .filter(|_| self.continuation_base.is_some())
28404 .map(Arc::clone)
28405 else {
28406 return Ok(());
28407 };
28408 let rng = snapshot.invocation;
28409 if rng != original.published_parent()?.1.rng_binding()?
28410 || snapshot
28411 .witness
28412 .as_ref()
28413 .is_some_and(|(witness, _)| witness.reader_token != original._witness.reader_token)
28414 {
28415 return Err(publication_input_error(
28416 "policy snapshots and continuation belong to different original parents",
28417 ));
28418 }
28419 let witness = snapshot.witness.clone();
28422 if let Some((witness, stream)) = &witness {
28423 self.enqueue_content_witness(witness, *stream, true)?;
28424 }
28425 self.guard_continuation_content(&original)?;
28426 let snapshot = self
28427 .pending_policy
28428 .take()
28429 .expect("checked original policy snapshots");
28430 self.policy = Some(PolicyStorage {
28431 buffers: snapshot.buffers,
28432 replacement: Some(snapshot.replacement),
28433 _policy_witness: witness.map(|(witness, _)| witness),
28434 text_binding: Arc::clone(&original),
28435 tape_live: false,
28436 temporal_vjp_recorded: BTreeSet::new(),
28437 });
28438 self.validate_ranges()?;
28439 if let Err(error) = self.order_content_consumers(original.consumer_stream) {
28440 self.poisoned = true;
28441 return Err(error);
28442 }
28443 self.rng = Some(rng);
28444 self.next_proposal = u64::from(rng.proposal);
28445 Ok(())
28446 }
28447
28448 #[cfg(feature = "semantic-policy")]
28459 pub fn backward_policy(
28460 &mut self,
28461 invocation: SemanticRngBinding,
28462 score_cotangents: &TrackedCudaSlice<f64>,
28463 ) -> Result<SemanticPolicyGradients, SemanticTransitionError> {
28464 self.backward_policy_view(invocation, score_cotangents.view(), 1)
28465 }
28466
28467 #[cfg(feature = "semantic-policy")]
28471 pub fn backward_policy_dlpack(
28472 &mut self,
28473 invocation: SemanticRngBinding,
28474 score_cotangents: DlpackManagedTensor,
28475 consumer_stream: u64,
28476 ) -> Result<SemanticPolicyGradients, SemanticTransitionError> {
28477 let mut handoff = RetainedTensorAdmission {
28478 inputs: Some(vec![score_cotangents]),
28479 stream: Arc::clone(self.provider.device().inner().stream()),
28480 ready: false,
28481 };
28482 dlpack_consumer_stream(consumer_stream)?;
28483 let pointer = handoff
28484 .inputs
28485 .as_ref()
28486 .expect("retained cotangent producer")[0]
28487 .as_ptr();
28488 if pointer.is_null() {
28489 return Err(publication_input_error(
28490 "selected-score cotangent managed owner is null",
28491 ));
28492 }
28493 let (data, bytes) = unsafe {
28496 policy_score_cotangent_metadata(
28497 &(*pointer).dl_tensor,
28498 self.provider.device().ordinal() as i32,
28499 )
28500 }?;
28501 handoff.ready = true;
28502 let tensor = handoff
28503 .inputs
28504 .take()
28505 .expect("retained cotangent producer")
28506 .pop()
28507 .expect("one cotangent");
28508 let bytes = unsafe { CudaColumn::dlpack(data, bytes, Arc::clone(&handoff.stream), tensor) }
28511 .device_view();
28512 let values = unsafe { bytes.cast::<f64>() }.ok_or_else(|| {
28515 publication_input_error("selected-score cotangent span is not aligned F64 storage")
28516 })?;
28517 self.backward_policy_view(invocation, values, consumer_stream)
28518 }
28519
28520 #[cfg(feature = "semantic-policy")]
28521 fn checked_prepared_policy_tape(
28522 &self,
28523 step: &SemanticPreparedStep,
28524 invocation: SemanticRngBinding,
28525 ) -> Result<usize, SemanticTransitionError> {
28526 let owner = self.checked_prepared_step(step, false)?;
28527 if !self
28528 .prepared_segment
28529 .as_ref()
28530 .is_some_and(|build| build.completed)
28531 || !owner
28532 .prepared
28533 .as_ref()
28534 .is_some_and(|prepared| prepared.observed)
28535 {
28536 return Err(publication_input_error(
28537 "prepared policy requires its actual completed native outcome",
28538 ));
28539 }
28540 self.policy_tapes
28541 .iter()
28542 .position(|tape| {
28543 tape.invocation == invocation
28544 && tape.policy.text_binding._witness.reader_token == step.token
28545 })
28546 .ok_or_else(|| {
28547 publication_input_error(
28548 "prepared policy has no unconsumed original tape for this step",
28549 )
28550 })
28551 }
28552
28553 #[cfg(feature = "semantic-policy")]
28556 fn completed_prepared_policy_tape(
28557 &mut self,
28558 step: &SemanticPreparedStep,
28559 ) -> Result<usize, SemanticTransitionError> {
28560 let header_view = self
28561 .checked_prepared_step(step, false)?
28562 .inputs
28563 .as_ref()
28564 .ok_or(SemanticTransitionError::ObservationMismatch)?
28565 .header
28566 .view();
28567 let parent = self.publication_read(header_view)?[0];
28568 let index = self.checked_prepared_policy_tape(step, parent.rng_binding()?)?;
28569 let tape = &self.policy_tapes[index];
28570 if tape.prepared_bank != Some((parent.publication_word & 1) as usize)
28573 || tape.refusal.is_some()
28574 {
28575 return Err(SemanticTransitionError::ObservationMismatch);
28576 }
28577 Ok(index)
28578 }
28579
28580 #[cfg(feature = "semantic-policy")]
28583 pub fn require_prepared_policy_invocation(
28584 &self,
28585 step: &SemanticPreparedStep,
28586 invocation: SemanticRngBinding,
28587 ) -> Result<usize, SemanticTransitionError> {
28588 let index = self.checked_prepared_policy_tape(step, invocation)?;
28589 self.policy_tapes[index]
28590 .prepared_bank
28591 .ok_or(SemanticTransitionError::ObservationMismatch)
28592 }
28593
28594 #[cfg(feature = "semantic-policy")]
28596 pub fn backward_prepared_policy_dlpack(
28597 &mut self,
28598 step: &SemanticPreparedStep,
28599 invocation: SemanticRngBinding,
28600 score_cotangents: DlpackManagedTensor,
28601 consumer_stream: u64,
28602 ) -> Result<SemanticPolicyGradients, SemanticTransitionError> {
28603 self.checked_prepared_policy_tape(step, invocation)?;
28604 self.backward_policy_dlpack(invocation, score_cotangents, consumer_stream)
28605 }
28606
28607 #[cfg(feature = "semantic-policy")]
28613 pub fn backward_selected_prepared_policy(
28614 &mut self,
28615 step: &SemanticPreparedStep,
28616 update_step: &SemanticPreparedStep,
28617 invocation: SemanticRngBinding,
28618 consumer_stream: u64,
28619 ) -> Result<SemanticSelectedPolicyGradients, SemanticTransitionError> {
28620 self.ensure_quiescent()?;
28621 dlpack_consumer_stream(consumer_stream)?;
28622 let tape_index = self.checked_prepared_policy_tape(step, invocation)?;
28623 if let Some(refusal) = self.policy_tapes[tape_index].refusal {
28624 return Err(refusal.into_error());
28625 }
28626 let update_owner = self.checked_prepared_step(update_step, false)?;
28627 let build = self
28628 .prepared_segment
28629 .as_ref()
28630 .expect("checked prepared segment");
28631 if !build.completed
28632 || !update_owner
28633 .prepared
28634 .as_ref()
28635 .is_some_and(|prepared| prepared.observed)
28636 {
28637 return Err(publication_input_error(
28638 "selected policy backward requires the actual completed Update step",
28639 ));
28640 }
28641 if build.requested_kind(update_step, &self.publication_issuer)?
28642 != SemanticTransitionKind::Update
28643 {
28644 return Err(publication_input_error(
28645 "selected policy backward requires a prepared Update step",
28646 ));
28647 }
28648 let origin_candidate = build
28649 .tokens
28650 .iter()
28651 .position(|token| *token == step.token)
28652 .ok_or(SemanticTransitionError::ObservationMismatch)?;
28653 let update_ordinal = build
28654 .tokens
28655 .iter()
28656 .position(|token| *token == update_step.token)
28657 .ok_or(SemanticTransitionError::ObservationMismatch)?;
28658 if origin_candidate >= update_ordinal {
28659 return Err(publication_input_error(
28660 "selected policy backward requires a preceding proposal candidate",
28661 ));
28662 }
28663 let origin_candidate = u64::try_from(origin_candidate)
28664 .map_err(|_| SemanticTransitionError::GenerationExhausted)?;
28665 let original = Arc::clone(&self.policy_tapes[tape_index].policy.text_binding);
28666 self.guard_continuation_content(&original)?;
28667 if let Err(error) =
28668 self.order_step_content_inputs(original._witness.reader_token, consumer_stream)
28669 {
28670 self.poisoned = true;
28671 return Err(error);
28672 }
28673 let publication = Arc::clone(
28674 self.publication
28675 .as_ref()
28676 .ok_or(SemanticTransitionError::NotBound)?,
28677 );
28678 let step_aliases = Arc::clone(&self.steps[&original._witness.reader_token].aliases);
28679 let tape = &self.policy_tapes[tape_index];
28680 let policy = &tape.policy;
28681 let state = tape.prepared_bank.map_or(&self.state, |bank| {
28682 &self.steps[&original._witness.reader_token]
28683 .prepared
28684 .as_ref()
28685 .expect("checked prepared policy owner")
28686 .branches[bank]
28687 .state
28688 });
28689 let training = self.steps[&update_step.token]
28690 .prepared
28691 .as_ref()
28692 .expect("checked prepared Update owner")
28693 .training_view
28694 .as_ref()
28695 .ok_or_else(|| {
28696 publication_input_error(
28697 "selected policy backward requires the Update training-view owner",
28698 )
28699 })?;
28700 let origin_bank = tape.prepared_bank.ok_or_else(|| {
28701 publication_input_error("selected policy backward requires a prepared policy bank")
28702 })?;
28703 let origin_lease = &self.steps[&original._witness.reader_token]
28704 .prepared
28705 .as_ref()
28706 .expect("checked prepared policy owner")
28707 .reader;
28708 let PolicyVjpRecording {
28709 descriptor,
28710 recorder,
28711 } = self.prepare_policy_vjp_recording(
28712 policy,
28713 policy.buffers.adjoints.as_ref().ok_or_else(|| {
28714 publication_input_error("original policy adjoint banks have already been consumed")
28715 })?,
28716 &tape.support,
28717 &tape.receipts,
28718 state,
28719 &tape.components,
28720 &tape.codebooks,
28721 PolicyVjpInput::UpdateObjective {
28722 training,
28723 origin_candidate,
28724 origin_lease,
28725 origin_bank,
28726 },
28727 )?;
28728 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
28729 .map_err(|error| runtime_error("selected policy backward stream admission", error))?;
28730 let execute = self.execute.clone();
28731 let layout = policy.layout.clone();
28732 let binding = tape.binding;
28733 let support_cells = tape.support.len();
28734 let baseline_snapshot = policy.component_baselines.view();
28735 let PolicyAdjointBuffers {
28736 parameters,
28737 text_logits,
28738 component_baselines,
28739 recurrent,
28740 scores,
28741 coefficients,
28742 status,
28743 numerical,
28744 } = self.policy_tapes[tape_index]
28745 .policy
28746 .buffers
28747 .adjoints
28748 .take()
28749 .expect("checked original adjoint banks");
28750 let vjp_workspace = Arc::new(PolicyVjpWorkspace {
28751 _numerical: Arc::clone(&numerical),
28752 _component_baselines: None,
28753 _recurrent: recurrent,
28754 _scores: scores,
28755 coefficients,
28756 _status: status,
28757 score_cotangents: None,
28758 });
28759 let output_views = [¶meters, &text_logits, &component_baselines]
28760 .into_iter()
28761 .map(|buffer| {
28762 unsafe { buffer.view().cast::<u8>() }.expect("F32 adjoint byte view")
28764 });
28765 let step_owner = self
28766 .steps
28767 .get_mut(&original._witness.reader_token)
28768 .expect("retained original step");
28769 step_owner.adjoints.extend(output_views);
28770 step_owner
28771 .policy_vjp_workspaces
28772 .push(Arc::clone(&vjp_workspace));
28773 record_policy_vjp(
28774 &self.domain,
28775 &mut self.poisoned,
28776 recorder,
28777 execute,
28778 descriptor,
28779 &vjp_workspace.coefficients,
28780 None,
28781 Some(&baseline_snapshot),
28782 )?;
28783 if let Err(error) = self.order_content_consumers(consumer_stream) {
28784 self.poisoned = true;
28785 return Err(error);
28786 }
28787 self.policy_tapes.remove(tape_index);
28788 Ok(SemanticSelectedPolicyGradients {
28789 numerical,
28790 binding,
28791 invocation,
28792 layout,
28793 parameters,
28794 text_logits,
28795 component_baselines,
28796 provider: Arc::clone(&self.provider),
28797 step_aliases,
28798 publication,
28799 continuation: original,
28800 vjp_workspace,
28801 support_cells,
28802 })
28803 }
28804
28805 #[cfg(feature = "semantic-policy")]
28806 pub fn record_prepared_update_policy_vjp(
28810 &mut self,
28811 step: &SemanticPreparedStep,
28812 bank: usize,
28813 update_step: &SemanticPreparedStep,
28814 consumer_stream: u64,
28815 ) -> Result<SemanticPreparedPolicyGradients, SemanticTransitionError> {
28816 self.record_prepared_policy_vjp(step, bank, update_step, None, false, consumer_stream)
28817 }
28818
28819 #[cfg(feature = "semantic-policy")]
28823 pub fn record_prepared_group_member_policy_vjp(
28824 &mut self,
28825 step: &SemanticPreparedStep,
28826 bank: usize,
28827 update_step: &SemanticPreparedStep,
28828 member_ordinal: u64,
28829 member_row: &SemanticTrainingViewRow,
28830 consumer_stream: u64,
28831 ) -> Result<SemanticPreparedPolicyGradients, SemanticTransitionError> {
28832 self.record_prepared_policy_vjp(
28833 step,
28834 bank,
28835 update_step,
28836 Some((member_ordinal, member_row)),
28837 false,
28838 consumer_stream,
28839 )
28840 }
28841
28842 #[cfg(feature = "semantic-policy")]
28845 pub fn record_prepared_policy_group_vjp(
28846 &mut self,
28847 step: &SemanticPreparedStep,
28848 bank: usize,
28849 update_step: &SemanticPreparedStep,
28850 member_ordinal: u64,
28851 member_row: &SemanticTrainingViewRow,
28852 consumer_stream: u64,
28853 ) -> Result<SemanticPreparedPolicyGradients, SemanticTransitionError> {
28854 let actor_member = self
28855 .steps
28856 .get(&update_step.token)
28857 .and_then(|step| step.prepared.as_ref())
28858 .and_then(|step| step.training_view.as_ref())
28859 .ok_or_else(|| publication_input_error("Update has no selected training view"))?
28860 .actor_group_members()
28861 .iter()
28862 .any(|member| member.ordinal == member_ordinal);
28863 if actor_member {
28864 self.record_prepared_group_member_policy_vjp(
28865 step,
28866 bank,
28867 update_step,
28868 member_ordinal,
28869 member_row,
28870 consumer_stream,
28871 )
28872 } else {
28873 self.record_prepared_edit_member_policy_vjp(
28874 step,
28875 bank,
28876 update_step,
28877 member_ordinal,
28878 member_row,
28879 consumer_stream,
28880 )
28881 }
28882 }
28883
28884 #[cfg(feature = "semantic-policy")]
28887 pub fn record_prepared_edit_member_policy_vjp(
28888 &mut self,
28889 step: &SemanticPreparedStep,
28890 bank: usize,
28891 update_step: &SemanticPreparedStep,
28892 member_ordinal: u64,
28893 member_row: &SemanticTrainingViewRow,
28894 consumer_stream: u64,
28895 ) -> Result<SemanticPreparedPolicyGradients, SemanticTransitionError> {
28896 self.record_prepared_policy_vjp(
28897 step,
28898 bank,
28899 update_step,
28900 Some((member_ordinal, member_row)),
28901 true,
28902 consumer_stream,
28903 )
28904 }
28905
28906 #[cfg(feature = "semantic-policy")]
28907 fn record_prepared_policy_vjp(
28908 &mut self,
28909 step: &SemanticPreparedStep,
28910 bank: usize,
28911 update_step: &SemanticPreparedStep,
28912 member: Option<(u64, &SemanticTrainingViewRow)>,
28913 edit_only: bool,
28914 consumer_stream: u64,
28915 ) -> Result<SemanticPreparedPolicyGradients, SemanticTransitionError> {
28916 dlpack_consumer_stream(consumer_stream)?;
28917 self.check_prepared_content_stream(update_step, consumer_stream)?;
28918 if bank > 1 {
28919 return Err(publication_input_error(
28920 "temporal policy backward requires proposal bank zero or one",
28921 ));
28922 }
28923 let build = self
28924 .prepared_segment
28925 .as_ref()
28926 .ok_or_else(|| publication_input_error("no prepared segment is being recorded"))?;
28927 if build.completed
28928 || build.requested_kind(step, &self.publication_issuer)?
28929 != SemanticTransitionKind::Proposal
28930 || build.requested_kind(update_step, &self.publication_issuer)?
28931 != SemanticTransitionKind::Update
28932 {
28933 return Err(publication_input_error(
28934 "temporal policy backward requires a preceding Proposal and the recording Update",
28935 ));
28936 }
28937 let origin_candidate = build
28938 .tokens
28939 .iter()
28940 .position(|token| *token == step.token)
28941 .ok_or(SemanticTransitionError::ObservationMismatch)?;
28942 let update_ordinal = build
28943 .tokens
28944 .iter()
28945 .position(|token| *token == update_step.token)
28946 .ok_or(SemanticTransitionError::ObservationMismatch)?;
28947 if origin_candidate >= update_ordinal {
28948 return Err(publication_input_error(
28949 "temporal policy backward requires a preceding proposal candidate",
28950 ));
28951 }
28952 let origin_candidate = u64::try_from(origin_candidate)
28953 .map_err(|_| SemanticTransitionError::GenerationExhausted)?;
28954 let update = self.steps[&update_step.token]
28955 .prepared
28956 .as_ref()
28957 .expect("checked prepared Update owner");
28958 let update_capture_bank = update
28959 .model_work
28960 .as_ref()
28961 .and_then(|work| work.capture_bank)
28962 .ok_or_else(|| {
28963 publication_input_error(
28964 "temporal policy backward requires an active Update bank capture",
28965 )
28966 })?;
28967 if update_capture_bank > 1 {
28968 return Err(publication_input_error(
28969 "temporal policy backward has an invalid Update capture bank",
28970 ));
28971 }
28972 let training = update.training_view.as_ref().ok_or_else(|| {
28973 publication_input_error("prepared Update has no selected training-view owner")
28974 })?;
28975 let member_index = if edit_only {
28976 None
28977 } else {
28978 member
28979 .map(|(ordinal, row)| training.actor_group_member_index(ordinal, row))
28980 .transpose()?
28981 };
28982 let edit_member = member
28983 .map(|(ordinal, row)| training.edit_group_member_index(ordinal, row))
28984 .transpose()?
28985 .flatten()
28986 .is_some();
28987 if let Some((ordinal, _)) = member {
28988 if edit_only
28989 && (!edit_member
28990 || training
28991 .actor_group_members()
28992 .iter()
28993 .any(|row| row.ordinal == ordinal))
28994 {
28995 return Err(publication_input_error(
28996 "edit-only VJP requires a frozen edit row outside the actor group",
28997 ));
28998 }
28999 if update.group_critic_recorded & (1 << update_capture_bank) != 0
29000 || (edit_only && update.group_edit_members[update_capture_bank].contains(&ordinal))
29001 || (!edit_only && update.group_vjp_members[update_capture_bank].contains(&ordinal))
29002 {
29003 return Err(publication_input_error(
29004 "prepared actor group member already contributed to this Update bank",
29005 ));
29006 }
29007 }
29008 let critic_term = member_index.map(|index| training.critic_term(index));
29009 let proposal = self.steps[&step.token]
29010 .prepared
29011 .as_ref()
29012 .expect("checked prepared Proposal owner");
29013 if proposal.transition_recorded & (1 << bank) == 0 {
29014 return Err(publication_input_error(
29015 "temporal policy backward requires the recorded original Proposal branch",
29016 ));
29017 }
29018 let branch = &proposal.branches[bank];
29019 let policy = branch.policy.as_ref().ok_or_else(|| {
29020 publication_input_error("prepared Proposal bank has no bound policy tape")
29021 })?;
29022 let update_capture = (update_step.token, update_capture_bank);
29023 if policy.temporal_vjp_recorded.contains(&update_capture) {
29024 return Err(publication_input_error(
29025 "prepared Proposal bank already recorded this Update capture's policy VJP",
29026 ));
29027 }
29028 let support = branch.support.as_ref().ok_or_else(|| {
29029 publication_input_error("prepared Proposal bank has no policy support")
29030 })?;
29031 let receipts = branch.receipts.as_ref().ok_or_else(|| {
29032 publication_input_error("prepared Proposal bank has no policy receipts")
29033 })?;
29034 let components = self.device_components.view();
29035 let codebooks = self.device_codebooks.view();
29036 let owner = Arc::clone(&policy.buffers.temporal_adjoints);
29037 let PolicyVjpRecording {
29038 descriptor,
29039 recorder,
29040 } = self.prepare_policy_vjp_recording(
29041 policy,
29042 &owner,
29043 support,
29044 receipts,
29045 &branch.state,
29046 &components,
29047 &codebooks,
29048 if let (Some((member_ordinal, _)), true) = (member, edit_only) {
29049 PolicyVjpInput::EditMember {
29050 training,
29051 member_ordinal,
29052 origin_candidate,
29053 origin_lease: &proposal.reader,
29054 origin_bank: bank,
29055 }
29056 } else if let (Some((member_ordinal, _)), Some(critic_term)) = (member, &critic_term) {
29057 PolicyVjpInput::GroupMember {
29058 training,
29059 member_ordinal,
29060 origin_candidate,
29061 origin_lease: &proposal.reader,
29062 origin_bank: bank,
29063 critic_term,
29064 }
29065 } else {
29066 PolicyVjpInput::UpdateObjective {
29067 training,
29068 origin_candidate,
29069 origin_lease: &proposal.reader,
29070 origin_bank: bank,
29071 }
29072 },
29073 )?;
29074 let baseline_snapshot = policy.component_baselines.view();
29075 let layout = policy.layout.clone();
29076 let continuation = Arc::clone(&policy.text_binding);
29077 let support_cells = support.len();
29078 let parameters = owner.parameters.view();
29079 let text_logits = owner.text_logits.view();
29080 let component_baselines = owner.component_baselines.view();
29081 let step_aliases = Arc::clone(&self.steps[&step.token].aliases);
29082 let publication = Arc::clone(
29083 self.publication
29084 .as_ref()
29085 .ok_or(SemanticTransitionError::NotBound)?,
29086 );
29087 record_policy_vjp(
29088 &self.domain,
29089 &mut self.poisoned,
29090 recorder,
29091 self.execute.clone(),
29092 descriptor,
29093 &owner.coefficients,
29094 None,
29095 Some(&baseline_snapshot),
29096 )?;
29097 self.steps
29098 .get_mut(&step.token)
29099 .expect("checked prepared Proposal owner")
29100 .prepared
29101 .as_mut()
29102 .expect("checked prepared Proposal")
29103 .branches[bank]
29104 .policy
29105 .as_mut()
29106 .expect("checked prepared policy tape")
29107 .temporal_vjp_recorded
29108 .insert(update_capture);
29109 if let Some((member_ordinal, _)) = member {
29110 let update = self
29111 .steps
29112 .get_mut(&update_step.token)
29113 .expect("checked prepared Update owner")
29114 .prepared
29115 .as_mut()
29116 .expect("checked prepared Update");
29117 if !edit_only {
29118 update.group_vjp_members[update_capture_bank].insert(member_ordinal);
29119 }
29120 if edit_member {
29121 update.group_edit_members[update_capture_bank].insert(member_ordinal);
29122 }
29123 }
29124 Ok(SemanticPreparedPolicyGradients {
29125 layout,
29126 parameters,
29127 text_logits,
29128 component_baselines,
29129 provider: Arc::clone(&self.provider),
29130 step_aliases,
29131 publication,
29132 continuation,
29133 owner,
29134 support_cells,
29135 })
29136 }
29137
29138 #[cfg(feature = "semantic-policy")]
29143 pub fn record_prepared_group_critic(
29144 &mut self,
29145 update_step: &SemanticPreparedStep,
29146 bank: usize,
29147 consumer_stream: u64,
29148 ) -> Result<SemanticPreparedGroupCritic, SemanticTransitionError> {
29149 dlpack_consumer_stream(consumer_stream)?;
29150 self.check_prepared_content_stream(update_step, consumer_stream)?;
29151 if bank > 1 {
29152 return Err(publication_input_error(
29153 "group critic requires bank zero or one",
29154 ));
29155 }
29156 let build = self
29157 .prepared_segment
29158 .as_ref()
29159 .ok_or_else(|| publication_input_error("group critic requires a prepared segment"))?;
29160 if build.completed
29161 || build.requested_kind(update_step, &self.publication_issuer)?
29162 != SemanticTransitionKind::Update
29163 {
29164 return Err(publication_input_error(
29165 "group critic requires the recording Update step",
29166 ));
29167 }
29168 let prepared = self.steps[&update_step.token]
29169 .prepared
29170 .as_ref()
29171 .expect("checked prepared Update owner");
29172 if prepared
29173 .model_work
29174 .as_ref()
29175 .and_then(|work| work.capture_bank)
29176 != Some(bank)
29177 || prepared.group_critic_recorded & (1 << bank) != 0
29178 {
29179 return Err(publication_input_error(
29180 "group critic requires one active, not yet reduced Update bank",
29181 ));
29182 }
29183 let training = prepared.training_view.as_ref().ok_or_else(|| {
29184 publication_input_error("prepared Update has no selected training-view owner")
29185 })?;
29186 let actor_members = training
29187 .actor_group_members()
29188 .iter()
29189 .map(|member| member.ordinal)
29190 .collect::<BTreeSet<_>>();
29191 if prepared.group_vjp_members[bank] != actor_members {
29192 return Err(publication_input_error(
29193 "group critic requires every frozen actor member exactly once",
29194 ));
29195 }
29196 let edit_members = training
29197 .edit_group_members()
29198 .iter()
29199 .map(|member| member.ordinal)
29200 .collect::<BTreeSet<_>>();
29201 if prepared.group_edit_members[bank] != edit_members {
29202 return Err(publication_input_error(
29203 "group critic requires every frozen edit member exactly once",
29204 ));
29205 }
29206 let terms = training.critic_terms();
29207 let total = training.critic_total();
29208 let objective = training.objective();
29209 let count = u64::try_from(training.actor_group_members().len())
29210 .map_err(|_| SemanticTransitionError::GenerationExhausted)?;
29211 let reduce = self
29212 .provider
29213 .device()
29214 .inner()
29215 .get_func("xlog_semantic_transition", "semantic_group_critic_reduce")
29216 .ok_or_else(|| publication_input_error("group critic reducer is unavailable"))?;
29217 let mut recorder = self.domain.new_strict_recorder();
29218 recorder.read(&terms);
29219 recorder.read(&objective);
29220 recorder.write(&total);
29221 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
29222 unsafe {
29225 reduce
29226 .launch_in(
29227 enqueue,
29228 LaunchConfig {
29229 grid_dim: (1, 1, 1),
29230 block_dim: (1, 1, 1),
29231 shared_mem_bytes: 0,
29232 },
29233 (
29234 *terms.device_ptr(),
29235 *total.device_ptr(),
29236 count,
29237 *objective.device_ptr(),
29238 ),
29239 )
29240 .map_err(|error| XlogError::Kernel(format!("group critic reduction: {error}")))
29241 }
29242 })?;
29243 self.steps
29244 .get_mut(&update_step.token)
29245 .expect("checked prepared Update owner")
29246 .prepared
29247 .as_mut()
29248 .expect("checked prepared Update")
29249 .group_critic_recorded |= 1 << bank;
29250 Ok(SemanticPreparedGroupCritic {
29251 value: total,
29252 provider: Arc::clone(&self.provider),
29253 step_aliases: Arc::clone(&self.steps[&update_step.token].aliases),
29254 publication: Arc::clone(
29255 self.publication
29256 .as_ref()
29257 .ok_or(SemanticTransitionError::NotBound)?,
29258 ),
29259 })
29260 }
29261
29262 #[cfg(feature = "semantic-policy")]
29263 pub fn require_recorded_group_critic(
29264 &self,
29265 update_step: &SemanticPreparedStep,
29266 ) -> Result<(), SemanticTransitionError> {
29267 if self.is_poisoned() {
29268 return Err(SemanticTransitionError::Poisoned);
29269 }
29270 let step = self.checked_prepared_step(update_step, false)?;
29271 let prepared = step.prepared.as_ref().expect("checked prepared owner");
29272 if !self
29273 .prepared_segment
29274 .as_ref()
29275 .is_some_and(|build| build.completed)
29276 || prepared.training_view.is_none()
29277 || prepared.group_critic_recorded != 0b11
29278 || !prepared.group_update_published
29279 {
29280 return Err(publication_input_error(
29281 "retained group member requires completed execution of both full-group Update banks",
29282 ));
29283 }
29284 Ok(())
29285 }
29286
29287 #[cfg(feature = "semantic-policy")]
29290 pub fn require_completed_unpublished_group_update(
29291 &self,
29292 update_step: &SemanticPreparedStep,
29293 ) -> Result<(), SemanticTransitionError> {
29294 if self.is_poisoned() {
29295 return Err(SemanticTransitionError::Poisoned);
29296 }
29297 let step = self.checked_prepared_step(update_step, false)?;
29298 let build = self
29299 .prepared_segment
29300 .as_ref()
29301 .ok_or(SemanticTransitionError::NotBound)?;
29302 if !build.completed
29303 || build.requested_kind(update_step, &self.publication_issuer)?
29304 != SemanticTransitionKind::Update
29305 || step
29306 .prepared
29307 .as_ref()
29308 .expect("checked prepared owner")
29309 .group_update_published
29310 {
29311 return Err(publication_input_error(
29312 "retained replay requires a completed Update that did not publish",
29313 ));
29314 }
29315 Ok(())
29316 }
29317
29318 #[cfg(feature = "semantic-policy")]
29323 pub fn require_retired_prepared_step(
29324 &self,
29325 step: &SemanticPreparedStep,
29326 ) -> Result<(), SemanticTransitionError> {
29327 if self.is_poisoned() {
29328 return Err(SemanticTransitionError::Poisoned);
29329 }
29330 if !Arc::ptr_eq(&step.issuer, &self.publication_issuer)
29331 || self.prepared_segment.is_some()
29332 || self.captured.is_some()
29333 || self.pending
29334 || !self.prepared_resources.is_empty()
29335 || self.steps.contains_key(&step.token)
29336 {
29337 return Err(publication_input_error(
29338 "retained source requires completed retirement of its target segment",
29339 ));
29340 }
29341 Ok(())
29342 }
29343
29344 #[cfg(feature = "semantic-policy")]
29348 #[expect(
29349 clippy::too_many_arguments,
29350 reason = "the frozen target and original published invocation have distinct owners"
29351 )]
29352 pub fn record_imported_group_member_policy_vjp(
29353 &mut self,
29354 update_step: &SemanticPreparedStep,
29355 bank: usize,
29356 source: &mut SemanticTransitionSession,
29357 source_lease: &SemanticPublishedLease,
29358 invocation: SemanticRngBinding,
29359 member_ordinal: u64,
29360 member_row: &SemanticTrainingViewRow,
29361 consumer_stream: u64,
29362 ) -> Result<SemanticPreparedPolicyGradients, SemanticTransitionError> {
29363 self.record_imported_policy_vjp(
29364 update_step,
29365 bank,
29366 source,
29367 source_lease,
29368 invocation,
29369 member_ordinal,
29370 member_row,
29371 false,
29372 consumer_stream,
29373 )
29374 }
29375
29376 #[cfg(feature = "semantic-policy")]
29379 #[expect(
29380 clippy::too_many_arguments,
29381 reason = "the frozen target and original published invocation have distinct owners"
29382 )]
29383 pub fn record_imported_policy_group_vjp(
29384 &mut self,
29385 update_step: &SemanticPreparedStep,
29386 bank: usize,
29387 source: &mut SemanticTransitionSession,
29388 source_lease: &SemanticPublishedLease,
29389 invocation: SemanticRngBinding,
29390 member_ordinal: u64,
29391 member_row: &SemanticTrainingViewRow,
29392 consumer_stream: u64,
29393 ) -> Result<SemanticPreparedPolicyGradients, SemanticTransitionError> {
29394 let actor_member = self
29395 .steps
29396 .get(&update_step.token)
29397 .and_then(|step| step.prepared.as_ref())
29398 .and_then(|step| step.training_view.as_ref())
29399 .ok_or_else(|| publication_input_error("Update has no selected training view"))?
29400 .actor_group_members()
29401 .iter()
29402 .any(|member| member.ordinal == member_ordinal);
29403 if actor_member {
29404 self.record_imported_group_member_policy_vjp(
29405 update_step,
29406 bank,
29407 source,
29408 source_lease,
29409 invocation,
29410 member_ordinal,
29411 member_row,
29412 consumer_stream,
29413 )
29414 } else {
29415 self.record_imported_edit_member_policy_vjp(
29416 update_step,
29417 bank,
29418 source,
29419 source_lease,
29420 invocation,
29421 member_ordinal,
29422 member_row,
29423 consumer_stream,
29424 )
29425 }
29426 }
29427
29428 #[cfg(feature = "semantic-policy")]
29430 #[expect(
29431 clippy::too_many_arguments,
29432 reason = "the frozen target and original published invocation have distinct owners"
29433 )]
29434 pub fn record_imported_edit_member_policy_vjp(
29435 &mut self,
29436 update_step: &SemanticPreparedStep,
29437 bank: usize,
29438 source: &mut SemanticTransitionSession,
29439 source_lease: &SemanticPublishedLease,
29440 invocation: SemanticRngBinding,
29441 member_ordinal: u64,
29442 member_row: &SemanticTrainingViewRow,
29443 consumer_stream: u64,
29444 ) -> Result<SemanticPreparedPolicyGradients, SemanticTransitionError> {
29445 self.record_imported_policy_vjp(
29446 update_step,
29447 bank,
29448 source,
29449 source_lease,
29450 invocation,
29451 member_ordinal,
29452 member_row,
29453 true,
29454 consumer_stream,
29455 )
29456 }
29457
29458 #[cfg(feature = "semantic-policy")]
29459 #[expect(
29460 clippy::too_many_arguments,
29461 reason = "the frozen target, original invocation and exact row are independent owners"
29462 )]
29463 fn record_imported_policy_vjp(
29464 &mut self,
29465 update_step: &SemanticPreparedStep,
29466 bank: usize,
29467 source: &mut SemanticTransitionSession,
29468 source_lease: &SemanticPublishedLease,
29469 invocation: SemanticRngBinding,
29470 member_ordinal: u64,
29471 member_row: &SemanticTrainingViewRow,
29472 edit_only: bool,
29473 consumer_stream: u64,
29474 ) -> Result<SemanticPreparedPolicyGradients, SemanticTransitionError> {
29475 dlpack_consumer_stream(consumer_stream)?;
29476 self.check_prepared_content_stream(update_step, consumer_stream)?;
29477 source.ensure_quiescent()?;
29478 if bank > 1
29479 || Arc::ptr_eq(&self.publication_issuer, &source.publication_issuer)
29480 || self.provider.device().ordinal() != source.provider.device().ordinal()
29481 || self.task_content() != source.task_content()
29482 || self.task_content().is_none()
29483 || self.task_scoring_law_identity()? != source.task_scoring_law_identity()?
29484 {
29485 return Err(publication_input_error(
29486 "imported group member requires a distinct original Session on the same bound task and device",
29487 ));
29488 }
29489 let build = self.prepared_segment.as_ref().ok_or_else(|| {
29490 publication_input_error("imported group member requires a prepared segment")
29491 })?;
29492 if build.completed
29493 || build.requested_kind(update_step, &self.publication_issuer)?
29494 != SemanticTransitionKind::Update
29495 {
29496 return Err(publication_input_error(
29497 "imported group member requires the recording Update step",
29498 ));
29499 }
29500 let prepared = self.steps[&update_step.token]
29501 .prepared
29502 .as_ref()
29503 .expect("checked prepared Update owner");
29504 if prepared
29505 .model_work
29506 .as_ref()
29507 .and_then(|work| work.capture_bank)
29508 != Some(bank)
29509 || prepared.group_critic_recorded & (1 << bank) != 0
29510 || (edit_only && prepared.group_edit_members[bank].contains(&member_ordinal))
29511 || (!edit_only && prepared.group_vjp_members[bank].contains(&member_ordinal))
29512 {
29513 return Err(publication_input_error(
29514 "imported group member requires an unused active Update bank slot",
29515 ));
29516 }
29517 let training = prepared.training_view.as_ref().ok_or_else(|| {
29518 publication_input_error("prepared Update has no selected training-view owner")
29519 })?;
29520 let member_index = if edit_only {
29521 None
29522 } else {
29523 Some(training.actor_group_member_index(member_ordinal, member_row)?)
29524 };
29525 let edit_member = training
29526 .edit_group_member_index(member_ordinal, member_row)?
29527 .is_some();
29528 if edit_only
29529 && (!edit_member
29530 || training
29531 .actor_group_members()
29532 .iter()
29533 .any(|row| row.ordinal == member_ordinal))
29534 {
29535 return Err(publication_input_error(
29536 "edit-only VJP requires a frozen edit row outside the actor group",
29537 ));
29538 }
29539 let critic_term = member_index.map(|index| training.critic_term(index));
29540 let source_index = source
29541 .policy_tapes
29542 .iter()
29543 .position(|tape| tape.invocation == invocation)
29544 .ok_or(SemanticTransitionError::ObservationMismatch)?;
29545 let continuation = Arc::clone(&source.policy_tapes[source_index].policy.text_binding);
29546 source.checked_content_witness(source_lease, &continuation._witness)?;
29547 source.guard_continuation_content(&continuation)?;
29548 let reader = source.checked_reader(source_lease)?;
29549 let tape = &source.policy_tapes[source_index];
29550 if tape.refusal.is_some() || tape.prepared_bank.is_some() {
29551 return Err(publication_input_error(
29552 "imported group member requires its successful published policy tape",
29553 ));
29554 }
29555 let state = tape.origin_state.as_ref().ok_or_else(|| {
29556 publication_input_error("imported group member has no original published state")
29557 })?;
29558 let owner = Arc::clone(&tape.policy.buffers.temporal_adjoints);
29559 let PolicyVjpRecording {
29560 descriptor,
29561 recorder,
29562 } = self.prepare_policy_vjp_recording(
29563 &tape.policy,
29564 &owner,
29565 &tape.support,
29566 &tape.receipts,
29567 state,
29568 &tape.components,
29569 &tape.codebooks,
29570 if let Some(critic_term) = &critic_term {
29571 PolicyVjpInput::GroupMember {
29572 training,
29573 member_ordinal,
29574 origin_candidate: u64::MAX,
29575 origin_lease: &reader.device,
29576 origin_bank: (source_lease.header.publication_word & 1) as usize,
29577 critic_term,
29578 }
29579 } else {
29580 PolicyVjpInput::EditMember {
29581 training,
29582 member_ordinal,
29583 origin_candidate: u64::MAX,
29584 origin_lease: &reader.device,
29585 origin_bank: (source_lease.header.publication_word & 1) as usize,
29586 }
29587 },
29588 )?;
29589 let baseline_snapshot = tape.policy.component_baselines.view();
29590 let layout = tape.policy.layout.clone();
29591 let continuation = Arc::clone(&tape.policy.text_binding);
29592 let support_cells = tape.support.len();
29593 let parameters = owner.parameters.view();
29594 let text_logits = owner.text_logits.view();
29595 let component_baselines = owner.component_baselines.view();
29596 let step_aliases = Arc::clone(&source.steps[&source_lease.token].aliases);
29597 let publication = Arc::clone(
29598 source
29599 .publication
29600 .as_ref()
29601 .ok_or(SemanticTransitionError::NotBound)?,
29602 );
29603 record_policy_vjp(
29604 &self.domain,
29605 &mut self.poisoned,
29606 recorder,
29607 self.execute.clone(),
29608 descriptor,
29609 &owner.coefficients,
29610 None,
29611 Some(&baseline_snapshot),
29612 )?;
29613 let update = self
29614 .steps
29615 .get_mut(&update_step.token)
29616 .expect("checked prepared Update owner")
29617 .prepared
29618 .as_mut()
29619 .expect("checked prepared Update");
29620 if !edit_only {
29621 update.group_vjp_members[bank].insert(member_ordinal);
29622 }
29623 if edit_member {
29624 update.group_edit_members[bank].insert(member_ordinal);
29625 }
29626 update.group_imported_vjp_members[bank].insert(member_ordinal);
29627 Ok(SemanticPreparedPolicyGradients {
29628 layout,
29629 parameters,
29630 text_logits,
29631 component_baselines,
29632 provider: Arc::clone(&source.provider),
29633 step_aliases,
29634 publication,
29635 continuation,
29636 owner,
29637 support_cells,
29638 })
29639 }
29640
29641 #[cfg(feature = "semantic-policy")]
29642 pub fn finish_prepared_policy_invocation(
29643 &mut self,
29644 step: &SemanticPreparedStep,
29645 invocation: SemanticRngBinding,
29646 consumer_stream: u64,
29647 ) -> Result<(), SemanticTransitionError> {
29648 let index = self.checked_prepared_policy_tape(step, invocation)?;
29649 self.finish_policy_tape(index, consumer_stream)
29650 }
29651
29652 #[cfg(feature = "semantic-policy")]
29656 pub fn finish_recorded_training_policy_invocation(
29657 &mut self,
29658 step: &SemanticPreparedStep,
29659 update_step: &SemanticPreparedStep,
29660 invocation: SemanticRngBinding,
29661 consumer_stream: u64,
29662 ) -> Result<(), SemanticTransitionError> {
29663 let index = self.checked_prepared_policy_tape(step, invocation)?;
29664 let update_owner = self.checked_prepared_step(update_step, false)?;
29665 let build = self
29666 .prepared_segment
29667 .as_ref()
29668 .expect("checked prepared segment");
29669 if !build.completed
29670 || !update_owner
29671 .prepared
29672 .as_ref()
29673 .is_some_and(|prepared| prepared.observed)
29674 || build.requested_kind(update_step, &self.publication_issuer)?
29675 != SemanticTransitionKind::Update
29676 {
29677 return Err(publication_input_error(
29678 "recorded training completion requires its actual completed Update step",
29679 ));
29680 }
29681 let proposal_ordinal = build
29682 .tokens
29683 .iter()
29684 .position(|token| *token == step.token)
29685 .ok_or(SemanticTransitionError::ObservationMismatch)?;
29686 let update_ordinal = build
29687 .tokens
29688 .iter()
29689 .position(|token| *token == update_step.token)
29690 .ok_or(SemanticTransitionError::ObservationMismatch)?;
29691 if proposal_ordinal >= update_ordinal {
29692 return Err(publication_input_error(
29693 "recorded training completion requires a preceding Proposal step",
29694 ));
29695 }
29696 let tape = &self.policy_tapes[index];
29697 if tape.refusal.is_some()
29698 || !(0..2).all(|bank| {
29699 tape.policy
29700 .temporal_vjp_recorded
29701 .contains(&(update_step.token, bank))
29702 })
29703 {
29704 return Err(publication_input_error(
29705 "published training completion requires the exact Update VJP in both captured banks",
29706 ));
29707 }
29708 self.finish_policy_tape(index, consumer_stream)
29709 }
29710
29711 #[cfg(feature = "semantic-policy")]
29715 pub fn finish_unselected_recorded_training_policy_invocation(
29716 &mut self,
29717 step: &SemanticPreparedStep,
29718 update_step: &SemanticPreparedStep,
29719 invocation: SemanticRngBinding,
29720 consumer_stream: u64,
29721 ) -> Result<(), SemanticTransitionError> {
29722 let update_published = self
29723 .checked_prepared_step(update_step, false)?
29724 .prepared
29725 .as_ref()
29726 .expect("checked prepared owner")
29727 .group_update_published;
29728 if update_published {
29729 self.require_recorded_group_critic(update_step)?;
29730 } else {
29731 self.require_completed_unpublished_group_update(update_step)?;
29732 }
29733 let index = self.checked_prepared_policy_tape(step, invocation)?;
29734 let build = self
29735 .prepared_segment
29736 .as_ref()
29737 .expect("checked completed prepared segment");
29738 if build.requested_kind(step, &self.publication_issuer)? != SemanticTransitionKind::Proposal
29739 || build.requested_kind(update_step, &self.publication_issuer)?
29740 != SemanticTransitionKind::Update
29741 {
29742 return Err(publication_input_error(
29743 "unselected training completion requires its actual Proposal and Update steps",
29744 ));
29745 }
29746 let proposal_ordinal = build
29747 .tokens
29748 .iter()
29749 .position(|token| *token == step.token)
29750 .ok_or(SemanticTransitionError::ObservationMismatch)?;
29751 let update_ordinal = build
29752 .tokens
29753 .iter()
29754 .position(|token| *token == update_step.token)
29755 .ok_or(SemanticTransitionError::ObservationMismatch)?;
29756 if proposal_ordinal >= update_ordinal
29757 || self.policy_tapes[index].refusal.is_some()
29758 || !self.policy_tapes[index]
29759 .policy
29760 .temporal_vjp_recorded
29761 .is_empty()
29762 {
29763 return Err(publication_input_error(
29764 "unselected training completion requires an earlier published Proposal with no recorded Update VJP",
29765 ));
29766 }
29767 self.finish_policy_tape(index, consumer_stream)
29768 }
29769
29770 #[cfg(feature = "semantic-policy")]
29774 pub fn finish_policy_invocation(
29775 &mut self,
29776 lease: &SemanticPublishedLease,
29777 invocation: SemanticRngBinding,
29778 consumer_stream: u64,
29779 ) -> Result<(), SemanticTransitionError> {
29780 self.ensure_quiescent()?;
29781 self.checked_step(lease)?;
29782 dlpack_consumer_stream(consumer_stream)?;
29783 let index = self
29784 .policy_tapes
29785 .iter()
29786 .position(|tape| tape.invocation == invocation)
29787 .ok_or(SemanticTransitionError::ObservationMismatch)?;
29788 let original = Arc::clone(&self.policy_tapes[index].policy.text_binding);
29789 self.checked_content_witness(lease, &original._witness)?;
29790 self.finish_policy_tape(index, consumer_stream)
29791 }
29792
29793 #[cfg(feature = "semantic-policy")]
29794 fn finish_policy_tape(
29795 &mut self,
29796 index: usize,
29797 consumer_stream: u64,
29798 ) -> Result<(), SemanticTransitionError> {
29799 self.ensure_quiescent()?;
29800 dlpack_consumer_stream(consumer_stream)?;
29801 let original = Arc::clone(&self.policy_tapes[index].policy.text_binding);
29802 let result = (|| {
29803 self.order_step_content_inputs(original._witness.reader_token, consumer_stream)?;
29804 self.guard_continuation_content(&original)?;
29805 self.order_content_consumers(consumer_stream)
29806 })();
29807 if let Err(error) = result {
29808 self.poisoned = true;
29809 return Err(error);
29810 }
29811 self.policy_tapes.remove(index);
29812 Ok(())
29813 }
29814
29815 #[cfg(feature = "semantic-policy")]
29816 #[expect(
29817 clippy::too_many_arguments,
29818 reason = "policy VJP recording retains each native owner explicitly"
29819 )]
29820 fn prepare_policy_vjp_recording(
29821 &self,
29822 policy: &PolicyStorage,
29823 adjoints: &PolicyAdjointBuffers,
29824 support: &TrackedCudaSlice<u8>,
29825 receipts: &TrackedCudaSlice<SemanticTransitionReceipt>,
29826 state: &TrackedCudaSlice<DeviceState>,
29827 components: &DeviceMemoryView<SemanticComponent>,
29828 codebooks: &DeviceMemoryView<u64>,
29829 input: PolicyVjpInput<'_>,
29830 ) -> Result<PolicyVjpRecording, SemanticTransitionError> {
29831 if let PolicyVjpInput::External(score_cotangents) = input {
29832 if score_cotangents.len() != COMPONENT_COUNT {
29833 return Err(SemanticTransitionError::InvalidInput {
29834 detail: "selected-score cotangents must follow the complete component roster"
29835 .into(),
29836 });
29837 }
29838 }
29839 let PolicyAdjointBuffers {
29840 parameters,
29841 text_logits,
29842 component_baselines,
29843 recurrent,
29844 scores,
29845 coefficients,
29846 status,
29847 numerical,
29848 } = adjoints;
29849 let io = TransitionKernelIo {
29850 logits: &policy.text_logits,
29851 support,
29852 receipts,
29853 state,
29854 policy: Some(policy),
29855 text: Some(&policy.text_binding),
29856 lease: None,
29857 model_work: None,
29858 model_update: None,
29859 replay_custody: None,
29860 training_selection: None,
29861 };
29862 let task = match input {
29863 PolicyVjpInput::External(_) => None,
29864 PolicyVjpInput::UpdateObjective { training, .. }
29865 | PolicyVjpInput::GroupMember { training, .. }
29866 | PolicyVjpInput::EditMember { training, .. } => {
29867 if matches!(input, PolicyVjpInput::UpdateObjective { .. })
29868 && training.actor_group_member_count() != 1
29869 {
29870 return Err(publication_input_error(
29871 "single-proposal policy backward cannot represent the complete actor group",
29872 ));
29873 }
29874 let (binding, device) = self.task.as_ref().ok_or_else(|| {
29875 publication_input_error(
29876 "Update policy backward requires the bound semantic task ground",
29877 )
29878 })?;
29879 if binding.goal_witness().is_none() {
29880 return Err(publication_input_error(
29881 "Update policy backward requires the bound semantic goal closure",
29882 ));
29883 }
29884 Some(device)
29885 }
29886 };
29887 let mut descriptor = self.descriptor_with(&io);
29888 descriptor.components = *components.device_ptr();
29889 descriptor.codebooks = *codebooks.device_ptr();
29890 descriptor.publication = PublicationCommand::default();
29891 let (
29892 selection,
29893 objective,
29894 objective_groups,
29895 objective_group_members,
29896 roster_rows,
29897 origin_candidate,
29898 origin_lease,
29899 origin_bank,
29900 mode,
29901 member_ordinal,
29902 critic_term,
29903 ) = match input {
29904 PolicyVjpInput::External(_) => (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
29905 PolicyVjpInput::UpdateObjective {
29906 training,
29907 origin_candidate,
29908 origin_lease,
29909 origin_bank,
29910 } => (
29911 *training.selection().device_ptr(),
29912 *training.objective().device_ptr(),
29913 *training.objective_groups().device_ptr(),
29914 *training.objective_group_members().device_ptr(),
29915 *training.roster_rows().device_ptr(),
29916 origin_candidate,
29917 origin_lease.device_ptr_value(),
29918 origin_bank as u64,
29919 1,
29920 0,
29921 0,
29922 ),
29923 PolicyVjpInput::GroupMember {
29924 training,
29925 member_ordinal,
29926 origin_candidate,
29927 origin_lease,
29928 origin_bank,
29929 critic_term,
29930 } => (
29931 *training.selection().device_ptr(),
29932 *training.objective().device_ptr(),
29933 *training.objective_groups().device_ptr(),
29934 *training.objective_group_members().device_ptr(),
29935 *training.roster_rows().device_ptr(),
29936 origin_candidate,
29937 origin_lease.device_ptr_value(),
29938 origin_bank as u64,
29939 2,
29940 member_ordinal,
29941 *critic_term.device_ptr(),
29942 ),
29943 PolicyVjpInput::EditMember {
29944 training,
29945 member_ordinal,
29946 origin_candidate,
29947 origin_lease,
29948 origin_bank,
29949 } => (
29950 *training.selection().device_ptr(),
29951 *training.objective().device_ptr(),
29952 *training.objective_groups().device_ptr(),
29953 *training.objective_group_members().device_ptr(),
29954 *training.roster_rows().device_ptr(),
29955 origin_candidate,
29956 origin_lease.device_ptr_value(),
29957 origin_bank as u64,
29958 3,
29959 member_ordinal,
29960 0,
29961 ),
29962 };
29963 descriptor.backward = PolicyBackward {
29964 numerical: numerical.descriptor(),
29965 cotangents: coefficients.device_ptr_value(),
29966 parameters: parameters.device_ptr_value(),
29967 text: text_logits.device_ptr_value(),
29968 baselines: component_baselines.device_ptr_value(),
29969 recurrent: recurrent.device_ptr_value(),
29970 scores: scores.device_ptr_value(),
29971 status: status.device_ptr_value(),
29972 parameter_cells: policy.layout.parameter_cells as u64,
29973 text_cells: policy.text_logits.len() as u64,
29974 selection,
29975 objective,
29976 objective_groups,
29977 objective_group_members,
29978 roster_rows,
29979 origin_candidate,
29980 origin_lease,
29981 origin_bank,
29982 mode,
29983 member_ordinal,
29984 critic_term,
29985 };
29986 self.validate_ranges_with(&io)?;
29987 let mut recorder = self.domain.new_strict_recorder();
29988 recorder.read(support);
29989 recorder.read(receipts);
29990 recorder.read(codebooks);
29991 recorder.read(components);
29992 recorder.read(&policy.parameters);
29993 recorder.read(&policy.recurrent);
29994 recorder.read(&policy.text_logits);
29995 recorder.read(&policy.component_baselines);
29996 policy.numerical.record(&mut recorder);
29997 policy.text_binding.record(&mut recorder);
29998 match input {
29999 PolicyVjpInput::External(score_cotangents) => {
30000 recorder.read(score_cotangents);
30001 }
30002 PolicyVjpInput::UpdateObjective {
30003 training,
30004 origin_lease,
30005 ..
30006 }
30007 | PolicyVjpInput::GroupMember {
30008 training,
30009 origin_lease,
30010 ..
30011 }
30012 | PolicyVjpInput::EditMember {
30013 training,
30014 origin_lease,
30015 ..
30016 } => {
30017 recorder.read(&training.selection());
30018 recorder.read(&training.objective());
30019 recorder.read(&training.objective_groups());
30020 recorder.read(&training.objective_group_members());
30021 recorder.read(&training.roster_rows());
30022 recorder.read(state);
30023 recorder.read(origin_lease);
30024 recorder.read(task.expect("validated Update task ground"));
30025 }
30026 }
30027 if let PolicyVjpInput::GroupMember { critic_term, .. } = input {
30028 recorder.write(critic_term);
30029 }
30030 recorder.write(&self.scratch);
30031 recorder.write(&policy.hidden);
30032 recorder.write(&policy.scores);
30033 for buffer in [
30034 parameters,
30035 text_logits,
30036 component_baselines,
30037 recurrent,
30038 scores,
30039 ] {
30040 recorder.write(buffer);
30041 }
30042 recorder.write(coefficients);
30043 recorder.write(status);
30044 for buffer in numerical.buffers() {
30045 recorder.write(buffer);
30046 }
30047 Ok(PolicyVjpRecording {
30048 descriptor,
30049 recorder,
30050 })
30051 }
30052
30053 #[cfg(feature = "semantic-policy")]
30054 fn backward_policy_view(
30055 &mut self,
30056 invocation: SemanticRngBinding,
30057 score_cotangents: DeviceMemoryView<f64>,
30058 consumer_stream: u64,
30059 ) -> Result<SemanticPolicyGradients, SemanticTransitionError> {
30060 self.ensure_quiescent()?;
30061 dlpack_consumer_stream(consumer_stream)?;
30062 let tape_index = self
30063 .policy_tapes
30064 .iter()
30065 .position(|tape| tape.invocation == invocation)
30066 .ok_or(SemanticTransitionError::ObservationMismatch)?;
30067 if let Some(refusal) = self.policy_tapes[tape_index].refusal {
30068 return Err(refusal.into_error());
30069 }
30070 let original = Arc::clone(&self.policy_tapes[tape_index].policy.text_binding);
30071 self.guard_continuation_content(&original)?;
30072 if let Err(error) =
30073 self.order_step_content_inputs(original._witness.reader_token, consumer_stream)
30074 {
30075 self.poisoned = true;
30076 return Err(error);
30077 }
30078 let publication = Arc::clone(
30079 self.publication
30080 .as_ref()
30081 .ok_or(SemanticTransitionError::NotBound)?,
30082 );
30083 let step_aliases = Arc::clone(&self.steps[&original._witness.reader_token].aliases);
30084 let tape = &self.policy_tapes[tape_index];
30085 let policy = &tape.policy;
30086 let state = if let Some(bank) = tape.prepared_bank {
30087 &self.steps[&original._witness.reader_token]
30088 .prepared
30089 .as_ref()
30090 .expect("retained prepared policy step")
30091 .branches[bank]
30092 .state
30093 } else {
30094 tape.origin_state
30095 .as_ref()
30096 .expect("ordinary policy tape retains its original state")
30097 };
30098 let PolicyVjpRecording {
30099 descriptor,
30100 recorder,
30101 } = self.prepare_policy_vjp_recording(
30102 policy,
30103 policy.buffers.adjoints.as_ref().ok_or_else(|| {
30104 publication_input_error("original policy adjoint banks have already been consumed")
30105 })?,
30106 &tape.support,
30107 &tape.receipts,
30108 state,
30109 &tape.components,
30110 &tape.codebooks,
30111 PolicyVjpInput::External(&score_cotangents),
30112 )?;
30113 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
30114 .map_err(|e| runtime_error("policy backward stream admission", e))?;
30115 let execute = self.execute.clone();
30116 let layout = policy.layout.clone();
30117 let binding = tape.binding;
30118 let support_cells = tape.support.len();
30119 let PolicyAdjointBuffers {
30123 parameters,
30124 text_logits,
30125 component_baselines,
30126 recurrent,
30127 scores,
30128 coefficients,
30129 status,
30130 numerical,
30131 } = self.policy_tapes[tape_index]
30132 .policy
30133 .buffers
30134 .adjoints
30135 .take()
30136 .expect("checked original adjoint banks");
30137 let vjp_workspace = Arc::new(PolicyVjpWorkspace {
30138 _component_baselines: None,
30139 _numerical: Arc::clone(&numerical),
30140 _recurrent: recurrent,
30141 _scores: scores,
30142 coefficients,
30143 _status: status,
30144 score_cotangents: Some(score_cotangents),
30145 });
30146 let output_views = [¶meters, &text_logits, &component_baselines]
30150 .into_iter()
30151 .map(|buffer| {
30152 unsafe { buffer.view().cast::<u8>() }.expect("F32 adjoint byte view")
30154 });
30155 let step_owner = self
30156 .steps
30157 .get_mut(&original._witness.reader_token)
30158 .expect("retained original step");
30159 step_owner.adjoints.extend(output_views);
30160 step_owner
30161 .policy_vjp_workspaces
30162 .push(Arc::clone(&vjp_workspace));
30163 record_policy_vjp(
30164 &self.domain,
30165 &mut self.poisoned,
30166 recorder,
30167 execute,
30168 descriptor,
30169 &vjp_workspace.coefficients,
30170 vjp_workspace.score_cotangents.as_ref(),
30171 None,
30172 )?;
30173 if let Err(error) = self.order_content_consumers(consumer_stream) {
30174 self.poisoned = true;
30175 return Err(error);
30176 }
30177 self.policy_tapes.remove(tape_index);
30178 Ok(SemanticPolicyGradients {
30179 component_baselines,
30180 numerical,
30181 binding,
30182 invocation,
30183 layout,
30184 parameters,
30185 text_logits,
30186 provider: Arc::clone(&self.provider),
30187 step_aliases,
30188 publication,
30189 continuation: original,
30190 vjp_workspace,
30191 support_cells,
30192 })
30193 }
30194
30195 fn upload_cold_codebooks(&mut self) -> Result<(), SemanticTransitionError> {
30198 let upload = (|| {
30199 self.provider
30200 .htod_sync_copy_into_tracked(&self.codebooks.words, &mut self.device_codebooks)?;
30201 self.provider.htod_sync_copy_into_tracked(
30202 &self.codebooks.components,
30203 &mut self.device_components,
30204 )
30205 })();
30206 upload.map_err(|error| {
30207 self.poisoned = true;
30208 runtime_error("cold codebook upload", error)
30209 })
30210 }
30211
30212 fn upload_rng_state(
30213 &mut self,
30214 binding: SemanticCatalogueBinding,
30215 rng: SemanticRngBinding,
30216 ) -> Result<(), SemanticTransitionError> {
30217 let state = DeviceState {
30218 model_generation: rng.model_generation,
30219 family_id: u32::from(rng.family_id),
30220 stream_serial: rng.stream_serial,
30221 next_proposal: u64::from(rng.proposal),
30222 catalogue_generation: binding.generation,
30223 catalogue_digest: Identity256::from_bytes(CATALOGUE_DIGEST),
30224 binding_digest: binding.digest,
30225 ..DeviceState::default()
30226 };
30227 let upload = self
30228 .provider
30229 .htod_sync_copy_into_tracked(&[state], &mut self.state);
30230 upload.map_err(|e| {
30231 self.poisoned = true;
30232 runtime_error("RNG state upload", e)
30233 })
30234 }
30235
30236 pub fn capture(&mut self) -> Result<(), SemanticTransitionError> {
30237 self.ensure_rebindable()?;
30238 if self.publication.is_some()
30239 && (self.continuation_base.is_none()
30240 || self
30241 .admitted_transition
30242 .is_none_or(|(_, word, _)| Some(word) != self.continuation_base))
30243 {
30244 return Err(publication_input_error(
30245 "publication capture requires the admitted acquired-parent continuation",
30246 ));
30247 }
30248 if self.rng.is_none() {
30249 return Err(SemanticTransitionError::NotBound);
30250 }
30251 self.validate_ranges()?;
30252 let descriptor = self.descriptor();
30253 let execute = self.execute.clone();
30254 let recorder = self.kernel_recorder();
30255 self.graph.enter_transition();
30256 self.poisoned = true;
30259 let captured =
30260 CapturedCudaGraph::capture_on_stream_retaining(&self.stream, Vec::new(), || {
30261 let enqueued = unsafe {
30263 self.domain.enqueue(recorder, |enqueue| {
30264 execute
30265 .launch_in(
30266 enqueue,
30267 LaunchConfig {
30268 grid_dim: (1, 1, 1),
30269 block_dim: (256, 1, 1),
30270 shared_mem_bytes: 0,
30271 },
30272 (descriptor,),
30273 )
30274 .map_err(|error| XlogError::Kernel(error.to_string()))
30275 })
30276 }
30277 .map_err(LaunchEnqueueError::into_xlog_error)?;
30278 enqueued.commit().map_err(|error| {
30279 XlogError::Kernel(format!("semantic transition capture commit: {error}"))
30280 })
30281 })
30282 .map_err(|error| runtime_error("capture", error))?;
30283 self.captured = Some(captured);
30284 self.poisoned = false;
30285 Ok(())
30286 }
30287
30288 pub fn launch(&mut self) -> Result<(), SemanticTransitionError> {
30290 self.ensure_rebindable()?;
30291 if let Some(binding) = self.text_binding.as_ref().map(Arc::clone) {
30292 self.guard_continuation_content(&binding)?;
30293 }
30294 let graph = self
30295 .captured
30296 .as_ref()
30297 .ok_or(SemanticTransitionError::NotCaptured)?;
30298 if self.next_proposal > u64::from(u32::MAX) {
30299 return Err(SemanticTransitionError::GenerationExhausted);
30300 }
30301 let recorder = self.kernel_recorder();
30302 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |stream| {
30305 graph.launch_in(stream)
30306 })?;
30307 self.pending = true;
30308 #[cfg(feature = "semantic-policy")]
30309 if let Some(policy) = &mut self.policy {
30310 policy.tape_live = true;
30311 }
30312 Ok(())
30313 }
30314
30315 pub fn observe(
30319 &mut self,
30320 expected_proposal: u32,
30321 ) -> Result<SemanticTransitionOutcome, SemanticTransitionError> {
30322 if self.is_poisoned() {
30323 return Err(SemanticTransitionError::Poisoned);
30324 }
30325 if !self.pending {
30326 return Err(SemanticTransitionError::NoPendingLaunch);
30327 }
30328 #[cfg(feature = "semantic-policy")]
30331 let policy_invocation = self.rng;
30332 let result = self.observe_terminal(expected_proposal);
30333 if result.is_err() {
30334 self.poisoned = true;
30335 } else {
30336 self.pending = false;
30337 #[cfg(feature = "semantic-policy")]
30338 if let Err(error) = self.retain_policy_tape(
30339 policy_invocation,
30340 match &result {
30341 Ok(SemanticTransitionOutcome::Refused(refusal)) => Some(*refusal),
30342 _ => None,
30343 },
30344 ) {
30345 self.poisoned = true;
30346 return Err(error);
30347 }
30348 self.task_observed = self.task.is_some() && self.publication.is_none();
30349 if self.publication.is_some() {
30350 self.continuation_base = None;
30351 self.admitted_transition = None;
30352 self.text_binding = None;
30353 }
30354 }
30355 result
30356 }
30357
30358 #[cfg(feature = "semantic-policy")]
30359 fn retain_policy_tape(
30360 &mut self,
30361 invocation: Option<SemanticRngBinding>,
30362 refusal: Option<SemanticTransitionRefusal>,
30363 ) -> Result<(), SemanticTransitionError> {
30364 let Some(policy) = self.policy.as_ref() else {
30365 return Ok(());
30366 };
30367 let invocation = invocation.ok_or(SemanticTransitionError::ObservationMismatch)?;
30368 let next_state = &policy
30369 .replacement
30370 .as_ref()
30371 .expect("proposal reserved its next working banks")
30372 .state;
30373 let mut recorder = self.domain.new_strict_recorder();
30374 recorder.read(&self.state);
30375 recorder.write(next_state);
30376 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |enqueue| {
30377 unsafe {
30380 sys::cuMemcpyDtoDAsync_v2(
30381 next_state.device_ptr_value(),
30382 self.state.device_ptr_value(),
30383 size_of::<DeviceState>(),
30384 enqueue.stream().cu_stream(),
30385 )
30386 }
30387 .result()
30388 .map_err(|error| XlogError::Kernel(error.to_string()))
30389 })?;
30390 let mut policy = self.policy.take().expect("checked original policy");
30391 let replacement = policy
30392 .replacement
30393 .take()
30394 .expect("proposal reserved its next working banks");
30395 self.rng = None;
30396 self.captured = None;
30397 self.policy_tapes.push(PolicyTape {
30398 invocation,
30399 refusal,
30400 binding: self.binding(),
30401 policy,
30402 support: std::mem::replace(&mut self.support, replacement.support),
30403 receipts: std::mem::replace(&mut self.receipts, replacement.receipts),
30404 prepared_bank: None,
30405 origin_state: Some(std::mem::replace(&mut self.state, replacement.state)),
30406 components: self.device_components.view(),
30407 codebooks: self.device_codebooks.view(),
30408 });
30409 Ok(())
30410 }
30411
30412 fn observe_terminal(
30413 &mut self,
30414 expected_proposal: u32,
30415 ) -> Result<SemanticTransitionOutcome, SemanticTransitionError> {
30416 let _ordinary = crate::cuda_graph::reserve_uncaptured_stream(&self.stream)
30417 .map_err(|error| runtime_error("terminal observation stream admission", error))?;
30418 wait_on_stream(
30419 &self.stream,
30420 &mut self.poisoned,
30421 &mut self.stream_waits,
30422 "terminal wait",
30423 CudaStream::synchronize,
30424 )?;
30425 let mut recorder = self.domain.new_strict_recorder();
30426 recorder.read(&self.state);
30427 recorder.read(&self.receipts);
30428 enqueue_recorded(&self.domain, &mut self.poisoned, recorder, |stream| {
30431 self.pinned.enqueue_copy(
30432 self.state.device_ptr_value(),
30433 self.receipts.device_ptr_value(),
30434 stream.stream(),
30435 )
30436 })?;
30437 wait_on_stream(
30438 &self.stream,
30439 &mut self.poisoned,
30440 &mut self.stream_waits,
30441 "observation wait",
30442 CudaStream::synchronize,
30443 )?;
30444 let (state, components) = unsafe { self.pinned.read()? };
30446 self.provider
30447 .record_final_observation_transfer(size_of::<DeviceState>() as u64);
30448 self.provider.record_final_observation_transfer(
30449 (COMPONENT_COUNT * size_of::<SemanticTransitionReceipt>()) as u64,
30450 );
30451 if matches!(state.status, 2 | 5 | 11 | 12..=14) && self.publication.is_some() {
30452 let refusal = self.reconcile_refusal(&state, expected_proposal)?;
30453 return Ok(SemanticTransitionOutcome::Refused(refusal));
30454 }
30455 if state.status == 2 {
30456 return Err(SemanticTransitionError::InvalidFinalSupport {
30457 completed_draws: state.blocks,
30458 });
30459 }
30460 if state.status == 5 {
30461 return Err(SemanticTransitionError::NonFinitePolicyInput {
30462 completed_draws: state.blocks,
30463 });
30464 }
30465 if state.status == 11 {
30466 return Err(SemanticTransitionError::WorkCounterOverflow {
30467 completed_draws: state.blocks,
30468 });
30469 }
30470 if matches!(state.status, 12..=14) {
30471 return Err(SemanticTransitionError::InvalidTrainingView {
30472 status: state.status - 11,
30473 });
30474 }
30475 match state.status {
30476 7 => return Err(SemanticTransitionError::InvalidTaskBank),
30477 8 => return Err(SemanticTransitionError::InvalidTaskBase),
30478 9 => return Err(SemanticTransitionError::TaskOwnerFailure),
30479 _ => {}
30480 }
30481 let published = if self.publication.is_some() {
30482 Some(self.reconcile_publication(&state, expected_proposal)?)
30483 } else {
30484 None
30485 };
30486 let rng = self
30487 .rng
30488 .ok_or(SemanticTransitionError::ObservationMismatch)?;
30489 if expected_proposal != rng.proposal || u64::from(expected_proposal) != self.next_proposal {
30490 return Err(SemanticTransitionError::ObservationMismatch);
30491 }
30492 let policy_text = false;
30493 #[cfg(feature = "semantic-policy")]
30494 let policy_text = self.policy.is_some() || policy_text;
30495 self.finish_observed_transition(state, components, rng, published, policy_text)
30496 }
30497
30498 fn finish_observed_transition(
30499 &mut self,
30500 state: DeviceState,
30501 components: Vec<SemanticTransitionReceipt>,
30502 rng: SemanticRngBinding,
30503 published: Option<(
30504 PublicationHeader,
30505 (SemanticRootHandle, SemanticRootSnapshot),
30506 SemanticTransitionKind,
30507 )>,
30508 policy_text: bool,
30509 ) -> Result<SemanticTransitionOutcome, SemanticTransitionError> {
30510 let proposal = u64::from(rng.proposal);
30511 if state.model_generation != rng.model_generation
30512 || state.family_id != u32::from(rng.family_id)
30513 || state.stream_serial != rng.stream_serial
30514 {
30515 return Err(SemanticTransitionError::ObservationMismatch);
30516 }
30517 if let Some((header, (root, snapshot), kind)) = published {
30518 if kind != SemanticTransitionKind::Proposal {
30519 if state.status != 0
30520 || state.blocks != 0
30521 || state.proposal != proposal
30522 || state.next_proposal != proposal
30523 || state.importance_weight != 1.0
30524 {
30525 return Err(SemanticTransitionError::ObservationMismatch);
30526 }
30527 self.root = root;
30528 self.base_snapshot = snapshot;
30529 self.next_proposal = header.proposal;
30530 return Ok(SemanticTransitionOutcome::Published(
30531 SemanticTransitionObservation {
30532 components: Vec::new(),
30533 root_handle: root,
30534 root: snapshot,
30535 next_proposal: header.proposal,
30536 lanes: std::array::from_fn(|_| SemanticTransitionLane {
30537 root: None,
30538 task_refusal: None,
30539 program_rules: [None; 2],
30540 edits: [Ok(None), Ok(None)],
30541 work: SemanticTransitionWork::default(),
30542 }),
30543 importance_weight: state.importance_weight,
30544 task_evaluation: None,
30545 },
30546 ));
30547 }
30548 }
30549 if state.semantic_receipts[0][0] != 0 {
30550 self.graph
30551 .observe_transition_root(state.semantic_receipts[0])
30552 .map_err(SemanticTransitionError::Semantic)?;
30553 }
30554 let binding = SemanticActionCatalogue::current().binding();
30555 let editable_program = self
30556 .task
30557 .as_ref()
30558 .is_some_and(|(task, _)| task.spec().program.editable_program().is_some());
30559 if state.status != 0
30560 || state.proposal != proposal
30561 || state.next_proposal != proposal + 1
30562 || components.len() != COMPONENT_COUNT
30563 || state.blocks != COMPONENT_COUNT as u64
30564 || state.catalogue_generation != binding.generation
30565 || state.catalogue_digest != binding.digest
30566 || state.binding_digest != self.binding().digest
30567 || state
30568 .work
30569 .iter()
30570 .any(|work| !work.is_valid(editable_program))
30571 || (published.is_none() && state.retired_roots_mask != 0)
30572 || state.retired_roots_mask & !3 != 0
30573 || !state.importance_weight.is_finite()
30574 || state.importance_weight <= 0.0
30575 {
30576 return Err(SemanticTransitionError::ObservationMismatch);
30577 }
30578 for (row, component) in components.iter().zip(&self.codebooks.components) {
30579 let inactive_text = policy_text
30580 && component.kind == COMPONENT_KIND_TEXT as u32
30581 && canonical_text_null(row);
30582 if row.ordinal != component.ordinal
30583 || row.lane != component.lane
30584 || row.slot != component.slot
30585 || row.field != component.field
30586 || row.kind != component.kind
30587 || row.proposal != state.proposal
30588 || row.catalogue_generation != binding.generation
30589 || row.catalogue_digest != binding.digest
30590 || row.admission_binding != self.binding().digest
30591 || if inactive_text {
30592 !canonical_text_null(row)
30593 } else {
30594 row.choice >= component.cardinality
30595 }
30596 || row.cdf_start > row.draw
30597 || row.draw >= row.cdf_end
30598 || row.cdf_end > 1u64 << 63
30599 || row.cdf_end - row.cdf_start != row.mass
30600 || row.mass < 1u64 << 32
30601 {
30602 return Err(SemanticTransitionError::ObservationMismatch);
30603 }
30604 }
30605 let mut integrity_error = None;
30606 let task_evaluation = if let Some((binding, _)) = &self.task {
30607 let task = &state.task_evaluation;
30608 if task.query_count < 3
30609 || task.query_count > 9
30610 || !task.query_count.is_multiple_of(3)
30611 || task.winner > 2
30612 || task.facts[task.winner as usize].eligible != 1
30613 || task.lane_refusal.iter().any(|&code| code > 4)
30614 || (binding.spec.program.editable_program().is_none()
30615 && task.lane_refusal.iter().any(|&code| code >= 3))
30616 {
30617 return Err(SemanticTransitionError::ObservationMismatch);
30618 }
30619 Some(SemanticTaskEvaluation {
30620 binding: binding.identity(),
30621 query_count: task.query_count,
30622 winner: task.winner,
30623 return_value: task.return_value,
30624 facts: task.facts,
30625 })
30626 } else {
30627 None
30628 };
30629 let edit_choices: [[[u32; 18]; 2]; 2] = std::array::from_fn(|lane| {
30630 std::array::from_fn(|slot| {
30631 std::array::from_fn(|field| components[lane * 68 + 32 + slot * 18 + field].choice)
30632 })
30633 });
30634 let mut program_rules = [[None; 2]; 2];
30635 if let Some((task, _)) = &self.task {
30636 if let Some(program) = task.spec().program.editable_program() {
30637 if let Err(error) = validate_program_query_receipts(
30638 program,
30639 task.identity(),
30640 &self.codebooks,
30641 &state,
30642 &edit_choices,
30643 ) {
30644 self.poisoned = true;
30645 return Err(error);
30646 }
30647 for lane in 0..2 {
30648 for slot in 0..2 {
30649 let choices = &edit_choices[lane][slot];
30650 let receipt = &state.semantic_receipts[1 + lane * 3 + slot];
30651 if choices[0] == 1 && choices[1] == 2 {
30652 let previous = (slot == 1).then_some(&edit_choices[lane][0]);
30653 match validated_rule_receipt(
30654 &self.codebooks,
30655 program,
30656 task.identity(),
30657 lane,
30658 slot,
30659 choices,
30660 previous,
30661 receipt,
30662 ) {
30663 Ok((decoded, _)) => program_rules[lane][slot] = Some(decoded.rule),
30664 Err(error) => {
30665 self.poisoned = true;
30666 return Err(error);
30667 }
30668 }
30669 } else if choices[0] == 1 || receipt[1] == 3 {
30670 self.poisoned = true;
30671 return Err(SemanticTransitionError::ObservationMismatch);
30672 }
30673 }
30674 }
30675 }
30676 }
30677 let lanes = std::array::from_fn(|i| {
30678 let task_refusal = if task_evaluation.is_some() {
30679 match state.task_evaluation.lane_refusal[i] {
30680 1 => Some(SemanticTaskRefusal::Scope),
30681 2 => Some(SemanticTaskRefusal::HardConstraint),
30682 3 => Some(SemanticTaskRefusal::FactCapacity),
30683 4 => Some(SemanticTaskRefusal::FuelExhausted),
30684 _ => None,
30685 }
30686 } else {
30687 None
30688 };
30689 let root =
30690 (task_refusal.is_none() && state.retired_roots_mask & (1 << i) == 0).then(|| {
30691 self.graph
30692 .observe_transition_root(state.semantic_receipts[3 + i * 3])
30693 });
30694 if self.graph.ensure_not_poisoned().is_err() {
30695 if let Some(Err(error)) = &root {
30696 integrity_error.get_or_insert_with(|| error.clone());
30697 }
30698 }
30699 let edits = std::array::from_fn(|j| {
30700 let result = if program_rules[i][j].is_some() {
30701 Ok(None)
30702 } else {
30703 self.graph
30704 .observe_transition_edit(state.semantic_receipts[1 + i * 3 + j])
30705 };
30706 if self.graph.ensure_not_poisoned().is_err() {
30707 if let Err(error) = &result {
30708 integrity_error.get_or_insert_with(|| error.clone());
30709 }
30710 }
30711 result
30712 });
30713 SemanticTransitionLane {
30714 root,
30715 task_refusal,
30716 program_rules: program_rules[i],
30717 edits,
30718 work: state.work[i],
30719 }
30720 });
30721 if let Some(error) = integrity_error {
30722 return Err(SemanticTransitionError::Semantic(error));
30723 }
30724 if let Some((_, (root, snapshot), _)) = published {
30725 self.root = root;
30726 self.base_snapshot = snapshot;
30727 }
30728 self.next_proposal = state.next_proposal;
30729 if let Ok(proposal) = u32::try_from(self.next_proposal) {
30730 self.rng = Some(SemanticRngBinding { proposal, ..rng });
30731 }
30732 Ok(SemanticTransitionOutcome::Published(
30733 SemanticTransitionObservation {
30734 components,
30735 root_handle: self.root,
30736 root: self.base_snapshot,
30737 next_proposal: state.next_proposal,
30738 lanes,
30739 importance_weight: state.importance_weight,
30740 task_evaluation,
30741 },
30742 ))
30743 }
30744
30745 fn reconcile_refusal(
30746 &mut self,
30747 state: &DeviceState,
30748 expected_proposal: u32,
30749 ) -> Result<SemanticTransitionRefusal, SemanticTransitionError> {
30750 let rng = self
30751 .rng
30752 .ok_or(SemanticTransitionError::ObservationMismatch)?;
30753 if rng.proposal != expected_proposal || u64::from(expected_proposal) != self.next_proposal {
30754 return Err(SemanticTransitionError::ObservationMismatch);
30755 }
30756 let refusal = refused_terminal(
30757 state,
30758 rng,
30759 SemanticActionCatalogue::current().binding(),
30760 self.binding().digest,
30761 None,
30762 )?;
30763 let storage = Arc::clone(
30764 self.publication
30765 .as_ref()
30766 .ok_or(SemanticTransitionError::NotBound)?,
30767 );
30768 let (token, base_word, _) = self
30769 .admitted_transition
30770 .ok_or(SemanticTransitionError::ObservationMismatch)?;
30771 let original = Arc::clone(
30772 self.text_binding
30773 .as_ref()
30774 .ok_or(SemanticTransitionError::ObservationMismatch)?,
30775 );
30776 let reader = self
30777 .readers
30778 .get(&token)
30779 .ok_or(SemanticTransitionError::ObservationMismatch)?;
30780 let step = self
30781 .steps
30782 .get(&token)
30783 .ok_or(SemanticTransitionError::ObservationMismatch)?;
30784 if self.continuation_base != Some(base_word)
30785 || original._witness.reader_token != token
30786 || original.published_parent()?.0 != (base_word & 1) as usize
30787 || !Arc::ptr_eq(&original._witness.issuer, &self.publication_issuer)
30788 || !Arc::ptr_eq(&original._witness._witness, &step.content_witnesses)
30789 || step
30790 .content
30791 .get(original._witness.index)
30792 .is_none_or(|content| !matches!(content.seals, TensorContentSeals::Captured(_)))
30793 {
30794 return Err(SemanticTransitionError::ObservationMismatch);
30795 }
30796 let lease_view = reader.device.view();
30797 let lease = self.publication_read(lease_view)?[0];
30798 let control = self.publication_read(storage.control.view())?[0];
30799 if lease.abi != 1
30800 || lease.status != 0
30801 || lease.active != 1
30802 || lease.instance != storage.instance
30803 || lease.word != base_word
30804 || lease.bank != base_word & 1
30805 || lease.epoch != base_word >> 1
30806 || control.reader_counts[lease.bank as usize] == 0
30807 || control.abi != 1
30808 || control.instance != storage.instance
30809 || control.word != base_word
30810 || control.reader_gate != 0
30811 || control.refusal != 0
30812 {
30813 return Err(SemanticTransitionError::ObservationMismatch);
30814 }
30815 let (bank, parent_header) = original.published_parent()?;
30816 let header = self.read_publication_header(bank)?;
30817 if header != parent_header
30818 || header.abi != 1
30819 || header.instance != storage.instance
30820 || header.publication_word != base_word
30821 || header.sealed_epoch != base_word >> 1
30822 || header.proposal != state.proposal
30823 || header.model_generation != u64::from(state.model_generation)
30824 || header.family_id != u64::from(state.family_id)
30825 || header.stream_serial != state.stream_serial
30826 {
30827 return Err(SemanticTransitionError::ObservationMismatch);
30828 }
30829 let (root, snapshot) = self.observe_publication_root(state, &header, 0)?;
30832 if root != self.root || snapshot != self.base_snapshot {
30833 return Err(SemanticTransitionError::ObservationMismatch);
30834 }
30835 refused_root_cleanup(
30836 state,
30837 self.graph.transition_arena()[1],
30838 u64::from(root.slot()),
30839 root.generation(),
30840 )?;
30841 Ok(refusal)
30842 }
30843
30844 fn observe_publication_root(
30845 &mut self,
30846 state: &DeviceState,
30847 header: &PublicationHeader,
30848 index: usize,
30849 ) -> Result<(SemanticRootHandle, SemanticRootSnapshot), SemanticTransitionError> {
30850 let (root, snapshot) = self
30851 .graph
30852 .observe_transition_root(state.semantic_receipts[index])
30853 .map_err(SemanticTransitionError::Semantic)?;
30854 let extents = snapshot.extents();
30855 if header.semantic_owner != self.graph.transition_arena()[1]
30856 || header.semantic_slot != u64::from(root.slot())
30857 || header.semantic_generation != root.generation()
30858 || header.semantic_digest.as_bytes() != snapshot.digest().as_bytes()
30859 || header.semantic_extents
30860 != [
30861 u64::from(extents.statements()),
30862 u64::from(extents.supports()),
30863 u64::from(extents.versions()),
30864 ]
30865 {
30866 return Err(SemanticTransitionError::ObservationMismatch);
30867 }
30868 Ok((root, snapshot))
30869 }
30870
30871 fn reconcile_publication(
30872 &mut self,
30873 state: &DeviceState,
30874 expected_proposal: u32,
30875 ) -> Result<
30876 (
30877 PublicationHeader,
30878 (SemanticRootHandle, SemanticRootSnapshot),
30879 SemanticTransitionKind,
30880 ),
30881 SemanticTransitionError,
30882 > {
30883 let storage = Arc::clone(
30884 self.publication
30885 .as_ref()
30886 .ok_or(SemanticTransitionError::NotBound)?,
30887 );
30888 let (_, base_word, kind) = self
30889 .admitted_transition
30890 .ok_or(SemanticTransitionError::ObservationMismatch)?;
30891 let control = self.publication_read(storage.control.view())?[0];
30892 if control.refusal != 0 || state.status == 10 {
30893 return Err(SemanticTransitionError::PublicationRefused {
30894 status: control.refusal,
30895 });
30896 }
30897 let epoch = (base_word >> 1)
30898 .checked_add(1)
30899 .filter(|&epoch| epoch <= u64::MAX >> 1)
30900 .ok_or(SemanticTransitionError::GenerationExhausted)?;
30901 let expected_word = (epoch << 1) | ((base_word ^ 1) & 1);
30902 if state.status != 0
30903 || control.abi != 1
30904 || control.instance != storage.instance
30905 || control.word != expected_word
30906 || self.continuation_base != Some(base_word)
30907 || u64::from(expected_proposal) != self.next_proposal
30908 {
30909 return Err(SemanticTransitionError::ObservationMismatch);
30910 }
30911 let header = self.read_publication_header((expected_word & 1) as usize)?;
30912 let next_proposal = self
30913 .next_proposal
30914 .checked_add(u64::from(kind == SemanticTransitionKind::Proposal))
30915 .ok_or(SemanticTransitionError::GenerationExhausted)?;
30916 if header.abi != 1
30917 || header.instance != control.instance
30918 || header.base_word != base_word
30919 || header.publication_word != expected_word
30920 || header.sealed_epoch != epoch
30921 || header.proposal != next_proposal
30922 {
30923 return Err(SemanticTransitionError::ObservationMismatch);
30924 }
30925 let winner = if kind == SemanticTransitionKind::Proposal {
30926 state.task_evaluation.winner
30927 } else {
30928 0
30929 };
30930 let index = match winner {
30931 0 => 0,
30932 1 => 3,
30933 2 => 6,
30934 _ => return Err(SemanticTransitionError::ObservationMismatch),
30935 };
30936 if winner > 0 && state.retired_roots_mask & (1 << (winner - 1)) != 0 {
30937 return Err(SemanticTransitionError::ObservationMismatch);
30938 }
30939 let root = self.observe_publication_root(state, &header, index)?;
30940 Ok((header, root, kind))
30941 }
30942
30943 fn ensure_quiescent(&self) -> Result<(), SemanticTransitionError> {
30944 if self.is_poisoned() {
30945 Err(SemanticTransitionError::Poisoned)
30946 } else if self.pending {
30947 Err(SemanticTransitionError::OverlappingLaunch)
30948 } else {
30949 Ok(())
30950 }
30951 }
30952
30953 fn ensure_rebindable(&self) -> Result<(), SemanticTransitionError> {
30954 if self.initial_prefill.is_some() {
30955 return Err(publication_input_error(
30956 "an imported task's initial prefill stage cannot be rebound",
30957 ));
30958 }
30959 self.ensure_rebindable_with_prefill()
30960 }
30961
30962 fn ensure_rebindable_with_prefill(&self) -> Result<(), SemanticTransitionError> {
30963 self.ensure_quiescent()?;
30964 #[cfg(feature = "semantic-policy")]
30965 self.require_closed_evaluations()?;
30966 validate_rebinding_ownership(
30967 self.prepared_segment.as_ref(),
30968 self.steps.values().any(|step| step.identity.is_none()),
30969 )?;
30970 if self.task_observed {
30971 return Err(SemanticTransitionError::UnpublishedTask);
30972 }
30973 #[cfg(feature = "semantic-policy")]
30974 if self.policy.as_ref().is_some_and(|policy| policy.tape_live) {
30975 return Err(SemanticTransitionError::UnconsumedPolicyTape);
30976 }
30977 Ok(())
30978 }
30979
30980 fn transition_kernel_io(&self) -> TransitionKernelIo<'_> {
30981 let logits = &self.logits;
30982 let text = self.text_binding.as_deref();
30983 #[cfg(feature = "semantic-policy")]
30984 let (logits, text) = self.policy.as_ref().map_or((logits, text), |policy| {
30985 (&policy.text_logits, Some(policy.text_binding.as_ref()))
30986 });
30987 TransitionKernelIo {
30988 logits,
30989 support: &self.support,
30990 receipts: &self.receipts,
30991 state: &self.state,
30992 text,
30993 model_work: None,
30994 replay_custody: None,
30995 model_update: None,
30996 lease: self
30997 .admitted_transition
30998 .map(|(token, _, _)| &self.readers[&token].device),
30999 #[cfg(feature = "semantic-policy")]
31000 policy: self.policy.as_ref(),
31001 training_selection: None,
31002 }
31003 }
31004
31005 #[cfg(feature = "semantic-policy")]
31006 fn prepared_kernel_io(
31007 &self,
31008 step: &SemanticPreparedStep,
31009 bank: usize,
31010 ) -> Result<TransitionKernelIo<'_>, SemanticTransitionError> {
31011 let prepared = self
31012 .steps
31013 .get(&step.token)
31014 .and_then(|owner| owner.prepared.as_ref())
31015 .ok_or_else(|| {
31016 publication_input_error("prepared transition has no original storage")
31017 })?;
31018 let branch = prepared
31019 .branches
31020 .get(bank)
31021 .ok_or_else(|| publication_input_error("prepared transition bank is invalid"))?;
31022 let policy = branch.policy.as_ref();
31023 let text = &branch
31024 .continuation
31025 .as_ref()
31026 .ok_or_else(|| {
31027 publication_input_error("prepared transition has no original continuation")
31028 })?
31029 .text_binding;
31030 let logits = match policy {
31031 Some(policy) => &policy.text_logits,
31032 None => {
31033 &branch
31034 .policy_buffers
31035 .as_ref()
31036 .ok_or_else(|| {
31037 publication_input_error("prepared transition has no retained cold buffers")
31038 })?
31039 .text_logits
31040 }
31041 };
31042 Ok(TransitionKernelIo {
31043 logits,
31046 support: branch
31047 .support
31048 .as_ref()
31049 .ok_or_else(|| publication_input_error("prepared support has retired"))?,
31050 receipts: branch
31051 .receipts
31052 .as_ref()
31053 .ok_or_else(|| publication_input_error("prepared receipts have retired"))?,
31054 state: &branch.state,
31055 text: Some(text),
31056 lease: Some(&prepared.reader),
31057 policy,
31058 model_work: prepared.model_work.as_ref(),
31059 replay_custody: prepared.replay_custody.as_ref(),
31060 model_update: branch.model_update.as_ref(),
31061 training_selection: branch
31062 .continuation
31063 .as_ref()
31064 .and_then(|continuation| continuation.training_selection.as_ref()),
31065 })
31066 }
31067
31068 #[cfg(feature = "semantic-policy")]
31069 fn prepared_drain_kernel_io(
31070 &self,
31071 step: &SemanticPreparedStep,
31072 ) -> Result<TransitionKernelIo<'_>, SemanticTransitionError> {
31073 let prepared = self
31074 .steps
31075 .get(&step.token)
31076 .and_then(|owner| owner.prepared.as_ref())
31077 .ok_or_else(|| publication_input_error("prepared drain has no original storage"))?;
31078 let branch = &prepared.branches[0];
31079 let logits = if let Some(policy) = branch.policy.as_ref() {
31080 &policy.text_logits
31081 } else {
31082 &branch
31083 .policy_buffers
31084 .as_ref()
31085 .ok_or_else(|| {
31086 publication_input_error("prepared drain has no retained cold buffers")
31087 })?
31088 .text_logits
31089 };
31090 Ok(TransitionKernelIo {
31091 logits,
31092 support: branch
31093 .support
31094 .as_ref()
31095 .ok_or_else(|| publication_input_error("prepared support has retired"))?,
31096 receipts: branch
31097 .receipts
31098 .as_ref()
31099 .ok_or_else(|| publication_input_error("prepared receipts have retired"))?,
31100 state: &branch.state,
31101 text: None,
31102 lease: Some(&prepared.reader),
31103 policy: None,
31104 model_work: None,
31105 model_update: None,
31106 training_selection: None,
31107 replay_custody: None,
31108 })
31109 }
31110
31111 fn descriptor(&self) -> Descriptor {
31112 self.descriptor_with(&self.transition_kernel_io())
31113 }
31114
31115 fn descriptor_with(&self, io: &TransitionKernelIo<'_>) -> Descriptor {
31116 #[cfg(not(feature = "semantic-policy"))]
31117 let policy = PolicyDescriptor::default();
31118 #[cfg(feature = "semantic-policy")]
31119 let policy = io.policy.map_or(PolicyDescriptor::default(), |policy| {
31120 Self::retained_policy_descriptor(&policy.buffers)
31121 });
31122 Descriptor {
31123 logits: 0,
31124 support: 0,
31125 scratch: self.scratch.device_ptr_value(),
31126 receipts: 0,
31127 state: 0,
31128 components: self.device_components.device_ptr_value(),
31129 codebooks: self.device_codebooks.device_ptr_value(),
31130 arena: self.graph.transition_arena(),
31131 policy: PolicyDescriptor::default(),
31132 backward: PolicyBackward::default(),
31133 task: self
31134 .task
31135 .as_ref()
31136 .map_or(0, |(_, device)| device.device_ptr_value()),
31137 task_words: self
31138 .task
31139 .as_ref()
31140 .map_or(0, |(_, device)| device.len() as u64),
31141 task_return_bound: self
31142 .task
31143 .as_ref()
31144 .map_or(0, |(binding, _)| binding.objective_law.return_bound as u64),
31145 publication: PublicationCommand {
31146 control: self
31147 .publication
31148 .as_ref()
31149 .map_or(0, |storage| storage.control.device_ptr_value()),
31150 lease: 0,
31151 operation: 0,
31152 },
31153 text: TextBinding::default(),
31154 model_work: ModelWorkInput::default(),
31155 replay: io.replay_custody.map_or(
31156 PreparedReplayDescriptor::default(),
31157 PreparedReplayCustody::descriptor,
31158 ),
31159 }
31160 .with_transition(TransitionKernelPointers {
31161 logits: io.logits.device_ptr_value(),
31162 support: io.support.device_ptr_value(),
31163 receipts: io.receipts.device_ptr_value(),
31164 state: io.state.device_ptr_value(),
31165 lease: io.lease.map_or(0, TrackedCudaSlice::device_ptr_value),
31166 text: io
31167 .text
31168 .map_or(TextBinding::default(), TextBindingStorage::descriptor),
31169 policy,
31170 model_work: io
31171 .model_work
31172 .map_or(ModelWorkInput::default(), PreparedModelWork::descriptor),
31173 })
31174 }
31175
31176 #[cfg(feature = "semantic-policy")]
31177 fn retained_policy_descriptor(policy: &PolicyBuffers) -> PolicyDescriptor {
31178 let parameter = |offset: usize| policy.parameters.device_ptr_value() + (offset * 4) as u64;
31179 let mut retained_offset = 0usize;
31180 let fields = std::array::from_fn(|i| {
31181 let field = &policy.layout.fields[i];
31182 let result = PolicyField {
31183 embeddings: if field.embeddings.is_empty() {
31184 0
31185 } else {
31186 parameter(field.embeddings.start)
31187 },
31188 biases: if field.biases.is_empty() {
31189 0
31190 } else {
31191 parameter(field.biases.start)
31192 },
31193 cardinality: field.cardinality as u32,
31194 null_category: field.null_category.map_or(-1, |index| index as i32),
31195 retained_offset: retained_offset as u64,
31196 };
31197 retained_offset += field.cardinality;
31198 result
31199 });
31200 PolicyDescriptor {
31201 z: parameter(policy.layout.z.start),
31202 recurrence: parameter(policy.layout.recurrence.start),
31203 positions: parameter(policy.layout.positions.start),
31204 hidden: policy.hidden.device_ptr_value(),
31205 scores: policy.scores.device_ptr_value(),
31206 recurrent: policy.recurrent.device_ptr_value(),
31207 retained_scores: policy.retained_scores.device_ptr_value(),
31208 retained_score_stride: policy.layout.retained_score_stride() as u64,
31209 final_masks: policy.final_masks.device_ptr_value(),
31210 active_sets: policy.active_sets.device_ptr_value(),
31211 pwl_cells: policy.pwl_cells.device_ptr_value(),
31212 selected_score_vjps: policy.selected_score_vjps.device_ptr_value(),
31213 component_baselines: policy.component_baselines.device_ptr_value(),
31214 fields,
31215 numerical: policy.numerical.descriptor(policy.layout.parameter_cells),
31216 }
31217 }
31218
31219 fn validate_ranges(&self) -> Result<(), SemanticTransitionError> {
31220 self.validate_ranges_with(&self.transition_kernel_io())
31221 }
31222
31223 fn validate_ranges_with(
31224 &self,
31225 io: &TransitionKernelIo<'_>,
31226 ) -> Result<(), SemanticTransitionError> {
31227 let d = self.descriptor_with(io);
31228 let mut ranges = vec![
31229 (d.logits, (io.logits.len() * 4) as u64),
31230 (d.support, io.support.len() as u64),
31231 (d.scratch, SCRATCH_BYTES as u64),
31232 (
31233 d.receipts,
31234 (io.receipts.len() * size_of::<SemanticTransitionReceipt>()) as u64,
31235 ),
31236 (d.state, size_of::<DeviceState>() as u64),
31237 (
31238 d.components,
31239 (COMPONENT_COUNT * size_of::<SemanticComponent>()) as u64,
31240 ),
31241 (d.codebooks, (self.codebooks.words.len() * 8) as u64),
31242 (d.arena[0], d.arena[6] * 8),
31243 ];
31244 if let Some((_, device)) = &self.task {
31245 ranges.push((device.device_ptr_value(), (device.len() * 8) as u64));
31246 }
31247 #[cfg(feature = "semantic-policy")]
31248 {
31249 if let Some(policy) = io.policy {
31250 for buffer in policy.numerical.buffers() {
31251 ranges.push((buffer.device_ptr_value(), (buffer.len() * 8) as u64));
31252 }
31253 for buffer in [
31254 &policy.parameters,
31255 &policy.hidden,
31256 &policy.scores,
31257 &policy.retained_scores,
31258 &policy.recurrent,
31259 &policy.component_baselines,
31260 ] {
31261 if !buffer.is_empty() {
31262 ranges.push((buffer.device_ptr_value(), (buffer.len() * 4) as u64));
31263 }
31264 }
31265 for buffer in [&policy.final_masks, &policy.active_sets] {
31266 if !buffer.is_empty() {
31267 ranges.push((buffer.device_ptr_value(), buffer.len() as u64));
31268 }
31269 }
31270 ranges.push((
31271 policy.pwl_cells.device_ptr_value(),
31272 (policy.pwl_cells.len() * size_of::<SemanticPolicyPwlCell>()) as u64,
31273 ));
31274 ranges.push((
31275 policy.selected_score_vjps.device_ptr_value(),
31276 (policy.selected_score_vjps.len() * size_of::<SemanticPolicySelectedScoreVjp>())
31277 as u64,
31278 ));
31279 }
31280 }
31281 if let Some(text) = io.text {
31282 for input in &text.inputs {
31283 if let Some(source) = &input.source {
31284 ranges.push((input.data, source.len() as u64));
31285 }
31286 }
31287 }
31288 if let Some(selection) = io.training_selection {
31289 ranges.push((
31290 *selection.device_ptr(),
31291 size_of::<SemanticTrainingViewSelection>() as u64,
31292 ));
31293 }
31294 if let Some(update) = io.model_update {
31295 ranges.push((
31296 update.bindings.device_ptr_value(),
31297 (update.bindings.len() * size_of::<ModelUpdateBinding>()) as u64,
31298 ));
31299 if let Some(output) = &update.output {
31300 for allocation in &output.allocations {
31301 if let Some(source) = &allocation.source {
31302 ranges.push((allocation.data, source.len() as u64));
31303 }
31304 }
31305 if let Some(source) = &output.admissibility.source {
31306 ranges.push((output.admissibility.data, source.len() as u64));
31307 }
31308 if let Some(source) = &output.baseline_logits.source {
31309 ranges.push((output.baseline_logits.data, source.len() as u64));
31310 }
31311 if let Some(source) = &output.candidate_logits.source {
31312 ranges.push((output.candidate_logits.data, source.len() as u64));
31313 }
31314 }
31315 }
31316 disjoint_ranges(&ranges)
31317 }
31318
31319 fn kernel_recorder(&self) -> LaunchRecorder {
31320 self.kernel_recorder_with(&self.transition_kernel_io())
31321 }
31322
31323 fn kernel_recorder_with(&self, io: &TransitionKernelIo<'_>) -> LaunchRecorder {
31324 let mut recorder = self.domain.new_strict_recorder();
31327 recorder.read(io.logits);
31328 recorder.read(io.support);
31329 if let Some(work) = io.model_work {
31330 recorder.read(&work.device);
31331 recorder.read(&work.actual);
31332 }
31333 if let Some(custody) = io.replay_custody {
31334 custody.record(&mut recorder);
31335 }
31336 if let Some(update) = io.model_update {
31337 update.record(&mut recorder);
31338 }
31339 recorder.write(&self.scratch);
31340 recorder.write(io.receipts);
31341 recorder.read_write(io.state);
31342 recorder.read(&self.device_codebooks);
31343 recorder.read(&self.device_components);
31344 if let Some((_, device)) = &self.task {
31345 recorder.read(device);
31346 }
31347 #[cfg(feature = "semantic-policy")]
31348 if let Some(policy) = io.policy {
31349 policy.numerical.record(&mut recorder);
31350 recorder.read(&policy.parameters);
31351 recorder.read(&policy.component_baselines);
31352 recorder.write(&policy.hidden);
31353 recorder.write(&policy.scores);
31354 recorder.write(&policy.retained_scores);
31355 recorder.write(&policy.final_masks);
31356 recorder.write(&policy.active_sets);
31357 recorder.write(&policy.pwl_cells);
31358 recorder.write(&policy.selected_score_vjps);
31359 recorder.write(&policy.recurrent);
31360 }
31361 self.graph.record_transition(&mut recorder);
31362 if let Some(publication) = &self.publication {
31363 publication.record(&mut recorder);
31364 }
31365 if let Some(lease) = io.lease {
31366 recorder.read(lease);
31367 }
31368 if let Some(text) = io.text {
31369 text.record(&mut recorder);
31370 }
31371 if let Some(selection) = io.training_selection {
31372 recorder.read(selection);
31373 }
31374 recorder
31375 }
31376}
31377
31378fn enqueue_recorded<E: fmt::Display>(
31379 domain: &ResidentExecutionDomain,
31380 poisoned: &mut bool,
31381 recorder: LaunchRecorder,
31382 operation: impl FnOnce(&CudaEnqueue<'_>) -> Result<(), E>,
31383) -> Result<(), SemanticTransitionError> {
31384 let result = unsafe {
31388 domain.enqueue(recorder, |stream| {
31389 *poisoned = true;
31390 operation(stream)
31391 })
31392 };
31393 let enqueued = result.map_err(|e| {
31394 if matches!(
31395 &e,
31396 LaunchEnqueueError::Operation(_) | LaunchEnqueueError::OperationAndCleanup { .. }
31397 ) {
31398 *poisoned = true;
31399 }
31400 runtime_error("enqueue", e)
31401 })?;
31402 enqueued
31403 .commit()
31404 .map_err(|e| runtime_error("enqueue commit", e))?;
31405 *poisoned = false;
31406 Ok(())
31407}
31408
31409fn wait_on_stream<E: fmt::Display>(
31410 stream: &CudaStream,
31411 poisoned: &mut bool,
31412 waits: &mut u64,
31413 operation: &'static str,
31414 wait: impl FnOnce(&CudaStream) -> Result<(), E>,
31415) -> Result<(), SemanticTransitionError> {
31416 *waits += 1;
31417 wait(stream).map_err(|e| {
31418 *poisoned = true;
31419 runtime_error(operation, e)
31420 })
31421}
31422
31423fn validate_bound_inputs(
31424 components: &[SemanticComponent],
31425 rng: SemanticRngBinding,
31426 inputs: &[SemanticComponentInput],
31427) -> Result<(), SemanticTransitionError> {
31428 let invalid = |detail: &str| SemanticTransitionError::InvalidInput {
31429 detail: detail.into(),
31430 };
31431 if rng.stream_serial >= 1u64 << 56 {
31432 return Err(invalid("stream serial exceeds 56 bits"));
31433 }
31434 if inputs.len() != COMPONENT_COUNT {
31435 return Err(invalid("input roster must contain exactly 136 components"));
31436 }
31437 for (component, input) in components.iter().zip(inputs) {
31438 if input.logits.len() != component.cardinality as usize
31439 || input.product_support.len() != input.logits.len()
31440 {
31441 return Err(invalid("logits/support shape differs from the catalogue"));
31442 }
31443 if input.product_support.iter().any(|&m| m > 1) {
31444 return Err(invalid("product support must be binary"));
31445 }
31446 debug_assert!(component.is_text() || component.kind == COMPONENT_KIND_EDIT as u32);
31447 let has_support = input.product_support.contains(&1);
31448 if !has_support {
31449 return Err(invalid("empty product support"));
31450 }
31451 if input
31452 .logits
31453 .iter()
31454 .zip(&input.product_support)
31455 .any(|(&z, &m)| m == 1 && !z.is_finite())
31456 {
31457 return Err(invalid("legal logits must be finite FP32"));
31458 }
31459 }
31460 Ok(())
31461}
31462
31463fn disjoint_ranges(ranges: &[(u64, u64)]) -> Result<(), SemanticTransitionError> {
31464 for (i, &(start, len)) in ranges.iter().enumerate() {
31465 let end = start
31466 .checked_add(len)
31467 .filter(|_| start != 0 && len != 0)
31468 .ok_or(SemanticTransitionError::OverlappingInputs)?;
31469 for &(other, other_len) in &ranges[..i] {
31470 let other_end = other
31471 .checked_add(other_len)
31472 .ok_or(SemanticTransitionError::OverlappingInputs)?;
31473 if start < other_end && other < end {
31474 return Err(SemanticTransitionError::OverlappingInputs);
31475 }
31476 }
31477 }
31478 Ok(())
31479}
31480
31481#[cfg(test)]
31482mod tests {
31483 #[test]
31484 fn raw_prefix_export_retains_the_original_input_seal() {
31485 let range = PublicationRange {
31486 role: 1,
31487 index: 0,
31488 generation: 1,
31489 length_bytes: 64,
31490 logical_begin: 0,
31491 logical_end: 1,
31492 ..PublicationRange::default()
31493 };
31494 let input = StepInputPlan {
31495 role: 1,
31496 index: 0,
31497 layout: committed_prefix_layout(&range, 4).unwrap(),
31498 banks: [
31499 StepInputBankPlan {
31500 storage_slot: 0,
31501 span: 0..256,
31502 },
31503 StepInputBankPlan {
31504 storage_slot: 0,
31505 span: 0..256,
31506 },
31507 ],
31508 };
31509 let raw = publication_record_layout(&range);
31510 let exported = publication_export_span(&range, &raw, 256).unwrap();
31511 assert_eq!(exported, 0..64);
31512 assert!(step_input_alias_matches(
31513 &input,
31514 &range,
31515 4096,
31516 256,
31517 (raw, 0, 0, 4096, exported.len())
31518 ));
31519 assert!(!step_input_alias_matches(
31520 &input,
31521 &range,
31522 4096,
31523 256,
31524 (raw, 0, 0, 4097, exported.len())
31525 ));
31526 assert!(!step_input_alias_matches(
31527 &input,
31528 &range,
31529 4096,
31530 256,
31531 (raw, 0, 1, 4096, exported.len())
31532 ));
31533 assert!(!step_input_alias_matches(
31534 &input,
31535 &range,
31536 4096,
31537 256,
31538 (raw, 0, 0, 4096, 128)
31539 ));
31540 assert!(step_input_alias_matches(
31541 &input,
31542 &range,
31543 4096,
31544 256,
31545 (input.layout, 0, 1, 4096, 256)
31546 ));
31547 let empty = PublicationRange {
31548 length_bytes: 0,
31549 logical_end: 0,
31550 ..range
31551 };
31552 let raw_empty = publication_record_layout(&empty);
31553 assert_eq!(
31554 publication_export_span(&empty, &raw_empty, 256).unwrap(),
31555 0..0
31556 );
31557 assert!(step_input_alias_matches(
31558 &input,
31559 &empty,
31560 4096,
31561 256,
31562 (raw_empty, 0, 0, 4096, 0)
31563 ));
31564 }
31565
31566 #[test]
31567 fn transition_descriptors_preserve_each_original_policy_and_outcome() {
31568 use super::*;
31569 let shared = Descriptor {
31570 logits: 0,
31571 support: 0,
31572 scratch: 8,
31573 receipts: 0,
31574 state: 0,
31575 components: 16,
31576 codebooks: 24,
31577 arena: [32; 7],
31578 policy: PolicyDescriptor::default(),
31579 backward: PolicyBackward::default(),
31580 task: 40,
31581 task_words: 66,
31582 task_return_bound: 0,
31583 publication: PublicationCommand {
31584 control: 48,
31585 lease: 0,
31586 operation: 0,
31587 },
31588 text: TextBinding::default(),
31589 model_work: ModelWorkInput::default(),
31590 replay: PreparedReplayDescriptor::default(),
31591 };
31592 let original = |base| TransitionKernelPointers {
31593 logits: base,
31594 support: base + 8,
31595 receipts: base + 16,
31596 state: base + 24,
31597 lease: base + 32,
31598 text: TextBinding {
31599 rows: base + 40,
31600 count: base + 48,
31601 selected: base + 56,
31602 },
31603 policy: PolicyDescriptor {
31604 z: base + 64,
31605 recurrent: base + 72,
31606 ..PolicyDescriptor::default()
31607 },
31608 model_work: ModelWorkInput {
31609 events: base + 80,
31610 count: base + 88,
31611 bound: base + 96,
31612 },
31613 };
31614 let first = shared.with_transition(original(1024));
31615 let second = shared.with_transition(original(2048));
31616 for (descriptor, base) in [(first, 1024), (second, 2048)] {
31617 assert_eq!(
31618 (
31619 descriptor.logits,
31620 descriptor.support,
31621 descriptor.receipts,
31622 descriptor.state
31623 ),
31624 (base, base + 8, base + 16, base + 24)
31625 );
31626 assert_eq!(
31627 (
31628 descriptor.policy.z,
31629 descriptor.policy.recurrent,
31630 descriptor.publication.lease
31631 ),
31632 (base + 64, base + 72, base + 32)
31633 );
31634 assert_eq!(
31635 (
31636 descriptor.text.rows,
31637 descriptor.text.count,
31638 descriptor.text.selected
31639 ),
31640 (base + 40, base + 48, base + 56)
31641 );
31642 assert_eq!(
31643 (
31644 descriptor.model_work.events,
31645 descriptor.model_work.count,
31646 descriptor.model_work.bound
31647 ),
31648 (base + 80, base + 88, base + 96)
31649 );
31650 assert_eq!(
31651 (
31652 descriptor.scratch,
31653 descriptor.components,
31654 descriptor.codebooks,
31655 descriptor.task
31656 ),
31657 (8, 16, 24, 40)
31658 );
31659 assert_eq!(descriptor.publication.control, 48);
31660 }
31661 assert_ne!(first.policy.recurrent, second.policy.recurrent);
31662 assert_ne!(first.receipts, second.receipts);
31663 }
31664
31665 const COLD_CAPACITY: SemanticSegmentColdCapacity = SemanticSegmentColdCapacity {
31666 tensor_content_capacity: 1,
31667 model_work_capacity: 1,
31668 segment_capacity_bytes: 1,
31669 other_external_cuda_bytes: 0,
31670 };
31671
31672 #[test]
31673 fn prepared_schedule_preserves_each_requested_mode_until_recording() {
31674 let issuer = Arc::new(());
31675 let schedule = [
31676 SemanticTransitionKind::Proposal,
31677 SemanticTransitionKind::Recompute,
31678 SemanticTransitionKind::Proposal,
31679 ];
31680 let mut build = PreparedSegmentState::new(
31681 Arc::clone(&issuer),
31682 vec![4, 5, 6],
31683 schedule.into_iter(),
31684 COLD_CAPACITY,
31685 )
31686 .unwrap();
31687 let steps = build.handles().unwrap();
31688 assert!(build.enter(&steps[1], &issuer).is_err());
31689 for (step, expected) in steps.iter().zip(schedule) {
31690 assert_eq!(build.requested_kind(step, &issuer).unwrap(), expected);
31691 assert_eq!(build.enter(step, &issuer).unwrap(), expected);
31692 build.leave(step, &issuer).unwrap();
31693 }
31694 build.finish().unwrap();
31695 build.submit().unwrap();
31696 assert!(build.submit().is_err());
31697 assert!(build.requested_kind(&steps[0], &Arc::new(())).is_err());
31698 assert!(PreparedSegmentState::new(
31699 Arc::clone(&issuer),
31700 vec![9],
31701 schedule.into_iter(),
31702 COLD_CAPACITY
31703 )
31704 .is_err());
31705 assert!(PreparedSegmentState::new(
31706 issuer,
31707 vec![9],
31708 std::iter::once(SemanticTransitionKind::Drain),
31709 COLD_CAPACITY,
31710 )
31711 .is_err());
31712 }
31713
31714 #[test]
31715 fn prepared_step_scope_rejects_foreign_owners_and_out_of_order_recording() {
31716 let issuer = Arc::new(());
31717 let mut build = PreparedSegmentState::new(
31718 Arc::clone(&issuer),
31719 vec![4, 5],
31720 [
31721 SemanticTransitionKind::Proposal,
31722 SemanticTransitionKind::Proposal,
31723 ]
31724 .into_iter(),
31725 COLD_CAPACITY,
31726 )
31727 .unwrap();
31728 let steps = build.handles().unwrap();
31729 assert!(build.check(&steps[0], &issuer, false).is_ok());
31730 assert!(build.check(&steps[0], &Arc::new(()), false).is_err());
31731 assert!(build.enter(&steps[1], &issuer).is_err());
31732 build.enter(&steps[0], &issuer).unwrap();
31733 assert!(build.check(&steps[0], &issuer, true).is_ok());
31734 assert!(build.check(&steps[1], &issuer, true).is_err());
31735 assert!(build.finish().is_err());
31736 build.leave(&steps[0], &issuer).unwrap();
31737 assert!(build.enter(&steps[0], &issuer).is_err());
31738 build.enter(&steps[1], &issuer).unwrap();
31739 build.leave(&steps[1], &issuer).unwrap();
31740 build.finish().unwrap();
31741 assert!(build.check(&steps[0], &issuer, false).is_err());
31742 assert!(
31743 PreparedSegmentState::new(issuer, Vec::new(), std::iter::empty(), COLD_CAPACITY)
31744 .is_err()
31745 );
31746 }
31747 use super::*;
31748 use xlog_core::MemoryBudget;
31749
31750 #[test]
31751 fn publication_role_roster_preserves_every_required_owner() {
31752 let mut counts = [1; 55];
31753 counts[15] = 3;
31754 assert!(validate_publication_counts(&counts).is_ok());
31755 for code in [1usize, 14, 17, 38, 47, 55] {
31756 let mut omitted = counts;
31757 omitted[code - 1] = 0;
31758 assert!(validate_publication_counts(&omitted).is_err());
31759 }
31760 counts[18] = 0;
31761 counts[19] = 0;
31762 counts[20] = 0;
31763 counts[23] = 0;
31764 counts[24] = 0;
31765 assert!(validate_publication_counts(&counts).is_ok());
31766 counts[50] = 2;
31767 assert!(validate_publication_counts(&counts).is_err());
31768 assert!(SemanticStateRole::from_code(0).is_none());
31769 assert!(SemanticStateRole::from_code(56).is_none());
31770 assert!(SemanticStateRole::from_code(u64::MAX).is_none());
31771 for code in 1..=55 {
31772 assert_eq!(SemanticStateRole::from_code(code).unwrap() as u64, code);
31773 }
31774 }
31775
31776 #[test]
31777 fn prefix_snapshot_copy_respects_owned_capacity_strides() {
31778 let source = SemanticTensorLayout {
31779 role: 4,
31780 index: 0,
31781 element_bytes: 2,
31782 scalar_type: 4,
31783 rank: 4,
31784 logical_axis: 2,
31785 dimensions: [1, 2, 3, 4],
31786 strides_bytes: [48, 24, 8, 2],
31787 };
31788 let destination = prefix_capacity_layout(source, 8).unwrap();
31789 assert_eq!(destination.dimensions, [1, 2, 8, 4]);
31790 assert_eq!(destination.strides_bytes, [128, 64, 8, 2]);
31791 assert_eq!(
31792 tensor_copy_plan(&source, &destination).unwrap(),
31793 [(0, 0, 24), (24, 64, 24)]
31794 );
31795 let mut empty = source;
31796 empty.dimensions[2] = 0;
31797 assert!(tensor_copy_plan(&empty, &destination).unwrap().is_empty());
31798 }
31799
31800 #[cfg(feature = "semantic-policy")]
31801 #[test]
31802 fn policy_score_cotangent_admission_requires_exact_fp64_metadata() {
31803 use crate::dlpack::{DLDataType, DLDevice, DLTensor, K_DLCUDA, K_DLFLOAT, K_DLINT};
31804
31805 let mut shape = [COMPONENT_COUNT as i64];
31806 let mut stride = [1i64];
31807 let mut tensor = DLTensor {
31810 data: 4096usize as *mut std::ffi::c_void,
31811 device: DLDevice {
31812 device_type: K_DLCUDA,
31813 device_id: 0,
31814 },
31815 ndim: 1,
31816 dtype: DLDataType {
31817 code: K_DLFLOAT,
31818 bits: 64,
31819 lanes: 1,
31820 },
31821 shape: shape.as_mut_ptr(),
31822 strides: std::ptr::null_mut(),
31823 byte_offset: 0,
31824 };
31825 let admit = |tensor: &DLTensor| unsafe { policy_score_cotangent_metadata(tensor, 0) };
31827 assert_eq!(
31828 admit(&tensor).unwrap(),
31829 (4096, COMPONENT_COUNT * size_of::<f64>())
31830 );
31831 tensor.strides = stride.as_mut_ptr();
31832 tensor.byte_offset = 8;
31833 assert_eq!(
31834 admit(&tensor).unwrap(),
31835 (4104, COMPONENT_COUNT * size_of::<f64>())
31836 );
31837 tensor.byte_offset = 0;
31838 tensor.dtype.code = K_DLINT;
31839 assert!(
31840 admit(&tensor).is_err(),
31841 "Int64 cells must not be bitcast as FP64 cotangents"
31842 );
31843 tensor.dtype.code = K_DLFLOAT;
31844 tensor.dtype.bits = 32;
31845 assert!(admit(&tensor).is_err());
31846 tensor.dtype.bits = 64;
31847 tensor.dtype.lanes = 2;
31848 assert!(admit(&tensor).is_err());
31849 tensor.dtype.lanes = 1;
31850 for extent in [0, COMPONENT_COUNT as i64 - 1, COMPONENT_COUNT as i64 + 1] {
31851 shape[0] = extent;
31852 assert!(admit(&tensor).is_err());
31853 }
31854 shape[0] = COMPONENT_COUNT as i64;
31855 tensor.shape = shape.as_mut_ptr();
31856 stride[0] = 2;
31857 assert!(matches!(
31858 admit(&tensor),
31859 Err(SemanticTransitionError::InvalidInput { .. })
31860 ));
31861 stride[0] = 1;
31862 tensor.strides = stride.as_mut_ptr();
31863 tensor.ndim = 2;
31864 assert!(admit(&tensor).is_err());
31865 tensor.ndim = 1;
31866 tensor.device.device_id = 1;
31867 assert!(admit(&tensor).is_err());
31868 tensor.device.device_id = 0;
31869 tensor.byte_offset = 4;
31870 assert!(admit(&tensor).is_err());
31871 }
31872
31873 #[cfg(feature = "semantic-policy")]
31874 #[test]
31875 #[ignore = "requires an explicitly authorized CUDA runtime"]
31876 fn policy_dlpack_binding_snapshots_actual_producer_allocations() {
31877 policy_dlpack_binding_fixture(PolicyFixtureCompletion::Backward);
31878 }
31879
31880 #[cfg(feature = "semantic-policy")]
31881 #[test]
31882 #[ignore = "requires an explicitly authorized CUDA runtime"]
31883 fn policy_inference_finish_retires_published_and_refused_original_owners() {
31884 for completion in [
31885 PolicyFixtureCompletion::Inference,
31886 PolicyFixtureCompletion::NumericalRefusal,
31887 ] {
31888 policy_dlpack_binding_fixture(completion);
31889 }
31890 }
31891
31892 #[cfg(feature = "semantic-policy")]
31893 #[derive(Clone, Copy)]
31894 enum PolicyFixtureCompletion {
31895 Backward,
31896 Inference,
31897 NumericalRefusal,
31898 }
31899
31900 #[cfg(feature = "semantic-policy")]
31901 fn policy_dlpack_binding_fixture(completion: PolicyFixtureCompletion) {
31902 use crate::memory::CudaColumn;
31903 use xlog_core::{ScalarType, Schema};
31904
31905 let provider = Arc::new(
31907 crate::CudaProviderBuilder::new(0, MemoryBudget::with_limit(4 * 1024 * 1024 * 1024))
31908 .with_stream_capacity(1)
31909 .build()
31910 .unwrap(),
31911 );
31912 let runtime = Arc::clone(provider.memory().runtime().unwrap());
31913 let id = runtime.stream_pool().acquire().unwrap();
31914 let stream = runtime.stream_pool().resolve(id).unwrap();
31915 let domain = provider
31916 .bind_resident_execution_domain(runtime, id, stream)
31917 .unwrap();
31918 let mut session =
31919 super::text_parent_tests::publication_test_session(Arc::clone(&provider), &domain);
31920 session
31921 .bind_parent(super::text_parent_tests::publication_test_parent(&provider))
31922 .unwrap();
31923 let mut parent = session.acquire().unwrap();
31924 session
31925 .admit_transition(&parent, SemanticTransitionKind::Proposal)
31926 .unwrap();
31927 let (continuation, witness) =
31928 super::text_parent_tests::publication_test_continuation_with_numerical_admissibility(
31929 &mut session,
31930 &parent,
31931 &provider,
31932 u8::from(!matches!(
31933 completion,
31934 PolicyFixtureCompletion::NumericalRefusal
31935 )),
31936 );
31937 session
31938 .bind_continuation(&parent, continuation, &witness, 1)
31939 .unwrap();
31940 let witness = if matches!(completion, PolicyFixtureCompletion::Backward) {
31941 drop(witness);
31942 None
31943 } else {
31944 Some(witness)
31945 };
31946 let layout = session.policy_layout().unwrap();
31947 let mut logits = provider
31948 .memory()
31949 .alloc::<f32>(32 * TEXT_CARDINALITY)
31950 .unwrap();
31951 let mut support = provider
31952 .memory()
31953 .alloc::<u8>(session.codebooks.input_cells)
31954 .unwrap();
31955 let mut parameters = provider
31956 .memory()
31957 .alloc::<f32>(layout.parameter_cells)
31958 .unwrap();
31959 let mut component_baselines = provider.memory().alloc::<f32>(COMPONENT_COUNT).unwrap();
31960 provider
31961 .htod_sync_copy_into_tracked(&vec![2.0; logits.len()], &mut logits)
31962 .unwrap();
31963 provider
31964 .htod_sync_copy_into_tracked(&vec![1u8; support.len()], &mut support)
31965 .unwrap();
31966 provider
31967 .htod_sync_copy_into_tracked(&vec![3.0; parameters.len()], &mut parameters)
31968 .unwrap();
31969 provider
31970 .htod_sync_copy_into_tracked(
31971 &vec![0.5; component_baselines.len()],
31972 &mut component_baselines,
31973 )
31974 .unwrap();
31975 let original_logit = logits.view().slice(0..1);
31976 let original_support = support.view().slice(0..1);
31977 let original_parameter = parameters.view().slice(0..1);
31978 let layouts = policy_numerical_producer_layouts(
31979 session.codebooks.input_cells,
31980 layout.parameter_cells,
31981 )
31982 .unwrap();
31983 let mut sources = vec![
31984 logits.into_bytes().view(),
31985 support.view(),
31986 parameters.into_bytes().view(),
31987 component_baselines.into_bytes().view(),
31988 ];
31989 for (index, numerical_layout) in layouts.iter().enumerate().skip(4) {
31990 let cells = numerical_layout.dimensions[..numerical_layout.rank as usize]
31991 .iter()
31992 .product::<u64>() as usize;
31993 let values = match index {
31996 4 | 5 => vec![0.0; cells],
31997 6..=8 => {
31998 let magnitude = [3.0, 2.0, 0.5][index - 6];
31999 [magnitude, 0.0, 0.0, magnitude].repeat(cells / 4)
32000 }
32001 _ => unreachable!("five original numerical inputs"),
32002 };
32003 let mut numerical = provider.memory().alloc::<f64>(cells).unwrap();
32004 provider
32005 .htod_sync_copy_into_tracked(&values, &mut numerical)
32006 .unwrap();
32007 sources.push(numerical.into_bytes().view());
32008 }
32009 let publication = Arc::clone(session.publication.as_ref().unwrap());
32010 let export = |view: DeviceMemoryView<u8>, tensor_layout: SemanticTensorLayout| {
32011 let rank = tensor_layout.rank as usize;
32012 export_owned_allocation(
32013 view,
32014 tensor_layout.dimensions[..rank]
32015 .iter()
32016 .map(|&n| n as i64)
32017 .collect(),
32018 tensor_layout.strides_bytes[..rank]
32019 .iter()
32020 .map(|&n| (n / tensor_layout.element_bytes) as i64)
32021 .collect(),
32022 (
32023 if tensor_layout.scalar_type == 8 { 6 } else { 2 },
32024 (tensor_layout.element_bytes * 8) as u8,
32025 ),
32026 provider.device().ordinal() as i32,
32027 Arc::new(()),
32028 Arc::clone(&publication),
32029 None,
32030 None,
32031 )
32032 };
32033 let capture = sources
32034 .iter()
32035 .cloned()
32036 .zip(layouts)
32037 .map(|(view, layout)| SemanticTensorInput {
32038 tensor: export(view, layout),
32039 layout,
32040 logical_begin: 0,
32041 logical_end: 0,
32042 native_allocation: None,
32043 })
32044 .collect();
32045 let policy_witness = session.capture_tensor_content(&parent, capture, 1).unwrap();
32046 let producers = sources
32047 .into_iter()
32048 .zip(layouts)
32049 .map(|(view, layout)| export(view, layout))
32050 .collect::<Vec<_>>();
32051 let [logits, support, parameters, component_baselines, numerical @ ..]:
32052 [DlpackManagedTensor; 9] = producers.try_into().ok().unwrap();
32053 let rng = session.continuation_rng(&parent).unwrap();
32054 let original_components = session.device_components.device_ptr_value();
32055 let original_codebooks = session.device_codebooks.device_ptr_value();
32056 let before_policy_binding = session.host_io_stats();
32057 session
32058 .bind_policy_dlpack(
32059 &parent,
32060 session.binding(),
32061 rng,
32062 logits,
32063 support,
32064 parameters,
32065 component_baselines,
32066 numerical,
32067 &policy_witness,
32068 1,
32069 )
32070 .unwrap();
32071 assert_eq!(
32072 session.host_io_stats(),
32073 before_policy_binding,
32074 "policy binding must not upload state or immutable catalogue metadata"
32075 );
32076 let policy = session.policy.as_ref().unwrap();
32079 assert_ne!(
32080 policy.text_logits.device_ptr_value(),
32081 *original_logit.device_ptr()
32082 );
32083 assert_ne!(
32084 session.support.device_ptr_value(),
32085 *original_support.device_ptr()
32086 );
32087 assert_ne!(
32088 policy.parameters.device_ptr_value(),
32089 *original_parameter.device_ptr()
32090 );
32091 let read = |view: crate::memory::DeviceMemoryView<f32>| {
32092 provider.device().inner().dtoh_sync_copy(&view).unwrap()[0]
32093 };
32094 assert_eq!(
32095 read(
32096 session
32097 .policy
32098 .as_ref()
32099 .unwrap()
32100 .text_logits
32101 .view()
32102 .slice(0..1)
32103 ),
32104 2.0
32105 );
32106 assert_eq!(
32107 read(
32108 session
32109 .policy
32110 .as_ref()
32111 .unwrap()
32112 .parameters
32113 .view()
32114 .slice(0..1)
32115 ),
32116 3.0
32117 );
32118 assert_eq!(
32119 provider
32120 .device()
32121 .inner()
32122 .dtoh_sync_copy(&session.support.view().slice(0..1))
32123 .unwrap(),
32124 [1u8]
32125 );
32126 assert_eq!(session.rng, Some(rng));
32127 if matches!(completion, PolicyFixtureCompletion::Backward) {
32129 assert!(session.release(&mut parent, &[1]).is_err());
32130 }
32131 session.capture().unwrap();
32132 let before_launch = session.host_io_stats();
32133 session.launch().unwrap();
32134 assert_eq!(session.host_io_stats(), before_launch);
32135 let outcome = session.observe(0).unwrap();
32136 assert_eq!(
32137 session.device_components.device_ptr_value(),
32138 original_components
32139 );
32140 assert_eq!(
32141 session.device_codebooks.device_ptr_value(),
32142 original_codebooks
32143 );
32144 assert_eq!(
32145 *session.policy_tapes[0].components.device_ptr(),
32146 original_components
32147 );
32148 assert_eq!(
32149 *session.policy_tapes[0].codebooks.device_ptr(),
32150 original_codebooks
32151 );
32152 match (&completion, &outcome) {
32153 (
32154 PolicyFixtureCompletion::NumericalRefusal,
32155 SemanticTransitionOutcome::Refused(
32156 SemanticTransitionRefusal::NonFinitePolicyInput { completed_draws: 0 },
32157 ),
32158 ) => {}
32159 (
32160 PolicyFixtureCompletion::Backward | PolicyFixtureCompletion::Inference,
32161 SemanticTransitionOutcome::Published(_),
32162 ) => {}
32163 _ => panic!("policy fixture returned the wrong native outcome: {outcome:?}"),
32164 }
32165 let parent_identity = session.retained_step_identity(&parent).unwrap();
32166 session.release_published_reader(&mut parent, &[1]).unwrap();
32167 assert!(!parent.active && !session.readers.contains_key(&parent.token));
32168 assert_eq!(
32169 session.retained_step_identity(&parent).unwrap(),
32170 parent_identity
32171 );
32172 assert!(session.published_identity(&parent).is_err());
32173 if !matches!(completion, PolicyFixtureCompletion::Backward) {
32174 let mut foreign_session =
32175 super::text_parent_tests::publication_test_session(Arc::clone(&provider), &domain);
32176 foreign_session
32177 .bind_parent(super::text_parent_tests::publication_test_parent(&provider))
32178 .unwrap();
32179 let mut foreign_parent = foreign_session.acquire().unwrap();
32180 let parent_identity = session.retained_step_identity(&parent).unwrap();
32181 let witness_owners = Arc::strong_count(&session.steps[&parent.token].content_witnesses);
32182 assert!(witness_owners > 1);
32183 assert_eq!(session.policy_tapes.len(), 1);
32184 assert_eq!(session.policy_tapes[0].invocation, rng);
32185 let before_final_use = session.host_io_stats();
32186 for invalid_stream in [0, 2] {
32187 assert!(session
32188 .finish_policy_invocation(&parent, rng, invalid_stream)
32189 .is_err());
32190 assert_eq!(session.policy_tapes.len(), 1);
32191 assert_eq!(session.policy_tapes[0].invocation, rng);
32192 assert_eq!(
32193 Arc::strong_count(&session.steps[&parent.token].content_witnesses),
32194 witness_owners
32195 );
32196 }
32197 assert!(session
32198 .finish_policy_invocation(&foreign_parent, rng, 1)
32199 .is_err());
32200 assert_eq!(session.policy_tapes.len(), 1);
32201 assert_eq!(session.policy_tapes[0].invocation, rng);
32202 assert_eq!(
32203 Arc::strong_count(&session.steps[&parent.token].content_witnesses),
32204 witness_owners
32205 );
32206 assert_eq!(
32207 session.retained_step_identity(&parent).unwrap(),
32208 parent_identity
32209 );
32210 session.finish_policy_invocation(&parent, rng, 1).unwrap();
32211 assert!(session.policy_tapes.is_empty());
32212 assert!(session.steps[&parent.token].consumer_streams.contains(&1));
32213 assert_eq!(
32214 session.host_io_stats(),
32215 before_final_use,
32216 "inference final use must use original device guards and stream events only"
32217 );
32218 let retained_witness_owners =
32219 Arc::strong_count(&session.steps[&parent.token].content_witnesses);
32220 assert!(retained_witness_owners > 1 && !parent.active);
32221 assert!(session.finish_policy_invocation(&parent, rng, 1).is_err());
32222 assert_eq!(
32223 Arc::strong_count(&session.steps[&parent.token].content_witnesses),
32224 retained_witness_owners
32225 );
32226 assert_eq!(
32227 session.retained_step_identity(&parent).unwrap(),
32228 parent_identity
32229 );
32230 drop(witness);
32231 drop(policy_witness);
32232 drop((original_logit, original_support, original_parameter));
32233 drop(outcome);
32234 assert_eq!(
32235 Arc::strong_count(&session.steps[&parent.token].content_witnesses),
32236 1
32237 );
32238 session.release(&mut parent, &[1]).unwrap();
32239 assert!(!parent.active && !session.readers.contains_key(&parent.token));
32240 assert!(!session.is_poisoned());
32241 foreign_session.release(&mut foreign_parent, &[1]).unwrap();
32242 return;
32243 }
32244 let mut coefficients = provider.memory().alloc::<f64>(COMPONENT_COUNT).unwrap();
32245 provider
32246 .htod_sync_copy_into_tracked(&vec![1.0f64; COMPONENT_COUNT], &mut coefficients)
32247 .unwrap();
32248 let buffer = provider
32249 .buffer_from_columns(
32250 vec![CudaColumn::Owned(coefficients.into_bytes())],
32251 COMPONENT_COUNT as u64,
32252 Schema::new(vec![("cotangent".into(), ScalarType::F64)]),
32253 )
32254 .unwrap();
32255 let cotangents = provider.to_dlpack_table(buffer).column(0).unwrap();
32256 let before_backward = session.host_io_stats();
32257 let gradients = session.backward_policy_dlpack(rng, cotangents, 1).unwrap();
32258 let parameter_pointer = gradients.parameters.device_ptr_value();
32259 let text_pointer = gradients.text_logits.device_ptr_value();
32260 let [parameters, text, numerical @ ..] = gradients.into_dlpack().unwrap();
32261 assert_eq!(
32262 session.host_io_stats(),
32263 before_backward,
32264 "backward and original gradient exports must use device guards and stream events only"
32265 );
32266 unsafe {
32269 let parameter_tensor = &(*parameters.as_ptr()).dl_tensor;
32270 let text_tensor = &(*text.as_ptr()).dl_tensor;
32271 assert_eq!((parameter_tensor.ndim, text_tensor.ndim), (1, 2));
32272 assert!(
32273 !parameter_tensor.shape.is_null()
32274 && !text_tensor.shape.is_null()
32275 && !text_tensor.strides.is_null()
32276 );
32277 assert_eq!(
32278 std::slice::from_raw_parts(parameter_tensor.shape, 1),
32279 [layout.parameter_cells as i64]
32280 );
32281 assert_eq!(
32282 std::slice::from_raw_parts(text_tensor.shape, 2),
32283 [32, TEXT_CARDINALITY as i64]
32284 );
32285 assert_eq!(
32286 std::slice::from_raw_parts(text_tensor.strides, 2),
32287 [TEXT_CARDINALITY as i64, 1]
32288 );
32289 assert_eq!(parameter_tensor.data as usize as u64, parameter_pointer);
32290 assert_eq!(text_tensor.data as usize as u64, text_pointer);
32291 assert_eq!(
32292 (
32293 text_tensor.dtype.code,
32294 text_tensor.dtype.bits,
32295 text_tensor.dtype.lanes
32296 ),
32297 (2, 32, 1)
32298 );
32299 assert_eq!(
32300 text_tensor.device.device_id,
32301 provider.device().ordinal() as i32
32302 );
32303 let dimensions = [
32304 vec![1, COMPONENT_COUNT as i64],
32305 vec![layout.parameter_cells as i64, 2],
32306 vec![32, TEXT_CARDINALITY as i64, 2],
32307 vec![1, COMPONENT_COUNT as i64, 2],
32308 vec![2, layout.parameter_cells as i64, 4],
32309 vec![2, 32, TEXT_CARDINALITY as i64, 4],
32310 vec![2, 1, COMPONENT_COUNT as i64, 4],
32311 ];
32312 for (index, (tensor, dimensions)) in numerical.iter().zip(dimensions).enumerate() {
32313 let tensor = &(*tensor.as_ptr()).dl_tensor;
32314 assert_eq!(tensor.ndim as usize, dimensions.len());
32315 assert!(!tensor.shape.is_null());
32316 assert_eq!(
32317 std::slice::from_raw_parts(tensor.shape, dimensions.len()),
32318 dimensions
32319 );
32320 assert_eq!(
32321 (tensor.dtype.code, tensor.dtype.bits, tensor.dtype.lanes),
32322 (2, if index == 0 { 32 } else { 64 }, 1)
32323 );
32324 assert_eq!(tensor.device.device_id, provider.device().ordinal() as i32);
32325 }
32326 }
32327 assert!(session.steps[&parent.token].consumer_streams.contains(&1));
32328 assert!(
32329 session.release(&mut parent, &[1]).is_err(),
32330 "live gradient owners retain their original parent"
32331 );
32332 drop(parameters);
32333 drop(text);
32334 assert!(
32335 session.release(&mut parent, &[1]).is_err(),
32336 "baseline and numerical gradient owners retain their original parent"
32337 );
32338 drop(numerical);
32339 drop(witness);
32340 drop(policy_witness);
32341 drop((original_logit, original_support, original_parameter));
32342 drop(outcome);
32343 session.release(&mut parent, &[1]).unwrap();
32344 assert!(session.retained_step_identity(&parent).is_err());
32345 drop(session);
32346 }
32347
32348 #[test]
32349 fn semantic_work_accepts_refused_prefixes_and_rejects_impossible_effects() {
32350 for (edit_commands, added_supports, defined_truth_changes, valid) in [
32351 (0, 0, 0, true), (1, 0, 0, true), (2, 1, 0, true), (2, 2, 1, true), (2, 2, 2, true), (3, 0, 0, false),
32357 (0, 1, 0, false),
32358 (1, 2, 0, false),
32359 (1, 1, 2, false),
32360 (u64::MAX, 0, 0, false),
32361 ] {
32362 let work = SemanticTransitionWork {
32363 edit_commands,
32364 added_supports,
32365 defined_truth_changes,
32366 };
32367 assert_eq!(work.is_valid(false), valid, "{work:?}");
32368 }
32369 }
32370
32371 #[test]
32372 fn editable_program_work_counts_materialized_facts_and_bounds_signed_return() {
32373 let work = SemanticTransitionWork {
32374 edit_commands: 2,
32375 added_supports: crate::semantic_program::RESIDENT_PROGRAM_FACT_CAPACITY as u64,
32376 defined_truth_changes: 3,
32377 };
32378 assert!(!work.is_valid(false));
32379 assert!(work.is_valid(true));
32380 assert!(!SemanticTransitionWork {
32381 added_supports: work.added_supports + 1,
32382 ..work
32383 }
32384 .is_valid(true));
32385 let scoring = SemanticTaskScoring {
32386 correct_weight: 14,
32387 all_correct_weight: 7,
32388 work_weight: 1,
32389 improvement_weight: 45,
32390 refusal_weight: 15,
32391 spent_weight: 1,
32392 };
32393 assert_eq!(scoring.return_bound(false).unwrap(), 2522);
32394 assert_eq!(scoring.return_bound(true).unwrap(), 186799);
32395 }
32396
32397 #[test]
32398 fn structural_cost_law_tracks_program_mode_without_task_identity() {
32399 let graph = semantic_structural_cost_descriptor(false);
32400 let editable = semantic_structural_cost_descriptor(true);
32401 assert_eq!(graph.cap, 6);
32402 assert_eq!(editable.cap, 4101);
32403 assert_ne!(graph.unit, editable.unit);
32404 assert_ne!(graph.unit, Identity256::default());
32405 assert_eq!(graph, semantic_structural_cost_descriptor(false));
32406 assert_eq!(editable, semantic_structural_cost_descriptor(true));
32407 let maximum = SemanticTransitionWork {
32408 edit_commands: 2,
32409 added_supports: 4096,
32410 defined_truth_changes: 3,
32411 };
32412 assert_eq!(maximum.raw_structural_cost(), editable.cap);
32413 assert_eq!(SemanticTransitionWork::default().raw_structural_cost(), 0);
32414 }
32415
32416 #[test]
32417 #[cfg(feature = "semantic-policy")]
32418 fn candidate_resource_refusals_preserve_the_completed_base() {
32419 let scoring = SemanticTaskScoring {
32420 correct_weight: 0,
32421 all_correct_weight: 0,
32422 work_weight: 1,
32423 improvement_weight: 0,
32424 refusal_weight: 1,
32425 spent_weight: 0,
32426 };
32427 let facts = [
32428 SemanticTaskFacts {
32429 eligible: 1,
32430 ..SemanticTaskFacts::default()
32431 },
32432 SemanticTaskFacts {
32433 c: 1,
32434 v: -1,
32435 ..SemanticTaskFacts::default()
32436 },
32437 SemanticTaskFacts::default(),
32438 ];
32439 let work = [
32440 SemanticTransitionWork {
32441 edit_commands: 1,
32442 ..SemanticTransitionWork::default()
32443 },
32444 SemanticTransitionWork::default(),
32445 ];
32446 assert!(validate_completed_task_scoring(
32447 scoring,
32448 true,
32449 &[],
32450 &facts,
32451 &work,
32452 [3, 4],
32453 3,
32454 0,
32455 -2,
32456 ));
32457 assert!(!validate_completed_task_scoring(
32458 scoring,
32459 true,
32460 &[],
32461 &facts,
32462 &work,
32463 [3, 5],
32464 3,
32465 0,
32466 -2,
32467 ));
32468 assert!(!validate_completed_task_scoring(
32469 scoring,
32470 false,
32471 &[],
32472 &facts,
32473 &work,
32474 [3, 4],
32475 3,
32476 0,
32477 -2,
32478 ));
32479 assert_eq!(
32480 SemanticTaskRefusal::FactCapacity.canonical_kind(),
32481 "fact-capacity"
32482 );
32483 assert_eq!(
32484 SemanticTaskRefusal::FuelExhausted.canonical_kind(),
32485 "fuel-exhausted"
32486 );
32487 }
32488
32489 #[test]
32490 #[cfg(feature = "semantic-policy")]
32491 fn completed_scoring_accepts_program_materialization_cost() {
32492 let scoring = SemanticTaskScoring {
32493 correct_weight: 14,
32494 all_correct_weight: 7,
32495 work_weight: 1,
32496 improvement_weight: 45,
32497 refusal_weight: 15,
32498 spent_weight: 1,
32499 };
32500 let work = SemanticTransitionWork {
32501 edit_commands: 2,
32502 added_supports: crate::semantic_program::RESIDENT_PROGRAM_FACT_CAPACITY as u64,
32503 defined_truth_changes: 3,
32504 };
32505 let facts = [
32506 SemanticTaskFacts {
32507 eligible: 1,
32508 ..SemanticTaskFacts::default()
32509 },
32510 SemanticTaskFacts {
32511 truth: [1; 3],
32512 correct: [1; 3],
32513 g: 3,
32514 p: 1,
32515 c: 4101,
32516 v: -4052,
32517 eligible: 1,
32518 },
32519 SemanticTaskFacts::default(),
32520 ];
32521 let work = [work, SemanticTransitionWork::default()];
32522 assert!(validate_completed_task_scoring(
32523 scoring,
32524 true,
32525 &[],
32526 &facts,
32527 &work,
32528 [0, 1],
32529 6,
32530 1,
32531 -182361,
32532 ));
32533 assert!(!validate_completed_task_scoring(
32534 scoring,
32535 false,
32536 &[],
32537 &facts,
32538 &work,
32539 [0, 1],
32540 6,
32541 1,
32542 -182361,
32543 ));
32544 }
32545
32546 #[test]
32547 fn policy_storage_follows_native_codebooks_without_allocating_null_embeddings() {
32548 let layout = SemanticPolicyLayout::from_components(COMPONENTS).unwrap();
32549 assert_eq!(layout.z, 0..4 * 128);
32550 assert_eq!(layout.recurrence, layout.z.end..layout.z.end + 128 * 128);
32551 assert_eq!(
32552 layout.positions,
32553 layout.recurrence.end..layout.recurrence.end + 18 * 128
32554 );
32555 let mut cursor = layout.positions.end;
32556 for (field, component) in layout.fields.iter().zip(&COMPONENTS[32..50]) {
32557 let cardinality = component.cardinality as usize;
32558 let null = component.field != 0;
32559 assert_eq!(field.null_category, if null { Some(0) } else { None });
32560 assert_eq!(field.cardinality, cardinality);
32561 assert_eq!(
32562 field.embeddings,
32563 cursor..cursor + (cardinality - usize::from(null)) * 128
32564 );
32565 cursor = field.embeddings.end;
32566 let bias_count = if null && cardinality == 1 {
32567 0
32568 } else {
32569 cardinality
32570 };
32571 assert_eq!(field.biases, cursor..cursor + bias_count);
32572 cursor = field.biases.end;
32573 }
32574 assert_eq!(layout.parameter_cells, cursor);
32575 assert_eq!(layout.recurrent_cells(), 2 * 37 * 128);
32576 assert_eq!(
32577 layout.score_cells(),
32578 COMPONENTS[32..50]
32579 .iter()
32580 .map(|c| c.cardinality as usize)
32581 .max()
32582 .unwrap()
32583 );
32584 }
32585
32586 #[test]
32587 fn resident_ranges_reject_partial_overlap_overflow_and_empty_storage() {
32588 assert!(disjoint_ranges(&[(8, 16), (24, 8)]).is_ok());
32589 for ranges in [
32590 [(8, 16), (16, 16)],
32591 [(8, 16), (8, 8)],
32592 [(8, 16), (u64::MAX, 8)],
32593 [(8, 0), (16, 8)],
32594 ] {
32595 assert_eq!(
32596 disjoint_ranges(&ranges),
32597 Err(SemanticTransitionError::OverlappingInputs)
32598 );
32599 }
32600 }
32601
32602 #[test]
32603 fn policy_layout_tracks_admitted_cardinality_and_rejects_inconsistent_slots() {
32604 let mut components = COMPONENTS.to_vec();
32605 for lane in 0..2 {
32606 for slot in 0..2 {
32607 components[lane * 68 + 32 + slot * 18 + 2].cardinality = 7;
32608 }
32609 }
32610 let layout = SemanticPolicyLayout::from_components(&components).unwrap();
32611 assert_eq!(layout.fields[2].embeddings.len(), 6 * 128);
32612 assert_eq!(layout.fields[2].biases.len(), 7);
32613 assert_eq!(layout.fields[2].null_category, Some(0));
32614 assert_eq!(layout.fields[0].null_category, None);
32615 assert_eq!(
32616 layout.fields[0].embeddings.len(),
32617 layout.fields[0].cardinality * 128
32618 );
32619 components[32 + 18 + 2].cardinality = 6;
32620 assert!(SemanticPolicyLayout::from_components(&components).is_err());
32621 assert!(SemanticPolicyLayout::from_components(&COMPONENTS[..135]).is_err());
32622 let mut malformed = COMPONENTS.to_vec();
32623 malformed[32].lane = 0;
32624 assert!(SemanticPolicyLayout::from_components(&malformed).is_err());
32625 malformed[32] = COMPONENTS[32];
32626 malformed[32].cardinality = 0;
32627 assert!(SemanticPolicyLayout::from_components(&malformed).is_err());
32628 }
32629
32630 #[test]
32631 fn decoded_support_corruption_rolls_back_first_lane_and_poison_closes_session() {
32632 use crate::{
32633 SemanticPolarity, SemanticPredicateRecord, SemanticRecordRole, SemanticSupportRecord,
32634 SemanticTypedRecord,
32635 };
32636 use cudarc::nvrtc::Ptx;
32637 use xlog_core::{RelId, Schema};
32638 if std::env::var("XLOG_REQUIRE_CUDA").as_deref() != Ok("1") {
32639 return;
32640 }
32641 #[derive(Clone, Copy)]
32642 enum IntegrityFault {
32643 SecondEdit,
32644 AfterSealedLane,
32645 RefusedEditThenInvalidLogit,
32646 }
32647 for fault_case in [
32648 IntegrityFault::SecondEdit,
32649 IntegrityFault::AfterSealedLane,
32650 IntegrityFault::RefusedEditThenInvalidLogit,
32651 ] {
32652 let late_failure = matches!(fault_case, IntegrityFault::AfterSealedLane);
32653 let refused_then_invalid =
32654 matches!(fault_case, IntegrityFault::RefusedEditThenInvalidLogit);
32655 let global_failure = late_failure || refused_then_invalid;
32656 let provider =
32657 crate::CudaProviderBuilder::new(0, MemoryBudget::with_limit(256 * 1024 * 1024))
32658 .with_stream_capacity(1)
32659 .build()
32660 .unwrap();
32661 let provider = Arc::new(provider);
32662 let runtime = Arc::clone(provider.memory().runtime().unwrap());
32663 let id = runtime.stream_pool().acquire().unwrap();
32664 let stream = runtime.stream_pool().resolve(id).unwrap();
32665 let domain = provider
32666 .bind_resident_execution_domain(runtime, id, stream)
32667 .unwrap();
32668 let mut graph = provider
32669 .allocate_semantic_hypergraph(
32670 &domain,
32671 SemanticHypergraphCapacities::try_new(3, 4, 4, 4).unwrap(),
32672 )
32673 .unwrap();
32674 let base = graph.empty_root();
32675 let roles = [
32676 SemanticRecordRole::Statement,
32677 SemanticRecordRole::Provenance,
32678 SemanticRecordRole::Source,
32679 SemanticRecordRole::Context,
32680 SemanticRecordRole::Scope,
32681 ];
32682 graph
32683 .admit_records(
32684 base,
32685 SemanticAdmissionRecords {
32686 predicates: roles
32687 .into_iter()
32688 .enumerate()
32689 .map(|(i, role)| SemanticPredicateRecord {
32690 predicate: RelId(i as u32),
32691 role,
32692 schema: Schema::new(vec![]),
32693 })
32694 .collect(),
32695 records: (0..5)
32696 .map(|i| SemanticTypedRecord {
32697 predicate: RelId(i),
32698 arguments: vec![],
32699 qualifiers: vec![],
32700 })
32701 .collect(),
32702 supports: vec![SemanticSupportRecord {
32703 statement: 0,
32704 polarity: SemanticPolarity::Pro,
32705 provenance: 1,
32706 source: 2,
32707 context: 3,
32708 scope: 4,
32709 }],
32710 },
32711 SemanticAdmissionLimits {
32712 max_records: 12,
32713 max_terms: 0,
32714 max_references: 5,
32715 max_utf8_bytes: 0,
32716 },
32717 )
32718 .unwrap();
32719 let mut session = SemanticTransitionSession::from_hypergraph(graph).unwrap();
32720
32721 let source = include_str!("../kernels/semantic_transition.cu");
32726 let anchor = if late_failure {
32727 "lane_live=candidate.words[41]!=0;"
32728 } else {
32729 "decode_action(books,choices,&statement,&event);"
32730 };
32731 assert_eq!(source.matches(anchor).count(), 1);
32732 let fault = if late_failure {
32733 "if (lane==1) {failed=1;state->status=3;}"
32734 } else if refused_then_invalid {
32735 "if (lane==0 && component.slot==0) event.polarity=0;"
32736 } else {
32737 "if (lane==0 && component.slot==1) event.polarity=0;"
32738 };
32739 let source = source.replacen(anchor, &format!("{anchor}\n{fault}"), 1);
32740 struct CompilationFiles(std::path::PathBuf);
32743 impl Drop for CompilationFiles {
32744 fn drop(&mut self) {
32745 for file in ["transition.cu", "transition.ptx"] {
32746 if let Err(error) = std::fs::remove_file(self.0.join(file)) {
32747 if error.kind() != std::io::ErrorKind::NotFound {
32748 eprintln!("failed to remove test compiler output: {error}");
32749 }
32750 }
32751 }
32752 if let Err(error) = std::fs::remove_dir(&self.0) {
32753 eprintln!("failed to remove test compiler directory: {error}");
32754 }
32755 }
32756 }
32757 let unique = std::time::SystemTime::now()
32758 .duration_since(std::time::UNIX_EPOCH)
32759 .unwrap()
32760 .as_nanos();
32761 let path = std::env::temp_dir().join(format!(
32762 "xlog-decoded-support-{}-{unique}",
32763 std::process::id()
32764 ));
32765 std::fs::create_dir(&path).unwrap();
32766 let files = CompilationFiles(path);
32767 std::fs::write(files.0.join("transition.cu"), source).unwrap();
32768 let output = std::process::Command::new(
32769 std::env::var_os("NVCC_PATH").unwrap_or_else(|| "nvcc".into()),
32770 )
32771 .args([
32772 "--ptx",
32773 "-arch=sm_75",
32774 "-O3",
32775 "-std=c++17",
32776 "-I",
32777 env!("OUT_DIR"),
32778 "-I",
32779 concat!(env!("CARGO_MANIFEST_DIR"), "/kernels"),
32780 ])
32781 .arg(files.0.join("transition.cu"))
32782 .arg("-o")
32783 .arg(files.0.join("transition.ptx"))
32784 .output()
32785 .expect("compile canonical transition with decoded support corruption");
32786 assert!(
32787 output.status.success(),
32788 "{}",
32789 String::from_utf8_lossy(&output.stderr)
32790 );
32791 let ptx =
32792 Ptx::from_src(std::fs::read_to_string(files.0.join("transition.ptx")).unwrap());
32793 drop(files);
32794 let device = provider.device().inner();
32795 let module = "semantic_transition_decoded_support_corruption";
32796 device
32797 .load_ptx(ptx, module, &["semantic_transition_execute"])
32798 .unwrap();
32799 session.execute = device
32800 .get_func(module, "semantic_transition_execute")
32801 .unwrap();
32802 let inputs: Vec<_> = session
32803 .components()
32804 .iter()
32805 .map(|component| {
32806 let mut product_support = vec![0; component.cardinality as usize];
32807 let choice = usize::from(
32808 !component.is_text() && matches!(component.field, 0 | 1 | 2 | 11 | 17),
32809 );
32810 product_support[choice] = 1;
32811 SemanticComponentInput {
32812 logits: vec![0.; product_support.len()],
32813 product_support,
32814 }
32815 })
32816 .collect();
32817 session
32818 .bind_inputs(
32819 session.binding(),
32820 SemanticRngBinding {
32821 model_generation: 1,
32822 stream_serial: 1,
32823 family_id: 1,
32824 proposal: 0,
32825 },
32826 &inputs,
32827 )
32828 .unwrap();
32829 if refused_then_invalid {
32830 let mut corrupted_logits: Vec<_> = inputs
32835 .iter()
32836 .flat_map(|input| input.logits.iter().copied())
32837 .collect();
32838 let component = session.components()[50];
32839 assert_eq!((component.lane, component.slot, component.field), (1, 1, 0));
32840 corrupted_logits[component.offset as usize + 1] = f32::NAN;
32841 provider
32842 .htod_sync_copy_into_tracked(&corrupted_logits, &mut session.logits)
32843 .unwrap();
32844 }
32845 let [arena_ptr, _, root_capacity, statement_capacity, _, _, arena_words] =
32846 session.graph.transition_arena();
32847 assert_eq!(
32848 (root_capacity, statement_capacity, arena_words),
32849 (3, 4, 260)
32850 );
32851 assert_eq!(base.slot(), 0);
32852 let readback_stream = Arc::clone(&session.stream);
32853 let read_resident_arena = || {
32854 readback_stream.synchronize().unwrap();
32855 let mut words = vec![0u64; arena_words as usize];
32856 assert_eq!(
32859 unsafe {
32860 sys::cuMemcpyDtoH_v2(
32861 words.as_mut_ptr().cast(),
32862 arena_ptr,
32863 std::mem::size_of_val(words.as_slice()),
32864 )
32865 },
32866 sys::cudaError_enum::CUDA_SUCCESS
32867 );
32868 words
32869 };
32870 let original_arena = read_resident_arena();
32873 let base_record = 16..32;
32876 let heads_start = (arena_words - (root_capacity + 1) * statement_capacity) as usize;
32877 let base_heads = heads_start..heads_start + statement_capacity as usize;
32878 assert_eq!(&original_arena[19..22], &[0, 0, 0]);
32879 assert!(original_arena[base_heads.clone()]
32880 .iter()
32881 .all(|head| *head == 0));
32882 session.capture().unwrap();
32883 assert_eq!(session.captured.as_ref().unwrap().node_count().unwrap(), 1);
32884 let before = session.host_io_stats();
32885 session.launch().unwrap();
32886 assert_eq!(session.host_io_stats(), before);
32887 let error = session.observe(0).unwrap_err();
32888 if refused_then_invalid {
32889 assert!(matches!(
32890 error,
32891 SemanticTransitionError::NonFinitePolicyInput {
32892 completed_draws: 50
32893 }
32894 ));
32895 } else if late_failure {
32896 assert!(matches!(
32897 error,
32898 SemanticTransitionError::ObservationMismatch
32899 ));
32900 } else {
32901 assert!(matches!(error, SemanticTransitionError::Semantic(_)));
32902 }
32903 assert!(session.is_poisoned());
32904 assert_eq!(
32905 session.next_proposal, 0,
32906 "integrity error must not publish RNG successor"
32907 );
32908 assert!(matches!(
32909 session.launch(),
32910 Err(SemanticTransitionError::Poisoned)
32911 ));
32912 assert!(matches!(
32913 session.observe(0),
32914 Err(SemanticTransitionError::Poisoned)
32915 ));
32916
32917 let (state, components) = unsafe { session.pinned.read() }.unwrap();
32920 if global_failure {
32921 assert_eq!(
32922 (state.status, state.blocks, state.next_proposal),
32923 if late_failure { (3, 68, 0) } else { (5, 50, 0) }
32924 );
32925 if late_failure {
32926 assert_eq!(state.semantic_receipts[3][1], 1, "first lane really sealed");
32927 assert_eq!(state.retired_roots_mask, 1);
32928 assert_eq!(state.cleanup_receipts[1][0], 0, "sealed root reclaimed");
32929 } else {
32930 assert_eq!(
32931 state.semantic_receipts[1][0], 12,
32932 "original edit refusal retained"
32933 );
32934 assert_eq!(&state.semantic_receipts[1][40..42], &[0, 1]);
32935 assert_eq!(state.retired_roots_mask, 0, "no root was sealed");
32936 }
32937 assert_eq!(state.cleanup_receipts[0][0], 0, "live candidate discarded");
32938 assert_eq!(&state.cleanup_receipts[0][40..42], &[0, 0]);
32939 let terminal_arena = read_resident_arena();
32940 assert_eq!(
32941 &terminal_arena[base_record.clone()],
32942 &original_arena[base_record]
32943 );
32944 assert_eq!(
32945 &terminal_arena[base_heads.clone()],
32946 &original_arena[base_heads]
32947 );
32948 for slot in [32, 48, 64] {
32949 assert_eq!(terminal_arena[slot], 0, "no pending root or candidate");
32950 }
32951 drop(session);
32952 provider.memory().reap_pending_deallocations().unwrap();
32953 assert_eq!(provider.memory().allocated_bytes(), 0);
32954 assert_eq!(provider.memory().deallocation_failure_bytes(), 0);
32955 continue;
32956 }
32957 assert_eq!((state.status, state.blocks), (0, 136));
32958 for (row, component) in components.iter().zip(session.components()) {
32959 assert_eq!(row.ordinal, component.ordinal);
32960 assert_eq!(row.admission_binding, session.binding().digest);
32961 assert_eq!(
32962 row.choice,
32963 u32::from(
32964 !component.is_text() && matches!(component.field, 0 | 1 | 2 | 11 | 17)
32965 )
32966 );
32967 assert_eq!(
32968 (row.cdf_start, row.cdf_end, row.mass),
32969 (0, 1 << 63, 1 << 63)
32970 );
32971 assert!(row.draw < row.cdf_end);
32972 }
32973 let receipts = state.semantic_receipts;
32974 assert_eq!(receipts[0][0], 0); assert_eq!(&receipts[0][13..16], &[0, 0, 0]);
32976 assert_eq!(&receipts[1][0..3], &[0, 1, 1]); assert_eq!(receipts[2][0], 12); assert_eq!(receipts[3][0], 12); assert_eq!(&receipts[3][40..42], &[0, 1]); assert_eq!(&receipts[4][0..3], &[0, 1, 1]); assert_eq!(&receipts[5][0..3], &[0, 2, 1]); assert_eq!(&receipts[4][40..42], &[0, 2]); assert_eq!(&receipts[5][40..42], &[0, 2]);
32984 assert_eq!(receipts[6][0], 0);
32985 assert_eq!(&receipts[6][13..16], &[1, 1, 1]);
32986 assert_eq!(receipts[6][6], 3); assert_eq!(&receipts[6][3..5], &[1, 1]); for slot in [7, 9, 11] {
32989 assert_eq!(receipts[4][slot], receipts[1][slot]);
32990 assert!(receipts[4][slot + 1] > receipts[1][slot + 1]);
32991 }
32992 let terminal_arena = read_resident_arena();
32997 assert_eq!(&terminal_arena[..16], &original_arena[..16]);
32998 assert_eq!(
32999 &terminal_arena[base_record.clone()],
33000 &original_arena[base_record]
33001 );
33002 assert_eq!(
33003 &terminal_arena[base_heads.clone()],
33004 &original_arena[base_heads]
33005 );
33006 drop(session);
33007 provider.memory().reap_pending_deallocations().unwrap();
33008 assert_eq!(provider.memory().allocated_bytes(), 0);
33009 assert_eq!(provider.memory().deallocation_failure_bytes(), 0);
33010 }
33011 }
33012
33013 #[test]
33014 fn actual_enqueued_work_and_terminal_wait_faults_poison_public_session() {
33015 if std::env::var("XLOG_REQUIRE_CUDA").as_deref() != Ok("1") {
33016 return;
33017 }
33018 let provider =
33019 crate::CudaProviderBuilder::new(0, MemoryBudget::with_limit(256 * 1024 * 1024))
33020 .with_stream_capacity(1)
33021 .build()
33022 .unwrap();
33023 let provider = Arc::new(provider);
33024 let runtime = Arc::clone(provider.memory().runtime().unwrap());
33025 let id = runtime.stream_pool().acquire().unwrap();
33026 let stream = runtime.stream_pool().resolve(id).unwrap();
33027 let domain = provider
33028 .bind_resident_execution_domain(runtime, id, stream)
33029 .unwrap();
33030 for failure in 0..12 {
33031 let mut session = SemanticTransitionSession::new(&provider, &domain).unwrap();
33032 let inputs: Vec<_> = session
33033 .components()
33034 .iter()
33035 .map(|c| {
33036 let mut mask = vec![0; c.cardinality as usize];
33037 mask[0] = 1;
33038 SemanticComponentInput {
33039 logits: vec![0.; mask.len()],
33040 product_support: mask,
33041 }
33042 })
33043 .collect();
33044 session
33045 .bind_inputs(
33046 session.binding(),
33047 SemanticRngBinding {
33048 model_generation: 1,
33049 stream_serial: 2,
33050 family_id: 3,
33051 proposal: 4,
33052 },
33053 &inputs,
33054 )
33055 .unwrap();
33056 session.capture().unwrap();
33057 assert_eq!(session.captured.as_ref().unwrap().node_count().unwrap(), 1);
33058 if failure == 0 {
33059 let recorder = session.kernel_recorder();
33060 let graph = session.captured.as_ref().unwrap();
33061 let result = enqueue_recorded(&domain, &mut session.poisoned, recorder, |stream| {
33062 graph.launch_in(stream)?;
33063 Err::<(), _>(XlogError::Kernel(
33064 "injected error after actual graph enqueue".into(),
33065 ))
33066 });
33067 assert!(result.is_err());
33068 } else if failure == 1 {
33069 session.launch().unwrap();
33070 let result = wait_on_stream(
33071 &session.stream,
33072 &mut session.poisoned,
33073 &mut session.stream_waits,
33074 "terminal wait",
33075 |stream| {
33076 stream.synchronize().unwrap();
33077 Err::<(), _>(XlogError::Kernel(
33078 "injected terminal wait error after actual completion".into(),
33079 ))
33080 },
33081 );
33082 assert!(result.is_err());
33083 } else if failure == 2 {
33084 let invalid = DeviceState {
33087 next_proposal: 4,
33088 ..DeviceState::default()
33089 };
33090 provider
33091 .htod_sync_copy_into_tracked(&[invalid], &mut session.state)
33092 .unwrap();
33093 session.launch().unwrap();
33094 assert!(matches!(
33095 session.observe(4),
33096 Err(SemanticTransitionError::ObservationMismatch)
33097 ));
33098 } else if failure == 3 {
33099 assert!(!session.is_poisoned());
33101 } else if failure == 4 {
33102 session.capture().unwrap();
33105 session.launch().unwrap();
33106 session.observe(4).unwrap();
33107 } else if failure == 5 {
33108 let mut words = [0; 42];
33111 words[0] = 11;
33112 assert!(session.graph.observe_transition_edit(words).is_err());
33113 } else if failure == 6 {
33114 let mut words = [0; 42];
33115 words[3] = u64::MAX;
33116 assert!(session.graph.observe_transition_root(words).is_err());
33117 } else {
33118 let mut words = [0; 42];
33119 words[1] = if failure == 11 { 2 } else { 1 };
33120 words[8] = 1;
33121 words[10] = 1;
33122 words[12] = 1;
33123 words[39] = session.graph.transition_arena()[1];
33124 match failure {
33125 7 => words[39] = 0,
33126 8 => words[8] = 0,
33127 9 => words[10] = 0,
33128 _ => words[12] = 0,
33129 }
33130 assert!(session.graph.observe_transition_edit(words).is_err());
33131 }
33132 if !(3..5).contains(&failure) {
33133 assert!(session.is_poisoned());
33134 assert!(matches!(
33135 session.launch(),
33136 Err(SemanticTransitionError::Poisoned)
33137 ));
33138 assert!(matches!(
33139 session.observe(4),
33140 Err(SemanticTransitionError::Poisoned)
33141 ));
33142 }
33143 drop(session);
33144 provider.memory().reap_pending_deallocations().unwrap();
33145 assert_eq!(provider.memory().allocated_bytes(), 0);
33146 assert_eq!(provider.memory().deallocation_failure_bytes(), 0);
33147 }
33148 }
33149}
33150
33151#[cfg(test)]
33152mod text_parent_tests {
33153 use super::*;
33154
33155 #[test]
33156 fn model_content_snapshot_copies_original_seals_and_exact_contract_interval() {
33157 let directory = [
33158 PublicationRange {
33159 role: 18,
33160 generation: 1,
33161 length_bytes: 4,
33162 ..PublicationRange::default()
33163 },
33164 PublicationRange {
33165 role: 44,
33166 generation: 1,
33167 storage_slot: 2,
33168 offset_bytes: 7,
33169 length_bytes: 11,
33170 ..PublicationRange::default()
33171 },
33172 PublicationRange {
33173 role: 20,
33174 generation: 1,
33175 length_bytes: 4,
33176 ..PublicationRange::default()
33177 },
33178 ];
33179 let plan = model_content_copy_plan(&directory, &[2, 0], &[4, 4, 19]).unwrap();
33180 assert_eq!(
33181 plan.directory_offsets,
33182 [
33183 2 * size_of::<PublicationRange>(),
33184 0,
33185 size_of::<PublicationRange>()
33186 ]
33187 );
33188 assert_eq!(plan.contract_storage_slot, 2);
33189 assert_eq!(plan.contract_span, 7..18);
33190 let mut changed = directory;
33191 changed[1].digest = Identity256::from_bytes([91; 32]);
33192 let changed_plan = model_content_copy_plan(&changed, &[2, 0], &[4, 4, 19]).unwrap();
33193 assert_eq!(
33194 changed_plan.directory_offsets, plan.directory_offsets,
33195 "copy geometry must not upload a host-cached expected digest"
33196 );
33197 }
33198
33199 #[test]
33200 fn model_content_snapshot_refuses_incomplete_or_unowned_ranges() {
33201 let directory = [
33202 PublicationRange {
33203 role: 18,
33204 generation: 1,
33205 length_bytes: 4,
33206 ..PublicationRange::default()
33207 },
33208 PublicationRange {
33209 role: 44,
33210 generation: 1,
33211 storage_slot: 1,
33212 offset_bytes: 3,
33213 length_bytes: 5,
33214 ..PublicationRange::default()
33215 },
33216 ];
33217 let plan = |rows: &[PublicationRange], indices: &[usize], allocations: &[usize]| {
33218 model_content_copy_plan(rows, indices, allocations)
33219 };
33220 assert!(plan(&directory, &[], &[4, 8]).is_err());
33221 assert!(plan(&directory, &[2], &[4, 8]).is_err());
33222 assert!(plan(&directory, &[1], &[4, 8]).is_err());
33223 assert!(plan(&directory, &[0, 0], &[4, 8]).is_err());
33224 assert!(plan(&directory[..1], &[0], &[4, 8]).is_err());
33225 assert!(plan(&directory, &[0], &[4]).is_err());
33226 assert!(plan(&directory, &[0], &[4, 7]).is_err());
33227 let mut changed = directory;
33228 changed[1].offset_bytes = u64::MAX;
33229 assert!(plan(&changed, &[0], &[4, usize::MAX]).is_err());
33230 changed = directory;
33231 changed[1].length_bytes = 0;
33232 assert!(plan(&changed, &[0], &[4, 8]).is_err());
33233 changed = directory;
33234 changed[1].generation = 2;
33235 assert!(plan(&changed, &[0], &[4, 8]).is_err());
33236 changed = directory;
33237 changed[1].index = 1;
33238 assert!(plan(&changed, &[0], &[4, 8]).is_err());
33239 let duplicate = [directory[0], directory[1], directory[1]];
33240 assert!(plan(&duplicate, &[0], &[4, 8]).is_err());
33241 }
33242
33243 #[test]
33244 fn model_content_binding_requires_the_complete_original_roster() {
33245 let layout = |role, index| SemanticTensorLayout {
33246 role,
33247 index,
33248 scalar_type: 6,
33249 element_bytes: 4,
33250 rank: 2,
33251 logical_axis: u64::MAX,
33252 dimensions: [2, 3, 0, 0],
33253 strides_bytes: [12, 4, 0, 0],
33254 };
33255 let layouts: BTreeMap<_, _> = [(18, 0), (18, 1), (19, 0), (20, 0)]
33256 .into_iter()
33257 .map(|key| (key, layout(key.0, key.1)))
33258 .collect();
33259 let mut directory: Vec<_> = layouts
33260 .values()
33261 .map(|layout| PublicationRange {
33262 role: layout.role,
33263 index: layout.index,
33264 generation: 1,
33265 length_bytes: 24,
33266 ..PublicationRange::default()
33267 })
33268 .collect();
33269 directory.push(PublicationRange {
33270 role: 44,
33271 generation: 1,
33272 length_bytes: 8,
33273 ..PublicationRange::default()
33274 });
33275 let original: Vec<_> = layouts.values().map(|&layout| (layout, 0, 0, 24)).collect();
33276 let bind = |rows: &[(SemanticTensorLayout, u64, u64, usize)]| {
33277 model_content_ranges(&directory, &layouts, rows.iter().copied())
33278 };
33279 assert_eq!(bind(&original).unwrap(), vec![0, 1, 2, 3]);
33280 assert!(bind(&original[..3]).is_err());
33281 assert!(bind(&[]).is_err());
33282 let mut duplicate = original.clone();
33283 duplicate[3] = original[2];
33284 assert!(bind(&duplicate).is_err());
33285 let mut transient = original.clone();
33286 transient[0].0.role = 0;
33287 assert!(bind(&transient).is_err());
33288 let mut extra = original.clone();
33289 extra.push((layout(18, 2), 0, 0, 24));
33290 assert!(bind(&extra).is_err());
33291 let mut reordered = original.clone();
33292 reordered.reverse();
33293 assert_eq!(bind(&reordered).unwrap(), vec![3, 2, 1, 0]);
33294 let without_adapter: Vec<_> = directory
33295 .iter()
33296 .copied()
33297 .filter(|row| row.role != 19)
33298 .collect();
33299 let absent_adapter: Vec<_> = original
33300 .iter()
33301 .copied()
33302 .filter(|row| row.0.role != 19)
33303 .collect();
33304 assert!(
33305 model_content_ranges(&without_adapter, &layouts, absent_adapter.iter().copied())
33306 .is_ok()
33307 );
33308 assert!(
33309 model_content_ranges(&without_adapter, &layouts, original.iter().copied()).is_err()
33310 );
33311 assert!(model_content_ranges(&directory[..4], &layouts, original.iter().copied()).is_err());
33312 }
33313
33314 #[test]
33315 fn model_content_binding_accepts_logical_equality_not_changed_shape_or_interval() {
33316 let expected = SemanticTensorLayout {
33317 role: 18,
33318 index: 0,
33319 scalar_type: 6,
33320 element_bytes: 4,
33321 rank: 2,
33322 logical_axis: 0,
33323 dimensions: [2, 3, 0, 0],
33324 strides_bytes: [12, 4, 0, 0],
33325 };
33326 let layouts = BTreeMap::from([((18, 0), expected)]);
33327 let directory = [
33328 PublicationRange {
33329 role: 18,
33330 generation: 1,
33331 length_bytes: 24,
33332 logical_begin: 5,
33333 logical_end: 7,
33334 ..PublicationRange::default()
33335 },
33336 PublicationRange {
33337 role: 44,
33338 generation: 1,
33339 length_bytes: 8,
33340 ..PublicationRange::default()
33341 },
33342 ];
33343 let bind = |layout, begin, end, bytes| {
33344 model_content_ranges(
33345 &directory,
33346 &layouts,
33347 std::iter::once((layout, begin, end, bytes)),
33348 )
33349 };
33350 let mut actual = expected;
33351 actual.strides_bytes = [4, 8, 0, 0];
33352 assert_eq!(bind(actual, 5, 7, 24).unwrap(), vec![0]);
33353 actual.strides_bytes = [32, 4, 0, 0];
33354 assert_eq!(bind(actual, 5, 7, 44).unwrap(), vec![0]);
33355 assert!(bind(actual, 5, 7, 24).is_err());
33356 assert!(bind(actual, 6, 8, 44).is_err());
33357 actual.strides_bytes = [4, 4, 0, 0];
33358 assert!(bind(actual, 5, 7, 16).is_err());
33359 actual = expected;
33360 actual.dimensions = [3, 2, 0, 0];
33361 actual.strides_bytes = [8, 4, 0, 0];
33362 assert!(bind(actual, 5, 8, 24).is_err());
33363 actual = expected;
33364 actual.scalar_type = 2;
33365 assert!(bind(actual, 5, 7, 24).is_err());
33366 }
33367
33368 #[test]
33369 fn tensor_content_range_accepts_private_operands_without_publication_roles() {
33370 for (scalar_type, element_bytes, dtype) in [
33371 (
33372 9,
33373 8,
33374 crate::dlpack::DLDataType {
33375 code: crate::dlpack::K_DLFLOAT,
33376 bits: 64,
33377 lanes: 1,
33378 },
33379 ),
33380 (
33381 7,
33382 8,
33383 crate::dlpack::DLDataType {
33384 code: 0,
33385 bits: 64,
33386 lanes: 1,
33387 },
33388 ),
33389 (
33390 8,
33391 1,
33392 crate::dlpack::DLDataType {
33393 code: 6,
33394 bits: 8,
33395 lanes: 1,
33396 },
33397 ),
33398 (
33399 6,
33400 4,
33401 crate::dlpack::DLDataType {
33402 code: 2,
33403 bits: 32,
33404 lanes: 1,
33405 },
33406 ),
33407 ] {
33408 let mut layout = SemanticTensorLayout {
33409 role: 0,
33410 index: 0,
33411 scalar_type,
33412 element_bytes,
33413 rank: 2,
33414 logical_axis: u64::MAX,
33415 dimensions: [2, 3, 0, 0],
33416 strides_bytes: [element_bytes, 2 * element_bytes, 0, 0],
33417 };
33418 let metadata = TensorMetadata {
33419 device_type: 2,
33420 device_id: 0,
33421 dtype,
33422 shape: &[2, 3],
33423 strides: Some(&[1, 2]),
33424 data: 4096,
33425 byte_offset: 0,
33426 };
33427 let bytes = 6 * element_bytes as usize;
33428 assert_eq!(
33429 validate_tensor_metadata(&layout, &metadata, 0).unwrap(),
33430 (4096, bytes)
33431 );
33432 assert_eq!(tensor_content_range(&layout, 0, 0, bytes).unwrap().role, 0);
33433 assert!(SemanticStateRole::from_code(0).is_none());
33434 layout.role = 56;
33435 assert!(validate_tensor_metadata(&layout, &metadata, 0).is_err());
33436 assert!(tensor_content_range(&layout, 0, 0, bytes).is_err());
33437 layout.role = 0;
33438 layout.dimensions[0] = 0;
33439 assert_eq!(
33440 tensor_content_range(&layout, 0, 0, 0).unwrap().length_bytes,
33441 0
33442 );
33443 }
33444 }
33445
33446 #[test]
33447 fn content_coordinates_keep_private_occurrences_in_original_roster_order() {
33448 assert!(validate_content_coordinates([(0, 0), (0, 1), (0, 2)].into_iter()).is_ok());
33449 assert!(validate_content_coordinates([(4, 1), (0, 1), (5, 1)].into_iter()).is_ok());
33450 for coordinates in [
33451 vec![(0, 1)],
33452 vec![(0, 0), (0, 0)],
33453 vec![(0, 0), (0, 2)],
33454 vec![(4, 0), (4, 0)],
33455 vec![(56, 0)],
33456 ] {
33457 assert!(validate_content_coordinates(coordinates.into_iter()).is_err());
33458 }
33459 }
33460
33461 #[test]
33462 fn tensor_content_range_preserves_signed_tokens_and_boolean_masks() {
33463 for (scalar_type, element_bytes, dtype) in [
33464 (
33465 7,
33466 8,
33467 crate::dlpack::DLDataType {
33468 code: 0,
33469 bits: 64,
33470 lanes: 1,
33471 },
33472 ),
33473 (
33474 8,
33475 1,
33476 crate::dlpack::DLDataType {
33477 code: 6,
33478 bits: 8,
33479 lanes: 1,
33480 },
33481 ),
33482 ] {
33483 let layout = SemanticTensorLayout {
33484 role: 1,
33485 index: 0,
33486 scalar_type,
33487 element_bytes,
33488 rank: 2,
33489 logical_axis: 1,
33490 dimensions: [1, 3, 0, 0],
33491 strides_bytes: [3 * element_bytes, element_bytes, 0, 0],
33492 };
33493 let metadata = TensorMetadata {
33494 device_type: 2,
33495 device_id: 0,
33496 dtype,
33497 shape: &[1, 3],
33498 strides: Some(&[3, 1]),
33499 data: 4096,
33500 byte_offset: 0,
33501 };
33502 assert_eq!(
33503 validate_tensor_metadata(&layout, &metadata, 0).unwrap(),
33504 (4096, 3 * element_bytes as usize)
33505 );
33506 let range = tensor_content_range(&layout, 11, 14, 3 * element_bytes as usize).unwrap();
33507 assert_eq!(
33508 (
33509 range.role,
33510 range.index,
33511 range.logical_begin,
33512 range.logical_end
33513 ),
33514 (1, 0, 11, 14)
33515 );
33516 assert!(tensor_content_range(&layout, 11, 13, 3 * element_bytes as usize).is_err());
33517 let mut wrong = metadata;
33518 wrong.dtype.code = 1;
33519 assert!(validate_tensor_metadata(&layout, &wrong, 0).is_err());
33520 }
33521 }
33522
33523 #[test]
33524 fn tensor_content_range_checks_transposed_empty_and_exact_byte_extents() {
33525 let mut layout = SemanticTensorLayout {
33526 role: 4,
33527 index: 2,
33528 scalar_type: 6,
33529 element_bytes: 4,
33530 rank: 2,
33531 logical_axis: u64::MAX,
33532 dimensions: [2, 3, 0, 0],
33533 strides_bytes: [4, 8, 0, 0],
33534 };
33535 assert_eq!(
33536 tensor_content_range(&layout, 0, 0, 24)
33537 .unwrap()
33538 .length_bytes,
33539 24
33540 );
33541 assert!(tensor_content_range(&layout, 0, 1, 24).is_err());
33542 assert!(tensor_content_range(&layout, 0, 0, 23).is_err());
33543 assert!(tensor_content_range(&layout, 0, 0, 25).is_err());
33544 layout.logical_axis = 0;
33545 layout.dimensions[0] = 0;
33546 assert_eq!(
33547 tensor_content_range(&layout, 9, 9, 0).unwrap().length_bytes,
33548 0
33549 );
33550 assert!(tensor_content_range(&layout, 9, 8, 0).is_err());
33551 }
33552
33553 fn publication_test_tensor(
33554 provider: &CudaKernelProvider,
33555 role: u64,
33556 value: f32,
33557 ) -> SemanticTensorInput {
33558 let bytes = value.to_le_bytes();
33559 let owner = allocate_publication::<u8>(provider, bytes.len()).unwrap();
33560 upload_publication(provider, &bytes, &owner).unwrap();
33561 let tensor = crate::dlpack::export_slice_managed_tensor(
33562 Arc::new(owner),
33563 provider.device().ordinal() as i32,
33564 crate::dlpack::DLDataType {
33565 code: 2,
33566 bits: 32,
33567 lanes: 1,
33568 },
33569 1,
33570 1,
33571 )
33572 .unwrap();
33573 SemanticTensorInput {
33574 layout: SemanticTensorLayout {
33575 role,
33576 index: 0,
33577 scalar_type: 6,
33578 element_bytes: 4,
33579 rank: 2,
33580 logical_axis: u64::MAX,
33581 dimensions: [1, 1, 0, 0],
33582 strides_bytes: [4, 4, 0, 0],
33583 },
33584 logical_begin: 0,
33585 logical_end: 0,
33586 tensor,
33587 native_allocation: None,
33588 }
33589 }
33590
33591 pub(super) fn publication_test_session(
33592 provider: Arc<CudaKernelProvider>,
33593 domain: &ResidentExecutionDomain,
33594 ) -> SemanticTransitionSession {
33595 use crate::{SemanticArgument, SemanticPredicateRecord, SemanticTypedRecord};
33596 use xlog_core::{RelId, ScalarType, Schema};
33597 let mut graph = provider
33598 .allocate_semantic_hypergraph(
33599 domain,
33600 crate::SemanticHypergraphCapacities::try_new(4, 8, 8, 8).unwrap(),
33601 )
33602 .unwrap();
33603 let records = SemanticAdmissionRecords {
33604 predicates: vec![SemanticPredicateRecord {
33605 predicate: RelId(1),
33606 role: SemanticRecordRole::Statement,
33607 schema: Schema::new(vec![
33608 ("left".into(), ScalarType::U32),
33609 ("right".into(), ScalarType::U32),
33610 ])
33611 .with_sort_labels(vec!["bit".into(), "bit".into()])
33612 .unwrap(),
33613 }],
33614 records: [[1, 1], [0, 1]]
33615 .into_iter()
33616 .map(|values| SemanticTypedRecord {
33617 predicate: RelId(1),
33618 arguments: values.map(SemanticArgument::U32).to_vec(),
33619 qualifiers: vec![],
33620 })
33621 .collect(),
33622 supports: vec![],
33623 };
33624 graph
33625 .admit_records(
33626 graph.empty_root(),
33627 records,
33628 SemanticAdmissionLimits {
33629 max_records: 8,
33630 max_terms: 32,
33631 max_references: 8,
33632 max_utf8_bytes: 256,
33633 },
33634 )
33635 .unwrap();
33636 let mut session = SemanticTransitionSession::from_hypergraph(graph).unwrap();
33637 session
33638 .bind_task_evaluation(task_binding_tests::task_spec([0, 1, 1], vec![]))
33639 .unwrap();
33640 session
33641 }
33642
33643 fn publication_test_provider() -> (Arc<CudaKernelProvider>, ResidentExecutionDomain) {
33644 let provider = Arc::new(
33645 crate::CudaProviderBuilder::new(
33646 0,
33647 xlog_core::MemoryBudget::with_limit(512 * 1024 * 1024),
33648 )
33649 .with_stream_capacity(1)
33650 .build()
33651 .unwrap(),
33652 );
33653 let runtime = Arc::clone(provider.memory().runtime().unwrap());
33654 let stream_id = runtime.stream_pool().acquire().unwrap();
33655 let stream = runtime.stream_pool().resolve(stream_id).unwrap();
33656 let domain = provider
33657 .bind_resident_execution_domain(runtime, stream_id, stream)
33658 .unwrap();
33659 (provider, domain)
33660 }
33661
33662 pub(super) fn publication_test_parent(provider: &CudaKernelProvider) -> SemanticParentBinding {
33663 let mut counts = [1u64; 55];
33664 counts[15] = 3;
33665 for role in [4, 5, 6, 7, 19, 20, 21, 22, 23, 24, 25, 51, 52, 53, 54] {
33666 counts[role - 1] = 0;
33667 }
33668 let mut records = Vec::new();
33669 let mut model_contract_layout = SemanticModelContractLayout::default();
33670 for role in 1..=55 {
33671 if is_tensor_role(role) || matches!(role, 1..=3 | 14..=16 | 30..=33 | 43 | 47 | 48 | 55)
33672 {
33673 continue;
33674 }
33675 let mut bytes = format!("application record {role}").into_bytes();
33676 if role == 44 {
33677 model_contract_layout = SemanticModelContractLayout {
33678 schema_begin: 104,
33679 schema_bytes: bytes.len() as u64,
33680 schema_digest_offset: 0,
33681 generation_offset: 32,
33682 numerical_digest_offset: 40,
33683 identity_offset: 72,
33684 };
33685 let mut record = vec![0; 104];
33686 record.extend_from_slice(&bytes);
33687 bytes = record;
33688 }
33689 records.push(SemanticStateRecord {
33690 role: SemanticStateRole::from_code(role).unwrap(),
33691 index: 0,
33692 capacity_bytes: 128,
33693 bytes,
33694 });
33695 }
33696 let slot = |token, logical_position, committed| SemanticTextSlot {
33697 token,
33698 logical_position,
33699 kind: 1,
33700 provenance: 1,
33701 valid: 1,
33702 committed,
33703 recomputed: 1,
33704 provenance_record: 0,
33705 };
33706 let mut source = [SemanticTextSlot::default(); 32];
33707 source[0] = slot(7, 0, 0);
33708 source[1] = slot(8, 1, 0);
33709 let model_owner = Arc::new(allocate_publication::<u8>(provider, 4).unwrap());
33710 upload_publication(provider, &18f32.to_le_bytes(), &model_owner).unwrap();
33711 let tensor = crate::dlpack::export_slice_managed_tensor(
33712 Arc::clone(&model_owner),
33713 provider.device().ordinal() as i32,
33714 crate::dlpack::DLDataType {
33715 code: 2,
33716 bits: 32,
33717 lanes: 1,
33718 },
33719 1,
33720 1,
33721 )
33722 .unwrap();
33723 let backing = crate::dlpack::export_slice_managed_tensor(
33724 Arc::clone(&model_owner),
33725 provider.device().ordinal() as i32,
33726 crate::dlpack::DLDataType {
33727 code: 1,
33728 bits: 8,
33729 lanes: 1,
33730 },
33731 1,
33732 4,
33733 )
33734 .unwrap();
33735 unsafe {
33739 let metadata = &mut (*backing.as_ptr()).dl_tensor;
33740 metadata.ndim = 1;
33741 metadata.shape = metadata.shape.add(1);
33742 }
33743 let model_layout = SemanticTensorLayout {
33744 role: 18,
33745 index: 0,
33746 scalar_type: 6,
33747 element_bytes: 4,
33748 rank: 2,
33749 logical_axis: u64::MAX,
33750 dimensions: [1, 1, 0, 0],
33751 strides_bytes: [4, 4, 0, 0],
33752 };
33753 let mut tensors = (8..=13)
33754 .map(|role| publication_test_tensor(provider, role, role as f32))
33755 .collect::<Vec<_>>();
33756 tensors.push(SemanticTensorInput {
33757 layout: model_layout,
33758 logical_begin: 0,
33759 logical_end: 0,
33760 tensor,
33761 native_allocation: None,
33762 });
33763 let mut parent = SemanticParentBinding {
33764 recovered_instance: None,
33765 source,
33766 prefix: vec![],
33767 ring_head: 2,
33768 provenance_records: 0,
33769 prefix_capacity: 64,
33770 feedback_capacity: 3,
33771 max_position: 262144,
33772 pad_token: 0,
33773 terminal_tokens: vec![100],
33774 final_intent_payload_bytes: 8,
33775 intent_effect: b"record result".to_vec(),
33776 intent_entry_capacity: 4,
33777 intent_payload_capacity_bytes: 256,
33778 acknowledgement_payload_capacity_bytes: 4096,
33779 model_generation: 1,
33780 policy_generation: 1,
33781 neural_generation: 1,
33782 cache_generation: 1,
33783 model_numerical_mode: b"native test numerical mode".to_vec(),
33784 model_contract_layout,
33785 authority_generation: 1,
33786 training_cursor: 0,
33787 training_rng: [1, 2, 3, 4],
33788 fuel: 8,
33789 rng: SemanticRngBinding {
33790 model_generation: 1,
33791 stream_serial: 5,
33792 family_id: 2,
33793 proposal: 0,
33794 },
33795 topology_identity: Identity256::from_bytes([4; 32]),
33796 table_identity: Identity256::from_bytes([5; 32]),
33797 role_counts: counts,
33798 records,
33799 tensors,
33800 model_memory: SemanticModelMemory {
33801 allocations: vec![SemanticTensorInput {
33802 layout: SemanticTensorLayout {
33803 role: 0,
33804 index: 0,
33805 scalar_type: 1,
33806 element_bytes: 1,
33807 rank: 1,
33808 logical_axis: u64::MAX,
33809 dimensions: [4, 0, 0, 0],
33810 strides_bytes: [1, 0, 0, 0],
33811 },
33812 logical_begin: 0,
33813 logical_end: 0,
33814 tensor: backing,
33815 native_allocation: None,
33816 }],
33817 storages: vec![SemanticModelStorage {
33818 allocation: 0,
33819 byte_offset: 0,
33820 span_bytes: 4,
33821 }],
33822 views: vec![SemanticModelView {
33823 role: 18,
33824 index: 0,
33825 storage: 0,
33826 byte_offset: 0,
33827 }],
33828 },
33829 active_layouts: vec![],
33830 };
33831 parent
33832 .bind_initial_sources(
33833 &[SemanticObservedSource {
33834 identity: "observed-input".into(),
33835 tokens: vec![7, 8],
33836 origin: b"complete observed fixture input".to_vec(),
33837 }],
33838 &(0..2)
33839 .map(|position| SemanticSourceMapping {
33840 source: "observed-input".into(),
33841 offset: position,
33842 logical_position: position,
33843 })
33844 .collect::<Vec<_>>(),
33845 b"current fixture authority",
33846 64,
33847 )
33848 .unwrap();
33849 parent
33850 }
33851
33852 #[test]
33853 #[ignore = "requires an explicitly authorized remote CUDA run"]
33854 fn nonempty_initial_prefix_cannot_bind_without_its_prefill_stage() {
33855 let (provider, domain) = publication_test_provider();
33856 let mut session = publication_test_session(Arc::clone(&provider), &domain);
33857 let mut parent = publication_test_parent(&provider);
33858 parent.prefix.push(SemanticTextSlot {
33859 token: 7,
33860 logical_position: 0,
33861 kind: 1,
33862 provenance: 1,
33863 valid: 1,
33864 committed: 1,
33865 ..SemanticTextSlot::default()
33866 });
33867 assert!(matches!(
33868 session.bind_parent(parent),
33869 Err(SemanticTransitionError::InvalidInput { .. })
33870 ));
33871 session
33872 .bind_parent(publication_test_parent(&provider))
33873 .unwrap();
33874 }
33875
33876 fn publication_test_tensor_pair(
33877 provider: &CudaKernelProvider,
33878 layout: SemanticTensorLayout,
33879 bytes: &[u8],
33880 ) -> (SemanticTensorInput, SemanticTensorInput) {
33881 use xlog_core::{ScalarType, Schema};
33882 let owner = allocate_publication::<u8>(provider, bytes.len()).unwrap();
33883 upload_publication(provider, bytes, &owner).unwrap();
33884 let scalar = match layout.scalar_type {
33885 3 => ScalarType::U64,
33886 6 => ScalarType::F32,
33887 8 => ScalarType::Bool,
33888 _ => panic!("fixture tensor has an unsupported scalar type"),
33889 };
33890 let (original, captured) = if layout.rank == 1 {
33891 let buffer = provider
33892 .buffer_from_columns(
33893 vec![crate::CudaColumn::Owned(owner)],
33894 layout.dimensions[0],
33895 Schema::new(vec![("value".into(), scalar)]),
33896 )
33897 .unwrap();
33898 let table = provider.to_dlpack_table(buffer);
33899 (table.column(0).unwrap(), table.column(0).unwrap())
33900 } else {
33901 assert_eq!(layout.rank, 2);
33902 let dtype = match scalar {
33903 ScalarType::U64 => crate::dlpack::DLDataType {
33904 code: 1,
33905 bits: 64,
33906 lanes: 1,
33907 },
33908 ScalarType::F32 => crate::dlpack::DLDataType {
33909 code: 2,
33910 bits: 32,
33911 lanes: 1,
33912 },
33913 _ => unreachable!("fixture matrices use floating point or unsigned integers"),
33914 };
33915 let owner = Arc::new(owner);
33916 let export = || {
33917 crate::dlpack::export_slice_managed_tensor(
33918 Arc::clone(&owner),
33919 provider.device().ordinal() as i32,
33920 dtype,
33921 layout.dimensions[0] as usize,
33922 layout.dimensions[1] as usize,
33923 )
33924 .unwrap()
33925 };
33926 (export(), export())
33927 };
33928 let input = |tensor| SemanticTensorInput {
33929 layout,
33930 logical_begin: 0,
33931 logical_end: 0,
33932 tensor,
33933 native_allocation: None,
33934 };
33935 (input(original), input(captured))
33936 }
33937
33938 pub(super) fn publication_test_continuation(
33939 session: &mut SemanticTransitionSession,
33940 old: &SemanticPublishedLease,
33941 provider: &CudaKernelProvider,
33942 ) -> (SemanticContinuationInput, SemanticTensorContentWitness) {
33943 publication_test_continuation_with_numerical_admissibility(session, old, provider, 1)
33944 }
33945
33946 pub(super) fn publication_test_continuation_with_numerical_admissibility(
33947 session: &mut SemanticTransitionSession,
33948 old: &SemanticPublishedLease,
33949 provider: &CudaKernelProvider,
33950 numerical_admissibility: u8,
33951 ) -> (SemanticContinuationInput, SemanticTensorContentWitness) {
33952 assert!(numerical_admissibility <= 1);
33953 let contract = session.publication.as_ref().unwrap().contract_value;
33954 let feedback = session
33955 .read_published_record_bytes(old, SemanticStateRole::RawFeedback)
33956 .unwrap();
33957 assert_eq!(
33958 feedback.len(),
33959 contract.feedback_capacity as usize * size_of::<RawFeedbackRecord>()
33960 );
33961 let mut filled: Vec<_> = old
33962 .source
33963 .iter()
33964 .enumerate()
33965 .filter(|(_, slot)| slot.valid == 1 && slot.kind == 1)
33966 .collect();
33967 let mut masks: Vec<_> = old
33968 .source
33969 .iter()
33970 .enumerate()
33971 .filter(|(_, slot)| slot.valid == 1 && slot.kind == 2)
33972 .collect();
33973 filled.sort_by_key(|(_, slot)| slot.logical_position);
33974 masks.sort_by_key(|(_, slot)| slot.logical_position);
33975 let mut text_rows = vec![0u64; 32 * 2];
33976 for (row, &(slot, source)) in masks.iter().enumerate() {
33977 text_rows[row * 2] = slot as u64;
33978 text_rows[row * 2 + 1] = source.logical_position;
33979 }
33980 let capacity = 32 + contract.feedback_capacity;
33981 let mut active_rows = vec![0u64; capacity as usize * 4];
33982 let mut active_count = 0u64;
33983 let mut append = |physical, slot, position, kind| {
33984 let offset = active_count as usize * 4;
33985 active_rows[offset..offset + 4].copy_from_slice(&[physical, slot, position, kind]);
33986 active_count += 1;
33987 };
33988 for (physical, &(slot, source)) in filled.iter().enumerate() {
33989 append(physical as u64, slot as u64, source.logical_position, 1);
33990 }
33991 for (slot, record) in feedback
33992 .as_chunks::<{ size_of::<RawFeedbackRecord>() }>()
33993 .0
33994 .iter()
33995 .enumerate()
33996 {
33997 let valid = u64::from_ne_bytes(record[..8].try_into().unwrap());
33998 assert!(valid <= 1);
33999 if valid == 1 {
34000 append(
34001 (filled.len() + slot) as u64,
34002 32 + slot as u64,
34003 contract.prefix_capacity + 32 + slot as u64,
34004 3,
34005 );
34006 }
34007 }
34008 for (offset, &(slot, source)) in masks.iter().enumerate() {
34009 append(
34010 filled.len() as u64 + contract.feedback_capacity + offset as u64,
34011 slot as u64,
34012 source.logical_position,
34013 2,
34014 );
34015 }
34016 let mut tensors = Vec::new();
34017 let mut capture = Vec::new();
34018 for role in 8..=13 {
34019 let layout = SemanticTensorLayout {
34020 role,
34021 index: 0,
34022 scalar_type: 6,
34023 element_bytes: 4,
34024 rank: 2,
34025 logical_axis: u64::MAX,
34026 dimensions: [1, 1, 0, 0],
34027 strides_bytes: [4, 4, 0, 0],
34028 };
34029 let (original, witnessed) =
34030 publication_test_tensor_pair(provider, layout, &(role as f32 + 1.0).to_ne_bytes());
34031 tensors.push(original);
34032 capture.push(witnessed);
34033 }
34034 let service_bytes = [
34035 publication_abi_bytes(&text_rows),
34036 publication_abi_bytes(&[masks.len() as u64]),
34037 vec![0u8; 32],
34038 publication_abi_bytes(&active_rows),
34039 publication_abi_bytes(&[active_count]),
34040 vec![numerical_admissibility],
34041 ];
34042 let layouts = continuation_service_layouts(tensors.len(), capacity, None).unwrap();
34043 let mut services = Vec::new();
34044 for (layout, bytes) in layouts.into_iter().zip(service_bytes) {
34045 let (original, witnessed) = publication_test_tensor_pair(provider, layout, &bytes);
34046 services.push(original.tensor);
34047 capture.push(witnessed);
34048 }
34049 let witness = session.capture_tensor_content(old, capture, 1).unwrap();
34050 let [text_rows, text_row_count, selected_text, active_rows, active_row_count, numerical_admissibility]:
34051 [DlpackManagedTensor; 6] = services.try_into().ok().unwrap();
34052 (
34053 SemanticContinuationInput {
34054 tensors,
34055 authority_decisions: b"current fixture continuation".to_vec(),
34056 text_rows,
34057 text_row_count,
34058 selected_text,
34059 active_rows,
34060 active_row_count,
34061 numerical_admissibility,
34062 numerical_blocks: None,
34063 model_schema_digest: None,
34064 model_identity: None,
34065 },
34066 witness,
34067 )
34068 }
34069
34070 fn publication_test_recompute(
34071 session: &mut SemanticTransitionSession,
34072 old: &SemanticPublishedLease,
34073 provider: &crate::CudaKernelProvider,
34074 ) {
34075 session
34076 .admit_transition(old, SemanticTransitionKind::Recompute)
34077 .unwrap();
34078 let (continuation, witness) = publication_test_continuation(session, old, provider);
34079 session
34080 .bind_continuation(old, continuation, &witness, 1)
34081 .unwrap();
34082 drop(witness);
34083 session.capture().unwrap();
34084 session.launch().unwrap();
34085 session.observe(0).unwrap();
34086 }
34087
34088 #[test]
34089 #[ignore = "requires an explicitly authorized remote CUDA run"]
34090 fn publication_material_native_restore_preserves_acquired_prefix_feedback_and_history() {
34091 let (provider, domain) = publication_test_provider();
34092 let mut session = publication_test_session(Arc::clone(&provider), &domain);
34093 session
34094 .bind_parent(publication_test_parent(&provider))
34095 .unwrap();
34096 let mut old = session.acquire().unwrap();
34097 let old_prefix = session
34098 .read_published_record_bytes(&old, SemanticStateRole::PrefixSource)
34099 .unwrap();
34100 let old_mode = session.published_model_numerical_mode(&old).unwrap();
34101 assert_eq!(old_mode, b"native test numerical mode");
34102 let old_material = session.published_state_material(&old).unwrap();
34103 let (_, alias) = session.published_prefix(&old, 1).unwrap();
34104 publication_test_recompute(&mut session, &old, &provider);
34105 let mut current = session.acquire().unwrap();
34106 assert_eq!(current.header.prefix_extent, old.header.prefix_extent + 1);
34107 assert_eq!(
34108 session
34109 .read_published_record_bytes(&old, SemanticStateRole::PrefixSource)
34110 .unwrap(),
34111 old_prefix
34112 );
34113 assert_eq!(
34114 session.published_state_material(&old).unwrap(),
34115 old_material
34116 );
34117 assert!(session.release(&mut old, &[1]).is_err());
34118 drop(alias);
34119 session.release(&mut old, &[1]).unwrap();
34120 let bytes = session.published_state_material(¤t).unwrap();
34121 let original = PublicationMaterial::decode(&bytes).unwrap();
34122 session.release(&mut current, &[]).unwrap();
34123 drop(session);
34124 let mut restored = publication_test_session(Arc::clone(&provider), &domain);
34125 let identity = restored.restore_state_material(&bytes).unwrap();
34126 assert_ne!(identity.instance, original.bank.header.instance);
34127 assert_eq!(identity.logical_digest, original.bank.header.logical_digest);
34128 assert_eq!(identity.state_digest, original.bank.header.state_digest);
34129 let mut lease = restored.acquire().unwrap();
34130 assert_eq!(
34131 restored.published_model_numerical_mode(&lease).unwrap(),
34132 old_mode
34133 );
34134 let reread =
34135 PublicationMaterial::decode(&restored.published_state_material(&lease).unwrap())
34136 .unwrap();
34137 for role in [1, 2, 14, 15, 27, 28, 30, 31, 32, 33, 43] {
34138 assert_eq!(
34139 reread
34140 .ranges
34141 .iter()
34142 .find(|item| item.range.role == role)
34143 .unwrap()
34144 .bytes,
34145 original
34146 .ranges
34147 .iter()
34148 .find(|item| item.range.role == role)
34149 .unwrap()
34150 .bytes,
34151 "role {role}"
34152 );
34153 }
34154 assert_eq!(reread.graph, original.graph);
34155 restored.release(&mut lease, &[]).unwrap();
34156 drop(restored);
34157 provider.memory().reap_pending_deallocations().unwrap();
34158 }
34159
34160 #[test]
34161 #[ignore = "requires an explicitly authorized remote CUDA run"]
34162 fn publication_material_runtime_reader_rejects_completed_layout_alias_writes() {
34163 let (provider, domain) = publication_test_provider();
34164 let mut session = publication_test_session(Arc::clone(&provider), &domain);
34165 session
34166 .bind_parent(publication_test_parent(&provider))
34167 .unwrap();
34168 let mut lease = session.acquire().unwrap();
34169 let mode = session.published_model_numerical_mode(&lease).unwrap();
34170 let original = session
34171 .read_published_record_bytes(&lease, SemanticStateRole::TensorLayout)
34172 .unwrap();
34173 let alias = session
34174 .published_record(&lease, SemanticStateRole::TensorLayout, 0, 1)
34175 .unwrap();
34176 let tensor = unsafe { &(*alias.as_ptr()).dl_tensor };
34179 let pointer = tensor.data as usize as u64 + tensor.byte_offset;
34180 for offset in [
34183 size_of::<TensorLayoutTableHeader>() + 2 * size_of::<u64>(),
34184 2 * size_of::<u64>(),
34185 ] {
34186 assert!(offset < original.len());
34187 assert_eq!(
34191 unsafe {
34192 sys::cuMemsetD8Async(
34193 pointer + offset as u64,
34194 original[offset] ^ 1,
34195 1,
34196 std::ptr::null_mut(),
34197 )
34198 },
34199 sys::cudaError_enum::CUDA_SUCCESS
34200 );
34201 assert!(matches!(
34202 session.published_model_numerical_mode(&lease),
34203 Err(SemanticTransitionError::ObservationMismatch)
34204 ));
34205 assert_eq!(
34208 unsafe {
34209 sys::cuMemsetD8Async(
34210 pointer + offset as u64,
34211 original[offset],
34212 1,
34213 std::ptr::null_mut(),
34214 )
34215 },
34216 sys::cudaError_enum::CUDA_SUCCESS
34217 );
34218 assert_eq!(
34219 session.published_model_numerical_mode(&lease).unwrap(),
34220 mode
34221 );
34222 }
34223 drop(alias);
34224 session.release(&mut lease, &[1]).unwrap();
34225 drop(session);
34226 provider.memory().reap_pending_deallocations().unwrap();
34227 }
34228
34229 #[test]
34230 #[ignore = "requires an explicitly authorized remote CUDA run; fatal cases use fresh processes"]
34231 fn replay_boundaries_reject_mutated_shared_predecessor_weights() {
34232 const CHILD_KIND: &str = "XLOG_REPLAY_CONTENT_TEST_CHILD";
34233 const COMPLETED: &str =
34234 "shared replay content mutation produced a fatal CUDA completion error";
34235 let Some(kind) = std::env::var_os(CHILD_KIND) else {
34236 let qualified = concat!(
34237 module_path!(),
34238 "::replay_boundaries_reject_mutated_shared_predecessor_weights"
34239 );
34240 let test_name = qualified.split_once("::").unwrap().1;
34241 for kind in ["verify", "evidence", "provenance"] {
34242 let output = std::process::Command::new(std::env::current_exe().unwrap())
34243 .args([
34244 "--exact",
34245 test_name,
34246 "--ignored",
34247 "--nocapture",
34248 "--test-threads=1",
34249 ])
34250 .env(CHILD_KIND, kind)
34251 .output()
34252 .unwrap();
34253 assert!(
34254 output.status.success(),
34255 "{kind} child did not verify a CUDA trap:\n{}\n{}",
34256 String::from_utf8_lossy(&output.stdout),
34257 String::from_utf8_lossy(&output.stderr)
34258 );
34259 assert!(
34260 String::from_utf8_lossy(&output.stdout).contains(COMPLETED),
34261 "{kind} child did not reach the typed CUDA completion check"
34262 );
34263 }
34264 return;
34265 };
34266 assert!(kind == "verify" || kind == "evidence" || kind == "provenance");
34267 let (provider, domain) = publication_test_provider();
34268 let mut original = publication_test_session(Arc::clone(&provider), &domain);
34269 original
34270 .bind_parent(publication_test_parent(&provider))
34271 .unwrap();
34272 let mut old = original.acquire().unwrap();
34273 let predecessor_bytes = original.published_state_material(&old).unwrap();
34274 publication_test_recompute(&mut original, &old, &provider);
34275 let mut current = original.acquire().unwrap();
34276 let evidence = original.published_replay_evidence(&old, ¤t).unwrap();
34277 assert!(
34278 original.release_events.is_empty(),
34279 "completed export events must not wait for reader release"
34280 );
34281 let material = SemanticReplayMaterial::decode(
34282 &predecessor_bytes,
34283 &evidence,
34284 old.identity.logical_digest,
34285 current.identity.logical_digest,
34286 )
34287 .unwrap();
34288 original.release(&mut old, &[1]).unwrap();
34289 original.release(&mut current, &[1]).unwrap();
34290 drop(original);
34291
34292 let mut replay = publication_test_session(Arc::clone(&provider), &domain);
34293 replay.restore_replay_material(&material).unwrap();
34294 let predecessor = replay.acquire().unwrap();
34295 publication_test_recompute(&mut replay, &predecessor, &provider);
34296 let successor = replay.acquire().unwrap();
34297 let alias = replay
34298 .published_tensor(&predecessor, SemanticStateRole::SlowWeights, 0, 1)
34299 .unwrap();
34300 let successor_alias = replay
34301 .published_tensor(&successor, SemanticStateRole::SlowWeights, 0, 1)
34302 .unwrap();
34303 let tensor = unsafe { &(*alias.as_ptr()).dl_tensor };
34306 let successor_tensor = unsafe { &(*successor_alias.as_ptr()).dl_tensor };
34307 assert_eq!(tensor.byte_offset, 0);
34308 assert_eq!(tensor.data, successor_tensor.data);
34309 let pointer = tensor.data as usize as u64;
34310 drop(successor_alias);
34311 replay
34312 .verify_replay_publication(&material, &predecessor, &successor)
34313 .unwrap();
34314 replay
34315 .published_replay_evidence(&predecessor, &successor)
34316 .unwrap();
34317 replay
34318 .published_replay_provenance(&predecessor, &successor)
34319 .unwrap();
34320 assert_eq!(
34323 unsafe { sys::cuMemsetD8Async(pointer, 0, 4, std::ptr::null_mut()) },
34324 sys::cudaError_enum::CUDA_SUCCESS
34325 );
34326 if kind == "verify" {
34327 drop(alias);
34328 replay.quiesce_published_reader(&predecessor, &[1]).unwrap();
34329 assert!(replay
34330 .verify_replay_publication(&material, &predecessor, &successor)
34331 .is_err());
34332 } else if kind == "evidence" {
34333 assert!(replay
34334 .published_replay_evidence(&predecessor, &successor)
34335 .is_err());
34336 } else {
34337 assert!(replay
34338 .published_replay_provenance(&predecessor, &successor)
34339 .is_err());
34340 }
34341 let completion = unsafe { sys::cuStreamSynchronize(std::ptr::null_mut()) };
34344 assert!(
34345 matches!(
34346 completion,
34347 sys::cudaError_enum::CUDA_ERROR_ILLEGAL_INSTRUCTION
34348 | sys::cudaError_enum::CUDA_ERROR_LAUNCH_FAILED
34349 ),
34350 "unexpected CUDA completion: {completion:?}"
34351 );
34352 println!("{COMPLETED}");
34353 std::io::Write::flush(&mut std::io::stdout()).unwrap();
34354 std::process::exit(0);
34355 }
34356
34357 fn publication_test_alias(
34358 session: &mut SemanticTransitionSession,
34359 lease: &SemanticPublishedLease,
34360 role: SemanticStateRole,
34361 consumer_stream: u64,
34362 ) -> SemanticTensorInput {
34363 let layout = session.publication.as_ref().unwrap().layouts[&(role as u64, 0)];
34364 let range = *lease
34365 .directory
34366 .iter()
34367 .find(|range| range.role == role as u64 && range.index == 0)
34368 .unwrap();
34369 let (native_allocation, backing) = session
34370 .published_tensor_allocation(lease, role, 0, consumer_stream)
34371 .unwrap();
34372 drop(backing);
34373 SemanticTensorInput {
34374 layout,
34375 logical_begin: range.logical_begin,
34376 logical_end: range.logical_end,
34377 tensor: session
34378 .published_tensor(lease, role, 0, consumer_stream)
34379 .unwrap(),
34380 native_allocation: Some(native_allocation),
34381 }
34382 }
34383
34384 struct ContentTestExport {
34385 managed: crate::dlpack::DLManagedTensor,
34386 _owner: DlpackManagedTensor,
34387 shape: [i64; 2],
34388 strides: [i64; 2],
34389 }
34390
34391 unsafe extern "C" fn delete_content_test_export(managed: *mut crate::dlpack::DLManagedTensor) {
34392 if managed.is_null() {
34393 return;
34394 }
34395 let owner = unsafe { (*managed).manager_ctx.cast::<ContentTestExport>() };
34398 if !owner.is_null() {
34399 drop(unsafe { Box::from_raw(owner) });
34400 }
34401 }
34402
34403 fn content_test_export(
34404 owner: Arc<TrackedCudaSlice<u8>>,
34405 device_id: i32,
34406 dtype: crate::dlpack::DLDataType,
34407 layout: SemanticTensorLayout,
34408 logical_interval: (u64, u64),
34409 ) -> SemanticTensorInput {
34410 assert_eq!(layout.rank, 2);
34411 let shape = [
34412 i64::try_from(layout.dimensions[0]).unwrap(),
34413 i64::try_from(layout.dimensions[1]).unwrap(),
34414 ];
34415 let strides = [
34416 i64::try_from(layout.strides_bytes[0] / layout.element_bytes).unwrap(),
34417 i64::try_from(layout.strides_bytes[1] / layout.element_bytes).unwrap(),
34418 ];
34419 let backing = crate::dlpack::export_slice_managed_tensor(
34420 owner,
34421 device_id,
34422 dtype,
34423 usize::try_from(shape[0]).unwrap(),
34424 usize::try_from(shape[1]).unwrap(),
34425 )
34426 .unwrap();
34427 let source = unsafe { &(*backing.as_ptr()).dl_tensor };
34431 let mut export = Box::new(ContentTestExport {
34432 managed: crate::dlpack::DLManagedTensor {
34433 dl_tensor: crate::dlpack::DLTensor {
34434 data: source.data,
34435 device: source.device,
34436 ndim: 2,
34437 dtype: source.dtype,
34438 shape: std::ptr::null_mut(),
34439 strides: std::ptr::null_mut(),
34440 byte_offset: source.byte_offset,
34441 },
34442 manager_ctx: std::ptr::null_mut(),
34443 deleter: Some(delete_content_test_export),
34444 },
34445 _owner: backing,
34446 shape,
34447 strides,
34448 });
34449 export.managed.dl_tensor.shape = export.shape.as_mut_ptr();
34450 export.managed.dl_tensor.strides = export.strides.as_mut_ptr();
34451 let owner = Box::into_raw(export);
34452 let tensor = unsafe {
34455 (*owner).managed.manager_ctx = owner.cast();
34456 DlpackManagedTensor::from_raw(&mut (*owner).managed)
34457 };
34458 SemanticTensorInput {
34459 layout,
34460 logical_begin: logical_interval.0,
34461 logical_end: logical_interval.1,
34462 tensor,
34463 native_allocation: None,
34464 }
34465 }
34466
34467 #[test]
34468 #[ignore = "requires an explicitly authorized remote CUDA run"]
34469 fn native_feedback_alias_capture_reuses_original_producer_seals() {
34470 let (provider, domain) = publication_test_provider();
34471 let mut session = publication_test_session(Arc::clone(&provider), &domain);
34472 session
34473 .bind_parent(publication_test_parent(&provider))
34474 .unwrap();
34475 let mut lease = session.acquire().unwrap();
34476 session
34477 .admit_transition(&lease, SemanticTransitionKind::Proposal)
34478 .unwrap();
34479 let feedback = session.published_feedback(&lease, 1).unwrap();
34480 let layouts = session.steps[&lease.token].feedback[0]
34481 .content
34482 .tensors
34483 .iter()
34484 .map(|tensor| tensor.layout)
34485 .collect::<Vec<_>>();
34486 let inputs = feedback
34487 .into_dlpack()
34488 .into_iter()
34489 .zip(layouts.iter().copied())
34490 .map(|(tensor, layout)| SemanticTensorInput {
34491 tensor,
34492 layout,
34493 logical_begin: 0,
34494 logical_end: 0,
34495 native_allocation: None,
34496 })
34497 .collect();
34498 let mut other = session.acquire().unwrap();
34499 assert!(
34500 session.capture_tensor_content(&other, inputs, 1).is_err(),
34501 "a second reader must not reseal the first reader's native outputs"
34502 );
34503 session.release(&mut other, &[1]).unwrap();
34504 let feedback = session.published_feedback(&lease, 1).unwrap();
34505 let inputs = feedback
34506 .into_dlpack()
34507 .into_iter()
34508 .zip(layouts)
34509 .map(|(tensor, layout)| SemanticTensorInput {
34510 tensor,
34511 layout,
34512 logical_begin: 0,
34513 logical_end: 0,
34514 native_allocation: None,
34515 })
34516 .collect();
34517 let witness = session.capture_tensor_content(&lease, inputs, 1).unwrap();
34518 let reader = &session.steps[&lease.token];
34519 let TensorContentSeals::Captured(original) = &reader.feedback[1].content.seals else {
34520 panic!("native producer seals");
34521 };
34522 let TensorContentSeals::Captured(consumer) = &reader.content[witness.index].seals else {
34523 panic!("original alias seals");
34524 };
34525 assert_eq!(original.len(), 6);
34526 for (original, consumer) in original.iter().zip(consumer) {
34527 let CapturedTensorDigest::Tensor {
34528 cells: original, ..
34529 } = original
34530 else {
34531 panic!("feedback producer digest");
34532 };
34533 let CapturedTensorDigest::Tensor {
34534 cells: consumer,
34535 producer_sealed,
34536 ..
34537 } = consumer
34538 else {
34539 panic!("feedback alias digest");
34540 };
34541 assert!(
34542 Arc::ptr_eq(original, consumer),
34543 "alias capture must not allocate a replacement digest"
34544 );
34545 assert!(
34546 *producer_sealed,
34547 "alias capture must verify, never overwrite the producer seal"
34548 );
34549 }
34550 drop(witness);
34551 session.release(&mut lease, &[1]).unwrap();
34552 drop(session);
34553 provider.memory().reap_pending_deallocations().unwrap();
34554 assert_eq!(provider.memory().allocated_bytes(), 0);
34555 }
34556
34557 #[test]
34558 #[ignore = "requires an explicitly authorized remote CUDA run"]
34559 fn retained_model_content_survives_reader_retirement_and_bank_reuse() {
34560 let (provider, domain) = publication_test_provider();
34561 let mut session = publication_test_session(Arc::clone(&provider), &domain);
34562 session
34563 .bind_parent(publication_test_parent(&provider))
34564 .unwrap();
34565 let mut lease = session.acquire().unwrap();
34566 let identity = session.published_identity(&lease).unwrap();
34567 let layout = session.publication.as_ref().unwrap().layouts[&(18, 0)];
34568 let live = Arc::new(allocate_publication::<u8>(&provider, 4).unwrap());
34569 upload_publication(&provider, &18.0f32.to_le_bytes(), &live).unwrap();
34570 let producer = || {
34571 content_test_export(
34572 Arc::clone(&live),
34573 provider.device().ordinal() as i32,
34574 crate::dlpack::DLDataType {
34575 code: 2,
34576 bits: 32,
34577 lanes: 1,
34578 },
34579 layout,
34580 (0, 0),
34581 )
34582 };
34583 let witness = session
34584 .bind_model_content(&lease, vec![producer()], 1)
34585 .unwrap();
34586 session
34587 .admit_transition(&lease, SemanticTransitionKind::Recompute)
34588 .unwrap();
34589 let feedback = session.published_feedback(&lease, 1).unwrap();
34590 assert!(session.release_published_reader(&mut lease, &[1]).is_err());
34591 let (continuation, continuation_witness) =
34592 publication_test_continuation(&mut session, &lease, &provider);
34593 session
34594 .bind_continuation(&lease, continuation, &continuation_witness, 1)
34595 .unwrap();
34596 drop(continuation_witness);
34597 session.capture().unwrap();
34598 session.launch().unwrap();
34599 session.observe(0).unwrap();
34600 let (_, bank_alias) = session.published_prefix(&lease, 1).unwrap();
34601 assert!(session.release_published_reader(&mut lease, &[1]).is_err());
34602 assert!(lease.is_active());
34603 drop(bank_alias);
34604 session.release_published_reader(&mut lease, &[1]).unwrap();
34605 assert!(!lease.is_active());
34606 assert_eq!(session.retained_step_identity(&lease).unwrap(), identity);
34607 assert!(session.published_source(&lease, 1).is_err());
34608 assert!(session.quiesce_published_reader(&lease, &[1]).is_err());
34609 assert!(session.release(&mut lease, &[1]).is_err());
34610 for _ in 0..2 {
34611 let mut current = session.acquire().unwrap();
34612 publication_test_recompute(&mut session, ¤t, &provider);
34613 session.release(&mut current, &[1]).unwrap();
34614 }
34615 let mut reused = session.acquire().unwrap();
34616 assert_eq!((reused.identity.word >> 1) - (identity.word >> 1), 3);
34617 session.release(&mut reused, &[]).unwrap();
34618 let before = session.host_io_stats();
34619 session
34620 .verify_tensor_content(&lease, &witness, vec![producer()], 1)
34621 .unwrap();
34622 assert_eq!(session.host_io_stats(), before);
34623 drop(witness);
34624 assert!(
34625 session.release(&mut lease, &[1]).is_err(),
34626 "original feedback exports retain their step"
34627 );
34628 drop(feedback);
34629 session.release(&mut lease, &[1]).unwrap();
34630 assert!(session.retained_step_identity(&lease).is_err());
34631 drop(live);
34632 drop(session);
34633 provider.memory().reap_pending_deallocations().unwrap();
34634 assert_eq!(provider.memory().allocated_bytes(), 0);
34635 }
34636
34637 #[test]
34638 #[ignore = "requires an explicitly authorized remote CUDA run"]
34639 fn model_content_binding_uses_original_seals_and_retires_each_reader() {
34640 let (provider, domain) = publication_test_provider();
34641 let mut session = publication_test_session(Arc::clone(&provider), &domain);
34642 session
34643 .bind_parent(publication_test_parent(&provider))
34644 .unwrap();
34645 for _ in 0..2 {
34646 let mut lease = session.acquire().unwrap();
34647 let layout = session.publication.as_ref().unwrap().layouts[&(18, 0)];
34648 let live = Arc::new(allocate_publication::<u8>(&provider, 4).unwrap());
34649 upload_publication(&provider, &18.0f32.to_le_bytes(), &live).unwrap();
34650 let producer = || {
34651 content_test_export(
34652 Arc::clone(&live),
34653 provider.device().ordinal() as i32,
34654 crate::dlpack::DLDataType {
34655 code: 2,
34656 bits: 32,
34657 lanes: 1,
34658 },
34659 layout,
34660 (0, 0),
34661 )
34662 };
34663 let original = producer();
34664 let same = producer();
34665 let substituted =
34666 publication_test_alias(&mut session, &lease, SemanticStateRole::SlowWeights, 1);
34667 let before = session.host_io_stats();
34668 let witness = session
34669 .bind_model_content(&lease, vec![original], 1)
34670 .unwrap();
34671 assert!(
34672 matches!(
34673 session.steps[&lease.token].content[witness.index].seals,
34674 TensorContentSeals::Model(_)
34675 ),
34676 "model binding must not capture a replacement baseline"
34677 );
34678 session
34679 .verify_tensor_content(&lease, &witness, vec![same], 1)
34680 .unwrap();
34681 assert_eq!(session.host_io_stats(), before);
34682 assert!(
34683 session
34684 .verify_tensor_content(&lease, &witness, vec![substituted], 1)
34685 .is_err(),
34686 "equal publication bytes cannot replace this invocation's original live storage"
34687 );
34688 assert!(session.release(&mut lease, &[1]).is_err());
34689 drop(witness);
34690 session.release(&mut lease, &[1]).unwrap();
34691 assert!(
34692 session.readers.is_empty(),
34693 "the first reader is not a permanent model baseline"
34694 );
34695 }
34696 drop(session);
34697 provider.memory().reap_pending_deallocations().unwrap();
34698 assert_eq!(provider.memory().allocated_bytes(), 0);
34699 assert_eq!(provider.memory().deallocation_failure_bytes(), 0);
34700 }
34701
34702 #[test]
34703 #[ignore = "requires an explicitly authorized remote CUDA run"]
34704 fn publication_content_guards_preserve_zero_transfer_and_release_parent_alias_witnesses() {
34705 let (provider, domain) = publication_test_provider();
34706 let mut session = publication_test_session(Arc::clone(&provider), &domain);
34707 session
34708 .bind_parent(publication_test_parent(&provider))
34709 .unwrap();
34710 let mut original = session.acquire().unwrap();
34711 let material = session.published_state_material(&original).unwrap();
34712 session.release(&mut original, &[]).unwrap();
34713 drop(session);
34714 let mut session = publication_test_session(Arc::clone(&provider), &domain);
34715 session.restore_state_material(&material).unwrap();
34716 let mut lease = session.acquire().unwrap();
34717 let before_exports = session.host_io_stats();
34718 let sealed_prefix = *lease
34719 .directory
34720 .iter()
34721 .find(|range| range.role == 1)
34722 .unwrap();
34723 let (_, prefix) = session.published_prefix(&lease, 1).unwrap();
34724 let source = session.published_source(&lease, 1).unwrap();
34725 let context = session.published_model_context(&lease, 1).unwrap();
34726 assert!(matches!(
34727 session.published_model_context(&lease, 2),
34728 Err(SemanticTransitionError::InvalidInput { .. })
34729 ));
34730 let outside_alias = session
34731 .published_tensor(&lease, SemanticStateRole::SlowWeights, 0, 1)
34732 .unwrap();
34733 assert_eq!(
34734 session.host_io_stats(),
34735 before_exports,
34736 "native capacity exports must not copy metadata or wait on the host"
34737 );
34738 let prefix_tensor = unsafe { &(*prefix.as_ptr()).dl_tensor };
34741 assert_eq!(prefix_tensor.ndim, 2);
34742 assert_eq!(
34743 unsafe { std::slice::from_raw_parts(prefix_tensor.shape, 2) },
34744 [64, 8]
34745 );
34746 assert_eq!(
34747 (prefix_tensor.dtype.code, prefix_tensor.dtype.bits),
34748 (1, 64)
34749 );
34750 let storage = session.publication.as_ref().unwrap();
34751 let bank = storage.banks[(lease.identity.word & 1) as usize].device_ptr_value();
34752 for (tensor, field) in [
34753 (&source, PublicationBankField::Source),
34754 (&context.source, PublicationBankField::Source),
34755 (&context.prefix.1, PublicationBankField::PrefixExtent),
34756 (&context.ring_head, PublicationBankField::RingHead),
34757 ] {
34758 let (range, shape, strides) = field.layout();
34759 let tensor = unsafe { &(*tensor.as_ptr()).dl_tensor };
34762 assert_eq!(
34763 tensor.data as usize as u64 + tensor.byte_offset,
34764 bank + range.start as u64
34765 );
34766 assert_eq!((tensor.dtype.code, tensor.dtype.bits), (1, 64));
34767 assert_eq!(tensor.ndim as usize, shape.len());
34768 assert_eq!(
34769 unsafe { std::slice::from_raw_parts(tensor.shape, shape.len()) },
34770 shape
34771 );
34772 assert_eq!(
34773 unsafe { std::slice::from_raw_parts(tensor.strides, strides.len()) },
34774 strides
34775 );
34776 }
34777 let prefix_range = lease
34778 .directory
34779 .iter()
34780 .find(|range| range.role == 3)
34781 .unwrap();
34782 let identity_tensor = unsafe { &(*context.prefix.0.as_ptr()).dl_tensor };
34783 assert_eq!(
34784 identity_tensor.data as usize as u64 + identity_tensor.byte_offset,
34785 storage.allocations[prefix_range.storage_slot as usize].device_ptr_value()
34786 + prefix_range.offset_bytes
34787 );
34788 assert_eq!(
34789 (
34790 identity_tensor.ndim,
34791 identity_tensor.dtype.code,
34792 identity_tensor.dtype.bits
34793 ),
34794 (1, 1, 8)
34795 );
34796 assert_eq!(unsafe { *identity_tensor.shape }, 32);
34797 assert_eq!(context.parent, lease.identity);
34798 assert_eq!(context.descriptor_digest, lease.header.descriptor_digest);
34799 let after_prefix = lease
34800 .directory
34801 .iter()
34802 .find(|range| range.role == 1)
34803 .unwrap();
34804 assert_eq!(
34805 (
34806 after_prefix.logical_begin,
34807 after_prefix.logical_end,
34808 after_prefix.length_bytes,
34809 after_prefix.digest
34810 ),
34811 (
34812 sealed_prefix.logical_begin,
34813 sealed_prefix.logical_end,
34814 sealed_prefix.length_bytes,
34815 sealed_prefix.digest
34816 )
34817 );
34818 drop(prefix);
34819 drop(source);
34820 drop(context);
34821 let mut captured = vec![publication_test_alias(
34824 &mut session,
34825 &lease,
34826 SemanticStateRole::SlowWeights,
34827 1,
34828 )];
34829 let mut verified = vec![publication_test_alias(
34830 &mut session,
34831 &lease,
34832 SemanticStateRole::SlowWeights,
34833 1,
34834 )];
34835 let mut owners = Vec::new();
34836 let cases = [
34837 (
34838 SemanticTensorLayout {
34839 role: 0,
34840 index: 0,
34841 scalar_type: 7,
34842 element_bytes: 8,
34843 rank: 2,
34844 logical_axis: u64::MAX,
34845 dimensions: [1, 3, 0, 0],
34846 strides_bytes: [24, 8, 0, 0],
34847 },
34848 crate::dlpack::DLDataType {
34849 code: crate::dlpack::K_DLINT,
34850 bits: 64,
34851 lanes: 1,
34852 },
34853 [i64::MIN, -7, i64::MAX]
34854 .into_iter()
34855 .flat_map(i64::to_le_bytes)
34856 .collect::<Vec<_>>(),
34857 (0, 0),
34858 ),
34859 (
34860 SemanticTensorLayout {
34861 role: 0,
34862 index: 0,
34863 scalar_type: 8,
34864 element_bytes: 1,
34865 rank: 2,
34866 logical_axis: u64::MAX,
34867 dimensions: [1, 3, 0, 0],
34868 strides_bytes: [3, 1, 0, 0],
34869 },
34870 crate::dlpack::DLDataType {
34871 code: crate::dlpack::K_DLBOOL,
34872 bits: 8,
34873 lanes: 1,
34874 },
34875 vec![0, 1, 1],
34876 (0, 0),
34877 ),
34878 (
34879 SemanticTensorLayout {
34880 role: 0,
34881 index: 0,
34882 scalar_type: 6,
34883 element_bytes: 4,
34884 rank: 2,
34885 logical_axis: u64::MAX,
34886 dimensions: [2, 3, 0, 0],
34887 strides_bytes: [4, 8, 0, 0],
34888 },
34889 crate::dlpack::DLDataType {
34890 code: crate::dlpack::K_DLFLOAT,
34891 bits: 32,
34892 lanes: 1,
34893 },
34894 [1.0f32, 4.0, 2.0, 5.0, 3.0, 6.0]
34895 .into_iter()
34896 .flat_map(f32::to_le_bytes)
34897 .collect(),
34898 (0, 0),
34899 ),
34900 (
34901 SemanticTensorLayout {
34902 role: 0,
34903 index: 0,
34904 scalar_type: 6,
34905 element_bytes: 4,
34906 rank: 2,
34907 logical_axis: u64::MAX,
34908 dimensions: [0, 3, 0, 0],
34909 strides_bytes: [12, 4, 0, 0],
34910 },
34911 crate::dlpack::DLDataType {
34912 code: crate::dlpack::K_DLFLOAT,
34913 bits: 32,
34914 lanes: 1,
34915 },
34916 Vec::new(),
34917 (0, 0),
34918 ),
34919 ];
34920 for (mut layout, dtype, bytes, interval) in cases {
34921 layout.index = captured.len() as u64;
34922 assert_eq!(tensor_layout_bytes(&layout).unwrap(), bytes.len());
34923 let owner = Arc::new(allocate_publication::<u8>(&provider, bytes.len()).unwrap());
34924 if !bytes.is_empty() {
34925 upload_publication(&provider, &bytes, &owner).unwrap();
34926 }
34927 let device = provider.device().ordinal() as i32;
34928 let rejected = content_test_export(Arc::clone(&owner), device, dtype, layout, interval);
34929 let mut invalid_parent = publication_test_parent(&provider);
34930 invalid_parent.tensors.push(rejected);
34931 let mut admission = publication_test_session(Arc::clone(&provider), &domain);
34932 assert!(matches!(admission.bind_parent(invalid_parent),
34933 Err(SemanticTransitionError::InvalidInput { detail })
34934 if detail == "initial parent tensor role is duplicate, uncomputed-active, or outside its model roster"));
34935 drop(admission);
34936 captured.push(content_test_export(
34937 Arc::clone(&owner),
34938 device,
34939 dtype,
34940 layout,
34941 interval,
34942 ));
34943 verified.push(content_test_export(
34944 Arc::clone(&owner),
34945 device,
34946 dtype,
34947 layout,
34948 interval,
34949 ));
34950 owners.push(owner);
34951 }
34952 let before = session.host_io_stats();
34953 session
34954 .guard_published_content(
34955 &lease,
34956 &[
34957 (SemanticStateRole::PrefixSource, 0),
34958 (SemanticStateRole::SlowWeights, 0),
34959 ],
34960 1,
34961 )
34962 .unwrap();
34963 let witness = session.capture_tensor_content(&lease, captured, 1).unwrap();
34964 session
34965 .verify_tensor_content(&lease, &witness, verified, 1)
34966 .unwrap();
34967 assert_eq!(
34968 session.host_io_stats(),
34969 before,
34970 "content guards must add no host transfers, metadata readback or session stream waits"
34971 );
34972 assert_eq!(
34975 unsafe { sys::cuStreamSynchronize(std::ptr::null_mut()) },
34976 sys::cudaError_enum::CUDA_SUCCESS
34977 );
34978 assert!(
34979 session.release(&mut lease, &[1]).is_err(),
34980 "a live witness retains its reader"
34981 );
34982 assert!(session.quiesce_published_reader(&lease, &[1]).is_err());
34983 drop(witness);
34984 assert!(
34985 session.release(&mut lease, &[1]).is_err(),
34986 "an external alias still retains its reader"
34987 );
34988 assert!(session.quiesce_published_reader(&lease, &[1]).is_err());
34989 drop(outside_alias);
34990 let identity = session.published_identity(&lease).unwrap();
34991 let publication = Arc::clone(session.publication.as_ref().unwrap());
34992 let readers = session
34993 .publication_read(publication.control.view())
34994 .unwrap()[0]
34995 .reader_counts;
34996 session.quiesce_published_reader(&lease, &[1]).unwrap();
34997 assert!(
34998 session.release_events.is_empty(),
34999 "quiescence must retire completed consumer events"
35000 );
35001 assert_eq!(session.published_identity(&lease).unwrap(), identity);
35002 assert!(lease.active);
35003 assert_eq!(
35004 session
35005 .publication_read(publication.control.view())
35006 .unwrap()[0]
35007 .reader_counts,
35008 readers,
35009 "quiescence must retain the actual acquired native reader"
35010 );
35011 session.release(&mut lease, &[1]).unwrap();
35012 drop(session);
35013 drop(owners);
35014 provider.memory().reap_pending_deallocations().unwrap();
35015 }
35016
35017 #[test]
35018 #[ignore = "requires an explicitly authorized remote CUDA run; each fatal case uses a fresh process"]
35019 fn mutated_content_stops_the_dependent_cuda_consumer() {
35020 const CHILD_KIND: &str = "XLOG_CONTENT_GUARD_TEST_CHILD";
35021 const COMPLETED: &str = "content mutation produced a fatal CUDA completion error";
35022 let Some(kind) = std::env::var_os(CHILD_KIND) else {
35023 let qualified = concat!(
35024 module_path!(),
35025 "::mutated_content_stops_the_dependent_cuda_consumer"
35026 );
35027 let test_name = qualified.split_once("::").unwrap().1;
35028 for kind in ["publication", "witness"] {
35029 let output = std::process::Command::new(std::env::current_exe().unwrap())
35030 .args([
35031 "--exact",
35032 test_name,
35033 "--ignored",
35034 "--nocapture",
35035 "--test-threads=1",
35036 ])
35037 .env(CHILD_KIND, kind)
35038 .output()
35039 .unwrap();
35040 assert!(
35041 output.status.success(),
35042 "{kind} child did not verify a CUDA trap:\n{}\n{}",
35043 String::from_utf8_lossy(&output.stdout),
35044 String::from_utf8_lossy(&output.stderr)
35045 );
35046 assert!(
35047 String::from_utf8_lossy(&output.stdout).contains(COMPLETED),
35048 "{kind} child did not reach the typed CUDA completion check"
35049 );
35050 }
35051 return;
35052 };
35053 assert!(kind == "publication" || kind == "witness");
35054 let (provider, domain) = publication_test_provider();
35055 let mut session = publication_test_session(Arc::clone(&provider), &domain);
35056 session
35057 .bind_parent(publication_test_parent(&provider))
35058 .unwrap();
35059 let lease = session.acquire().unwrap();
35060 let alias = session
35061 .published_tensor(&lease, SemanticStateRole::SlowWeights, 0, 1)
35062 .unwrap();
35063 let captured =
35064 publication_test_alias(&mut session, &lease, SemanticStateRole::SlowWeights, 1);
35065 let unchanged =
35066 publication_test_alias(&mut session, &lease, SemanticStateRole::SlowWeights, 1);
35067 let changed =
35068 publication_test_alias(&mut session, &lease, SemanticStateRole::SlowWeights, 1);
35069 let dependent = allocate_publication::<u8>(&provider, 4).unwrap();
35070 session
35071 .guard_published_content(&lease, &[(SemanticStateRole::SlowWeights, 0)], 1)
35072 .unwrap();
35073 let witness = session
35074 .capture_tensor_content(&lease, vec![captured], 1)
35075 .unwrap();
35076 session
35077 .verify_tensor_content(&lease, &witness, vec![unchanged], 1)
35078 .unwrap();
35079 assert_eq!(
35082 unsafe { sys::cuStreamSynchronize(std::ptr::null_mut()) },
35083 sys::cudaError_enum::CUDA_SUCCESS
35084 );
35085 let tensor = unsafe { &(*alias.as_ptr()).dl_tensor };
35088 assert_eq!(tensor.byte_offset, 0);
35089 let pointer = tensor.data as usize as u64;
35090 assert_eq!(
35093 unsafe { sys::cuMemsetD8Async(pointer, 0, 4, std::ptr::null_mut()) },
35094 sys::cudaError_enum::CUDA_SUCCESS
35095 );
35096 let guarded = if kind == "publication" {
35097 session.guard_published_content(&lease, &[(SemanticStateRole::SlowWeights, 0)], 1)
35098 } else {
35099 session.verify_tensor_content(&lease, &witness, vec![changed], 1)
35100 };
35101 if let Err(error) = guarded {
35104 eprintln!("content guard handoff: {error}");
35105 }
35106 let copied = unsafe {
35109 sys::cuMemcpyDtoDAsync_v2(
35110 dependent.device_ptr_value(),
35111 pointer,
35112 4,
35113 std::ptr::null_mut(),
35114 )
35115 };
35116 assert!(matches!(
35117 copied,
35118 sys::cudaError_enum::CUDA_SUCCESS
35119 | sys::cudaError_enum::CUDA_ERROR_ILLEGAL_INSTRUCTION
35120 | sys::cudaError_enum::CUDA_ERROR_LAUNCH_FAILED
35121 ));
35122 let completion = unsafe { sys::cuStreamSynchronize(std::ptr::null_mut()) };
35125 assert!(
35126 matches!(
35127 completion,
35128 sys::cudaError_enum::CUDA_ERROR_ILLEGAL_INSTRUCTION
35129 | sys::cudaError_enum::CUDA_ERROR_LAUNCH_FAILED
35130 ),
35131 "unexpected CUDA completion: {completion:?}"
35132 );
35133 println!("{COMPLETED}");
35134 std::io::Write::flush(&mut std::io::stdout()).unwrap();
35135 std::process::exit(0);
35138 }
35139
35140 #[test]
35141 #[ignore = "requires an explicitly authorized remote CUDA run; aborted live owners use a fresh process"]
35142 fn aborted_session_retains_step_after_reader_retirement() {
35143 const CHILD: &str = "XLOG_ABORT_RETAINED_STEP_TEST_CHILD";
35144 const COMPLETED: &str =
35145 "aborted retained step kept its original owners without a bank reader";
35146 if std::env::var_os(CHILD).is_none() {
35147 let qualified = concat!(
35148 module_path!(),
35149 "::aborted_session_retains_step_after_reader_retirement"
35150 );
35151 let test_name = qualified.split_once("::").unwrap().1;
35152 let output = std::process::Command::new(std::env::current_exe().unwrap())
35153 .args([
35154 "--exact",
35155 test_name,
35156 "--ignored",
35157 "--nocapture",
35158 "--test-threads=1",
35159 ])
35160 .env(CHILD, "1")
35161 .output()
35162 .unwrap();
35163 assert!(
35164 output.status.success(),
35165 "retained-step abort child failed:\n{}\n{}",
35166 String::from_utf8_lossy(&output.stdout),
35167 String::from_utf8_lossy(&output.stderr)
35168 );
35169 assert!(String::from_utf8_lossy(&output.stdout).contains(COMPLETED));
35170 return;
35171 }
35172 let (provider, domain) = publication_test_provider();
35173 let mut session = publication_test_session(Arc::clone(&provider), &domain);
35174 session
35175 .bind_parent(publication_test_parent(&provider))
35176 .unwrap();
35177 let mut lease = session.acquire().unwrap();
35178 let layout = session.publication.as_ref().unwrap().layouts[&(18, 0)];
35179 let live = Arc::new(allocate_publication::<u8>(&provider, 4).unwrap());
35180 upload_publication(&provider, &18.0f32.to_le_bytes(), &live).unwrap();
35181 let producer = || {
35182 content_test_export(
35183 Arc::clone(&live),
35184 provider.device().ordinal() as i32,
35185 crate::dlpack::DLDataType {
35186 code: 2,
35187 bits: 32,
35188 lanes: 1,
35189 },
35190 layout,
35191 (0, 0),
35192 )
35193 };
35194 let witness = session
35195 .bind_model_content(&lease, vec![producer()], 1)
35196 .unwrap();
35197 session.release_published_reader(&mut lease, &[1]).unwrap();
35198 assert!(session.readers.is_empty());
35199 let before = session.host_io_stats();
35200 session.abort();
35201 assert!(matches!(
35202 session.retained_step_identity(&lease),
35203 Err(SemanticTransitionError::Poisoned)
35204 ));
35205 assert!(matches!(
35206 session.verify_tensor_content(&lease, &witness, vec![producer()], 1),
35207 Err(SemanticTransitionError::Poisoned)
35208 ));
35209 assert!(matches!(
35210 session.release(&mut lease, &[1]),
35211 Err(SemanticTransitionError::Poisoned)
35212 ));
35213 assert_eq!(session.host_io_stats(), before);
35214 let prior = UNRELEASED_PUBLICATIONS.with(|owners| owners.borrow().len());
35215 drop(session);
35216 UNRELEASED_PUBLICATIONS.with(|owners| {
35217 let owners = owners.borrow();
35218 assert_eq!(owners.len(), prior + 1);
35219 let retained = owners.last().unwrap();
35220 assert!(retained._readers.is_empty());
35221 let step = &retained._steps[&lease.token];
35222 assert_eq!(step.identity, Some(lease.identity));
35223 assert!(matches!(
35224 step.content[witness.index].seals,
35225 TensorContentSeals::Model(_)
35226 ));
35227 assert_eq!(
35228 step.content[witness.index].tensors[0].data,
35229 live.device_ptr_value()
35230 );
35231 });
35232 println!("{COMPLETED}");
35233 std::io::Write::flush(&mut std::io::stdout()).unwrap();
35234 std::process::exit(0);
35235 }
35236
35237 #[test]
35238 #[ignore = "requires an explicitly authorized remote CUDA run; aborted live owners use a fresh process"]
35239 fn aborted_session_refuses_existing_publication_and_witness_owners() {
35240 const CHILD: &str = "XLOG_ABORT_SESSION_TEST_CHILD";
35241 const COMPLETED: &str = "aborted session rejected retained publication and witness reuse";
35242 if std::env::var_os(CHILD).is_none() {
35243 let qualified = concat!(
35244 module_path!(),
35245 "::aborted_session_refuses_existing_publication_and_witness_owners"
35246 );
35247 let test_name = qualified.split_once("::").unwrap().1;
35248 let output = std::process::Command::new(std::env::current_exe().unwrap())
35249 .args([
35250 "--exact",
35251 test_name,
35252 "--ignored",
35253 "--nocapture",
35254 "--test-threads=1",
35255 ])
35256 .env(CHILD, "1")
35257 .output()
35258 .unwrap();
35259 assert!(
35260 output.status.success(),
35261 "abort child did not verify unusable retained owners:\n{}\n{}",
35262 String::from_utf8_lossy(&output.stdout),
35263 String::from_utf8_lossy(&output.stderr)
35264 );
35265 assert!(
35266 String::from_utf8_lossy(&output.stdout).contains(COMPLETED),
35267 "abort child did not finish the native Poisoned checks"
35268 );
35269 return;
35270 }
35271 let (provider, domain) = publication_test_provider();
35272 let mut session = publication_test_session(Arc::clone(&provider), &domain);
35273 session
35274 .bind_parent(publication_test_parent(&provider))
35275 .unwrap();
35276 let lease = session.acquire().unwrap();
35277 let _outside_alias = session
35278 .published_tensor(&lease, SemanticStateRole::SlowWeights, 0, 1)
35279 .unwrap();
35280 let captured =
35281 publication_test_alias(&mut session, &lease, SemanticStateRole::SlowWeights, 1);
35282 let unchanged =
35283 publication_test_alias(&mut session, &lease, SemanticStateRole::SlowWeights, 1);
35284 let refused_capture =
35285 publication_test_alias(&mut session, &lease, SemanticStateRole::SlowWeights, 1);
35286 let refused_verify =
35287 publication_test_alias(&mut session, &lease, SemanticStateRole::SlowWeights, 1);
35288 let witness = session
35289 .capture_tensor_content(&lease, vec![captured], 1)
35290 .unwrap();
35291 session
35292 .verify_tensor_content(&lease, &witness, vec![unchanged], 1)
35293 .unwrap();
35294 let identity = session.published_identity(&lease).unwrap();
35295 assert!(!session.published_range_keys(&lease).unwrap().is_empty());
35296 assert_eq!(
35299 unsafe { sys::cuStreamSynchronize(std::ptr::null_mut()) },
35300 sys::cudaError_enum::CUDA_SUCCESS
35301 );
35302 let before = session.host_io_stats();
35303 session.abort();
35304 session.abort();
35305 assert!(session.is_poisoned());
35306 assert_eq!(
35307 session.host_io_stats(),
35308 before,
35309 "abort must not synchronize or transfer retained content"
35310 );
35311 assert!(
35312 session.publication.is_some(),
35313 "abort must retain live publication storage"
35314 );
35315 assert!(
35316 session.readers.contains_key(&lease.token),
35317 "abort must retain existing reader owners"
35318 );
35319 assert_eq!(
35320 lease.identity, identity,
35321 "an aborted Session retains its lease's historical identity"
35322 );
35323 assert!(matches!(
35324 session.acquire(),
35325 Err(SemanticTransitionError::Poisoned)
35326 ));
35327 assert!(matches!(
35328 session.published_identity(&lease),
35329 Err(SemanticTransitionError::Poisoned)
35330 ));
35331 assert!(matches!(
35332 session.published_range_keys(&lease),
35333 Err(SemanticTransitionError::Poisoned)
35334 ));
35335 assert!(matches!(
35336 session.published_tensor(&lease, SemanticStateRole::SlowWeights, 0, 1),
35337 Err(SemanticTransitionError::Poisoned)
35338 ));
35339 assert!(matches!(
35340 session.published_prefix(&lease, 1),
35341 Err(SemanticTransitionError::Poisoned)
35342 ));
35343 assert!(matches!(
35344 session.guard_published_content(&lease, &[(SemanticStateRole::SlowWeights, 0)], 1),
35345 Err(SemanticTransitionError::Poisoned)
35346 ));
35347 assert!(matches!(
35348 session.capture_tensor_content(&lease, vec![refused_capture], 1),
35349 Err(SemanticTransitionError::Poisoned)
35350 ));
35351 assert!(matches!(
35352 session.verify_tensor_content(&lease, &witness, vec![refused_verify], 1),
35353 Err(SemanticTransitionError::Poisoned)
35354 ));
35355 assert!(matches!(
35356 session.capture(),
35357 Err(SemanticTransitionError::Poisoned)
35358 ));
35359 assert!(matches!(
35360 session.launch(),
35361 Err(SemanticTransitionError::Poisoned)
35362 ));
35363 assert!(matches!(
35364 session.bind_task_evaluation(task_binding_tests::task_spec([0, 1, 1], vec![])),
35365 Err(SemanticTransitionError::Poisoned)
35366 ));
35367 assert!(session.is_poisoned());
35368 println!("{COMPLETED}");
35369 std::io::Write::flush(&mut std::io::stdout()).unwrap();
35370 std::process::exit(0);
35373 }
35374
35375 fn publication_material_sample() -> PublicationMaterial {
35378 let mut counts = [1u64; 55];
35379 counts[15] = 3;
35380 let layouts: BTreeMap<_, _> = (1..=55)
35381 .filter(|&role| is_tensor_role(role))
35382 .map(|role| {
35383 (
35384 (role, 0),
35385 SemanticTensorLayout {
35386 role,
35387 index: 0,
35388 scalar_type: 6,
35389 element_bytes: 4,
35390 rank: 2,
35391 logical_axis: u64::MAX,
35392 dimensions: [1, 1, 0, 0],
35393 strides_bytes: [4, 4, 0, 0],
35394 },
35395 )
35396 })
35397 .collect();
35398 let mut ranges = Vec::new();
35399 for (ordinal, &count) in counts.iter().enumerate() {
35400 for index in 0..count {
35401 let role = ordinal as u64 + 1;
35402 let bytes = if role == 55 {
35403 tensor_table_bytes(&layouts.values().copied().collect::<Vec<_>>(), false, &[])
35404 .unwrap()
35405 } else if role == 44 {
35406 let mut bytes = vec![0; 104];
35407 bytes.extend_from_slice(&[44, index as u8, 0x80, 0xff]);
35408 bytes
35409 } else if role == 32 {
35410 publication_abi_bytes(&[AcknowledgementQueueHeader {
35411 abi: 1,
35412 payload_capacity_bytes: 128,
35413 ..AcknowledgementQueueHeader::default()
35414 }])
35415 } else {
35416 vec![role as u8, index as u8, 0x80, 0xff]
35417 };
35418 ranges.push(PublicationMaterialRange {
35419 range: PublicationRange {
35420 role,
35421 index,
35422 generation: 1,
35423 length_bytes: bytes.len() as u64,
35424 storage_slot: ranges.len() as u64,
35425 ..PublicationRange::default()
35426 },
35427 capacity: bytes.len() + 128,
35428 bytes,
35429 });
35430 }
35431 }
35432 let header = PublicationHeader {
35433 abi: 1,
35434 model_generation: 7,
35435 authority_generation: 3,
35436 sealed_epoch: 8,
35437 publication_word: 16,
35438 range_count: ranges.len() as u64,
35439 state_digest: Identity256::from_bytes([29; 32]),
35440 ..PublicationHeader::default()
35441 };
35442 let mut model_memory = ModelMemoryGeometry::default();
35443 let mut model_allocations = Vec::new();
35444 for range in ranges
35445 .iter_mut()
35446 .filter(|range| matches!(range.range.role, 18..=25))
35447 {
35448 let ordinal = model_allocations.len() as u64;
35449 let mut bytes = vec![0; range.capacity];
35450 bytes[..range.bytes.len()].copy_from_slice(&range.bytes);
35451 range.range.backing_digest = Identity256::from_bytes(Sha256::digest(&bytes).into());
35452 model_memory.allocation_bytes.push(bytes.len() as u64);
35453 model_memory.storages.push(SemanticModelStorage {
35454 allocation: ordinal,
35455 byte_offset: 0,
35456 span_bytes: bytes.len() as u64,
35457 });
35458 model_memory.views.push(SemanticModelView {
35459 role: range.range.role,
35460 index: range.range.index,
35461 storage: ordinal,
35462 byte_offset: 0,
35463 });
35464 model_allocations.push(bytes);
35465 }
35466 let mut material = PublicationMaterial {
35467 bank: PublicationBank {
35468 header,
35469 source: [SemanticTextSlot::default(); 32],
35470 state: DeviceState::default(),
35471 receipts: [SemanticTransitionReceipt::default(); COMPONENT_COUNT],
35472 },
35473 contract: PublicationContract {
35474 abi: 1,
35475 model_generation: 7,
35476 authority_generation: 3,
35477 window_capacity: 32,
35478 role_count: 55,
35479 range_capacity: ranges.len() as u64,
35480 terminal_token_count: 1,
35481 model_contract_layout: SemanticModelContractLayout {
35482 schema_begin: 104,
35483 schema_bytes: 4,
35484 schema_digest_offset: 0,
35485 generation_offset: 32,
35486 numerical_digest_offset: 40,
35487 identity_offset: 72,
35488 },
35489 ..PublicationContract::default()
35490 },
35491 role_counts: counts,
35492 terminals: vec![3],
35493 layouts,
35494 model_memory,
35495 model_allocations,
35496 ranges,
35497 graph: SemanticRootMaterial {
35498 records: SemanticAdmissionRecords {
35499 predicates: vec![],
35500 records: vec![],
35501 supports: vec![],
35502 },
35503 symbols: vec![],
35504 insertions: vec![],
35505 digest: [0; 32],
35506 extents: [0; 3],
35507 admission_base_digest: [0; 32],
35508 admission_base_extents: [0; 3],
35509 },
35510 learning_phases: Vec::new(),
35511 };
35512 publication_material_sample_runtime(&mut material);
35513 for range in &mut material.ranges {
35514 if !is_tensor_role(range.range.role) {
35515 range.range.digest = range.original_record_digest();
35516 }
35517 }
35518 material.bank.header.descriptor_digest = material.original_descriptor_digest();
35519 material
35520 }
35521
35522 fn publication_material_sample_runtime(material: &mut PublicationMaterial) {
35525 material.bank.header.model_geometry_digest =
35526 material.model_memory.digest(&material.layouts).unwrap();
35527 let runtime = initial_runtime_contract_record(
35528 material.contract,
35529 &material.role_counts,
35530 &material.terminals,
35531 &material.layouts,
35532 material
35533 .ranges
35534 .iter()
35535 .filter(|item| item.range.role != 43)
35536 .map(|item| (item.range.role, item.range.index, item.capacity))
35537 .collect(),
35538 b"codec sample numerical mode",
35539 &material.model_memory,
35540 )
35541 .unwrap();
35542 let record = material
35543 .ranges
35544 .iter_mut()
35545 .find(|item| item.range.role == 43)
35546 .unwrap();
35547 record.capacity = runtime.capacity_bytes;
35548 record.bytes = runtime.bytes;
35549 record.range.length_bytes = record.bytes.len() as u64;
35550 record.range.digest = record.original_record_digest();
35551 }
35552
35553 #[test]
35554 fn publication_material_codec_preserves_all_ranges_and_rejects_incomplete_content() {
35555 let material = publication_material_sample();
35556 let bytes = material.encode().unwrap();
35557 let decoded = PublicationMaterial::decode(&bytes).unwrap();
35558 assert_eq!(decoded.encode().unwrap(), bytes);
35559 assert_eq!(decoded.ranges.len(), material.ranges.len());
35560 for (saved, actual) in material.ranges.iter().zip(&decoded.ranges) {
35561 assert_eq!(saved.bytes, actual.bytes);
35562 assert_eq!(saved.capacity, actual.capacity);
35563 }
35564 for boundary in [
35565 0,
35566 25,
35567 26,
35568 29,
35569 30,
35570 61,
35571 62,
35572 100,
35573 bytes.len() / 2,
35574 bytes.len() - 1,
35575 ] {
35576 assert!(PublicationMaterial::decode(&bytes[..boundary]).is_err());
35577 }
35578 let mut changed = bytes.clone();
35579 changed.push(0);
35580 assert!(PublicationMaterial::decode(&changed).is_err());
35581 changed = bytes.clone();
35582 changed[30] ^= 1;
35583 assert!(PublicationMaterial::decode(&changed).is_err());
35584 let mut incomplete = publication_material_sample();
35585 incomplete.ranges.pop();
35586 assert!(incomplete.encode().is_err());
35587 let mut reordered = publication_material_sample();
35588 reordered.ranges.swap(0, 1);
35589 assert!(reordered.encode().is_err());
35590 let mut address = publication_material_sample();
35591 address.contract.terminal_tokens = 0x1000;
35592 assert!(address.encode().is_err());
35593 let mut mismatched = publication_material_sample();
35594 mismatched.layouts.get_mut(&(4, 0)).unwrap().scalar_type = 2;
35595 assert!(mismatched.encode().is_err());
35596 }
35597
35598 #[test]
35599 fn publication_material_runtime_preserves_mode_and_exact_self_capacity() {
35600 let material = publication_material_sample();
35601 let bytes = material.encode().unwrap();
35602 let restored = PublicationMaterial::decode(&bytes).unwrap();
35603 assert_eq!(
35604 restored.model_numerical_mode().unwrap(),
35605 b"codec sample numerical mode"
35606 );
35607 let record = restored
35608 .ranges
35609 .iter()
35610 .find(|item| item.range.role == 43)
35611 .unwrap();
35612 assert_eq!(record.capacity, record.bytes.len());
35613 assert_eq!(restored.encode().unwrap(), bytes);
35614 let capacities = material
35615 .ranges
35616 .iter()
35617 .map(|item| (item.range.role, item.range.index, item.capacity))
35618 .collect::<Vec<_>>();
35619 let mut relocated = material.contract;
35620 relocated.terminal_tokens = 0x1020304050607080;
35621 relocated.role_counts = 0x8070605040302010;
35622 relocated.semantic_owner = 99;
35623 let original = runtime_contract_bytes(
35624 relocated,
35625 &material.role_counts,
35626 &material.terminals,
35627 &material.layouts,
35628 &capacities,
35629 material.model_numerical_mode().unwrap(),
35630 &material.model_memory,
35631 )
35632 .unwrap();
35633 assert_eq!(
35634 original, record.bytes,
35635 "runtime addresses and owner handles are not portable identity"
35636 );
35637 assert_ne!(
35638 runtime_contract_bytes(
35639 relocated,
35640 &material.role_counts,
35641 &material.terminals,
35642 &material.layouts,
35643 &capacities,
35644 b"different complete mode",
35645 &material.model_memory
35646 )
35647 .unwrap(),
35648 original
35649 );
35650 assert!(runtime_contract_bytes(
35651 relocated,
35652 &material.role_counts,
35653 &material.terminals,
35654 &material.layouts,
35655 &capacities,
35656 b"",
35657 &material.model_memory
35658 )
35659 .is_err());
35660 assert!(
35661 initial_runtime_contract_record(
35662 relocated,
35663 &material.role_counts,
35664 &material.terminals,
35665 &material.layouts,
35666 capacities,
35667 b"mode",
35668 &material.model_memory
35669 )
35670 .is_err(),
35671 "caller runtime entry cannot be inserted twice"
35672 );
35673 }
35674
35675 #[test]
35676 fn publication_material_runtime_binds_logical_contract_and_terminals() {
35677 let mut changed = publication_material_sample();
35678 changed.contract.max_position += 1;
35679 assert!(
35680 changed.encode().is_err(),
35681 "runtime record must bind the actual position contract"
35682 );
35683 let mut changed = publication_material_sample();
35684 changed.terminals[0] += 1;
35685 assert!(
35686 changed.encode().is_err(),
35687 "runtime record must retain actual terminal values"
35688 );
35689 }
35690
35691 #[test]
35692 fn publication_material_runtime_binds_allocation_capacity() {
35693 let mut changed = publication_material_sample();
35694 changed
35695 .ranges
35696 .iter_mut()
35697 .find(|range| range.range.role == 2)
35698 .unwrap()
35699 .capacity += 1;
35700 assert!(
35701 changed.encode().is_err(),
35702 "runtime record must bind actual cold capacity"
35703 );
35704 }
35705
35706 #[test]
35707 fn publication_material_runtime_rejects_changed_original_layout_table() {
35708 let material = publication_material_sample();
35709 assert_eq!(
35710 material.model_numerical_mode().unwrap(),
35711 b"codec sample numerical mode"
35712 );
35713 let table_index = material
35714 .ranges
35715 .iter()
35716 .position(|item| item.range.role == 55)
35717 .unwrap();
35718 for byte in 0..material.ranges[table_index].bytes.len() {
35719 let mut changed = publication_material_sample();
35720 changed.ranges[table_index].bytes[byte] ^= 1;
35721 assert!(
35722 changed.model_numerical_mode().is_err(),
35723 "changed table byte {byte}"
35724 );
35725 }
35726 }
35727
35728 #[test]
35729 fn publication_material_runtime_rejects_resealed_layout_disagreement() {
35730 let mut changed = publication_material_sample();
35731 let table = changed
35732 .ranges
35733 .iter_mut()
35734 .find(|item| item.range.role == 55)
35735 .unwrap();
35736 let (_, mut layouts, active) = decode_tensor_table(&table.bytes).unwrap();
35737 layouts[0].scalar_type = 2;
35738 table.bytes = tensor_table_bytes(&layouts, active.computed, &active.rows).unwrap();
35739 table.range.digest = table.original_record_digest();
35740 assert!(changed.model_numerical_mode().is_err());
35741 }
35742
35743 #[test]
35744 fn publication_material_runtime_allows_sealed_active_table_changes() {
35745 let mut changed = publication_material_sample();
35746 let mode = changed.model_numerical_mode().unwrap().to_vec();
35747 let table = changed
35748 .ranges
35749 .iter_mut()
35750 .find(|item| item.range.role == 55)
35751 .unwrap();
35752 let (_, layouts, _) = decode_tensor_table(&table.bytes).unwrap();
35753 table.bytes = tensor_table_bytes(&layouts, true, &[]).unwrap();
35754 table.range.digest = table.original_record_digest();
35755 assert_eq!(changed.model_numerical_mode().unwrap(), mode);
35756 }
35757
35758 #[test]
35759 fn publication_material_runtime_refuses_opaque_replacement_even_if_resealed() {
35760 let mut changed = publication_material_sample();
35761 let runtime = changed
35762 .ranges
35763 .iter_mut()
35764 .find(|range| range.range.role == 43)
35765 .unwrap();
35766 runtime.bytes.fill(0);
35767 runtime.range.digest = runtime.original_record_digest();
35768 changed.bank.header.descriptor_digest = changed.original_descriptor_digest();
35769 assert!(
35770 changed.encode().is_err(),
35771 "opaque caller bytes are not the native runtime contract"
35772 );
35773 }
35774
35775 #[test]
35776 fn capacity_prefix_export_preserves_extent_without_narrowing_shape() {
35777 let mut range = PublicationRange {
35778 role: 1,
35779 index: 0,
35780 generation: 1,
35781 length_bytes: 128,
35782 logical_begin: 0,
35783 logical_end: 2,
35784 ..PublicationRange::default()
35785 };
35786 let layout = committed_prefix_layout(&range, 8).unwrap();
35787 assert_eq!(layout.dimensions, [8, 8, 0, 0]);
35788 assert_eq!(tensor_layout_bytes(&layout).unwrap(), 512);
35789 assert_eq!(
35790 (range.logical_begin, range.logical_end, range.length_bytes),
35791 (0, 2, 128)
35792 );
35793 range.logical_end = 0;
35794 range.length_bytes = 0;
35795 assert_eq!(
35796 committed_prefix_layout(&range, 8).unwrap().dimensions,
35797 [8, 8, 0, 0]
35798 );
35799 assert!(committed_prefix_layout(
35800 &PublicationRange {
35801 logical_end: 9,
35802 length_bytes: 576,
35803 ..range
35804 },
35805 8
35806 )
35807 .is_err());
35808 }
35809
35810 #[test]
35811 fn capacity_export_stream_rejects_ambiguous_default_handles() {
35812 assert!(dlpack_consumer_stream(0).is_err());
35813 assert!(dlpack_consumer_stream(2).is_err());
35814 assert!(dlpack_consumer_stream(1).unwrap().is_null());
35815 assert_eq!(dlpack_consumer_stream(4096).unwrap() as usize, 4096);
35818 }
35819
35820 #[test]
35821 fn capacity_export_bounds_keep_seal_and_allocation_limits_distinct() {
35822 let range = PublicationRange {
35823 role: 1,
35824 index: 0,
35825 generation: 1,
35826 offset_bytes: 64,
35827 length_bytes: 128,
35828 logical_begin: 0,
35829 logical_end: 2,
35830 ..PublicationRange::default()
35831 };
35832 let layout = SemanticTensorLayout {
35833 role: 1,
35834 index: 0,
35835 scalar_type: 3,
35836 element_bytes: 8,
35837 rank: 2,
35838 logical_axis: 0,
35839 dimensions: [8, 8, 0, 0],
35840 strides_bytes: [64, 8, 0, 0],
35841 };
35842 assert_eq!(
35843 publication_export_span(&range, &layout, 576).unwrap(),
35844 64..576
35845 );
35846 assert!(publication_export_span(&range, &layout, 575).is_err());
35847 assert_eq!(
35848 (range.length_bytes, range.logical_begin, range.logical_end),
35849 (128, 0, 2)
35850 );
35851 for wrong in [
35852 PublicationRange {
35853 generation: 2,
35854 ..range
35855 },
35856 PublicationRange {
35857 offset_bytes: 65,
35858 ..range
35859 },
35860 PublicationRange {
35861 offset_bytes: u64::MAX - 7,
35862 ..range
35863 },
35864 PublicationRange {
35865 length_bytes: 513,
35866 ..range
35867 },
35868 PublicationRange {
35869 logical_end: 9,
35870 ..range
35871 },
35872 PublicationRange { index: 1, ..range },
35873 ] {
35874 assert!(publication_export_span(&wrong, &layout, 576).is_err());
35875 }
35876 let tensor = SemanticTensorLayout {
35877 role: 4,
35878 rank: 4,
35879 logical_axis: 2,
35880 dimensions: [1, 2, 8, 2],
35881 strides_bytes: [128, 64, 8, 4],
35882 scalar_type: 6,
35883 element_bytes: 4,
35884 ..layout
35885 };
35886 let tensor_range = PublicationRange {
35887 role: 4,
35888 offset_bytes: 0,
35889 length_bytes: 128,
35890 ..range
35891 };
35892 assert_eq!(
35893 publication_export_span(&tensor_range, &tensor, 128).unwrap(),
35894 0..128
35895 );
35896 let model = SemanticTensorLayout {
35897 role: 18,
35898 logical_axis: u64::MAX,
35899 ..tensor
35900 };
35901 assert_eq!(
35902 publication_export_span(
35903 &PublicationRange {
35904 role: 18,
35905 logical_begin: 0,
35906 logical_end: 0,
35907 ..tensor_range
35908 },
35909 &model,
35910 128
35911 )
35912 .unwrap(),
35913 0..128
35914 );
35915 assert!(publication_export_span(
35916 &PublicationRange {
35917 role: 18,
35918 length_bytes: 16,
35919 logical_begin: 0,
35920 logical_end: 0,
35921 ..tensor_range
35922 },
35923 &model,
35924 128
35925 )
35926 .is_err());
35927 }
35928
35929 #[test]
35930 fn committed_prefix_export_layout_preserves_native_rows_and_empty_extent() {
35931 let range = PublicationRange {
35932 role: SemanticStateRole::PrefixSource as u64,
35933 index: 0,
35934 generation: 1,
35935 offset_bytes: 64,
35936 length_bytes: 128,
35937 logical_begin: 0,
35938 logical_end: 2,
35939 ..PublicationRange::default()
35940 };
35941 let layout = committed_prefix_layout(&range, 2).unwrap();
35942 assert_eq!(
35943 (layout.scalar_type, layout.element_bytes, layout.rank),
35944 (3, 8, 2)
35945 );
35946 assert_eq!(layout.dimensions, [2, 8, 0, 0]);
35947 assert_eq!(layout.strides_bytes, [64, 8, 0, 0]);
35948 assert_eq!(tensor_layout_bytes(&layout).unwrap(), 128);
35949 let row = SemanticTextSlot {
35950 token: 71,
35951 logical_position: 1,
35952 kind: 1,
35953 provenance: 2,
35954 valid: 1,
35955 committed: 1,
35956 recomputed: 1,
35957 provenance_record: 19,
35958 };
35959 let words = publication_abi_bytes(&[row])
35960 .as_chunks::<8>()
35961 .0
35962 .iter()
35963 .map(|bytes| u64::from_ne_bytes(*bytes))
35964 .collect::<Vec<_>>();
35965 assert_eq!(words, [71, 1, 1, 2, 1, 1, 1, 19]);
35966 let empty = committed_prefix_layout(
35967 &PublicationRange {
35968 length_bytes: 0,
35969 logical_end: 0,
35970 ..range
35971 },
35972 0,
35973 )
35974 .unwrap();
35975 assert_eq!(empty.dimensions, [0, 8, 0, 0]);
35976 assert_eq!(empty.strides_bytes, [64, 8, 0, 0]);
35977 assert_eq!(tensor_layout_bytes(&empty).unwrap(), 0);
35978 }
35979
35980 #[test]
35981 fn committed_prefix_export_rejects_inconsistent_or_unaligned_extent() {
35982 let valid = PublicationRange {
35983 role: 1,
35984 index: 0,
35985 generation: 1,
35986 length_bytes: 128,
35987 logical_begin: 0,
35988 logical_end: 2,
35989 ..PublicationRange::default()
35990 };
35991 for wrong in [
35992 PublicationRange { role: 2, ..valid },
35993 PublicationRange { index: 1, ..valid },
35994 PublicationRange {
35995 offset_bytes: 1,
35996 ..valid
35997 },
35998 PublicationRange {
35999 logical_begin: 1,
36000 ..valid
36001 },
36002 PublicationRange {
36003 logical_end: 3,
36004 ..valid
36005 },
36006 PublicationRange {
36007 length_bytes: 64,
36008 ..valid
36009 },
36010 PublicationRange {
36011 length_bytes: 192,
36012 ..valid
36013 },
36014 ] {
36015 assert!(committed_prefix_layout(&wrong, 2).is_err());
36016 }
36017 assert!(committed_prefix_layout(&valid, u64::MAX).is_err());
36018 assert!(committed_prefix_layout(&valid, 0).is_err());
36019 }
36020
36021 #[test]
36022 fn publication_material_decode_checks_original_descriptor_before_relocation() {
36023 let material = publication_material_sample();
36024 let original = material.encode().unwrap();
36025 assert!(PublicationMaterial::decode(&original).is_ok());
36026
36027 for field in 0..4 {
36028 let mut changed = publication_material_sample();
36029 match field {
36030 0 => changed.bank.header.instance = Identity256::from_bytes([71; 32]),
36031 1 => changed.bank.header.recovered_instance = Identity256::from_bytes([72; 32]),
36032 2 => changed.bank.header.semantic_owner ^= 1,
36033 3 => changed.ranges[0].range.storage_slot ^= 1,
36034 _ => unreachable!(),
36035 }
36036 assert!(
36037 PublicationMaterial::decode(&changed.encode().unwrap()).is_err(),
36038 "cold decoding accepted changed original descriptor field {field}"
36039 );
36040 }
36041 }
36042
36043 #[test]
36044 fn publication_material_decode_checks_original_record_bytes() {
36045 for role in [2, 14, 15, 30, 33, 48] {
36048 let mut changed = publication_material_sample();
36049 let record = changed
36050 .ranges
36051 .iter_mut()
36052 .find(|item| item.range.role == role)
36053 .unwrap();
36054 record.bytes[0] ^= 1;
36055 assert!(
36056 PublicationMaterial::decode(&changed.encode().unwrap()).is_err(),
36057 "cold decoding accepted altered original record {role}"
36058 );
36059 }
36060 for word in [1, 5, 6, 39] {
36061 let mut changed = publication_material_sample();
36062 let record = changed
36063 .ranges
36064 .iter_mut()
36065 .find(|item| item.range.role == 33)
36066 .unwrap();
36067 record.bytes = publication_abi_bytes(&[AttemptReceipt::default()]);
36068 record.range.length_bytes = record.bytes.len() as u64;
36069 record.capacity = record.bytes.len();
36070 record.range.digest = record.original_record_digest();
36071 publication_material_sample_runtime(&mut changed);
36072 changed.bank.header.descriptor_digest = changed.original_descriptor_digest();
36073 assert!(PublicationMaterial::decode(&changed.encode().unwrap()).is_ok());
36074 changed
36075 .ranges
36076 .iter_mut()
36077 .find(|item| item.range.role == 33)
36078 .unwrap()
36079 .bytes[word * 8] ^= 1;
36080 assert!(
36081 PublicationMaterial::decode(&changed.encode().unwrap()).is_err(),
36082 "cold decoding accepted altered normalized-out attempt word {word}"
36083 );
36084 }
36085 }
36086
36087 #[test]
36088 fn checkpoint_projection_uses_validated_original_publication() {
36089 let material = publication_material_sample();
36090 let header = material.bank.header;
36091 let projection =
36092 SemanticTransitionSession::state_material_projection(&material.encode().unwrap())
36093 .unwrap();
36094 assert_eq!(projection.publication.instance, header.instance);
36095 assert_eq!(projection.publication.word, header.publication_word);
36096 assert_eq!(projection.publication.logical_digest, header.logical_digest);
36097 assert_eq!(projection.publication.state_digest, header.state_digest);
36098 assert_eq!(projection.semantic_root, header.semantic_digest);
36099 assert_eq!(projection.model_generation, header.model_generation);
36100 }
36101
36102 fn replay_material_sample() -> (PublicationMaterial, PublicationReplayEvidence) {
36105 let mut predecessor = publication_material_sample();
36106 predecessor.bank.header.instance = Identity256::from_bytes([11; 32]);
36107 predecessor.bank.header.logical_digest = Identity256::from_bytes([12; 32]);
36108 for (role, bytes) in [
36109 (
36110 30,
36111 publication_abi_bytes(&[IntentQueueHeader {
36112 abi: 1,
36113 ..IntentQueueHeader::default()
36114 }]),
36115 ),
36116 (33, publication_abi_bytes(&[AttemptReceipt::default()])),
36117 ] {
36118 let item = predecessor
36119 .ranges
36120 .iter_mut()
36121 .find(|item| item.range.role == role)
36122 .unwrap();
36123 item.range.length_bytes = bytes.len() as u64;
36124 item.capacity = bytes.len();
36125 item.bytes = bytes;
36126 }
36127 publication_material_sample_runtime(&mut predecessor);
36130 for item in &mut predecessor.ranges {
36131 if !is_tensor_role(item.range.role) {
36132 item.range.digest = item.original_record_digest();
36133 }
36134 }
36135 predecessor.bank.header.descriptor_digest = predecessor.original_descriptor_digest();
36136 let mut evidence = PublicationReplayEvidence {
36137 successor: SemanticPublishedIdentity {
36138 instance: predecessor.bank.header.instance,
36139 word: 19,
36140 logical_digest: Identity256::from_bytes([13; 32]),
36141 state_digest: Identity256::default(),
36142 },
36143 ranges: predecessor
36144 .ranges
36145 .iter()
36146 .filter(|item| REPLAY_EVIDENCE_ROLES.contains(&item.range.role))
36147 .cloned()
36148 .collect(),
36149 };
36150 let attempt = AttemptReceipt {
36151 abi: 2,
36152 transition_kind: 2,
36153 instance: evidence.successor.instance,
36154 base_word: predecessor.bank.header.publication_word,
36155 next_word: evidence.successor.word,
36156 logical_digest: evidence.successor.logical_digest,
36157 action_receipts_digest: Identity256::from_bytes(Sha256::digest([]).into()),
36158 semantic_receipts_digest: Identity256::from_bytes([14; 32]),
36159 coverage_digest: Identity256::from_bytes([15; 32]),
36160 replay_head_digest: evidence.range(27).unwrap().logical_record_digest().unwrap(),
36161 intent_head_digest: evidence.range(30).unwrap().logical_record_digest().unwrap(),
36162 acknowledgement_head_digest: evidence
36163 .range(32)
36164 .unwrap()
36165 .logical_record_digest()
36166 .unwrap(),
36167 previous_attempt_digest: predecessor
36168 .ranges
36169 .iter()
36170 .find(|item| item.range.role == 33)
36171 .unwrap()
36172 .logical_record_digest()
36173 .unwrap(),
36174 ..AttemptReceipt::default()
36175 };
36176 evidence.ranges.last_mut().unwrap().bytes = publication_abi_bytes(&[attempt]);
36177 seal_replay_sample(&mut evidence);
36178 (predecessor, evidence)
36179 }
36180
36181 fn seal_replay_sample(evidence: &mut PublicationReplayEvidence) {
36182 let item = evidence.ranges.last_mut().unwrap();
36183 let mut attempt = item.attempt().unwrap();
36184 attempt.receipt_digest = item.logical_record_digest().unwrap();
36185 item.bytes = publication_abi_bytes(&[attempt]);
36186 for item in &mut evidence.ranges {
36187 item.range.digest = item.original_record_digest();
36188 }
36189 evidence.successor.state_digest = evidence.state_digest().unwrap();
36190 }
36191
36192 #[test]
36193 fn selected_recompute_requires_the_current_sealed_native_attempt() {
36194 let (mut selected, mut evidence) = replay_material_sample();
36195 let current_coverage = CompletionCoverage {
36196 abi: 1,
36197 model_generation: selected.bank.header.model_generation,
36198 ..CompletionCoverage::default()
36199 };
36200 let coverage_range = selected
36201 .ranges
36202 .iter_mut()
36203 .find(|item| item.range.role == 14)
36204 .unwrap();
36205 coverage_range.bytes = publication_abi_bytes(&[current_coverage]);
36206 coverage_range.capacity = coverage_range.bytes.len();
36207 coverage_range.range.length_bytes = coverage_range.bytes.len() as u64;
36208 coverage_range.range.digest = coverage_range.original_record_digest();
36209 let coverage = coverage_range.logical_record_digest().unwrap();
36210 let attempt_range = evidence.ranges.last_mut().unwrap();
36211 let mut attempt = attempt_range.attempt().unwrap();
36212 attempt.coverage_digest = coverage;
36213 attempt_range.bytes = publication_abi_bytes(&[attempt]);
36214 seal_replay_sample(&mut evidence);
36215 let previous_word = selected.bank.header.publication_word;
36216 selected.bank.header.base_word = previous_word;
36217 selected.bank.header.publication_word = evidence.successor.word;
36218 selected.bank.header.logical_digest = evidence.successor.logical_digest;
36219 selected.bank.header.state_digest = evidence.successor.state_digest;
36220 selected.bank.header.terminal = 0;
36221 for replacement in &evidence.ranges {
36222 let original = selected
36223 .ranges
36224 .iter_mut()
36225 .find(|item| {
36226 (item.range.role, item.range.index)
36227 == (replacement.range.role, replacement.range.index)
36228 })
36229 .unwrap();
36230 *original = replacement.clone();
36231 }
36232 assert!(selected.require_successful_recompute().is_ok());
36233 let attempt_range = selected
36234 .ranges
36235 .iter_mut()
36236 .find(|item| item.range.role == 33)
36237 .unwrap();
36238 let original_attempt = attempt_range.bytes.clone();
36239 let mut update = attempt_range.attempt().unwrap();
36240 update.transition_kind = 4;
36241 attempt_range.bytes = publication_abi_bytes(&[update]);
36242 assert!(selected.require_successful_recompute().is_err());
36243 selected
36244 .ranges
36245 .iter_mut()
36246 .find(|item| item.range.role == 33)
36247 .unwrap()
36248 .bytes = original_attempt;
36249 selected.bank.header.publication_word += 2;
36250 assert!(selected.require_successful_recompute().is_err());
36251 }
36252
36253 #[test]
36254 fn semantic_replay_material_requires_complete_linked_evidence() {
36255 let (predecessor, evidence) = replay_material_sample();
36256 let bytes = predecessor.encode().unwrap();
36257 let parse = |evidence: &[u8]| {
36258 SemanticReplayMaterial::decode(
36259 &bytes,
36260 evidence,
36261 predecessor.bank.header.logical_digest,
36262 evidence_successor_logical(),
36263 )
36264 };
36265 let decoded = parse(&evidence.encode().unwrap()).unwrap();
36266 assert_eq!(
36267 decoded.predecessor_identity().instance,
36268 predecessor.bank.header.instance
36269 );
36270 assert_eq!(decoded.successor_identity(), evidence.successor);
36271 assert_eq!(decoded.transition_kind(), SemanticTransitionKind::Recompute);
36272 assert!(parse(&bytes).is_err());
36273 assert!(parse(&[]).is_err());
36274 let mut truncated = evidence.encode().unwrap();
36275 truncated.pop();
36276 assert!(parse(&truncated).is_err());
36277 let mut trailing = evidence.encode().unwrap();
36278 trailing.push(0);
36279 assert!(parse(&trailing).is_err());
36280 for change in 0..5 {
36281 let (_, mut changed) = replay_material_sample();
36282 match change {
36283 0 => changed.successor.instance = Identity256::from_bytes([90; 32]),
36284 1 => changed.successor.word += 4,
36285 2 => changed.successor.state_digest = Identity256::default(),
36286 3 => {
36287 changed.ranges.remove(0);
36288 }
36289 4 => {
36290 let item = changed.ranges.last_mut().unwrap();
36291 let mut attempt = item.attempt().unwrap();
36292 attempt.previous_attempt_digest = Identity256::from_bytes([91; 32]);
36293 item.bytes = publication_abi_bytes(&[attempt]);
36294 seal_replay_sample(&mut changed);
36295 }
36296 _ => unreachable!(),
36297 }
36298 assert!(
36299 parse(&changed.encode().unwrap()).is_err(),
36300 "accepted altered native evidence {change}"
36301 );
36302 }
36303 }
36304
36305 fn evidence_successor_logical() -> Identity256 {
36306 Identity256::from_bytes([13; 32])
36307 }
36308
36309 #[test]
36310 fn semantic_replay_provenance_preserves_original_authority_and_decision() {
36311 let (predecessor, evidence) = replay_material_sample();
36312 let replay = SemanticReplayMaterial::decode(
36313 &predecessor.encode().unwrap(),
36314 &evidence.encode().unwrap(),
36315 predecessor.bank.header.logical_digest,
36316 evidence.successor.logical_digest,
36317 )
36318 .unwrap();
36319 let authority = predecessor
36320 .ranges
36321 .iter()
36322 .find(|item| item.range.role == 38)
36323 .unwrap()
36324 .clone();
36325 let mut decision = predecessor
36326 .ranges
36327 .iter()
36328 .find(|item| item.range.role == 39)
36329 .unwrap()
36330 .clone();
36331 decision.bytes[0] ^= 1;
36332 decision.range.digest = decision.original_record_digest();
36333 let mut provenance = PublicationReplayProvenance {
36334 predecessor: replay.predecessor_identity(),
36335 authority,
36336 decision,
36337 };
36338 let bytes = provenance.encode().unwrap();
36339 assert_eq!(
36340 replay.verify_provenance(&bytes).unwrap(),
36341 provenance.decision.bytes
36342 );
36343 assert!(replay.verify_provenance(&bytes[..bytes.len() - 1]).is_err());
36344 let mut trailing = bytes.clone();
36345 trailing.push(0);
36346 assert!(replay.verify_provenance(&trailing).is_err());
36347 assert!(replay
36348 .verify_provenance(&predecessor.encode().unwrap())
36349 .is_err());
36350 provenance.predecessor.word += 2;
36351 assert!(replay
36352 .verify_provenance(&provenance.encode().unwrap())
36353 .is_err());
36354 provenance.predecessor = replay.predecessor_identity();
36355 provenance.authority.bytes[0] ^= 1;
36356 provenance.authority.range.digest = provenance.authority.original_record_digest();
36357 assert!(replay
36358 .verify_provenance(&provenance.encode().unwrap())
36359 .is_err());
36360 provenance.authority = predecessor
36361 .ranges
36362 .iter()
36363 .find(|item| item.range.role == 38)
36364 .unwrap()
36365 .clone();
36366 provenance.decision.bytes[0] ^= 1;
36367 assert!(replay
36368 .verify_provenance(&provenance.encode().unwrap())
36369 .is_err());
36370 }
36371
36372 #[test]
36373 fn semantic_replay_material_normalizes_only_native_audit_words() {
36374 let (_, evidence) = replay_material_sample();
36375 let mut attempt = evidence.range(33).unwrap().clone();
36376 let original = attempt.logical_record_digest().unwrap();
36377 for word in [1, 4, 5, 6, 39, 42] {
36378 attempt.bytes[word * 8] ^= 1;
36379 }
36380 assert_eq!(attempt.logical_record_digest().unwrap(), original);
36381 assert_ne!(
36382 attempt.original_record_digest(),
36383 evidence.range(33).unwrap().original_record_digest()
36384 );
36385 attempt.bytes[7 * 8] ^= 1;
36386 assert_ne!(attempt.logical_record_digest().unwrap(), original);
36387 for role in [27, 28, 31, 32] {
36388 let mut item = evidence.range(role).unwrap().clone();
36389 let original = item.logical_record_digest().unwrap();
36390 item.bytes[0] ^= 1;
36391 assert_ne!(
36392 item.logical_record_digest().unwrap(),
36393 original,
36394 "normalized opaque role {role}"
36395 );
36396 }
36397 }
36398
36399 fn replay_codebook_sample() -> PublicationMaterialRange {
36400 let mut words: Vec<u64> = (0..28).collect();
36401 words[8] = 25 * 8;
36402 words[9] = 3 * 8;
36403 let bytes = publication_abi_bytes(&words);
36404 let mut item = PublicationMaterialRange {
36405 range: PublicationRange {
36406 role: 48,
36407 generation: 1,
36408 length_bytes: bytes.len() as u64,
36409 ..PublicationRange::default()
36410 },
36411 capacity: bytes.len(),
36412 bytes,
36413 };
36414 item.range.digest = item.original_record_digest();
36415 item
36416 }
36417
36418 #[test]
36419 fn semantic_replay_receipt_hashes_preserve_every_nonruntime_field() {
36420 let codebook = replay_codebook_sample();
36421 let receipts = [SemanticTransitionReceipt {
36422 catalogue_generation: CATALOGUE_GENERATION,
36423 admission_binding: Identity256::from_bytes([17; 32]),
36424 choice: 5,
36425 ..SemanticTransitionReceipt::default()
36426 }];
36427 let expected = publication_action_receipts_digest(&codebook, &receipts).unwrap();
36428 for word in 0..codebook.bytes.len() / 8 {
36429 if matches!(word, 8 | 9) {
36430 continue;
36431 }
36432 let mut changed = codebook.clone();
36433 changed.bytes[word * 8] ^= 1;
36434 let equal =
36435 publication_action_receipts_digest(&changed, &receipts).unwrap() == expected;
36436 assert_eq!(
36437 equal,
36438 matches!(word, 14..=16 | 21..=24),
36439 "codebook word {word}"
36440 );
36441 }
36442 let mut changed = receipts;
36443 changed[0].admission_binding = Identity256::from_bytes([18; 32]);
36444 assert_eq!(
36445 publication_action_receipts_digest(&codebook, &changed).unwrap(),
36446 expected
36447 );
36448 changed[0].choice += 1;
36449 assert_ne!(
36450 publication_action_receipts_digest(&codebook, &changed).unwrap(),
36451 expected
36452 );
36453 let mut legacy = receipts;
36454 legacy[0].catalogue_generation = 0;
36455 let legacy_digest = publication_action_receipts_digest(&codebook, &legacy).unwrap();
36456 legacy[0].admission_binding = Identity256::from_bytes([18; 32]);
36457 assert_ne!(
36458 publication_action_receipts_digest(&codebook, &legacy).unwrap(),
36459 legacy_digest
36460 );
36461 assert_eq!(
36462 publication_action_receipts_digest(&codebook, &[]).unwrap(),
36463 Identity256::from_bytes(Sha256::digest([]).into())
36464 );
36465 let semantic = [[0u64; 42]; 7];
36466 let expected = publication_semantic_receipts_digest(&semantic);
36467 for ordinal in 0..semantic.len() {
36468 for word in 0..42 {
36469 let mut changed = semantic;
36470 changed[ordinal][word] = 1;
36471 assert_eq!(
36472 publication_semantic_receipts_digest(&changed) == expected,
36473 matches!(word, 3..=12 | 34..=41),
36474 "semantic receipt {ordinal} word {word}"
36475 );
36476 }
36477 }
36478 let header = IntentQueueHeader {
36479 abi: 1,
36480 count: 2,
36481 capacity: 2,
36482 ..IntentQueueHeader::default()
36483 };
36484 let mut bytes = publication_abi_bytes(&[header]);
36485 bytes.extend(publication_abi_bytes(&[IntentEntry::default(); 2]));
36486 let intent = PublicationMaterialRange {
36487 range: PublicationRange {
36488 role: 30,
36489 logical_end: 2,
36490 length_bytes: bytes.len() as u64,
36491 ..PublicationRange::default()
36492 },
36493 capacity: bytes.len(),
36494 bytes,
36495 };
36496 let expected = intent.logical_record_digest().unwrap();
36497 for ordinal in 0..2 {
36498 for word in 0..43 {
36499 let mut changed = intent.clone();
36500 changed.bytes[size_of::<IntentQueueHeader>()
36501 + ordinal * size_of::<IntentEntry>()
36502 + word * 8] ^= 1;
36503 assert_eq!(
36504 changed.logical_record_digest().unwrap() == expected,
36505 matches!(word, 30..=34),
36506 "intent entry {ordinal} word {word}"
36507 );
36508 }
36509 }
36510 }
36511
36512 #[test]
36513 fn semantic_replay_observed_attempt_checks_actual_receipts_and_coverage() {
36514 let (predecessor, mut evidence) = replay_material_sample();
36515 let mut bank = predecessor.bank;
36516 bank.header.instance = evidence.successor.instance;
36517 bank.header.base_word = predecessor.bank.header.publication_word;
36518 bank.header.publication_word = evidence.successor.word;
36519 bank.header.sealed_epoch = evidence.successor.word >> 1;
36520 bank.header.logical_digest = evidence.successor.logical_digest;
36521 bank.header.proposal = predecessor.bank.header.proposal + 1;
36522 bank.state.proposal = predecessor.bank.header.proposal;
36523 bank.state.next_proposal = bank.header.proposal;
36524 bank.state.blocks = COMPONENT_COUNT as u64;
36525 bank.receipts[0].catalogue_generation = CATALOGUE_GENERATION;
36526 let codebook = replay_codebook_sample();
36527 let component_receipts_digest =
36528 publication_action_receipts_digest(&codebook, &bank.receipts).unwrap();
36529 let semantic_receipts_digest =
36530 publication_semantic_receipts_digest(&bank.state.semantic_receipts);
36531 bank.state.action_batch = SemanticActionBatchReceipt {
36532 abi: 1,
36533 proposal: bank.state.proposal,
36534 stream_serial: bank.state.stream_serial,
36535 family_id: u64::from(bank.state.family_id),
36536 action_law_generation: bank.state.catalogue_generation,
36537 model_generation: u64::from(bank.state.model_generation),
36538 actor_eligible: bank.state.actor_eligible,
36539 component_count: COMPONENT_COUNT as u64,
36540 candidate_count: 3,
36541 winner: bank.state.task_evaluation.winner,
36542 total_return_bits: bank.state.task_evaluation.return_value as u64,
36543 base_word: bank.header.base_word,
36544 next_word: bank.header.publication_word,
36545 rng_base: bank.state.proposal * COMPONENT_COUNT as u64,
36546 rng_span: COMPONENT_COUNT as u64,
36547 rng_successor: bank.state.next_proposal * COMPONENT_COUNT as u64,
36548 catalogue_digest: bank.state.catalogue_digest,
36549 component_receipts_digest,
36550 semantic_receipts_digest,
36551 candidate_roots: [Identity256::default(); 3],
36552 base_logical_digest: predecessor.bank.header.logical_digest,
36553 execution_work: bank.state.execution_work,
36554 };
36555 bank.state.action_batch_root = publication_action_batch_root(&bank.state.action_batch);
36556 let mut completion = CompletionCoverage {
36557 abi: 1,
36558 instance: bank.header.instance,
36559 base_word: bank.header.base_word,
36560 ..CompletionCoverage::default()
36561 };
36562 let bytes = publication_abi_bytes(&[completion]);
36563 let mut coverage = PublicationMaterialRange {
36564 range: PublicationRange {
36565 role: 14,
36566 generation: 1,
36567 length_bytes: bytes.len() as u64,
36568 ..PublicationRange::default()
36569 },
36570 capacity: bytes.len(),
36571 bytes,
36572 };
36573 completion.receipt_digest = coverage.logical_record_digest().unwrap();
36574 coverage.bytes = publication_abi_bytes(&[completion]);
36575 coverage.range.digest = coverage.original_record_digest();
36576 let item = evidence.ranges.last_mut().unwrap();
36577 let mut attempt = item.attempt().unwrap();
36578 attempt.transition_kind = 1;
36579 attempt.action_receipts_digest = bank.state.action_batch_root;
36580 attempt.semantic_receipts_digest = semantic_receipts_digest;
36581 attempt.coverage_digest = coverage.logical_record_digest().unwrap();
36582 item.bytes = publication_abi_bytes(&[attempt]);
36583 seal_replay_sample(&mut evidence);
36584 bank.header.state_digest = evidence.successor.state_digest;
36585 assert_eq!(
36586 evidence.validate(&predecessor).unwrap(),
36587 SemanticTransitionKind::Proposal
36588 );
36589 evidence
36590 .validate_observed(&predecessor, &bank, &coverage, &codebook)
36591 .unwrap();
36592
36593 let mut changed = bank;
36594 changed.receipts[0].choice += 1;
36595 assert!(evidence
36596 .validate_observed(&predecessor, &changed, &coverage, &codebook)
36597 .is_err());
36598 changed = bank;
36599 changed.state.semantic_receipts[0][13] += 1;
36600 assert!(evidence
36601 .validate_observed(&predecessor, &changed, &coverage, &codebook)
36602 .is_err());
36603 changed = bank;
36604 changed.state.semantic_receipts[0][3] += 1;
36605 evidence
36606 .validate_observed(&predecessor, &changed, &coverage, &codebook)
36607 .unwrap();
36608 changed = bank;
36609 changed.state.blocks = 0;
36610 assert!(evidence
36611 .validate_observed(&predecessor, &changed, &coverage, &codebook)
36612 .is_err());
36613 changed = bank;
36614 changed.header.base_word += 2;
36615 assert!(evidence
36616 .validate_observed(&predecessor, &changed, &coverage, &codebook)
36617 .is_err());
36618 let mut changed_coverage = coverage.clone();
36619 changed_coverage.bytes[6 * 8] ^= 1;
36620 changed_coverage.range.digest = changed_coverage.original_record_digest();
36621 assert!(evidence
36622 .validate_observed(&predecessor, &bank, &changed_coverage, &codebook)
36623 .is_err());
36624 let mut changed_codebook = codebook.clone();
36625 changed_codebook.bytes[25 * 8] ^= 1;
36626 changed_codebook.range.digest = changed_codebook.original_record_digest();
36627 assert!(evidence
36628 .validate_observed(&predecessor, &bank, &coverage, &changed_codebook)
36629 .is_err());
36630 let item = evidence.ranges.last_mut().unwrap();
36631 let mut attempt = item.attempt().unwrap();
36632 attempt.semantic_receipts_digest = Identity256::from_bytes([92; 32]);
36633 item.bytes = publication_abi_bytes(&[attempt]);
36634 seal_replay_sample(&mut evidence);
36635 bank.header.state_digest = evidence.successor.state_digest;
36636 evidence.validate(&predecessor).unwrap();
36637 assert!(evidence
36638 .validate_observed(&predecessor, &bank, &coverage, &codebook)
36639 .is_err());
36640 }
36641
36642 #[test]
36643 fn publication_material_codebooks_relocate_only_runtime_coordinates() {
36644 let original: Vec<u64> = (0..48).collect();
36645 let mut actual = original.clone();
36646 for word in (14..=16).chain(21..=24) {
36647 actual[word] += 500;
36648 }
36649 let saved = publication_abi_bytes(&original);
36650 assert_eq!(
36651 relocate_publication_codebooks(&saved, &actual).unwrap(),
36652 publication_abi_bytes(&actual)
36653 );
36654 for word in (0..14).chain(17..=20).chain(25..48) {
36655 let mut corrupt = actual.clone();
36656 corrupt[word] += 1;
36657 assert!(
36658 relocate_publication_codebooks(&saved, &corrupt).is_err(),
36659 "logical word {word}"
36660 );
36661 }
36662 assert!(relocate_publication_codebooks(&saved[..saved.len() - 1], &actual).is_err());
36663 assert!(relocate_publication_codebooks(&saved, &actual[..47]).is_err());
36664 assert!(relocate_publication_codebooks(&[], &[]).is_err());
36665 }
36666
36667 type StepInputGeometryFixture = (
36668 [Vec<PublicationRange>; 2],
36669 BTreeMap<(u64, u64), SemanticTensorLayout>,
36670 Vec<usize>,
36671 );
36672
36673 fn step_input_geometry_fixture() -> StepInputGeometryFixture {
36674 let mut layouts = BTreeMap::new();
36675 let mut banks = [Vec::new(), Vec::new()];
36676 let mut sizes = Vec::new();
36677 for (role, index) in std::iter::once(1)
36678 .chain(3..=13)
36679 .chain(15..=17)
36680 .chain(std::iter::once(44))
36681 .flat_map(|role| (0..if role == 16 { 3 } else { 1 }).map(move |index| (role, index)))
36682 {
36683 let layout = if role == 1 {
36684 SemanticTensorLayout {
36685 role,
36686 index: 0,
36687 scalar_type: 3,
36688 element_bytes: 8,
36689 rank: 2,
36690 logical_axis: 0,
36691 dimensions: [64, 8, 0, 0],
36692 strides_bytes: [64, 8, 0, 0],
36693 }
36694 } else {
36695 canonical_tensor_layout(SemanticTensorLayout {
36696 role,
36697 index: 0,
36698 scalar_type: if role == 7 { 5 } else { 6 },
36699 element_bytes: if role == 7 { 2 } else { 4 },
36700 rank: 4,
36701 logical_axis: if role <= 5 { 2 } else { u64::MAX },
36702 dimensions: [1, 2, 64, 3],
36703 strides_bytes: [0; 4],
36704 })
36705 .unwrap()
36706 };
36707 if (4..=13).contains(&role) {
36708 layouts.insert((role, 0), layout);
36709 }
36710 let capacity = if role == 3 {
36711 32
36712 } else if role == 44 {
36713 108
36714 } else if role == 15 {
36715 2 * size_of::<RawFeedbackRecord>()
36716 } else if matches!(role, 16 | 17) {
36717 40 + index as usize * 8
36718 } else {
36719 tensor_layout_bytes(&layout).unwrap()
36720 };
36721 let shared = matches!(role, 1 | 16 | 17);
36722 let first_slot = sizes.len();
36723 sizes.push(capacity);
36724 if !shared {
36725 sizes.push(capacity);
36726 }
36727 for (bank, directory) in banks.iter_mut().enumerate() {
36728 directory.push(PublicationRange {
36729 role,
36730 index,
36731 storage_slot: (first_slot + usize::from(!shared) * bank) as u64,
36732 generation: 1,
36733 length_bytes: if role == 1 {
36734 64
36735 } else if role == 4 || role == 5 {
36736 24
36737 } else {
36738 capacity as u64
36739 },
36740 logical_end: u64::from(matches!(role, 1 | 4 | 5 | 15)),
36741 ..PublicationRange::default()
36742 });
36743 }
36744 }
36745 (banks, layouts, sizes)
36746 }
36747
36748 #[test]
36749 fn step_input_geometry_preserves_exact_roster_and_full_shared_capacity() {
36750 let (banks, layouts, sizes) = step_input_geometry_fixture();
36751 let plan = plan_step_inputs(&banks, &layouts, 64, &sizes).unwrap();
36752 assert_eq!(
36753 plan.iter()
36754 .map(|input| (input.role, input.index))
36755 .collect::<Vec<_>>(),
36756 std::iter::once((1, 0))
36757 .chain((3..=13).map(|role| (role, 0)))
36758 .chain([(15, 0), (16, 0), (16, 1), (16, 2), (17, 0), (44, 0),])
36759 .collect::<Vec<_>>()
36760 );
36761 assert_eq!(plan[0].banks[0].span.len(), 64 * size_of::<SourceSlot>());
36762 assert_eq!(plan[1].banks[0].span.len(), 32);
36763 for input in plan.iter().filter(|input| matches!(input.role, 4 | 5)) {
36764 assert_eq!(input.banks[0].span.len(), 2 * 64 * 3 * 4);
36765 }
36766 assert_eq!(size_of::<PublicationStepInput>(), 160);
36767 }
36768
36769 #[test]
36770 fn step_input_geometry_retains_raw_feedback_and_every_statement_record() {
36771 let (banks, layouts, sizes) = step_input_geometry_fixture();
36772 let plan = plan_step_inputs(&banks, &layouts, 64, &sizes).unwrap();
36773 let records = plan
36774 .iter()
36775 .filter(|input| matches!(input.role, 15..=17))
36776 .collect::<Vec<_>>();
36777 assert_eq!(
36778 records
36779 .iter()
36780 .map(|input| (input.role, input.index, input.banks[0].span.len()))
36781 .collect::<Vec<_>>(),
36782 vec![
36783 (15, 0, 768),
36784 (16, 0, 40),
36785 (16, 1, 48),
36786 (16, 2, 56),
36787 (17, 0, 40),
36788 ]
36789 );
36790 assert!(records
36791 .iter()
36792 .all(|input| input.layout.scalar_type == 1 && input.layout.element_bytes == 1));
36793 let mut missing = banks.clone();
36794 missing[1].retain(|range| (range.role, range.index) != (16, 2));
36795 assert!(plan_step_inputs(&missing, &layouts, 64, &sizes).is_err());
36796 let mut gapped = banks.clone();
36797 for bank in &mut gapped {
36798 bank.iter_mut()
36799 .find(|range| (range.role, range.index) == (16, 1))
36800 .unwrap()
36801 .index = 3;
36802 }
36803 assert!(plan_step_inputs(&gapped, &layouts, 64, &sizes).is_err());
36804 let mut shared_raw = banks;
36805 let slot = shared_raw[0]
36806 .iter()
36807 .find(|range| range.role == 15)
36808 .unwrap()
36809 .storage_slot;
36810 shared_raw[1]
36811 .iter_mut()
36812 .find(|range| range.role == 15)
36813 .unwrap()
36814 .storage_slot = slot;
36815 assert!(plan_step_inputs(&shared_raw, &layouts, 64, &sizes).is_err());
36816 }
36817
36818 #[test]
36819 fn feedback_record_material_preserves_original_seal_and_rejects_changed_content() {
36820 let mut original = PublicationMaterialRange {
36821 range: PublicationRange {
36822 role: 15,
36823 generation: 1,
36824 length_bytes: 768,
36825 logical_end: 1,
36826 ..PublicationRange::default()
36827 },
36828 capacity: 768,
36829 bytes: vec![0; 768],
36830 };
36831 original.range.digest = original.original_record_digest();
36832 let material = original.clone().into_feedback_record().unwrap();
36833 assert_eq!(material.identity, original.range.digest);
36834 assert_eq!(
36835 (
36836 material.logical_begin,
36837 material.logical_end,
36838 material.capacity_bytes
36839 ),
36840 (0, 1, 768)
36841 );
36842 assert_eq!(material.bytes, original.bytes);
36843 let mut changed = original.clone();
36844 changed.bytes[0] ^= 1;
36845 assert!(changed.into_feedback_record().is_err());
36846 let mut changed = original.clone();
36847 changed.range.logical_end = 2;
36848 assert!(changed.into_feedback_record().is_err());
36849 let mut changed = original;
36850 changed.range.role = 18;
36851 assert!(changed.into_feedback_record().is_err());
36852 }
36853
36854 #[test]
36855 fn step_input_geometry_rejects_missing_duplicate_and_noncanonical_coordinates() {
36856 let (banks, layouts, sizes) = step_input_geometry_fixture();
36857 let mut missing = banks.clone();
36858 missing[1].remove(4);
36859 assert!(plan_step_inputs(&missing, &layouts, 64, &sizes).is_err());
36860 let mut duplicate = banks.clone();
36861 let repeated = duplicate[0][4];
36862 duplicate[0].push(repeated);
36863 assert!(plan_step_inputs(&duplicate, &layouts, 64, &sizes).is_err());
36864 let mut wrong_index = banks;
36865 wrong_index[0][4].index = 1;
36866 assert!(plan_step_inputs(&wrong_index, &layouts, 64, &sizes).is_err());
36867 }
36868
36869 #[test]
36870 fn step_input_geometry_requires_shared_prefix_and_isolated_key_value_caches() {
36871 let (banks, layouts, sizes) = step_input_geometry_fixture();
36872 {
36873 let role = 1;
36874 let mut changed = banks.clone();
36875 changed[1]
36876 .iter_mut()
36877 .find(|range| range.role == role)
36878 .unwrap()
36879 .storage_slot += 1;
36880 assert!(plan_step_inputs(&changed, &layouts, 64, &sizes).is_err());
36881 }
36882 for role in [4, 5].into_iter().chain(std::iter::once(3)).chain(6..=13) {
36883 let mut changed = banks.clone();
36884 let slot = changed[0]
36885 .iter()
36886 .find(|range| range.role == role)
36887 .unwrap()
36888 .storage_slot;
36889 changed[1]
36890 .iter_mut()
36891 .find(|range| range.role == role)
36892 .unwrap()
36893 .storage_slot = slot;
36894 assert!(plan_step_inputs(&changed, &layouts, 64, &sizes).is_err());
36895 }
36896 }
36897
36898 #[test]
36899 fn step_input_geometry_checks_canonical_dtype_spans_and_allocation_bounds() {
36900 let (banks, layouts, sizes) = step_input_geometry_fixture();
36901 let plan = plan_step_inputs(&banks, &layouts, 64, &sizes).unwrap();
36902 let bf16 = plan.iter().find(|input| input.role == 7).unwrap();
36903 assert_eq!(
36904 (
36905 bf16.layout.scalar_type,
36906 bf16.layout.element_bytes,
36907 bf16.banks[0].span.len()
36908 ),
36909 (5, 2, 768)
36910 );
36911 let mut wrong = layouts.clone();
36912 wrong.get_mut(&(7, 0)).unwrap().strides_bytes[2] += 2;
36913 assert!(plan_step_inputs(&banks, &wrong, 64, &sizes).is_err());
36914 let mut short = sizes;
36915 short[banks[1]
36916 .iter()
36917 .find(|range| range.role == 7)
36918 .unwrap()
36919 .storage_slot as usize] -= 1;
36920 assert!(plan_step_inputs(&banks, &layouts, 64, &short).is_err());
36921 assert!(
36922 step_input_overlap(104, 0, 100, 8).unwrap(),
36923 "empty native aliases must still preserve their origin"
36924 );
36925 assert!(!step_input_overlap(108, 0, 100, 8).unwrap());
36926 assert!(step_input_overlap(96, 8, 100, 8).unwrap());
36927 assert!(step_input_overlap(u64::MAX, 2, 100, 8).is_err());
36928 }
36929
36930 #[test]
36931 #[ignore = "requires an explicitly authorized remote CUDA run"]
36932 fn step_inputs_keep_private_values_after_reader_retirement_and_current_bank_reuse() {
36933 let (provider, domain) = publication_test_provider();
36934 let mut session = publication_test_session(Arc::clone(&provider), &domain);
36935 session
36936 .bind_parent(publication_test_parent(&provider))
36937 .unwrap();
36938 let mut lease = session.acquire().unwrap();
36939 let context = session.published_model_context(&lease, 1).unwrap();
36940 let cache = session
36941 .published_tensor(&lease, SemanticStateRole::from_code(8).unwrap(), 0, 1)
36942 .unwrap();
36943 let inputs = Arc::clone(session.steps[&lease.token].inputs.as_ref().unwrap());
36944 let mut feedback_before = Vec::new();
36945 for (&(role, index), view) in inputs
36946 .views
36947 .first()
36948 .expect("two publication input banks")
36949 .iter()
36950 .filter(|(key, _)| matches!(key.0, 15..=17))
36951 {
36952 feedback_before.push((
36953 (role, index),
36954 session.publication_read(view.clone()).unwrap(),
36955 ));
36956 }
36957 assert_eq!(feedback_before.len(), 4);
36958 drop(inputs);
36959 let source_pointer = context.source.as_ptr();
36960 let cache_pointer = cache.as_ptr();
36961 let source_address = unsafe { (*source_pointer).dl_tensor.data as u64 };
36962 let cache_address = unsafe { (*cache_pointer).dl_tensor.data as u64 };
36963 let storage = Arc::clone(session.publication.as_ref().unwrap());
36964 assert!(!storage
36965 .banks
36966 .iter()
36967 .any(|bank| source_address >= bank.device_ptr_value()
36968 && source_address < bank.device_ptr_value() + size_of::<PublicationBank>() as u64));
36969 assert!(!storage
36970 .allocations
36971 .iter()
36972 .any(|allocation| cache_address >= allocation.device_ptr_value()
36973 && cache_address < allocation.device_ptr_value() + allocation.len() as u64));
36974 let again = session.published_source(&lease, 1).unwrap();
36975 assert_eq!(
36976 unsafe { (*again.as_ptr()).dl_tensor.data as u64 },
36977 source_address
36978 );
36979 let source_layout = SemanticTensorLayout {
36980 role: 0,
36981 index: 0,
36982 scalar_type: 3,
36983 element_bytes: 8,
36984 rank: 2,
36985 logical_axis: u64::MAX,
36986 dimensions: [32, 8, 0, 0],
36987 strides_bytes: [64, 8, 0, 0],
36988 };
36989 let source_input = |tensor| SemanticTensorInput {
36990 layout: source_layout,
36991 logical_begin: 0,
36992 logical_end: 0,
36993 tensor,
36994 native_allocation: None,
36995 };
36996 let original_source = source_input(session.published_source(&lease, 1).unwrap());
36997 let original_cache = publication_test_alias(
36998 &mut session,
36999 &lease,
37000 SemanticStateRole::from_code(8).unwrap(),
37001 1,
37002 );
37003 let later_source = source_input(session.published_source(&lease, 1).unwrap());
37004 let later_cache = publication_test_alias(
37005 &mut session,
37006 &lease,
37007 SemanticStateRole::from_code(8).unwrap(),
37008 1,
37009 );
37010 let witness = session
37011 .capture_tensor_content(&lease, vec![original_source, original_cache], 1)
37012 .unwrap();
37013 let TensorContentSeals::Captured(origins) =
37014 &session.steps[&lease.token].content[witness.index].seals
37015 else {
37016 panic!("native input origins");
37017 };
37018 assert!(
37019 origins
37020 .iter()
37021 .all(|origin| matches!(origin, CapturedTensorDigest::Publication(_))),
37022 "capture must retain the original native input seals"
37023 );
37024 session
37025 .guard_published_content(&lease, &[(SemanticStateRole::from_code(8).unwrap(), 0)], 1)
37026 .unwrap();
37027 publication_test_recompute(&mut session, &lease, &provider);
37028 session.release_published_reader(&mut lease, &[1]).unwrap();
37029 for _ in 0..2 {
37030 let mut current = session.acquire().unwrap();
37031 let current_context = session.published_model_context(¤t, 1).unwrap();
37032 let inputs = Arc::clone(session.steps[¤t.token].inputs.as_ref().unwrap());
37033 let copied_header = session.publication_read(inputs.header.view()).unwrap()[0];
37034 assert_eq!(copied_header.publication_word, current.identity.word);
37035 assert_ne!(
37036 unsafe { (*current_context.source.as_ptr()).dl_tensor.data as u64 },
37037 source_address
37038 );
37039 drop(current_context);
37040 publication_test_recompute(&mut session, ¤t, &provider);
37041 session.release(&mut current, &[1]).unwrap();
37042 }
37043 let inputs = Arc::clone(session.steps[&lease.token].inputs.as_ref().unwrap());
37044 assert_eq!(
37045 session.publication_read(inputs.header.view()).unwrap()[0].publication_word,
37046 lease.identity.word
37047 );
37048 for (key, bytes) in feedback_before {
37049 assert_eq!(session.publication_read(inputs.views[0][&key].clone()).unwrap(), bytes,
37050 "raw feedback and its original statements/provenance must survive physical bank reuse");
37051 }
37052 let before = session.host_io_stats();
37053 session
37054 .verify_tensor_content(&lease, &witness, vec![later_source, later_cache], 1)
37055 .unwrap();
37056 assert_eq!(session.host_io_stats(), before);
37057 drop(witness);
37058 assert!(session.release(&mut lease, &[1]).is_err());
37059 drop(context);
37060 drop(cache);
37061 drop(again);
37062 drop(storage);
37063 drop(inputs);
37064 session.release(&mut lease, &[1]).unwrap();
37065 drop(session);
37066 provider.memory().reap_pending_deallocations().unwrap();
37067 assert_eq!(provider.memory().allocated_bytes(), 0);
37068 }
37069
37070 #[test]
37071 fn model_context_joins_exact_acquired_header_prefix_and_ring() {
37072 let identity = |byte| Identity256::from_bytes([byte; 32]);
37073 let mut lease = SemanticPublishedLease {
37074 issuer: Arc::new(()),
37075 token: 7,
37076 active: true,
37077 identity: SemanticPublishedIdentity {
37078 instance: identity(1),
37079 word: 12,
37080 logical_digest: identity(2),
37081 state_digest: identity(3),
37082 },
37083 header: PublicationHeader {
37084 abi: 1,
37085 instance: identity(1),
37086 publication_word: 12,
37087 sealed_epoch: 6,
37088 logical_digest: identity(2),
37089 state_digest: identity(3),
37090 descriptor_digest: identity(4),
37091 semantic_owner: 5,
37092 semantic_slot: 6,
37093 semantic_generation: 7,
37094 semantic_digest: identity(8),
37095 semantic_extents: [9, 10, 11],
37096 prefix_extent: 2,
37097 ring_head: 17,
37098 model_generation: 12,
37099 neural_bank: 1,
37100 neural_generation: 13,
37101 cache_generation: 14,
37102 authority_generation: 15,
37103 ..PublicationHeader::default()
37104 },
37105 source: source_rows(),
37106 directory: Vec::new(),
37107 };
37108 let context = lease.model_context_header().unwrap();
37109 assert_eq!(context.descriptor_digest, identity(4));
37110 assert_eq!(
37111 (
37112 context.semantic_owner,
37113 context.semantic_slot,
37114 context.semantic_generation,
37115 context.semantic_digest,
37116 context.semantic_extents
37117 ),
37118 (5, 6, 7, identity(8), [9, 10, 11])
37119 );
37120 assert_eq!(context.ring_head, 17);
37121 assert_eq!(context.prefix_extent, 2);
37122 assert_eq!(
37123 (
37124 context.model_generation,
37125 context.neural_bank,
37126 context.neural_generation,
37127 context.cache_generation,
37128 context.authority_generation
37129 ),
37130 (12, 1, 13, 14, 15)
37131 );
37132 lease.header.state_digest = identity(19);
37133 assert!(lease.model_context_header().is_err());
37134 }
37135
37136 #[test]
37137 fn publication_bank_views_use_original_fields_and_slot_order() {
37138 let header = PublicationHeader {
37139 prefix_extent: 23,
37140 ring_head: 17,
37141 ..PublicationHeader::default()
37142 };
37143 let source = source_rows();
37144 let mut bytes = publication_abi_bytes(&[header]);
37145 bytes.extend(publication_abi_bytes(&source));
37146 let (range, shape, strides) = PublicationBankField::Source.layout();
37147 assert_eq!(range.start, std::mem::offset_of!(PublicationBank, source));
37148 assert_eq!(range.len(), size_of::<[SourceSlot; 32]>());
37149 assert_eq!((shape, strides), (vec![32, 8], vec![8, 1]));
37150 assert_eq!(&bytes[range], publication_abi_bytes(&source));
37151 for (field, value) in [
37152 (PublicationBankField::PrefixExtent, 23u64),
37153 (PublicationBankField::RingHead, 17u64),
37154 ] {
37155 let (range, shape, strides) = field.layout();
37156 assert_eq!(range.start % size_of::<u64>(), 0);
37157 assert_eq!(range.len(), size_of::<u64>());
37158 assert_eq!((shape, strides), (vec![1], vec![1]));
37159 assert_eq!(&bytes[range], value.to_ne_bytes());
37160 }
37161 }
37162
37163 #[test]
37164 fn active_row_table_requires_independent_publication_banks() {
37165 assert!(publication_mutable_role(
37166 SemanticStateRole::TensorLayout as u64
37167 ));
37168 }
37169
37170 #[test]
37171 fn active_text_rows_include_the_reserved_window_before_feedback_positions() {
37172 for position in [63, 64, 95, 96] {
37173 let mut source = [SourceSlot::default(); 32];
37174 source[7] = SourceSlot {
37175 token: MASK_TOKEN as u64,
37176 logical_position: position,
37177 kind: 2,
37178 valid: 1,
37179 ..SourceSlot::default()
37180 };
37181 let admitted = validate_text_parent(&source, 0, 64, 2, 262144, 0, 0);
37182 assert_eq!(admitted.is_ok(), position < 96);
37183 }
37184 }
37185
37186 #[test]
37187 fn active_table_keeps_computed_empty_distinct_from_uncomputed() {
37188 let layouts = [SemanticTensorLayout {
37189 role: 51,
37190 rank: 4,
37191 logical_axis: 2,
37192 element_bytes: 2,
37193 scalar_type: 4,
37194 dimensions: [1, 2, 35, 4],
37195 strides_bytes: [560, 280, 8, 2],
37196 ..SemanticTensorLayout::default()
37197 }];
37198 let cold = tensor_table_bytes(&layouts, false, &[]).unwrap();
37199 let empty = tensor_table_bytes(&layouts, true, &[]).unwrap();
37200 assert_ne!(cold, empty);
37201 assert_eq!(
37202 decode_tensor_table(&cold).unwrap().2,
37203 SemanticActiveRows {
37204 computed: false,
37205 rows: vec![]
37206 }
37207 );
37208 assert_eq!(
37209 decode_tensor_table(&empty).unwrap().2,
37210 SemanticActiveRows {
37211 computed: true,
37212 rows: vec![]
37213 }
37214 );
37215 assert_eq!(decode_tensor_table(&empty).unwrap().1, layouts);
37216 assert!(decode_tensor_table(&publication_abi_bytes(&layouts)).is_err());
37217 let mut invalid = empty.clone();
37218 invalid[16..24].copy_from_slice(&2u64.to_ne_bytes());
37219 assert!(decode_tensor_table(&invalid).is_err());
37220 invalid = empty.clone();
37221 invalid[24..32].copy_from_slice(&1u64.to_ne_bytes());
37222 assert!(decode_tensor_table(&invalid).is_err());
37223 assert!(decode_tensor_table(&empty[..empty.len() - 1]).is_err());
37224 let row = SemanticActiveRow {
37225 physical_row: 0,
37226 source_slot: 0,
37227 logical_position: 0,
37228 kind: 2,
37229 };
37230 assert!(tensor_table_bytes(&layouts, false, &[row]).is_err());
37231 assert!(tensor_table_capacity(usize::MAX, 35).is_err());
37232 }
37233
37234 #[test]
37235 fn active_tensor_geometry_preserves_full_physical_capacity() {
37236 let producer = SemanticTensorLayout {
37237 role: 51,
37238 rank: 4,
37239 logical_axis: 2,
37240 element_bytes: 2,
37241 scalar_type: 4,
37242 dimensions: [1, 2, 35, 4],
37243 strides_bytes: [560, 2, 16, 4],
37244 ..SemanticTensorLayout::default()
37245 };
37246 let cold = canonical_tensor_layout(producer).unwrap();
37247 assert!(validate_active_capacity(&cold, 35).is_ok());
37248 assert!(validate_active_capacity(&cold, 34).is_err());
37249 let pending = continuation_tensor_layout(&producer, 0, 35, &cold).unwrap();
37250 assert_eq!(pending.dimensions, producer.dimensions);
37251 assert_eq!(pending.strides_bytes, [560, 280, 8, 2]);
37252 assert!(tensor_copy_plan(&producer, &pending).is_ok());
37253 assert!(continuation_tensor_layout(&producer, 8, 9, &cold).is_err());
37254 assert!(continuation_tensor_layout(&producer, 0, 3, &cold).is_err());
37255 let linear = SemanticTensorLayout {
37256 role: 53,
37257 rank: 3,
37258 logical_axis: 0,
37259 element_bytes: 4,
37260 scalar_type: 6,
37261 dimensions: [35, 4, 2, 0],
37262 strides_bytes: [32, 8, 4, 0],
37263 ..SemanticTensorLayout::default()
37264 };
37265 assert!(validate_active_capacity(&linear, 35).is_ok());
37266 assert!(validate_active_capacity(
37267 &SemanticTensorLayout {
37268 logical_axis: u64::MAX,
37269 ..linear
37270 },
37271 35
37272 )
37273 .is_err());
37274 }
37275
37276 #[test]
37277 fn publication_rng_binding_uses_only_the_actual_header_coordinates() {
37278 let header = PublicationHeader {
37279 model_generation: 17,
37280 family_id: 29,
37281 stream_serial: (1u64 << 56) - 1,
37282 proposal: u64::from(u32::MAX),
37283 ..PublicationHeader::default()
37284 };
37285 assert_eq!(
37286 header.rng_binding().unwrap(),
37287 SemanticRngBinding {
37288 model_generation: 17,
37289 family_id: 29,
37290 stream_serial: (1u64 << 56) - 1,
37291 proposal: u32::MAX,
37292 }
37293 );
37294 for invalid in [
37295 PublicationHeader {
37296 model_generation: 1u64 << 32,
37297 ..header
37298 },
37299 PublicationHeader {
37300 family_id: 256,
37301 ..header
37302 },
37303 PublicationHeader {
37304 stream_serial: 1u64 << 56,
37305 ..header
37306 },
37307 PublicationHeader {
37308 proposal: 1u64 << 32,
37309 ..header
37310 },
37311 ] {
37312 assert!(invalid.rng_binding().is_err());
37313 }
37314 }
37315
37316 #[test]
37317 fn cold_continuation_layouts_match_original_fixed_output_snapshots() {
37318 let prefix = canonical_tensor_layout(SemanticTensorLayout {
37319 role: 4,
37320 rank: 4,
37321 logical_axis: 2,
37322 element_bytes: 2,
37323 scalar_type: 4,
37324 dimensions: [1, 2, 128, 4],
37325 ..SemanticTensorLayout::default()
37326 })
37327 .unwrap();
37328 let active = canonical_tensor_layout(SemanticTensorLayout {
37329 role: 51,
37330 rank: 4,
37331 logical_axis: 2,
37332 element_bytes: 2,
37333 scalar_type: 4,
37334 dimensions: [1, 2, 35, 4],
37335 ..SemanticTensorLayout::default()
37336 })
37337 .unwrap();
37338 let state = canonical_tensor_layout(SemanticTensorLayout {
37339 role: 6,
37340 rank: 2,
37341 logical_axis: u64::MAX,
37342 element_bytes: 4,
37343 scalar_type: 6,
37344 dimensions: [4, 128, 0, 0],
37345 ..SemanticTensorLayout::default()
37346 })
37347 .unwrap();
37348 let mut layouts = Vec::new();
37349 for (model, extent) in [(prefix, 32), (active, 35), (state, 0)] {
37350 let cold = continuation_capacity_layout(model).unwrap();
37351 let mut producer = cold;
37352 if model.role != 6 {
37353 producer.strides_bytes = [extent * 16, 2, 16, 4];
37356 }
37357 assert_eq!(
37358 continuation_tensor_layout(&producer, 0, extent, &model).unwrap(),
37359 cold
37360 );
37361 assert!(tensor_copy_plan(&producer, &cold).is_ok());
37362 layouts.push(cold);
37363 }
37364 assert_eq!(layouts[0].dimensions, [1, 2, 32, 4]);
37365 assert_eq!(layouts[1], active);
37366 assert_eq!(layouts[2], state);
37367 let table = tensor_table_bytes(&layouts, true, &[]).unwrap();
37368 let (_, decoded, rows) = decode_tensor_table(&table).unwrap();
37369 assert_eq!(decoded, layouts);
37370 assert_eq!(
37371 rows,
37372 SemanticActiveRows {
37373 computed: true,
37374 rows: vec![]
37375 }
37376 );
37377 assert!(continuation_capacity_layout(SemanticTensorLayout { role: 3, ..state }).is_err());
37378 assert!(continuation_capacity_layout(SemanticTensorLayout {
37379 logical_axis: 1,
37380 ..active
37381 })
37382 .is_err());
37383 }
37384
37385 #[test]
37386 fn continuation_services_preserve_original_device_roster_and_capacity() {
37387 let layouts = continuation_service_layouts(9, 66, None).unwrap();
37388 let expected = [
37389 (3, 8, [32, 2, 0, 0]),
37390 (3, 8, [1, 0, 0, 0]),
37391 (8, 1, [32, 0, 0, 0]),
37392 (3, 8, [66, 4, 0, 0]),
37393 (3, 8, [1, 0, 0, 0]),
37394 (8, 1, [1, 0, 0, 0]),
37395 ];
37396 for (ordinal, (layout, (scalar_type, element_bytes, dimensions))) in
37397 layouts.iter().zip(expected).enumerate()
37398 {
37399 assert_eq!((layout.role, layout.index), (0, 9 + ordinal as u64));
37400 assert_eq!(
37401 (layout.scalar_type, layout.element_bytes, layout.dimensions),
37402 (scalar_type, element_bytes, dimensions)
37403 );
37404 assert_eq!(layout.logical_axis, u64::MAX);
37405 let bytes = tensor_layout_bytes(layout).unwrap();
37406 let range = tensor_content_range(layout, 0, 0, bytes).unwrap();
37407 assert_eq!(range.index, layout.index);
37408 }
37409 assert!(continuation_service_layouts(usize::MAX, 66, None).is_err());
37410 assert!(continuation_service_layouts(0, 0, None).is_err());
37411 let proposal = continuation_service_layouts(9, 66, Some(2)).unwrap();
37412 assert_eq!(proposal.len(), 7);
37413 assert_eq!(proposal[6].index, 15);
37414 assert_eq!(proposal[6].scalar_type, 9);
37415 assert_eq!(proposal[6].element_bytes, 8);
37416 assert_eq!(proposal[6].dimensions, [2, 2, 3, 0]);
37417 assert_eq!(tensor_layout_bytes(&proposal[6]).unwrap(), 96);
37418 }
37419
37420 #[test]
37421 fn block_roster_comes_from_the_original_model_contract_schema() {
37422 let schema = br#"{"counter_encoding":"u32-hex8","model":{"physical":{"head":{"kind":"parameter"},"state":{"kind":"buffer"},"trunk":{"kind":"parameter"}}}}"#;
37423 let mut record = vec![0u8; 104];
37424 record.extend_from_slice(schema);
37425 let layout = SemanticModelContractLayout {
37426 schema_begin: 104,
37427 schema_bytes: schema.len() as u64,
37428 schema_digest_offset: 0,
37429 generation_offset: 32,
37430 numerical_digest_offset: 40,
37431 identity_offset: 72,
37432 };
37433 assert_eq!(
37434 model_physical_parameter_roster(&record, layout).unwrap(),
37435 Some(vec!["head".into(), "trunk".into()])
37436 );
37437 let mut invalid = record;
37438 let location = invalid
37439 .windows(6)
37440 .position(|window| window == b"buffer")
37441 .unwrap();
37442 invalid[location..location + 6].copy_from_slice(b"broken");
37443 assert!(model_physical_parameter_roster(&invalid, layout).is_err());
37444 }
37445
37446 #[test]
37447 fn continuation_transport_does_not_rebase_original_suffix_or_nonpositional_outputs() {
37448 let suffix = canonical_tensor_layout(SemanticTensorLayout {
37449 role: 4,
37450 rank: 4,
37451 logical_axis: 2,
37452 element_bytes: 2,
37453 scalar_type: 4,
37454 dimensions: [1, 2, 32, 4],
37455 ..SemanticTensorLayout::default()
37456 })
37457 .unwrap();
37458 let cold = prefix_capacity_layout(
37459 SemanticTensorLayout {
37460 dimensions: [1, 2, 0, 4],
37461 ..suffix
37462 },
37463 16,
37464 )
37465 .unwrap();
37466 for (prefix, end) in [(0, 0), (3, 5), (16, 16)] {
37467 let pending = continuation_tensor_layout(&suffix, 0, 32, &cold).unwrap();
37468 assert_eq!(pending, suffix);
37469 assert!(continuation_tensor_layout(&suffix, prefix, end, &cold).is_err());
37470 }
37471 let state = canonical_tensor_layout(SemanticTensorLayout {
37472 role: 6,
37473 rank: 2,
37474 logical_axis: u64::MAX,
37475 element_bytes: 4,
37476 scalar_type: 6,
37477 dimensions: [4, 128, 0, 0],
37478 ..SemanticTensorLayout::default()
37479 })
37480 .unwrap();
37481 assert_eq!(
37482 continuation_tensor_layout(&state, 0, 0, &state).unwrap(),
37483 state
37484 );
37485 assert!(continuation_tensor_layout(&state, 3, 5, &state).is_err());
37486 }
37487
37488 #[test]
37489 fn cold_intent_owner_constructs_an_empty_queue_with_the_actual_effect() {
37490 let effect = b"deliver the committed token sequence to the request output";
37491 let records = initial_intent_records(effect, 2, 4096, 1024).unwrap();
37492 assert_eq!(records[0].role, SemanticStateRole::IntentEntries);
37493 assert_eq!(records[0].bytes.len(), size_of::<IntentQueueHeader>());
37494 assert_eq!(
37495 records[0].capacity_bytes,
37496 size_of::<IntentQueueHeader>() + 2 * size_of::<IntentEntry>()
37497 );
37498 let header = unsafe {
37500 records[0]
37501 .bytes
37502 .as_ptr()
37503 .cast::<IntentQueueHeader>()
37504 .read_unaligned()
37505 };
37506 assert_eq!((header.abi, header.count, header.capacity), (1, 0, 2));
37507 assert_eq!(header.chain_head, Identity256::default());
37508 assert_eq!(
37509 (header.effect_offset_bytes, header.effect_length_bytes),
37510 (0, effect.len() as u64)
37511 );
37512 assert_eq!(header.payload_used_bytes, effect.len() as u64);
37513 assert_eq!(header.payload_capacity_bytes, 4096);
37514 assert_eq!(records[1].role, SemanticStateRole::IntentPayload);
37515 assert_eq!(records[1].bytes, effect);
37516 assert_eq!(records[1].capacity_bytes, 4096);
37517 assert!(initial_intent_records(&[], 2, 4096, 1024).is_err());
37518 assert!(initial_intent_records(effect, 0, 4096, 1024).is_err());
37519 assert!(initial_intent_records(effect, u64::MAX, 4096, 1024).is_err());
37520 assert!(initial_intent_records(effect, 2, effect.len() + 1023, 1024).is_err());
37521 }
37522
37523 #[test]
37524 fn checkpoint_intent_projection_rechecks_the_native_key_and_chain() {
37525 let effect = b"record result";
37526 let output = 1u64.to_le_bytes();
37527 let mut material = publication_material_sample();
37528 let mut entry = IntentEntry {
37529 checkpoint_lineage: Identity256::from_bytes([1; 32]),
37530 base_logical: Identity256::from_bytes([2; 32]),
37531 effective_delta: Identity256::from_bytes([3; 32]),
37532 result_logical: Identity256::from_bytes([4; 32]),
37533 effect_digest: Identity256::from_bytes(Sha256::digest(effect).into()),
37534 payload_digest: Identity256::from_bytes(Sha256::digest(output).into()),
37535 payload_offset: effect.len() as u64,
37536 payload_len: output.len() as u64,
37537 ..IntentEntry::default()
37538 };
37539 let mut key = Sha256::new();
37540 key.update(0x786c6f67696e7431u64.to_le_bytes());
37541 for part in [
37542 entry.checkpoint_lineage,
37543 entry.base_logical,
37544 entry.effective_delta,
37545 entry.result_logical,
37546 entry.effect_digest,
37547 entry.payload_digest,
37548 ] {
37549 key.update(part.as_bytes());
37550 }
37551 entry.stable_identity = Identity256::from_bytes(key.finalize().into());
37552 entry.chain = publication_fold_digest(Identity256::default(), 30, 0, entry.stable_identity);
37553 let header = IntentQueueHeader {
37554 abi: 1,
37555 count: 1,
37556 capacity: 2,
37557 payload_used_bytes: (effect.len() + output.len()) as u64,
37558 payload_capacity_bytes: 64,
37559 effect_offset_bytes: 0,
37560 effect_length_bytes: effect.len() as u64,
37561 chain_head: entry.chain,
37562 };
37563 for range in &mut material.ranges {
37564 match range.range.role {
37565 30 => {
37566 range.bytes = publication_abi_bytes(&[header]);
37567 range.bytes.extend(publication_abi_bytes(&[entry]));
37568 range.capacity = size_of::<IntentQueueHeader>() + 2 * size_of::<IntentEntry>();
37569 }
37570 31 => {
37571 range.bytes = [effect.as_slice(), output.as_slice()].concat();
37572 range.capacity = 64;
37573 }
37574 _ => continue,
37575 }
37576 range.range.length_bytes = range.bytes.len() as u64;
37577 range.range.digest = range.original_record_digest();
37578 }
37579 publication_material_sample_runtime(&mut material);
37580 material.bank.header.descriptor_digest = material.original_descriptor_digest();
37581 let encoded = material.encode().unwrap();
37582 let projected = output_intents_from_publication_material(&encoded).unwrap();
37583 assert_eq!(projected.len(), 1);
37584 assert_eq!(projected[0].stable_identity, entry.stable_identity);
37585 assert_eq!(projected[0].effect, effect);
37586 assert_eq!(projected[0].payload, output);
37587
37588 let entry_range = material
37589 .ranges
37590 .iter_mut()
37591 .find(|item| item.range.role == 30)
37592 .unwrap();
37593 let last = entry_range.bytes.last_mut().unwrap();
37594 *last ^= 1;
37595 entry_range.range.digest = entry_range.original_record_digest();
37596 material.bank.header.descriptor_digest = material.original_descriptor_digest();
37597 assert!(output_intents_from_publication_material(&material.encode().unwrap()).is_err());
37598 }
37599
37600 #[test]
37601 fn semantic_tensor_admission_preserves_original_type_strides_and_bounds() {
37602 let layout = SemanticTensorLayout {
37603 role: SemanticStateRole::AttentionKeys as u64,
37604 index: 0,
37605 element_bytes: 2,
37606 scalar_type: 4,
37607 rank: 4,
37608 logical_axis: 2,
37609 dimensions: [1, 2, 3, 4],
37610 strides_bytes: [48, 24, 8, 2],
37611 };
37612 let metadata = TensorMetadata {
37613 device_type: crate::dlpack::K_DLCUDA,
37614 device_id: 0,
37615 dtype: crate::dlpack::DLDataType {
37616 code: 2,
37617 bits: 16,
37618 lanes: 1,
37619 },
37620 shape: &[1, 2, 3, 4],
37621 strides: None,
37622 data: 0x1000,
37623 byte_offset: 2,
37624 };
37625 assert_eq!(
37626 validate_tensor_metadata(&layout, &metadata, 0).unwrap(),
37627 (0x1002, 48)
37628 );
37629 let mut wrong = metadata;
37630 wrong.dtype.code = 4; assert!(validate_tensor_metadata(&layout, &wrong, 0).is_err());
37632 wrong = metadata;
37633 wrong.strides = Some(&[0, 0, 0, 0]);
37634 assert!(validate_tensor_metadata(&layout, &wrong, 0).is_err());
37635 wrong = metadata;
37636 wrong.device_id = 1;
37637 assert!(validate_tensor_metadata(&layout, &wrong, 0).is_err());
37638 wrong = metadata;
37639 wrong.data = u64::MAX - 1;
37640 assert!(validate_tensor_metadata(&layout, &wrong, 0).is_err());
37641 wrong = metadata;
37642 wrong.byte_offset = 1;
37643 assert!(validate_tensor_metadata(&layout, &wrong, 0).is_err());
37644 let mut transposed = layout;
37645 transposed.strides_bytes = [48, 2, 16, 4];
37646 let mut strided = metadata;
37647 strided.strides = Some(&[24, 1, 8, 2]);
37648 assert_eq!(
37649 validate_tensor_metadata(&transposed, &strided, 0).unwrap(),
37650 (0x1002, 48)
37651 );
37652 let mut empty = layout;
37653 empty.dimensions[2] = 0;
37654 empty.strides_bytes = [0, 0, 8, 2];
37655 let mut empty_metadata = metadata;
37656 empty_metadata.shape = &[1, 2, 0, 4];
37657 empty_metadata.data = 0;
37658 empty_metadata.byte_offset = 0;
37659 assert_eq!(
37660 validate_tensor_metadata(&empty, &empty_metadata, 0).unwrap(),
37661 (0, 0)
37662 );
37663 }
37664
37665 #[test]
37666 fn semantic_tensor_scalar_keeps_one_cell_and_original_rank() {
37667 for (scalar_type, element_bytes, code) in [
37668 (1, 1, 1),
37669 (2, 4, 1),
37670 (3, 8, 1),
37671 (4, 2, 2),
37672 (5, 2, 4),
37673 (6, 4, 2),
37674 (7, 8, 0),
37675 (8, 1, 6),
37676 (9, 8, 2),
37677 ] {
37678 let layout = SemanticTensorLayout {
37679 role: 18,
37680 index: 0,
37681 scalar_type,
37682 element_bytes,
37683 rank: 0,
37684 logical_axis: u64::MAX,
37685 dimensions: [0; 4],
37686 strides_bytes: [0; 4],
37687 };
37688 let metadata = TensorMetadata {
37689 device_type: crate::dlpack::K_DLCUDA,
37690 device_id: 0,
37691 dtype: crate::dlpack::DLDataType {
37692 code,
37693 bits: (element_bytes * 8) as u8,
37694 lanes: 1,
37695 },
37696 shape: &[],
37697 strides: None,
37698 data: 4096,
37699 byte_offset: element_bytes,
37700 };
37701 assert_eq!(
37702 validate_tensor_metadata(&layout, &metadata, 0).unwrap(),
37703 (4096 + element_bytes, element_bytes as usize)
37704 );
37705 assert_eq!(
37706 tensor_layout_bytes(&layout).unwrap(),
37707 element_bytes as usize
37708 );
37709 assert_eq!(canonical_tensor_layout(layout).unwrap(), layout);
37710 assert_eq!(
37711 tensor_copy_plan(&layout, &layout).unwrap(),
37712 vec![(0, 0, element_bytes as usize)]
37713 );
37714 let mut wrong = metadata;
37715 wrong.data = 0;
37716 assert!(validate_tensor_metadata(&layout, &wrong, 0).is_err());
37717 wrong = metadata;
37718 wrong.shape = &[1];
37719 assert!(validate_tensor_metadata(&layout, &wrong, 0).is_err());
37720 let mut malformed = layout;
37721 malformed.logical_axis = 0;
37722 assert!(tensor_layout_bytes(&malformed).is_err());
37723 malformed = layout;
37724 malformed.dimensions[0] = 1;
37725 assert!(tensor_layout_bytes(&malformed).is_err());
37726 malformed = layout;
37727 malformed.strides_bytes[0] = element_bytes;
37728 assert!(tensor_layout_bytes(&malformed).is_err());
37729 }
37730 }
37731
37732 #[test]
37733 fn publication_material_scalar_layout_survives_cold_codec() {
37734 let mut material = publication_material_sample();
37735 let layout = material.layouts.get_mut(&(18, 0)).unwrap();
37736 layout.rank = 0;
37737 layout.dimensions = [0; 4];
37738 layout.strides_bytes = [0; 4];
37739 let scalar = *layout;
37740 let table = material
37741 .ranges
37742 .iter_mut()
37743 .find(|item| item.range.role == 55)
37744 .unwrap();
37745 table.bytes = tensor_table_bytes(
37746 &material.layouts.values().copied().collect::<Vec<_>>(),
37747 false,
37748 &[],
37749 )
37750 .unwrap();
37751 table.range.digest = table.original_record_digest();
37752 publication_material_sample_runtime(&mut material);
37753 material.bank.header.descriptor_digest = material.original_descriptor_digest();
37754 let encoded = material.encode().unwrap();
37755 let restored = PublicationMaterial::decode(&encoded).unwrap();
37756 assert_eq!(restored.layouts[&(18, 0)], scalar);
37757 let original = material
37758 .ranges
37759 .iter()
37760 .find(|item| item.range.role == 18)
37761 .unwrap();
37762 let actual = restored
37763 .ranges
37764 .iter()
37765 .find(|item| item.range.role == 18)
37766 .unwrap();
37767 assert_eq!(actual.bytes, original.bytes);
37768 assert_eq!(actual.bytes.len(), scalar.element_bytes as usize);
37769 assert_eq!(restored.encode().unwrap(), encoded);
37770 }
37771
37772 #[test]
37773 fn semantic_tensor_scalar_metadata_allows_null_zero_rank_arrays() {
37774 let mut value = 3.5f32;
37776 let mut descriptor = crate::dlpack::DLTensor {
37777 data: (&mut value as *mut f32).cast(),
37778 device: crate::dlpack::DLDevice {
37779 device_type: crate::dlpack::K_DLCUDA,
37780 device_id: 0,
37781 },
37782 ndim: 0,
37783 dtype: crate::dlpack::DLDataType {
37784 code: 2,
37785 bits: 32,
37786 lanes: 1,
37787 },
37788 shape: std::ptr::null_mut(),
37789 strides: std::ptr::null_mut(),
37790 byte_offset: 0,
37791 };
37792 let layout = SemanticTensorLayout {
37793 role: 18,
37794 index: 0,
37795 element_bytes: 4,
37796 scalar_type: 6,
37797 rank: 0,
37798 logical_axis: u64::MAX,
37799 dimensions: [0; 4],
37800 strides_bytes: [0; 4],
37801 };
37802 let actual = unsafe { semantic_tensor_metadata(&descriptor) }.unwrap();
37804 assert!(actual.shape.is_empty());
37805 assert!(actual.strides.is_none());
37806 assert_eq!(
37807 validate_tensor_metadata(&layout, &actual, 0).unwrap(),
37808 ((&value as *const f32) as usize as u64, size_of::<f32>())
37809 );
37810 for ndim in [-1, 1, 4, 5] {
37811 descriptor.ndim = ndim;
37812 assert!(unsafe { semantic_tensor_metadata(&descriptor) }.is_err());
37814 }
37815 }
37816
37817 #[test]
37818 fn publication_material_empty_model_buffer_keeps_zero_capacity() {
37819 for role in 18..=20 {
37820 let mut material = publication_material_sample();
37821 let layout = material.layouts.get_mut(&(role, 0)).unwrap();
37822 layout.rank = 3;
37823 layout.dimensions = [2, 0, 3, 0];
37824 layout.strides_bytes = [12, 12, 4, 0];
37825 let empty = *layout;
37826 let buffer = material
37827 .ranges
37828 .iter_mut()
37829 .find(|item| item.range.role == role)
37830 .unwrap();
37831 buffer.bytes.clear();
37832 buffer.capacity = 0;
37833 buffer.range.length_bytes = 0;
37834 let (allocation, offset) = material.model_memory.location(role, 0).unwrap();
37835 assert_eq!(offset, 0);
37836 material.model_allocations[allocation].clear();
37837 material.model_memory.allocation_bytes[allocation] = 0;
37838 material
37839 .model_memory
37840 .storages
37841 .iter_mut()
37842 .find(|storage| storage.allocation == allocation as u64)
37843 .unwrap()
37844 .span_bytes = 0;
37845 buffer.range.backing_digest = Identity256::from_bytes(Sha256::digest(b"").into());
37846 let table = material
37847 .ranges
37848 .iter_mut()
37849 .find(|item| item.range.role == 55)
37850 .unwrap();
37851 table.bytes = tensor_table_bytes(
37852 &material.layouts.values().copied().collect::<Vec<_>>(),
37853 false,
37854 &[],
37855 )
37856 .unwrap();
37857 table.range.digest = table.original_record_digest();
37858 publication_material_sample_runtime(&mut material);
37859 material.bank.header.descriptor_digest = material.original_descriptor_digest();
37860 let encoded = material.encode().unwrap();
37861 let restored = PublicationMaterial::decode(&encoded).unwrap();
37862 assert_eq!(restored.layouts[&(role, 0)], empty);
37863 let actual = restored
37864 .ranges
37865 .iter()
37866 .find(|item| item.range.role == role)
37867 .unwrap();
37868 assert!(actual.bytes.is_empty());
37869 assert_eq!(actual.capacity, 0);
37870 assert_eq!(tensor_layout_bytes(&empty).unwrap(), 0);
37871 assert!(tensor_copy_plan(&empty, &empty).unwrap().is_empty());
37872 assert_eq!(restored.encode().unwrap(), encoded);
37873 for (capacity, begin, end) in [(1, 0, 0), (0, 1, 1), (0, 0, 1)] {
37874 let buffer = material
37875 .ranges
37876 .iter_mut()
37877 .find(|item| item.range.role == role)
37878 .unwrap();
37879 buffer.capacity = capacity;
37880 buffer.range.logical_begin = begin;
37881 buffer.range.logical_end = end;
37882 publication_material_sample_runtime(&mut material);
37883 material.bank.header.descriptor_digest = material.original_descriptor_digest();
37884 assert!(
37885 material.encode().is_err(),
37886 "empty buffer accepted a fictitious capacity or interval"
37887 );
37888 }
37889 let buffer = material
37890 .ranges
37891 .iter_mut()
37892 .find(|item| item.range.role == role)
37893 .unwrap();
37894 buffer.capacity = 0;
37895 buffer.range.logical_begin = 0;
37896 buffer.range.logical_end = 0;
37897 publication_material_sample_runtime(&mut material);
37898 material.bank.header.descriptor_digest = material.original_descriptor_digest();
37899 material.layouts.get_mut(&(role, 0)).unwrap().dimensions[1] = 1;
37900 assert!(
37901 material.encode().is_err(),
37902 "nonempty model cells acquired zero capacity"
37903 );
37904 }
37905 }
37906
37907 #[test]
37908 fn feedback_payload_preserves_qualifiers_without_service_headers() {
37909 use crate::semantic_hypergraph::SemanticRecordEncoding;
37910 use crate::SemanticTypedRecord;
37911 use xlog_core::RelId;
37912
37913 let atom = |header: u8, value: u32| {
37914 let mut bytes = vec![header; 55];
37915 bytes.extend_from_slice(&17u32.to_le_bytes());
37916 bytes.extend_from_slice(&1u32.to_le_bytes());
37917 let start = bytes.len();
37918 bytes.push(1); bytes.extend_from_slice(&value.to_le_bytes());
37920 let end = bytes.len();
37921 SemanticRecordEncoding {
37922 bytes,
37923 arguments: std::iter::once(start..end).collect(),
37924 }
37925 };
37926 let record = |qualifiers| SemanticTypedRecord {
37927 predicate: RelId(17),
37928 arguments: vec![crate::SemanticArgument::U32(1)],
37929 qualifiers,
37930 };
37931 let records = SemanticAdmissionRecords {
37932 predicates: vec![],
37933 records: vec![record(vec![1, 2]), record(vec![]), record(vec![])],
37934 supports: vec![],
37935 };
37936 let encoded = vec![atom(0xA5, 1), atom(0xA5, 2), atom(0xA5, 3)];
37937 let payload = feedback_statement_payload(&records, &encoded, 0).unwrap();
37938 let changed_headers = vec![atom(0x5A, 1), atom(0x5A, 2), atom(0x5A, 3)];
37939 assert_eq!(
37940 payload,
37941 feedback_statement_payload(&records, &changed_headers, 0).unwrap()
37942 );
37943 assert_eq!(&payload[..8], &13u64.to_le_bytes());
37944 assert_eq!(&payload[8..12], &17u32.to_le_bytes());
37945 assert_eq!(&payload[21..25], &2u32.to_le_bytes());
37946 let changed_values = vec![atom(0xA5, 1), atom(0xA5, 9), atom(0xA5, 3)];
37947 assert_ne!(
37948 payload,
37949 feedback_statement_payload(&records, &changed_values, 0).unwrap()
37950 );
37951 let mut reordered = records;
37952 reordered.records[0].qualifiers.reverse();
37953 assert_ne!(
37954 payload,
37955 feedback_statement_payload(&reordered, &encoded, 0).unwrap()
37956 );
37957 }
37958
37959 #[test]
37960 fn publication_tensor_layout_keeps_dtype_distinct_from_byte_width() {
37961 assert_eq!(size_of::<SemanticTensorLayout>(), 112);
37962 }
37963
37964 fn source_rows() -> [SourceSlot; 32] {
37965 let mut rows = [SourceSlot::default(); 32];
37966 rows[5] = SourceSlot {
37968 token: 40,
37969 logical_position: 0,
37970 kind: 1,
37971 provenance: 1,
37972 valid: 1,
37973 committed: 0,
37974 recomputed: 0,
37975 provenance_record: 0,
37976 };
37977 rows[1] = SourceSlot {
37978 token: MASK_TOKEN as u64,
37979 logical_position: 1,
37980 kind: 2,
37981 provenance: 0,
37982 valid: 1,
37983 committed: 0,
37984 recomputed: 0,
37985 provenance_record: 0,
37986 };
37987 rows[12] = SourceSlot {
37988 token: 42,
37989 logical_position: 2,
37990 kind: 1,
37991 provenance: 2,
37992 valid: 1,
37993 committed: 0,
37994 recomputed: 0,
37995 provenance_record: 2,
37996 };
37997 rows
37998 }
37999
38000 #[test]
38001 fn initial_source_ledger_derives_tokens_and_private_provenance_without_changing_geometry() {
38002 let mut ring = [SourceSlot::default(); 32];
38003 ring[7] = SourceSlot {
38004 token: 41,
38005 logical_position: 3,
38006 kind: 1,
38007 provenance: 1,
38008 valid: 1,
38009 ..SourceSlot::default()
38010 };
38011 ring[2] = SourceSlot {
38012 token: MASK_TOKEN as u64,
38013 logical_position: 4,
38014 kind: 2,
38015 valid: 1,
38016 ..SourceSlot::default()
38017 };
38018 let prefix = vec![SourceSlot {
38019 token: 40,
38020 logical_position: 0,
38021 kind: 1,
38022 provenance: 1,
38023 valid: 1,
38024 committed: 1,
38025 ..SourceSlot::default()
38026 }];
38027 let sources = [SemanticObservedSource {
38028 identity: "observation".into(),
38029 tokens: vec![40, 41],
38030 origin: b"complete admitted observation and manifest".to_vec(),
38031 }];
38032 let mapping = [
38033 SemanticSourceMapping {
38034 source: "observation".into(),
38035 offset: 0,
38036 logical_position: 0,
38037 },
38038 SemanticSourceMapping {
38039 source: "observation".into(),
38040 offset: 1,
38041 logical_position: 3,
38042 },
38043 ];
38044 let (actual, committed, ledger) = initial_source_ledger(
38045 ring,
38046 prefix.clone(),
38047 &sources,
38048 &mapping,
38049 b"complete task authority",
38050 3,
38051 34,
38052 )
38053 .unwrap();
38054 assert_eq!(
38055 (
38056 actual[7].token,
38057 actual[7].logical_position,
38058 actual[7].provenance_record
38059 ),
38060 (41, 3, 1)
38061 );
38062 assert_eq!(committed[0].provenance_record, 0);
38063 assert_eq!(actual[2].provenance, 0);
38064 assert_eq!(ledger.bytes.len(), 2 * size_of::<TokenProvenance>());
38065 assert_eq!(ledger.capacity_bytes, 34 * size_of::<TokenProvenance>());
38066 let record = unsafe {
38068 ledger
38069 .bytes
38070 .as_ptr()
38071 .add(size_of::<TokenProvenance>())
38072 .cast::<TokenProvenance>()
38073 .read_unaligned()
38074 };
38075 assert_eq!(
38076 (
38077 record.source_slot,
38078 record.logical_position,
38079 record.token,
38080 record.ordinal,
38081 record.authority_generation
38082 ),
38083 (7, 3, 41, 1, 3)
38084 );
38085 assert_eq!(record.action_receipt_digest, Identity256::default());
38086 assert_ne!(record.origin_logical_digest, Identity256::default());
38087 assert_ne!(record.authority_closure_digest, Identity256::default());
38088 assert_ne!(record.record_digest, Identity256::default());
38089 for field in 0..7 {
38090 let mut changed = ring;
38091 let mut links = mapping.to_vec();
38092 match field {
38093 0 => changed[7].token = 42,
38094 1 => changed[7].provenance = 2,
38095 2 => changed[7].provenance_record = 99,
38096 3 => links[1].offset = 2,
38097 4 => links[1].logical_position = 4,
38098 5 => links[1].source = "foreign".into(),
38099 _ => links[1].logical_position = 0,
38100 }
38101 assert!(
38102 initial_source_ledger(
38103 changed,
38104 prefix.clone(),
38105 &sources,
38106 &links,
38107 b"complete task authority",
38108 3,
38109 34
38110 )
38111 .is_err(),
38112 "mutation {field}"
38113 );
38114 }
38115 }
38116
38117 #[test]
38118 fn initial_source_layout_preserves_admitted_tokens_across_prefix_and_ring() {
38119 let sources = [SemanticObservedSource {
38120 identity: "observation".into(),
38121 tokens: (0..40).collect(),
38122 origin: b"complete admitted observation and manifest".to_vec(),
38123 }];
38124 let mapping = (0..40)
38125 .map(|position| SemanticSourceMapping {
38126 source: "observation".into(),
38127 offset: position,
38128 logical_position: position,
38129 })
38130 .collect::<Vec<_>>();
38131 let layout = initial_source_layout(
38132 &sources,
38133 &mapping,
38134 b"complete task authority",
38135 3,
38136 72,
38137 64,
38138 3,
38139 262144,
38140 248000,
38141 )
38142 .unwrap();
38143 assert_eq!(layout.prefill_tokens, (0..8).collect::<Vec<_>>());
38144 assert_eq!(layout.prefix.len(), 8);
38145 assert_eq!(layout.prefix[7].token, 7);
38146 assert_eq!(layout.prefix[7].committed, 1);
38147 assert_eq!(layout.source[0].token, 8);
38148 assert_eq!(layout.source[0].logical_position, 8);
38149 assert_eq!(layout.source[31].token, 39);
38150 assert_eq!(layout.source[31].logical_position, 39);
38151 assert_eq!(layout.source[31].committed, 0);
38152 assert_eq!(layout.ring_head, 0);
38153 assert_eq!(
38154 validate_text_parent(&layout.source, 8, 64, 3, 262144, layout.ring_head, 40).unwrap(),
38155 40
38156 );
38157 }
38158
38159 #[test]
38160 fn short_admitted_source_needs_no_model_prefill_stage() {
38161 let sources = [SemanticObservedSource {
38162 identity: "observation".into(),
38163 tokens: vec![7, 8],
38164 origin: b"complete admitted observation".to_vec(),
38165 }];
38166 let mapping = (0..2)
38167 .map(|position| SemanticSourceMapping {
38168 source: "observation".into(),
38169 offset: position,
38170 logical_position: position,
38171 })
38172 .collect::<Vec<_>>();
38173 let layout = initial_source_layout(
38174 &sources,
38175 &mapping,
38176 b"complete task authority",
38177 1,
38178 64,
38179 64,
38180 2,
38181 262144,
38182 248000,
38183 )
38184 .unwrap();
38185 assert!(layout.prefix.is_empty());
38186 assert!(layout.prefill_tokens.is_empty());
38187 assert_eq!(layout.source[0].token, 7);
38188 assert_eq!(layout.source[1].token, 8);
38189 assert_eq!(layout.ring_head, 2);
38190 assert_eq!(
38191 validate_text_parent(&layout.source, 0, 64, 2, 262144, 2, 2).unwrap(),
38192 2
38193 );
38194 }
38195
38196 #[test]
38197 fn initial_source_layout_rejects_uncovered_prefix_and_over_capacity() {
38198 let sources = [SemanticObservedSource {
38199 identity: "observation".into(),
38200 tokens: (0..40).collect(),
38201 origin: b"complete admitted observation and manifest".to_vec(),
38202 }];
38203 let mut mapping = (0..40)
38204 .map(|position| SemanticSourceMapping {
38205 source: "observation".into(),
38206 offset: position,
38207 logical_position: position,
38208 })
38209 .collect::<Vec<_>>();
38210 assert!(initial_source_layout(
38211 &sources,
38212 &mapping,
38213 b"complete task authority",
38214 3,
38215 72,
38216 7,
38217 3,
38218 262144,
38219 248000,
38220 )
38221 .is_err());
38222 assert!(initial_source_layout(
38223 &sources,
38224 &mapping,
38225 b"complete task authority",
38226 3,
38227 72,
38228 8,
38229 3,
38230 262144,
38231 248000,
38232 )
38233 .is_err());
38234 mapping.remove(3);
38235 assert!(initial_source_layout(
38236 &sources,
38237 &mapping,
38238 b"complete task authority",
38239 3,
38240 72,
38241 64,
38242 3,
38243 262144,
38244 248000,
38245 )
38246 .is_err());
38247 }
38248
38249 #[test]
38250 fn initial_prefill_input_requires_the_exact_model_token_tensor_layout() {
38251 let expected = SemanticTensorLayout {
38252 role: 0,
38253 index: 0,
38254 element_bytes: 8,
38255 scalar_type: 7,
38256 rank: 2,
38257 logical_axis: 1,
38258 dimensions: [1, 8, 0, 0],
38259 strides_bytes: [64, 8, 0, 0],
38260 };
38261 assert!(validate_initial_prefill_input_layout(&expected, 8).is_ok());
38262 for changed in [
38263 SemanticTensorLayout {
38264 scalar_type: 3,
38265 ..expected
38266 },
38267 SemanticTensorLayout {
38268 dimensions: [1, 7, 0, 0],
38269 ..expected
38270 },
38271 SemanticTensorLayout {
38272 dimensions: [2, 8, 0, 0],
38273 ..expected
38274 },
38275 SemanticTensorLayout {
38276 strides_bytes: [64, 16, 0, 0],
38277 ..expected
38278 },
38279 ] {
38280 assert!(validate_initial_prefill_input_layout(&changed, 8).is_err());
38281 }
38282 assert!(validate_initial_prefill_input_layout(&expected, 0).is_err());
38283 }
38284
38285 #[test]
38286 fn initial_prefill_content_witness_rejects_foreign_or_stale_owners() {
38287 let issuer = Arc::new(());
38288 let scope = Arc::new(());
38289 let identity = Identity256::from_bytes([7; 32]);
38290 let witness = SemanticInitialPrefillContentWitness {
38291 issuer: Arc::clone(&issuer),
38292 scope: Arc::clone(&scope),
38293 task_identity: identity,
38294 task_epoch: 3,
38295 model_generation: 5,
38296 slot: InitialPrefillContentSlot::Captured(1),
38297 };
38298 assert!(witness.matches(&issuer, &scope, identity, 3, 5, 2));
38299 assert!(!witness.matches(&Arc::new(()), &scope, identity, 3, 5, 2));
38300 assert!(!witness.matches(&issuer, &Arc::new(()), identity, 3, 5, 2));
38301 assert!(!witness.matches(&issuer, &scope, Identity256::from_bytes([8; 32]), 3, 5, 2,));
38302 assert!(!witness.matches(&issuer, &scope, identity, 4, 5, 2));
38303 assert!(!witness.matches(&issuer, &scope, identity, 3, 6, 2));
38304 assert!(!witness.matches(&issuer, &scope, identity, 3, 5, 1));
38305 let model = SemanticInitialPrefillContentWitness {
38306 slot: InitialPrefillContentSlot::Model,
38307 ..witness
38308 };
38309 assert!(model.matches(&issuer, &scope, identity, 3, 5, 0));
38310 }
38311
38312 #[test]
38313 fn initial_prefill_parent_can_add_only_native_source_ledger_indices() {
38314 let expected = SemanticTextSlot {
38315 token: 17,
38316 logical_position: 3,
38317 kind: 1,
38318 provenance: 1,
38319 valid: 1,
38320 committed: 1,
38321 ..SemanticTextSlot::default()
38322 };
38323 let actual = SemanticTextSlot {
38324 provenance_record: 9,
38325 ..expected
38326 };
38327 assert!(same_initial_source_rows(&[expected], &[actual]));
38328 assert!(!same_initial_source_rows(
38329 &[expected],
38330 &[SemanticTextSlot {
38331 token: 18,
38332 ..actual
38333 }],
38334 ));
38335 assert!(!same_initial_source_rows(&[expected], &[]));
38336 }
38337
38338 #[test]
38339 fn cold_text_parent_derives_only_contiguous_acquired_filled_coverage() {
38340 let rows = source_rows();
38341 assert_eq!(
38342 validate_text_parent(&rows, 0, 64, 2, 262144, 0, 3).unwrap(),
38343 1
38344 );
38345 assert_eq!(rows[1].kind, 2);
38346 assert_eq!(rows[12].logical_position, 2);
38347 assert_eq!(size_of::<SourceSlot>(), 64);
38348 }
38349
38350 #[test]
38351 fn cold_mask_source_keeps_the_sentinel_without_fabricated_token_provenance() {
38352 let mut rows = [SourceSlot::default(); 32];
38353 rows[7] = SourceSlot {
38354 token: 248078,
38355 kind: 2,
38356 valid: 1,
38357 ..SourceSlot::default()
38358 };
38359 assert_eq!(
38360 validate_text_parent(&rows, 0, 64, 2, 262144, 0, 0).unwrap(),
38361 0
38362 );
38363 rows[7].token = 0;
38364 assert!(validate_text_parent(&rows, 0, 64, 2, 262144, 0, 0).is_err());
38365 rows[7].token = 248078;
38366 rows[7].provenance_record = 1;
38367 assert!(validate_text_parent(&rows, 0, 64, 2, 262144, 0, 2).is_err());
38368 }
38369
38370 #[test]
38371 fn cold_text_parent_rejects_inconsistent_kind_and_source_metadata() {
38372 for field in 0..7 {
38373 let mut rows = source_rows();
38374 match field {
38375 0 => rows[1].provenance = 1,
38376 1 => rows[1].recomputed = 1,
38377 2 => rows[5].valid = 0,
38378 3 => rows[5].committed = 1,
38379 4 => rows[12].logical_position = 0,
38380 5 => rows[0].logical_position = 8,
38381 _ => rows[1].provenance_record = 3,
38382 }
38383 assert!(validate_text_parent(&rows, 0, 64, 2, 262144, 0, 3).is_err());
38384 }
38385 }
38386
38387 #[test]
38388 fn cold_text_parent_checks_prefix_and_reserved_position_capacity() {
38389 let rows = source_rows();
38390 assert!(validate_text_parent(&rows, 0, 0, 2, 262144, 0, 3).is_err());
38391 assert!(validate_text_parent(&rows, 1, 64, 2, 262144, 0, 3).is_err());
38392 assert!(validate_text_parent(&rows, 0, 64, 2, 97, 0, 3).is_err());
38393 assert!(validate_text_parent(&rows, 0, 64, 2, 262144, 32, 3).is_err());
38394 assert!(validate_text_parent(&rows, 0, u64::MAX, 2, 262144, 0, 3).is_err());
38395 }
38396}
38397
38398#[cfg(test)]
38399pub(crate) mod task_binding_tests {
38400 use super::*;
38401 use crate::{
38402 SemanticArgument, SemanticPolarity, SemanticPredicateRecord, SemanticSupportRecord,
38403 SemanticTypedRecord,
38404 };
38405 use xlog_core::{RelId, ScalarType, Schema};
38406
38407 #[derive(Debug)]
38408 struct ArithmeticProgram;
38409
38410 impl SemanticTaskProgram for ArithmeticProgram {
38411 fn observe(
38412 &self,
38413 _provider: Arc<CudaKernelProvider>,
38414 ) -> Result<SemanticTaskObservation, SemanticTransitionError> {
38415 Ok(arithmetic_observation())
38416 }
38417 }
38418
38419 pub(crate) fn arithmetic_observation() -> SemanticTaskObservation {
38420 let inputs = [[1u32, 1u32], [0u32, 1u32], [1u32, 0u32]];
38421 let results = inputs.map(|[left, right]| (left + right) / 2);
38422 SemanticTaskObservation {
38423 program_source: b"fn observe(left: u32, right: u32) -> u32 { (left + right) / 2 }"
38424 .to_vec(),
38425 input_bytes: inputs
38426 .into_iter()
38427 .flatten()
38428 .flat_map(u32::to_le_bytes)
38429 .collect(),
38430 result_bytes: results.into_iter().flat_map(u32::to_le_bytes).collect(),
38431 expected_truth: results.map(|result| {
38432 if result == 1 {
38433 crate::SemanticTruth::True
38434 } else {
38435 crate::SemanticTruth::False
38436 }
38437 }),
38438 }
38439 }
38440
38441 pub(crate) fn task_spec(
38442 statement_records: [u32; 3],
38443 allowed_support_records: Vec<u32>,
38444 ) -> SemanticTaskEvaluationSpec {
38445 SemanticTaskEvaluationSpec {
38446 statement_records,
38447 allowed_support_records,
38448 program: Arc::new(ArithmeticProgram),
38449 scoring: SemanticTaskScoring {
38450 correct_weight: 14,
38451 all_correct_weight: 7,
38452 work_weight: 1,
38453 improvement_weight: 45,
38454 refusal_weight: 15,
38455 spent_weight: 1,
38456 },
38457 priority_levels: Vec::new(),
38458 admissible_truth_masks: [7, 7, 7],
38459 actor_eligible: true,
38460 training_domain: None,
38461 }
38462 }
38463
38464 fn carry_records() -> SemanticAdmissionRecords {
38465 let mut records = SemanticAdmissionRecords {
38466 predicates: vec![SemanticPredicateRecord {
38467 predicate: RelId(17),
38468 role: SemanticRecordRole::Statement,
38469 schema: Schema::new(vec![
38470 ("left".into(), ScalarType::U32),
38471 ("right".into(), ScalarType::U32),
38472 ])
38473 .with_sort_labels(vec!["bit".into(), "bit".into()])
38474 .unwrap(),
38475 }],
38476 records: vec![
38477 SemanticTypedRecord {
38478 predicate: RelId(17),
38479 arguments: vec![SemanticArgument::U32(1), SemanticArgument::U32(1)],
38480 qualifiers: vec![],
38481 },
38482 SemanticTypedRecord {
38483 predicate: RelId(17),
38484 arguments: vec![SemanticArgument::U32(0), SemanticArgument::U32(1)],
38485 qualifiers: vec![],
38486 },
38487 ],
38488 supports: vec![SemanticSupportRecord {
38489 statement: 0,
38490 polarity: SemanticPolarity::Pro,
38491 provenance: 2,
38492 source: 3,
38493 context: 4,
38494 scope: 5,
38495 }],
38496 };
38497 for (index, role) in [
38498 SemanticRecordRole::Provenance,
38499 SemanticRecordRole::Source,
38500 SemanticRecordRole::Context,
38501 SemanticRecordRole::Scope,
38502 ]
38503 .into_iter()
38504 .enumerate()
38505 {
38506 let predicate = RelId(18 + index as u32);
38507 records.predicates.push(SemanticPredicateRecord {
38508 predicate,
38509 role,
38510 schema: Schema::new(vec![]),
38511 });
38512 records.records.push(SemanticTypedRecord {
38513 predicate,
38514 arguments: vec![],
38515 qualifiers: vec![],
38516 });
38517 }
38518 records
38519 }
38520
38521 #[test]
38522 fn task_query_validation_does_not_interpret_argument_values() {
38523 let mut records = carry_records();
38524 records.records[0].arguments = vec![SemanticArgument::U32(17), SemanticArgument::U32(23)];
38525 task_spec([0, 1, 1], vec![0])
38526 .validate_records(&records)
38527 .unwrap();
38528 }
38529
38530 #[test]
38531 fn application_observer_retains_input_and_output_bytes() {
38532 let observation = arithmetic_observation();
38533 assert_eq!(
38534 observation.input_bytes,
38535 [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,]
38536 );
38537 assert_eq!(
38538 observation.result_bytes,
38539 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
38540 );
38541 assert_eq!(
38542 observation.expected_truth,
38543 [
38544 crate::SemanticTruth::True,
38545 crate::SemanticTruth::False,
38546 crate::SemanticTruth::False,
38547 ]
38548 );
38549 }
38550
38551 #[test]
38552 fn cold_content_matches_final_task_without_scoring_or_authority_inputs() {
38553 let admission = crate::semantic_hypergraph::tests::admit_material_records(carry_records());
38554 let cold = TaskEvaluationBinding::cold_content(
38555 &admission,
38556 [0, 1, 1],
38557 &[0],
38558 None,
38559 arithmetic_observation(),
38560 )
38561 .unwrap();
38562 let mut spec = task_spec([0, 1, 1], vec![0]);
38563 let bound = TaskEvaluationBinding::bind(&admission, spec.clone(), arithmetic_observation())
38564 .unwrap();
38565 assert_eq!(cold, bound.content());
38566
38567 spec.scoring.correct_weight += 1;
38568 spec.actor_eligible = false;
38569 assert_eq!(
38570 cold,
38571 TaskEvaluationBinding::bind(&admission, spec, arithmetic_observation())
38572 .unwrap()
38573 .content(),
38574 );
38575
38576 let mut changed = arithmetic_observation();
38577 changed.result_bytes.push(0);
38578 assert_ne!(
38579 cold,
38580 TaskEvaluationBinding::cold_content(&admission, [0, 1, 1], &[0], None, changed)
38581 .unwrap(),
38582 );
38583
38584 let mut changed_query = arithmetic_observation();
38585 changed_query.input_bytes.push(0);
38586 assert_ne!(
38587 cold,
38588 TaskEvaluationBinding::cold_content(&admission, [0, 1, 1], &[0], None, changed_query,)
38589 .unwrap(),
38590 );
38591 }
38592
38593 #[test]
38594 #[cfg(feature = "semantic-policy")]
38595 fn task_result_material_binds_native_observer_program_and_results() {
38596 let admission = crate::semantic_hypergraph::tests::admit_material_records(carry_records());
38597 let original_observation = arithmetic_observation();
38598 let binding = TaskEvaluationBinding::bind(
38599 &admission,
38600 task_spec([0, 1, 1], vec![0]),
38601 arithmetic_observation(),
38602 )
38603 .unwrap();
38604 let material = binding.completed_result_material();
38605 assert_eq!(
38606 Sha256::digest(&material.bytes).as_slice(),
38607 material.identity.as_bytes()
38608 );
38609 assert!(material
38610 .bytes
38611 .windows(original_observation.result_bytes.len())
38612 .any(|part| part == original_observation.result_bytes));
38613
38614 let mut changed = original_observation;
38615 changed.program_source.push(b' ');
38616 let changed =
38617 TaskEvaluationBinding::bind(&admission, task_spec([0, 1, 1], vec![0]), changed)
38618 .unwrap();
38619 assert_ne!(
38620 changed.completed_result_material().identity,
38621 material.identity
38622 );
38623 }
38624
38625 #[test]
38626 fn task_binding_identity_seals_observer_execution_and_configuration() {
38627 let admission = crate::semantic_hypergraph::tests::admit_material_records(carry_records());
38628 let identity = |spec, observation| {
38629 TaskEvaluationBinding::bind(&admission, spec, observation)
38630 .unwrap()
38631 .identity()
38632 };
38633 let original = identity(task_spec([0, 1, 1], vec![0]), arithmetic_observation());
38634 assert_eq!(
38635 original,
38636 identity(task_spec([0, 1, 1], vec![0]), arithmetic_observation()),
38637 "independent bindings with identical bytes must have the same identity"
38638 );
38639 for changed in 0..15 {
38640 let mut spec = task_spec([0, 1, 1], vec![0]);
38641 let mut observation = arithmetic_observation();
38642 let field = match changed {
38643 0 => {
38644 observation.program_source.push(b' ');
38645 "program source"
38646 }
38647 1 => {
38648 observation.input_bytes.push(0);
38649 "observer inputs"
38650 }
38651 2 => {
38652 observation.result_bytes.push(0);
38653 "observer results"
38654 }
38655 3 => {
38656 observation.expected_truth[0] = crate::SemanticTruth::Both;
38657 "first expected truth"
38658 }
38659 4 => {
38660 observation.expected_truth[1] = crate::SemanticTruth::Neither;
38661 "second expected truth"
38662 }
38663 5 => {
38664 observation.expected_truth[2] = crate::SemanticTruth::Neither;
38665 "third expected truth"
38666 }
38667 6 => {
38668 spec.scoring.correct_weight += 1;
38669 "correct weight"
38670 }
38671 7 => {
38672 spec.scoring.all_correct_weight += 1;
38673 "all-correct weight"
38674 }
38675 8 => {
38676 spec.scoring.work_weight += 1;
38677 "work weight"
38678 }
38679 9 => {
38680 spec.scoring.improvement_weight += 1;
38681 "improvement weight"
38682 }
38683 10 => {
38684 spec.scoring.refusal_weight += 1;
38685 "refusal weight"
38686 }
38687 11 => {
38688 spec.scoring.spent_weight += 1;
38689 "spent weight"
38690 }
38691 12 => {
38692 spec.admissible_truth_masks[0] = 15;
38693 "first truth mask"
38694 }
38695 13 => {
38696 spec.admissible_truth_masks[1] = 15;
38697 "second truth mask"
38698 }
38699 _ => {
38700 spec.admissible_truth_masks[2] = 15;
38701 "third truth mask"
38702 }
38703 };
38704 assert_ne!(
38705 original,
38706 identity(spec, observation),
38707 "identity omitted {field}"
38708 );
38709 }
38710 }
38711
38712 #[test]
38713 fn task_truth_eligibility_requires_nonempty_four_valued_masks() {
38714 let admission = crate::semantic_hypergraph::tests::admit_material_records(carry_records());
38715 for slot in 0..3 {
38716 for mask in [0, 16, 128, 255] {
38717 let mut spec = task_spec([0, 1, 1], vec![0]);
38718 spec.admissible_truth_masks[slot] = mask;
38719 let result =
38720 TaskEvaluationBinding::bind(&admission, spec, arithmetic_observation());
38721 assert!(
38722 matches!(result, Err(SemanticTransitionError::InvalidInput { detail })
38723 if detail.contains("nonempty four-valued mask")),
38724 "slot {slot}, mask {mask}"
38725 );
38726 }
38727 for mask in 1..=15 {
38728 let mut spec = task_spec([0, 1, 1], vec![0]);
38729 spec.admissible_truth_masks[slot] = mask;
38730 TaskEvaluationBinding::bind(&admission, spec, arithmetic_observation()).unwrap();
38731 }
38732 }
38733 }
38734
38735 #[test]
38736 fn rule_codebook_covers_the_complete_admitted_binary_schema() {
38737 use crate::semantic_hypergraph::tests::{admit_material_records, root_material_records};
38738
38739 let admission = admit_material_records(root_material_records());
38740 let program = crate::SemanticProgramAdmission {
38741 predicate_count: 5,
38742 initial_facts: vec![],
38743 initial_rules: vec![],
38744 queries: [
38745 crate::SemanticProgramFact {
38746 predicate: 4,
38747 first: 1,
38748 second: 3,
38749 },
38750 crate::SemanticProgramFact {
38751 predicate: 4,
38752 first: 1,
38753 second: 4,
38754 },
38755 crate::SemanticProgramFact {
38756 predicate: 4,
38757 first: 4,
38758 second: 3,
38759 },
38760 ],
38761 };
38762 let generic = ActionCodebooks::derive(&admission, 1, None).unwrap();
38763 let books = ActionCodebooks::derive(&admission, 1, Some(&program)).unwrap();
38764 assert_eq!(books.targets[..generic.targets.len()], generic.targets);
38765 assert_eq!(
38766 books.targets[generic.targets.len()..]
38767 .iter()
38768 .filter_map(|descriptor| match descriptor {
38769 SemanticActionDescriptor::RulePredicate { predicate } => Some(*predicate),
38770 _ => None,
38771 })
38772 .collect::<Vec<_>>(),
38773 (0..5).collect::<Vec<_>>()
38774 );
38775 assert_eq!(books.qualifiers.len(), generic.qualifiers.len());
38776 assert_eq!(books.leaves.len(), generic.leaves.len());
38777 assert_eq!(books.operands[..generic.operands.len()], generic.operands);
38778 assert_eq!(
38779 books.operands[generic.operands.len()..]
38780 .iter()
38781 .filter_map(|descriptor| match descriptor {
38782 SemanticActionDescriptor::RulePredicate { predicate } => Some(*predicate),
38783 _ => None,
38784 })
38785 .collect::<Vec<_>>(),
38786 (0..5).collect::<Vec<_>>()
38787 );
38788 assert_eq!(
38789 books.operands[generic.operands.len()..]
38790 .iter()
38791 .filter_map(|descriptor| match descriptor {
38792 SemanticActionDescriptor::RuleVariable { index } => Some(*index),
38793 _ => None,
38794 })
38795 .collect::<Vec<_>>(),
38796 (0..4).collect::<Vec<_>>()
38797 );
38798 for field in 3..=10 {
38799 assert_eq!(
38800 books.components[32 + field].cardinality as usize,
38801 books.operands.len() + 1
38802 );
38803 }
38804 for field in 7..=10 {
38805 assert_eq!(generic.components[32 + field].cardinality, 1);
38806 }
38807 assert_ne!(books.binding.digest, generic.binding.digest);
38808
38809 let mut changed_program = program.clone();
38810 changed_program
38811 .initial_facts
38812 .push(crate::SemanticProgramFact {
38813 predicate: 0,
38814 first: 10,
38815 second: 11,
38816 });
38817 let changed = ActionCodebooks::derive(&admission, 1, Some(&changed_program)).unwrap();
38818 assert_ne!(books.binding.digest, changed.binding.digest);
38819
38820 let predicate = |index| generic.operands.len() as u32 + 1 + index;
38821 let variable = |index| generic.operands.len() as u32 + 6 + index;
38822 let mut choices = [0u32; 18];
38823 choices[0] = 1;
38824 choices[1] = 2;
38825 choices[2] = generic.targets.len() as u32 + 5;
38826 choices[3] = predicate(0);
38827 choices[4] = predicate(1);
38828 choices[5] = variable(0);
38829 choices[6] = variable(2);
38830 choices[7] = variable(0);
38831 choices[8] = variable(1);
38832 choices[9] = variable(1);
38833 choices[10] = variable(2);
38834 let decoded = books.decoded_rule_insertion(&program, &choices).unwrap();
38835 assert_eq!(decoded.rule.head_predicate, 4);
38836 assert_eq!(decoded.rule.head_variables, [0, 2]);
38837 assert!(decoded.bytes.starts_with(b"XLOG-DECODED-RULE-INSERTION\0"));
38838 choices[6] = variable(3);
38839 assert!(books.decoded_rule_insertion(&program, &choices).is_err());
38840 choices[6] = variable(2);
38841 choices[3] = 1;
38842 assert!(books.decoded_rule_insertion(&program, &choices).is_err());
38843
38844 let mut too_many_predicates = program;
38845 too_many_predicates.predicate_count = 65_536;
38846 assert!(ActionCodebooks::derive(&admission, 1, Some(&too_many_predicates)).is_err());
38847 }
38848
38849 #[test]
38850 fn action_leaf_categories_preserve_equal_original_supports() {
38851 use crate::semantic_hypergraph::tests::{admit_material_records, root_material_records};
38852 let mut records = root_material_records();
38853 records.supports.push(records.supports[0].clone());
38854 records.supports.push(records.supports[0].clone());
38855 records.supports.last_mut().unwrap().statement = 1;
38856 let original_count = records.supports.len();
38857 let admission = admit_material_records(records);
38858 let books = ActionCodebooks::derive(&admission, 1, None).unwrap();
38859 assert_eq!(books.leaves.len(), original_count);
38860 assert_eq!(books.words[7], original_count as u64 + 1);
38861 let mut seen = BTreeSet::new();
38862 for (category, meaning) in books.leaves.iter().enumerate() {
38863 let SemanticActionDescriptor::SupportEvent { source_record } = meaning else {
38864 panic!("wrong leaf meaning")
38865 };
38866 assert!(seen.insert(*source_record));
38867 assert_eq!(
38868 books.words[books.words[6] as usize + 18 * (category + 1) + 17],
38869 u64::from(*source_record)
38870 );
38871 }
38872 assert_eq!(seen, (0..original_count as u32).collect());
38873 let layout = SemanticPolicyLayout::from_components(&books.components).unwrap();
38874 assert_eq!(layout.fields[17].cardinality, original_count + 1);
38875 assert_eq!(layout.fields[17].embeddings.len(), original_count * 128);
38876 }
38877
38878 #[test]
38879 #[cfg(feature = "semantic-policy")]
38880 fn policy_producer_geometry_keeps_full_mask_rows_and_boolean_support() {
38881 let layouts = policy_producer_layouts(97, 129).unwrap();
38882 let metadata = TensorMetadata {
38883 device_type: 2,
38884 device_id: 0,
38885 dtype: crate::dlpack::DLDataType {
38886 code: 2,
38887 bits: 32,
38888 lanes: 1,
38889 },
38890 shape: &[32, TEXT_CARDINALITY as i64],
38891 strides: None,
38892 data: 4096,
38893 byte_offset: 4,
38894 };
38895 assert_eq!(
38896 validate_tensor_metadata(&layouts[0], &metadata, 0).unwrap(),
38897 (4100, 32 * TEXT_CARDINALITY * 4)
38898 );
38899 let mut malformed = metadata;
38900 malformed.shape = &[1, TEXT_CARDINALITY as i64];
38901 assert!(validate_tensor_metadata(&layouts[0], &malformed, 0).is_err());
38902 malformed.shape = &[32 * TEXT_CARDINALITY as i64];
38903 assert!(validate_tensor_metadata(&layouts[0], &malformed, 0).is_err());
38904 malformed.shape = &[32, TEXT_CARDINALITY as i64];
38905 malformed.strides = Some(&[TEXT_CARDINALITY as i64 + 1, 1]);
38906 assert!(validate_tensor_metadata(&layouts[0], &malformed, 0).is_err());
38907 let support = TensorMetadata {
38908 device_type: 2,
38909 device_id: 0,
38910 dtype: crate::dlpack::DLDataType {
38911 code: 6,
38912 bits: 8,
38913 lanes: 1,
38914 },
38915 shape: &[97],
38916 strides: Some(&[1]),
38917 data: 4096,
38918 byte_offset: 0,
38919 };
38920 assert_eq!(
38921 validate_tensor_metadata(&layouts[1], &support, 0).unwrap(),
38922 (4096, 97)
38923 );
38924 let mut wrong_dtype = support;
38925 wrong_dtype.dtype.code = 1;
38926 assert!(validate_tensor_metadata(&layouts[1], &wrong_dtype, 0).is_err());
38927 assert_eq!(layouts[2].dimensions, [129, 0, 0, 0]);
38928 }
38929
38930 #[test]
38931 fn policy_support_reserves_every_original_category_span() {
38932 use crate::semantic_hypergraph::tests::{admit_material_records, root_material_records};
38933 let admission = admit_material_records(root_material_records());
38934 let books = ActionCodebooks::derive(&admission, 1, None).unwrap();
38935 let (spans, cells) = books.support_layout();
38936 assert_eq!(spans.len(), COMPONENT_COUNT);
38937 let mut cursor = 0;
38938 for (span, component) in spans.iter().zip(&books.components) {
38939 assert_eq!(span.start, cursor);
38940 assert_eq!(span.start, component.offset as usize);
38941 assert_eq!(span.len(), component.cardinality as usize);
38942 cursor = span.end;
38943 }
38944 assert_eq!(cells, cursor);
38945 assert_eq!(cells, books.input_cells);
38946 for lane in 0..2 {
38947 for slot in 0..32 {
38948 assert_eq!(spans[lane * 68 + slot].len(), TEXT_CARDINALITY);
38949 }
38950 }
38951 }
38952
38953 #[test]
38954 fn action_codebooks_retain_typed_reconstruction_sources() {
38955 use crate::semantic_hypergraph::tests::{admit_material_records, root_material_records};
38956 let admission = admit_material_records(root_material_records());
38957 let books = ActionCodebooks::derive(&admission, 1, None).unwrap();
38958 assert_eq!(
38959 books.words[4] - books.words[2],
38960 6 * books.words[3],
38961 "operand bank lost original argument reconstruction references"
38962 );
38963 assert_eq!(
38964 books.words[6] - books.words[4],
38965 3 * books.words[5],
38966 "qualifier bank lost original bundle reconstruction references"
38967 );
38968 for (category, meaning) in books.operands.iter().enumerate() {
38969 let SemanticActionDescriptor::Operand { encoded_value, .. } = meaning else {
38970 panic!("wrong operand meaning")
38971 };
38972 let row = books.words[2] as usize + 6 * (category + 1);
38973 let source = &admission.encoded_records[books.words[row + 4] as usize];
38974 assert_eq!(
38975 &source.bytes[source.arguments[books.words[row + 5] as usize].clone()],
38976 encoded_value
38977 );
38978 }
38979 for (category, meaning) in books.qualifiers.iter().enumerate() {
38980 let SemanticActionDescriptor::QualifierBundle { records } = meaning else {
38981 panic!("wrong qualifier meaning")
38982 };
38983 let source = books.words[books.words[4] as usize + 3 * (category + 1) + 2];
38984 if records.is_empty() {
38985 assert_eq!(source, u64::from(u32::MAX));
38986 } else {
38987 assert_eq!(
38988 &admission.records().records[source as usize].qualifiers,
38989 records
38990 );
38991 }
38992 }
38993 }
38994
38995 #[cfg(feature = "semantic-policy")]
38996 #[test]
38997 fn completed_action_law_and_codebook_materials_match_native_bindings() {
38998 use crate::semantic_hypergraph::tests::{admit_material_records, root_material_records};
38999
39000 let catalogue = SemanticActionCatalogue::current();
39001 let law = catalogue.completed_material();
39002 assert_eq!(law.identity, catalogue.binding().digest);
39003 assert_eq!(law.bytes, catalogue.canonical_bytes());
39004 assert_eq!(
39005 Sha256::digest(&law.bytes).as_slice(),
39006 law.identity.as_bytes()
39007 );
39008
39009 let admission = admit_material_records(root_material_records());
39010 let books = ActionCodebooks::derive(&admission, 1, None).unwrap();
39011 let codebook = books.completed_material();
39012 assert_eq!(codebook.identity, books.binding.digest);
39013 assert_eq!(codebook.bytes, publication_abi_bytes(&books.words));
39014 assert_ne!(codebook.identity, law.identity);
39015 assert_ne!(codebook.bytes, law.bytes);
39016
39017 let roster = books.completed_roster_material();
39018 assert_eq!(
39019 Sha256::digest(&roster.bytes).as_slice(),
39020 roster.identity.as_bytes()
39021 );
39022 assert_eq!(
39023 &roster.bytes[b"xlog.semantic-action-roster.v1\0".len()
39024 ..b"xlog.semantic-action-roster.v1\0".len() + 32],
39025 books.binding.digest.as_bytes()
39026 );
39027 assert_eq!(books.components.len(), COMPONENT_COUNT);
39028 let roster_rows = &roster.bytes[b"xlog.semantic-action-roster.v1\0".len() + 32 + 8..];
39029 assert_eq!(roster_rows.len(), COMPONENT_COUNT * 7 * 8);
39030 for (row, component) in roster_rows.chunks_exact(7 * 8).zip(&books.components) {
39031 let values: Vec<u64> = row
39032 .chunks_exact(8)
39033 .map(|word| u64::from_le_bytes(word.try_into().unwrap()))
39034 .collect();
39035 assert_eq!(
39036 values,
39037 [
39038 component.offset,
39039 component.ordinal as u64,
39040 component.lane as u64,
39041 component.slot as u64,
39042 component.field as u64,
39043 component.kind as u64,
39044 component.cardinality as u64,
39045 ]
39046 );
39047 }
39048 assert_ne!(roster.identity, codebook.identity);
39049 let other_owner_books = ActionCodebooks::derive(&admission, 2, None).unwrap();
39050 assert_ne!(
39051 other_owner_books.completed_material().identity,
39052 codebook.identity
39053 );
39054 assert_ne!(
39055 other_owner_books.completed_roster_material().identity,
39056 roster.identity
39057 );
39058 }
39059
39060 #[test]
39061 #[cfg(feature = "semantic-policy")]
39062 fn decoded_support_insertion_matches_admitted_native_identity() {
39063 use crate::semantic_hypergraph::tests::{
39064 admit_material_records, reconstructed_material_statement, root_material_records,
39065 };
39066
39067 let admission = admit_material_records(root_material_records());
39068 let books = ActionCodebooks::derive(&admission, 1, None).unwrap();
39069 let mut choices = [0u32; 18];
39070 choices[0] = 1;
39071 choices[1] = 1;
39072 choices[2] = 1;
39073 choices[3] = 1;
39074 choices[11] = 1;
39075 choices[17] = 1;
39076 let decoded = books
39077 .decoded_support_insertion(&admission, &choices)
39078 .unwrap()
39079 .unwrap();
39080 let statement =
39081 reconstructed_material_statement(&admission, None, &decoded.reconstruction).unwrap();
39082 assert_eq!(decoded.statement, statement.identity());
39083 assert_eq!(
39084 decoded.support,
39085 admission
39086 .support_event(decoded.source_event)
39087 .unwrap()
39088 .identity(decoded.statement)
39089 );
39090 assert!(decoded
39091 .bytes
39092 .starts_with(b"XLOG-DECODED-SUPPORT-INSERTION\0"));
39093 choices[0] = 0;
39094 assert!(books
39095 .decoded_support_insertion(&admission, &choices)
39096 .unwrap()
39097 .is_none());
39098 }
39099
39100 #[test]
39101 #[cfg(feature = "semantic-policy")]
39102 fn completed_theory_delta_requires_an_attempted_native_insertion() {
39103 use crate::semantic_hypergraph::tests::{admit_material_records, root_material_records};
39104
39105 let admission = admit_material_records(root_material_records());
39106 let books = ActionCodebooks::derive(&admission, 1, None).unwrap();
39107 let mut choices = [0u32; 18];
39108 choices[0] = 1;
39109 choices[1] = 1;
39110 choices[2] = 1;
39111 choices[3] = 1;
39112 choices[11] = 1;
39113 choices[17] = 1;
39114 let decoded = books
39115 .decoded_support_insertion(&admission, &choices)
39116 .unwrap()
39117 .unwrap();
39118 let owner = Identity256::from_bytes([3; 32]);
39119 let predecessor = Identity256::from_bytes([4; 32]);
39120 let mut hard_decode = [0u64; 42];
39121 hard_decode[1] = 1;
39122 hard_decode[20..24].copy_from_slice(&identity_words(*decoded.statement.as_bytes()));
39123 hard_decode[24..28].copy_from_slice(&identity_words(*decoded.support.as_bytes()));
39124 let admission_receipt = [0u64; 42];
39125 let components = [SemanticTransitionReceipt::default(); 18];
39126 let delta = completed_theory_delta_for_slot(
39127 &books,
39128 &admission,
39129 None,
39130 Identity256::from_bytes([0; 32]),
39131 owner,
39132 predecessor,
39133 0,
39134 0,
39135 &choices,
39136 None,
39137 &hard_decode,
39138 &admission_receipt,
39139 &components,
39140 0,
39141 )
39142 .unwrap()
39143 .unwrap();
39144 assert_eq!(delta.kind, "fact");
39145 assert_eq!(delta.theory_generation, predecessor);
39146 assert_eq!(delta.verdict, "accepted");
39147 assert!(delta
39148 .delta
39149 .bytes
39150 .windows(decoded.bytes.len())
39151 .any(|part| part == decoded.bytes));
39152 hard_decode[20] ^= 1;
39153 assert!(completed_theory_delta_for_slot(
39154 &books,
39155 &admission,
39156 None,
39157 Identity256::from_bytes([0; 32]),
39158 owner,
39159 predecessor,
39160 0,
39161 0,
39162 &choices,
39163 None,
39164 &hard_decode,
39165 &admission_receipt,
39166 &components,
39167 0,
39168 )
39169 .is_err());
39170 hard_decode[1] = 0;
39171 assert!(completed_theory_delta_for_slot(
39172 &books,
39173 &admission,
39174 None,
39175 Identity256::from_bytes([0; 32]),
39176 owner,
39177 predecessor,
39178 0,
39179 0,
39180 &choices,
39181 None,
39182 &hard_decode,
39183 &admission_receipt,
39184 &components,
39185 1,
39186 )
39187 .unwrap()
39188 .is_none());
39189 }
39190
39191 #[test]
39192 #[cfg(feature = "semantic-policy")]
39193 fn decoded_rule_delta_seals_every_structural_field_and_prior_edit() {
39194 use crate::semantic_hypergraph::tests::{admit_material_records, root_material_records};
39195
39196 let admission = admit_material_records(root_material_records());
39197 let program = crate::SemanticProgramAdmission {
39198 predicate_count: 3,
39199 initial_facts: vec![],
39200 initial_rules: vec![],
39201 queries: [
39202 crate::SemanticProgramFact {
39203 predicate: 2,
39204 first: 1,
39205 second: 3,
39206 },
39207 crate::SemanticProgramFact {
39208 predicate: 2,
39209 first: 1,
39210 second: 4,
39211 },
39212 crate::SemanticProgramFact {
39213 predicate: 2,
39214 first: 4,
39215 second: 3,
39216 },
39217 ],
39218 };
39219 let generic = ActionCodebooks::derive(&admission, 1, None).unwrap();
39220 let books = ActionCodebooks::derive(&admission, 1, Some(&program)).unwrap();
39221 let predicate = |index| generic.operands.len() as u32 + 1 + index;
39222 let variable = |index| generic.operands.len() as u32 + 4 + index;
39223 let mut choices = [0u32; 18];
39224 choices[0] = 1;
39225 choices[1] = 2;
39226 choices[2] = generic.targets.len() as u32 + 3;
39227 choices[3] = predicate(0);
39228 choices[4] = predicate(1);
39229 choices[5] = variable(0);
39230 choices[6] = variable(2);
39231 choices[7] = variable(0);
39232 choices[8] = variable(1);
39233 choices[9] = variable(1);
39234 choices[10] = variable(2);
39235 let decoded = books.decoded_rule_insertion(&program, &choices).unwrap();
39236 assert_eq!(decoded.rule.head_predicate, 2);
39237 assert_eq!(decoded.rule.head_variables, [0, 2]);
39238 let owner = Identity256::from_bytes([3; 32]);
39239 let predecessor = Identity256::from_bytes([4; 32]);
39240 let task = Identity256::from_bytes([9; 32]);
39241 let mut hard_decode = [0u64; 42];
39242 hard_decode[1] = 3;
39243 hard_decode[2] = 1;
39244 hard_decode[4..8].copy_from_slice(&identity_words(*task.as_bytes()));
39245 hard_decode[8..12].copy_from_slice(&identity_words(*books.binding.digest.as_bytes()));
39246 hard_decode[12..22].copy_from_slice(&semantic_program_rule_words(decoded.rule));
39247 let admission_receipt = [0u64; 42];
39248 let components = [SemanticTransitionReceipt::default(); 18];
39249 let project = |receipt: &[u64; 42], slot, previous| {
39250 completed_theory_delta_for_slot(
39251 &books,
39252 &admission,
39253 Some(&program),
39254 task,
39255 owner,
39256 predecessor,
39257 0,
39258 slot,
39259 &choices,
39260 previous,
39261 receipt,
39262 &admission_receipt,
39263 &components,
39264 0,
39265 )
39266 };
39267 let delta = project(&hard_decode, 0, None).unwrap().unwrap();
39268 assert_eq!(delta.kind, "rule");
39269 assert_eq!(
39270 delta.theory_generation,
39271 ActionCodebooks::program_binding(&program)
39272 );
39273 for field in 12..22 {
39274 let mut changed = hard_decode;
39275 changed[field] ^= 1;
39276 assert!(
39277 project(&changed, 0, None).is_err(),
39278 "unsealed rule field {field}"
39279 );
39280 }
39281 let mut second = hard_decode;
39282 second[3] = 1;
39283 second[24] = 1;
39284 second[25..35].copy_from_slice(&semantic_program_rule_words(decoded.rule));
39285 let second_delta = project(&second, 1, Some(&choices)).unwrap().unwrap();
39286 assert_ne!(second_delta.theory_generation, delta.theory_generation);
39287 second[25] ^= 1;
39288 assert!(project(&second, 1, Some(&choices)).is_err());
39289 let mut invalid = choices;
39290 invalid[6] = variable(3);
39291 assert!(books.decoded_rule_insertion(&program, &invalid).is_err());
39292 invalid = choices;
39293 invalid[3] = 1;
39294 assert!(books.decoded_rule_insertion(&program, &invalid).is_err());
39295
39296 let mut fact_choices = [0u32; 18];
39297 fact_choices[0] = 1;
39298 fact_choices[1] = 1;
39299 fact_choices[2] = 1;
39300 fact_choices[3] = 1;
39301 fact_choices[11] = 1;
39302 fact_choices[17] = 1;
39303 let fact = books
39304 .decoded_support_insertion(&admission, &fact_choices)
39305 .unwrap()
39306 .unwrap();
39307 let mut fact_receipt = [0u64; 42];
39308 fact_receipt[1] = 1;
39309 fact_receipt[20..24].copy_from_slice(&identity_words(*fact.statement.as_bytes()));
39310 fact_receipt[24..28].copy_from_slice(&identity_words(*fact.support.as_bytes()));
39311 assert!(completed_theory_delta_for_slot(
39312 &books,
39313 &admission,
39314 Some(&program),
39315 task,
39316 owner,
39317 predecessor,
39318 0,
39319 0,
39320 &fact_choices,
39321 None,
39322 &fact_receipt,
39323 &admission_receipt,
39324 &components,
39325 0,
39326 )
39327 .is_err());
39328 }
39329
39330 #[test]
39331 fn program_query_receipts_bind_each_executed_query_to_the_program() {
39332 use crate::semantic_hypergraph::tests::{admit_material_records, root_material_records};
39333
39334 let admission = admit_material_records(root_material_records());
39335 let fact = crate::SemanticProgramFact {
39336 predicate: 0,
39337 first: 1,
39338 second: 2,
39339 };
39340 let program = crate::SemanticProgramAdmission {
39341 predicate_count: 1,
39342 initial_facts: vec![fact],
39343 initial_rules: vec![],
39344 queries: [fact; 3],
39345 };
39346 let books = ActionCodebooks::derive(&admission, 1, Some(&program)).unwrap();
39347 let task = Identity256::from_bytes([7; 32]);
39348 let edits = [[[0u32; 18]; 2]; 2];
39349 let mut state = DeviceState {
39350 binding_digest: books.binding.digest,
39351 ..DeviceState::default()
39352 };
39353 state.task_evaluation.query_count = 9;
39354 for slot in 0..3 {
39355 state.task_evaluation.facts[slot].truth = [1; 3];
39356 for query in 0..3 {
39357 let receipt = &mut state.task_evaluation.query_receipts[slot][query];
39358 receipt[1] = 0x5850524f47515545;
39359 receipt[2] = 1;
39360 receipt[3] = slot as u64;
39361 receipt[4] = query as u64;
39362 receipt[5..9].copy_from_slice(&identity_words(*task.as_bytes()));
39363 receipt[9..13].copy_from_slice(&identity_words(*books.binding.digest.as_bytes()));
39364 receipt[34..37].copy_from_slice(&[0, 1, 2]);
39365 receipt[38] = 1;
39366 receipt[41] = 1;
39367 }
39368 }
39369 assert!(validate_program_query_receipts(&program, task, &books, &state, &edits).is_ok());
39370 state.task_evaluation.query_receipts[2][1][34] = 1;
39371 assert!(validate_program_query_receipts(&program, task, &books, &state, &edits).is_err());
39372 state.task_evaluation.query_receipts[2][1][34] = 0;
39373 let mut fact_edit = edits;
39374 fact_edit[0][0][0] = 1;
39375 fact_edit[0][0][1] = 1;
39376 assert!(
39377 validate_program_query_receipts(&program, task, &books, &state, &fact_edit).is_err()
39378 );
39379
39380 let generic = ActionCodebooks::derive(&admission, 1, None).unwrap();
39381 let predicate = generic.operands.len() as u32 + 1;
39382 let first = predicate + 1;
39383 let second = first + 1;
39384 let mut rule_choice = [0u32; 18];
39385 rule_choice[0..11].copy_from_slice(&[
39386 1,
39387 2,
39388 generic.targets.len() as u32 + 1,
39389 predicate,
39390 predicate,
39391 first,
39392 second,
39393 first,
39394 second,
39395 first,
39396 second,
39397 ]);
39398 let rule = books
39399 .decoded_rule_insertion(&program, &rule_choice)
39400 .unwrap()
39401 .rule;
39402 let mut rule_edits = edits;
39403 rule_edits[0] = [rule_choice; 2];
39404 for query in 0..3 {
39405 let receipt = &mut state.task_evaluation.query_receipts[1][query];
39406 receipt[13] = 2;
39407 receipt[14..24].copy_from_slice(&semantic_program_rule_words(rule));
39408 receipt[24..34].copy_from_slice(&semantic_program_rule_words(rule));
39409 receipt[37] = 2;
39410 }
39411 state.work[0].edit_commands = 2;
39412 assert!(
39413 validate_program_query_receipts(&program, task, &books, &state, &rule_edits).is_ok()
39414 );
39415 state.task_evaluation.query_receipts[1][2][25] ^= 1;
39416 assert!(
39417 validate_program_query_receipts(&program, task, &books, &state, &rule_edits).is_err()
39418 );
39419
39420 let mut hard_decode = [0u64; 42];
39421 hard_decode[1] = 3;
39422 hard_decode[2] = 1;
39423 hard_decode[4..8].copy_from_slice(&identity_words(*task.as_bytes()));
39424 hard_decode[8..12].copy_from_slice(&identity_words(*books.binding.digest.as_bytes()));
39425 hard_decode[12..22].copy_from_slice(&semantic_program_rule_words(rule));
39426 hard_decode[22] = 1;
39427 assert_eq!(
39428 validated_rule_receipt(
39429 &books,
39430 &program,
39431 task,
39432 0,
39433 0,
39434 &rule_choice,
39435 None,
39436 &hard_decode,
39437 )
39438 .unwrap()
39439 .0
39440 .rule,
39441 rule
39442 );
39443 hard_decode[12] ^= 1;
39444 assert!(validated_rule_receipt(
39445 &books,
39446 &program,
39447 task,
39448 0,
39449 0,
39450 &rule_choice,
39451 None,
39452 &hard_decode,
39453 )
39454 .is_err());
39455 }
39456
39457 #[test]
39458 #[cfg(feature = "semantic-policy")]
39459 fn completed_task_scoring_matches_native_work_and_selection() {
39460 let scoring = task_spec([0, 1, 0], vec![]).scoring;
39461 let facts = [
39462 SemanticTaskFacts {
39463 g: 1,
39464 v: 14,
39465 eligible: 1,
39466 ..SemanticTaskFacts::default()
39467 },
39468 SemanticTaskFacts {
39469 g: 2,
39470 c: 3,
39471 v: 25,
39472 eligible: 1,
39473 ..SemanticTaskFacts::default()
39474 },
39475 SemanticTaskFacts::default(),
39476 ];
39477 let work = [
39478 SemanticTransitionWork {
39479 edit_commands: 1,
39480 added_supports: 1,
39481 defined_truth_changes: 1,
39482 },
39483 SemanticTransitionWork::default(),
39484 ];
39485 assert!(validate_completed_task_scoring(
39486 scoring,
39487 false,
39488 &[],
39489 &facts,
39490 &work,
39491 [0, 1],
39492 6,
39493 1,
39494 474,
39495 ));
39496 let mut changed = facts;
39497 changed[1].c = 2;
39498 assert!(!validate_completed_task_scoring(
39499 scoring,
39500 false,
39501 &[],
39502 &changed,
39503 &work,
39504 [0, 1],
39505 6,
39506 1,
39507 474,
39508 ));
39509 changed = facts;
39510 changed[1].v = 26;
39511 assert!(!validate_completed_task_scoring(
39512 scoring,
39513 false,
39514 &[],
39515 &changed,
39516 &work,
39517 [0, 1],
39518 6,
39519 1,
39520 474,
39521 ));
39522 assert!(!validate_completed_task_scoring(
39523 scoring,
39524 false,
39525 &[],
39526 &facts,
39527 &work,
39528 [0, 1],
39529 6,
39530 0,
39531 474,
39532 ));
39533 assert!(!validate_completed_task_scoring(
39534 scoring,
39535 false,
39536 &[],
39537 &facts,
39538 &work,
39539 [0, 1],
39540 6,
39541 1,
39542 475,
39543 ));
39544
39545 let mut refused_after_first_edit = facts;
39546 refused_after_first_edit[2].c = 3;
39547 refused_after_first_edit[2].v = -3;
39548 let partial_work = [work[0], work[0]];
39549 assert!(validate_completed_task_scoring(
39550 scoring,
39551 false,
39552 &[],
39553 &refused_after_first_edit,
39554 &partial_work,
39555 [0, 1],
39556 6,
39557 1,
39558 472,
39559 ));
39560
39561 let mut tied = facts;
39562 tied[1].g = 1;
39563 tied[1].c = 0;
39564 tied[1].v = 14;
39565 assert!(validate_completed_task_scoring(
39566 scoring,
39567 false,
39568 &[],
39569 &tied,
39570 &[SemanticTransitionWork::default(); 2],
39571 [0, 1],
39572 6,
39573 0,
39574 -21,
39575 ));
39576 }
39577
39578 #[test]
39579 #[cfg(feature = "semantic-policy")]
39580 fn task_priority_can_select_lower_value_and_negative_return() {
39581 let scoring = task_spec([0, 1, 0], vec![]).scoring;
39582 let priority_levels = [SemanticTaskPriorityLevel {
39583 goals: vec![SemanticTaskPriorityGoal {
39584 query: 0,
39585 target_truth: 1,
39586 weight: 1,
39587 }],
39588 }];
39589 let facts = [
39590 SemanticTaskFacts {
39591 g: 2,
39592 v: 28,
39593 eligible: 1,
39594 truth: [0, 1, 1],
39595 ..SemanticTaskFacts::default()
39596 },
39597 SemanticTaskFacts {
39598 g: 1,
39599 c: 1,
39600 v: 13,
39601 eligible: 1,
39602 truth: [1, 0, 0],
39603 ..SemanticTaskFacts::default()
39604 },
39605 SemanticTaskFacts::default(),
39606 ];
39607 let work = [
39608 SemanticTransitionWork {
39609 edit_commands: 1,
39610 ..SemanticTransitionWork::default()
39611 },
39612 SemanticTransitionWork::default(),
39613 ];
39614 let return_value = 45 * (13 - 28) - 3;
39615 assert!(return_value < -44);
39616 assert!(i64::from(return_value).abs() <= scoring.return_bound(false).unwrap());
39617 assert!(validate_completed_task_scoring(
39618 scoring,
39619 false,
39620 &priority_levels,
39621 &facts,
39622 &work,
39623 [0, 0],
39624 3,
39625 1,
39626 i64::from(return_value),
39627 ));
39628 }
39629
39630 #[test]
39631 #[cfg(feature = "semantic-policy")]
39632 fn completed_task_scoring_law_retains_coefficients_and_finite_bound() {
39633 let scoring = task_spec([0, 1, 0], vec![]).scoring;
39634 let task = Identity256::from_bytes([11; 32]);
39635 let bytes = scoring.completed_law_bytes(task, false).unwrap();
39636 let mut expected = b"XLOG-TASK-SCORING-LAW\0".to_vec();
39637 expected.extend_from_slice(&2u64.to_le_bytes());
39638 expected.extend_from_slice(task.as_bytes());
39639 let cost = semantic_structural_cost_descriptor(false);
39640 expected.extend_from_slice(cost.unit.as_bytes());
39641 expected.extend_from_slice(&cost.cap.to_le_bytes());
39642 for weight in [14u64, 7, 1, 45, 15, 1] {
39643 expected.extend_from_slice(&weight.to_le_bytes());
39644 }
39645 expected.extend_from_slice(&scoring.return_bound(false).unwrap().to_le_bytes());
39646 assert_eq!(bytes, expected);
39647 assert_eq!(scoring.return_bound(false).unwrap(), 2522);
39648 let structural = scoring.completed_law_bytes(task, true).unwrap();
39649 assert_eq!(scoring.return_bound(true).unwrap(), 186799);
39650 assert_eq!(
39651 structural[structural.len() - size_of::<i64>()..],
39652 scoring.return_bound(true).unwrap().to_le_bytes()
39653 );
39654 }
39655
39656 #[test]
39657 fn checkpoint_scoring_identity_tracks_the_bound_law() {
39658 let scoring = SemanticTaskScoring {
39659 correct_weight: 14,
39660 all_correct_weight: 7,
39661 work_weight: 1,
39662 improvement_weight: 45,
39663 refusal_weight: 15,
39664 spent_weight: 1,
39665 };
39666 let task = SemanticTaskContentIdentity {
39667 query: Identity256::from_bytes([11; 32]),
39668 theory_program: Identity256::from_bytes([12; 32]),
39669 result: Identity256::from_bytes([13; 32]),
39670 };
39671 let baseline = checkpoint_scoring_law_identity(
39672 scoring,
39673 task,
39674 scoring.objective_law(false).unwrap(),
39675 None,
39676 );
39677 assert_ne!(
39678 baseline,
39679 checkpoint_scoring_law_identity(
39680 scoring,
39681 task,
39682 scoring.objective_law(true).unwrap(),
39683 None
39684 )
39685 );
39686 let mut changed = scoring;
39687 changed.correct_weight += 1;
39688 assert_ne!(
39689 baseline,
39690 checkpoint_scoring_law_identity(
39691 changed,
39692 task,
39693 changed.objective_law(false).unwrap(),
39694 None
39695 )
39696 );
39697 }
39698
39699 pub(crate) fn verify_native_decoded_reconstruction(
39700 executable: &std::path::Path,
39701 directory: &std::path::Path,
39702 run: &impl Fn(&mut std::process::Command),
39703 ) {
39704 use crate::semantic_hypergraph::tests::{
39705 admit_material_records, reconstructed_material_statement, root_material_records,
39706 };
39707 let mut records = root_material_records();
39708 records.supports.push(records.supports[0].clone());
39709 let admission = admit_material_records(records);
39710 let books = ActionCodebooks::derive(&admission, 1, None).unwrap();
39711 let leaf = books
39712 .leaves
39713 .iter()
39714 .position(|value| {
39715 matches!(
39716 value,
39717 SemanticActionDescriptor::SupportEvent { source_record: 3 }
39718 )
39719 })
39720 .unwrap() as u32
39721 + 1;
39722 for (ordinal, operand) in [1, books.operands.len() as u32].into_iter().enumerate() {
39723 let mut choices = [0u32; SEMANTIC_TRANSITION_COMPONENT_COUNT];
39724 choices[2] = 1;
39725 choices[3] = operand;
39726 choices[11] = 1;
39727 choices[17] = leaf;
39728 let mut input = format!("{}\n", books.words.len());
39729 for word in &books.words {
39730 input.push_str(&format!("{word} "));
39731 }
39732 for choice in choices {
39733 input.push_str(&format!("{choice} "));
39734 }
39735 let source = directory.join(format!("decoded-input-{ordinal}.txt"));
39736 let destination = directory.join(format!("decoded-output-{ordinal}.txt"));
39737 std::fs::write(&source, input).unwrap();
39738 run(std::process::Command::new(executable)
39739 .arg("--decode")
39740 .arg(&source)
39741 .arg(&destination));
39742 let words: Vec<u32> = std::fs::read_to_string(&destination)
39743 .unwrap()
39744 .split_whitespace()
39745 .map(|word| word.parse().unwrap())
39746 .collect();
39747 assert_eq!(words.len(), 20);
39748 assert_eq!(
39749 words[8],
39750 u32::MAX,
39751 "computed target invented an original occurrence"
39752 );
39753 assert_eq!(
39754 words[19], 3,
39755 "actual decoder selected a different equal support occurrence"
39756 );
39757 let reconstruction: [u32; 10] = words[9..19].try_into().unwrap();
39758 let key = reconstructed_material_statement(&admission, None, &reconstruction).unwrap();
39759 let digest: Vec<u8> = words[..8]
39760 .iter()
39761 .flat_map(|word| word.to_le_bytes())
39762 .collect();
39763 assert_eq!(
39764 digest.as_slice(),
39765 key.identity().as_bytes(),
39766 "actual decode differs from canonical restore"
39767 );
39768 if ordinal == 0 {
39769 assert_eq!(
39770 key.identity(),
39771 admission.statement_key(0).unwrap().identity()
39772 );
39773 } else {
39774 assert_ne!(
39775 key.identity(),
39776 admission.statement_key(0).unwrap().identity()
39777 );
39778 assert_ne!(
39779 key.identity(),
39780 admission.statement_key(1).unwrap().identity()
39781 );
39782 }
39783 assert!(
39784 reconstructed_material_statement(&admission, Some(0), &reconstruction).is_err(),
39785 "derived reconstruction was accepted as an original occurrence"
39786 );
39787 std::fs::remove_file(source).unwrap();
39788 std::fs::remove_file(destination).unwrap();
39789 }
39790 }
39791
39792 #[test]
39793 fn task_scoring_rejects_signed_return_overflow() {
39794 let mut spec = task_spec([0, 1, 1], vec![0]);
39795 spec.scoring.correct_weight = u32::MAX;
39796 spec.scoring.improvement_weight = u32::MAX;
39797 assert!(spec.validate_records(&carry_records()).is_err());
39798 }
39799
39800 #[test]
39801 fn cold_task_binding_requires_admitted_statement_scope() {
39802 let spec = task_spec([0, 1, 1], vec![0]);
39803 spec.validate_records(&carry_records()).unwrap();
39804 for invalid in 0..4 {
39805 let mut records = carry_records();
39806 match invalid {
39807 0 => records.records[1].predicate = RelId(18),
39808 1 => records.records[1].predicate = RelId(999),
39809 2 => records.predicates[0].role = SemanticRecordRole::Qualifier,
39810 _ => records.supports[0].statement = 2,
39811 }
39812 assert!(spec.validate_records(&records).is_err(), "case {invalid}");
39813 }
39814 assert!(task_spec([0, 2, 2], vec![])
39815 .validate_records(&carry_records())
39816 .is_err());
39817 assert!(task_spec([0, 1, 1], vec![1])
39818 .validate_records(&carry_records())
39819 .is_err());
39820 }
39821}