use std::collections::HashSet;
use crate::{Error, Result};
pub const CLAIM_STATUS_BLOCK: &str = "tokitai-claim-status-v1";
pub const VALIDATION_STATUS_BLOCK: &str = "tokitai-validation-status-v1";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StatusBlock {
pub name: String,
pub entries: Vec<(String, String)>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StatusBlockExpectation {
pub block_name: &'static str,
pub required_entries: Vec<(&'static str, &'static str)>,
}
impl StatusBlockExpectation {
pub fn new(
block_name: &'static str,
required_entries: Vec<(&'static str, &'static str)>,
) -> Self {
Self {
block_name,
required_entries,
}
}
}
impl StatusBlock {
pub fn value(&self, key: &str) -> Option<&str> {
self.entries
.iter()
.find_map(|(entry_key, value)| (entry_key == key).then_some(value.as_str()))
}
pub fn require_value(&self, key: &str, expected: &str) -> Result<()> {
match self.value(key) {
Some(value) if value == expected => Ok(()),
Some(value) => Err(Error::verification(format!(
"{} status key {} expected {}, found {}",
self.name, key, expected, value
))),
None => Err(Error::verification(format!(
"{} status block missing required key {}",
self.name, key
))),
}
}
pub fn require_entries(&self, required: &[(&str, &str)]) -> Result<()> {
for (key, expected) in required {
self.require_value(key, expected)?;
}
Ok(())
}
}
pub fn parse_status_block(content: &str, block_name: &str) -> Result<StatusBlock> {
let start_marker = format!("```{block_name}");
let start = content.find(&start_marker).ok_or_else(|| {
Error::verification(format!("document missing fenced status block {block_name}"))
})?;
let after_start = &content[start + start_marker.len()..];
let end = after_start.find("```").ok_or_else(|| {
Error::verification(format!("fenced status block {block_name} is not closed"))
})?;
let mut seen_keys = HashSet::new();
let mut entries = Vec::new();
for line in after_start[..end]
.lines()
.map(str::trim)
.filter(|line| !line.is_empty())
{
let (key, value) = line.split_once('=').ok_or_else(|| {
Error::verification(format!(
"{block_name} status block line must be key=value: {line}"
))
})?;
let key = key.trim();
if key.is_empty() {
return Err(Error::verification(format!(
"{block_name} status block contains an empty key"
)));
}
if !seen_keys.insert(key.to_string()) {
return Err(Error::verification(format!(
"{block_name} status block contains duplicate key {key}"
)));
}
entries.push((key.to_string(), value.trim().to_string()));
}
if entries.is_empty() {
return Err(Error::verification(format!(
"{block_name} status block must contain at least one entry"
)));
}
Ok(StatusBlock {
name: block_name.to_string(),
entries,
})
}
pub fn validate_claim_status_block(content: &str) -> Result<StatusBlock> {
validate_status_block(content, ¤t_claim_status_expectation())
}
pub fn validate_validation_status_block(content: &str) -> Result<StatusBlock> {
validate_status_block(content, ¤t_validation_status_expectation())
}
pub fn validate_status_block(
content: &str,
expectation: &StatusBlockExpectation,
) -> Result<StatusBlock> {
let block = parse_status_block(content, expectation.block_name)?;
block.require_entries(&expectation.required_entries)?;
Ok(block)
}
pub fn current_claim_status_expectation() -> StatusBlockExpectation {
StatusBlockExpectation::new(
CLAIM_STATUS_BLOCK,
vec![
("phase", "P440"),
("sync_through", "P440"),
(
"current_paper_route",
"certified_valuation_sparse_fixed_precision_padic_gemm",
),
("primary_claim_allowed", "true"),
("production_speedup_claim_allowed", "false"),
("portable_rocm_claim_allowed", "false"),
("verified_hip_machine_code_claim_allowed", "false"),
("full_formalization_claim_allowed", "false"),
("sci_q2_claim_allowed", "false"),
("submission_readiness_claim_allowed", "false"),
("acceptance_probability_claim_allowed", "false"),
("external_venue_evidence_status", "missing_author_evidence"),
],
)
}
pub fn current_validation_status_expectation() -> StatusBlockExpectation {
StatusBlockExpectation::new(
VALIDATION_STATUS_BLOCK,
vec![
("phase", "P440"),
("sync_through", "P440"),
("roadmap_range", "P248-P440"),
("default_validation_required", "true"),
("structured_roadmap_guards_required", "true"),
("claim_status_block_required", "true"),
("validation_status_block_required", "true"),
("production_speedup_claim_allowed", "false"),
("portable_rocm_claim_allowed", "false"),
("verified_hip_machine_code_claim_allowed", "false"),
("sci_q2_claim_allowed", "false"),
("submission_readiness_claim_allowed", "false"),
("acceptance_probability_claim_allowed", "false"),
("external_venue_evidence_status", "missing_author_evidence"),
],
)
}
pub fn p268_claim_status_expectation() -> StatusBlockExpectation {
StatusBlockExpectation::new(
CLAIM_STATUS_BLOCK,
vec![
("phase", "P268"),
("sync_through", "P268"),
(
"current_paper_route",
"certified_valuation_sparse_fixed_precision_padic_gemm",
),
("primary_claim_allowed", "true"),
("production_speedup_claim_allowed", "false"),
("portable_rocm_claim_allowed", "false"),
("verified_hip_machine_code_claim_allowed", "false"),
("full_formalization_claim_allowed", "false"),
("sci_q2_claim_allowed", "false"),
("submission_readiness_claim_allowed", "false"),
("acceptance_probability_claim_allowed", "false"),
("external_venue_evidence_status", "missing_author_evidence"),
],
)
}
pub fn p268_validation_status_expectation() -> StatusBlockExpectation {
StatusBlockExpectation::new(
VALIDATION_STATUS_BLOCK,
vec![
("phase", "P268"),
("sync_through", "P268"),
("roadmap_range", "P248-P268"),
("default_validation_required", "true"),
("structured_roadmap_guards_required", "true"),
("claim_status_block_required", "true"),
("validation_status_block_required", "true"),
("production_speedup_claim_allowed", "false"),
("portable_rocm_claim_allowed", "false"),
("verified_hip_machine_code_claim_allowed", "false"),
("sci_q2_claim_allowed", "false"),
("submission_readiness_claim_allowed", "false"),
("acceptance_probability_claim_allowed", "false"),
("external_venue_evidence_status", "missing_author_evidence"),
],
)
}