use std::collections::BTreeMap;
pub const MCP_MANIFEST_SCHEMA_VERSION: u32 = 1;
pub const CONTEXT_PROOF_V1_SCHEMA_VERSION: u32 = 1;
pub const CONTEXT_IR_V1_SCHEMA_VERSION: u32 = 1;
pub const INTENT_ROUTE_V1_SCHEMA_VERSION: u32 = 1;
pub const DEGRADATION_POLICY_V1_SCHEMA_VERSION: u32 = 1;
pub const WORKFLOW_EVIDENCE_LEDGER_V1_SCHEMA_VERSION: u32 = 1;
pub const AUTONOMY_DRIVERS_V1_SCHEMA_VERSION: u32 = 1;
pub const TOKENIZER_TRANSLATION_DRIVER_V1_SCHEMA_VERSION: u32 = 1;
pub const ATTENTION_LAYOUT_DRIVER_V1_SCHEMA_VERSION: u32 = 1;
pub const VERIFICATION_OBSERVABILITY_V1_SCHEMA_VERSION: u32 = 1;
pub const HANDOFF_LEDGER_V1_SCHEMA_VERSION: u32 = 1;
pub const HANDOFF_TRANSFER_BUNDLE_V1_SCHEMA_VERSION: u32 = 1;
pub const CCP_SESSION_BUNDLE_V1_SCHEMA_VERSION: u32 = 1;
pub const KNOWLEDGE_POLICY_V1_SCHEMA_VERSION: u32 = 1;
pub const GRAPH_REPRODUCIBILITY_V1_SCHEMA_VERSION: u32 = 1;
pub const A2A_SNAPSHOT_V1_SCHEMA_VERSION: u32 = 1;
pub const MEMORY_BOUNDARY_V1_SCHEMA_VERSION: u32 = 1;
pub const GOTCHAS_REMINDERS_V1_SCHEMA_VERSION: u32 = 1;
pub const PROVIDER_FRAMEWORK_V1_SCHEMA_VERSION: u32 = 1;
pub const CONTEXT_PACKAGE_V1_SCHEMA_VERSION: u32 = 1;
pub const CONTEXT_PACKAGE_V2_SCHEMA_VERSION: u32 = 2;
pub const CONTEXT_SNAPSHOT_V1_SCHEMA_VERSION: u32 = 1;
pub const PACKAGE_EXTENSION: &str = "ctxpkg";
pub const LEGACY_PACKAGE_EXTENSION: &str = "lctxpkg";
pub const MAX_PACKAGE_FILE_BYTES: u64 = 10 * 1024 * 1024;
pub fn is_package_file(path: &std::path::Path) -> bool {
path.extension()
.and_then(|e| e.to_str())
.is_some_and(|ext| ext == PACKAGE_EXTENSION || ext == LEGACY_PACKAGE_EXTENSION)
}
pub fn default_package_filename(name: &str, version: &str) -> String {
format!("{name}-{version}.{PACKAGE_EXTENSION}")
}
pub const HTTP_MCP_CONTRACT_VERSION: u32 = 1;
pub const TEAM_SERVER_CONTRACT_VERSION: u32 = 1;
pub const CAPABILITIES_CONTRACT_VERSION: u32 = 1;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ContractStatus {
Frozen,
Stable,
Experimental,
}
impl ContractStatus {
pub fn as_str(self) -> &'static str {
match self {
ContractStatus::Frozen => "frozen",
ContractStatus::Stable => "stable",
ContractStatus::Experimental => "experimental",
}
}
}
pub struct ContractDoc {
pub id: &'static str,
pub doc_file: &'static str,
pub version: u32,
pub status: ContractStatus,
}
pub fn contract_docs() -> Vec<ContractDoc> {
use ContractStatus::{Experimental, Frozen, Stable};
let doc = |id, doc_file, version, status| ContractDoc {
id,
doc_file,
version,
status,
};
vec![
doc("http-mcp", "http-mcp-contract-v1.md", 1, Frozen),
doc("team-server", "team-server-contract-v1.md", 1, Frozen),
doc("context-ir", "context-ir-v1.md", 1, Frozen),
doc(
"local-free-invariant",
"local-free-invariant-v1.md",
1,
Frozen,
),
doc(
"oss-plane-separation",
"oss-plane-separation-v1.md",
1,
Frozen,
),
doc("billing-plane", "billing-plane-v1.md", 1, Frozen),
doc("wasm-abi", "wasm-abi-v1.md", 1, Frozen),
doc("delivery-manifest", "delivery-manifest-v1.md", 1, Frozen),
doc(
"deployment-rehearsal",
"deployment-rehearsal-v1.md",
1,
Frozen,
),
doc(
"release-key-rotation",
"release-key-rotation-v1.md",
1,
Frozen,
),
doc("capabilities", "capabilities-contract-v1.md", 1, Stable),
doc("billing-plane-v2", "billing-plane-v2.md", 2, Stable),
doc("billing-plane-v3", "billing-plane-v3.md", 3, Stable),
doc("evidence-bundle", "evidence-bundle-v1.md", 1, Stable),
doc(
"settlement-evidence",
"settlement-evidence-v2.md",
2,
Stable,
),
doc("team-server-v2", "team-server-contract-v2.md", 2, Stable),
doc("a2a", "a2a-contract-v1.md", 1, Stable),
doc(
"attention-layout-driver",
"attention-layout-driver-v1.md",
1,
Stable,
),
doc("autonomy-drivers", "autonomy-drivers-v1.md", 1, Stable),
doc("ccp-session-bundle", "ccp-session-bundle-v1.md", 1, Stable),
doc("conformance", "conformance-v1.md", 1, Stable),
doc(
"ocla-verifier-conformance",
"ocla-verifier-conformance-v1.md",
1,
Stable,
),
doc("degradation-policy", "degradation-policy-v1.md", 1, Stable),
doc("extension-trust", "extension-trust-v1.md", 1, Stable),
doc("extractors", "extractors-v1.md", 1, Stable),
doc("contracts-readme", "README.md", 1, Stable),
doc("deprecation-policy", "DEPRECATION.md", 1, Stable),
doc("audit-schedule", "audit-schedule-v1.md", 1, Stable),
doc("branch-protection", "branch-protection-v1.md", 1, Stable),
doc(
"certification-levels",
"certification-levels-v1.md",
1,
Stable,
),
doc("release-integrity", "release-integrity-v1.md", 1, Stable),
doc(
"gotchas-reminders",
"gotchas-reminders-contract-v1.md",
1,
Stable,
),
doc(
"graph-reproducibility",
"graph-reproducibility-contract-v1.md",
1,
Stable,
),
doc(
"handoff-transfer-bundle",
"handoff-transfer-bundle-v1.md",
1,
Stable,
),
doc("intent-route", "intent-route-v1.md", 1, Stable),
doc(
"knowledge-policy",
"knowledge-policy-contract-v1.md",
1,
Stable,
),
doc(
"memory-boundary",
"memory-boundary-contract-v1.md",
1,
Stable,
),
doc("persona-spec", "persona-spec-v1.md", 1, Stable),
doc(
"provider-framework",
"provider-framework-contract-v1.md",
1,
Stable,
),
doc(
"tokenizer-translation-driver",
"tokenizer-translation-driver-v1.md",
1,
Stable,
),
doc(
"workflow-evidence-ledger",
"workflow-evidence-ledger-v1.md",
1,
Stable,
),
doc("wrapped-permalink", "wrapped-permalink-v1.md", 1, Stable),
doc("addon-manifest", "addon-manifest-v1.md", 1, Stable),
doc(
"context-candidate-admission",
"context-candidate-admission-v1.md",
1,
Experimental,
),
doc(
"multi-agent-efficiency-benchmark",
"multi-agent-efficiency-benchmark-v1.md",
1,
Experimental,
),
doc(
"test-deployment-evidence",
"test-deployment-evidence-v1.md",
1,
Experimental,
),
doc(
"ocla-config-tuning",
"ocla-config-tuning-v2.md",
2,
Experimental,
),
doc(
"hosted-personal-index",
"hosted-personal-index-v1.md",
1,
Experimental,
),
doc(
"personal-cloud-encryption",
"personal-cloud-encryption-v1.md",
1,
Experimental,
),
doc(
"context-policy-packs",
"context-policy-packs-v1.md",
1,
Experimental,
),
doc("device-overview", "device-overview-v1.md", 1, Experimental),
doc("email-digest", "email-digest-v1.md", 1, Experimental),
doc("org-audit-log", "org-audit-log-v1.md", 1, Experimental),
doc("org-sso-oidc", "org-sso-oidc-v1.md", 1, Experimental),
doc("quality-loop", "quality-loop-v1.md", 1, Experimental),
doc("edit-metering", "edit-metering-v1.md", 1, Experimental),
doc("ctxpkg-registry", "ctxpkg-registry-v1.md", 1, Experimental),
doc(
"context-snapshot",
"context-snapshot-v1.md",
1,
Experimental,
),
doc(
"team-invite-links",
"team-invite-links-v1.md",
1,
Experimental,
),
doc("org-policy", "org-policy-v1.md", 1, Experimental),
doc(
"compliance-report",
"compliance-report-v1.md",
1,
Experimental,
),
doc("pillar-boundaries", "pillar-boundaries-v1.md", 1, Stable),
doc(
"logical-session-presence",
"logical-session-presence-v1.md",
1,
Experimental,
),
doc(
"tokenizer-calibration",
"tokenizer-calibration-v1.md",
1,
Experimental,
),
]
}
pub fn status_kv() -> BTreeMap<&'static str, &'static str> {
contract_docs()
.into_iter()
.map(|d| (d.id, d.status.as_str()))
.collect()
}
pub fn versions_kv() -> BTreeMap<&'static str, u32> {
BTreeMap::from([
(
"leanctx.contract.mcp_manifest.schema_version",
MCP_MANIFEST_SCHEMA_VERSION,
),
(
"leanctx.contract.context_proof_v1.schema_version",
CONTEXT_PROOF_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.context_ir_v1.schema_version",
CONTEXT_IR_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.intent_route_v1.schema_version",
INTENT_ROUTE_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.degradation_policy_v1.schema_version",
DEGRADATION_POLICY_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.workflow_evidence_ledger_v1.schema_version",
WORKFLOW_EVIDENCE_LEDGER_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.autonomy_drivers_v1.schema_version",
AUTONOMY_DRIVERS_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.tokenizer_translation_driver_v1.schema_version",
TOKENIZER_TRANSLATION_DRIVER_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.attention_layout_driver_v1.schema_version",
ATTENTION_LAYOUT_DRIVER_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.verification_observability_v1.schema_version",
VERIFICATION_OBSERVABILITY_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.handoff_ledger_v1.schema_version",
HANDOFF_LEDGER_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.handoff_transfer_bundle_v1.schema_version",
HANDOFF_TRANSFER_BUNDLE_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.ccp_session_bundle_v1.schema_version",
CCP_SESSION_BUNDLE_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.knowledge_policy_v1.schema_version",
KNOWLEDGE_POLICY_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.graph_reproducibility_v1.schema_version",
GRAPH_REPRODUCIBILITY_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.a2a_snapshot_v1.schema_version",
A2A_SNAPSHOT_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.memory_boundary_v1.schema_version",
MEMORY_BOUNDARY_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.gotchas_reminders_v1.schema_version",
GOTCHAS_REMINDERS_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.provider_framework_v1.schema_version",
PROVIDER_FRAMEWORK_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.context_package_v1.schema_version",
CONTEXT_PACKAGE_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.context_package_v2.schema_version",
CONTEXT_PACKAGE_V2_SCHEMA_VERSION,
),
(
"leanctx.contract.context_snapshot_v1.schema_version",
CONTEXT_SNAPSHOT_V1_SCHEMA_VERSION,
),
(
"leanctx.contract.http_mcp.contract_version",
HTTP_MCP_CONTRACT_VERSION,
),
(
"leanctx.contract.team_server.contract_version",
TEAM_SERVER_CONTRACT_VERSION,
),
(
"leanctx.contract.capabilities.contract_version",
CAPABILITIES_CONTRACT_VERSION,
),
])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn contract_docs_have_unique_ids_and_files() {
let docs = contract_docs();
let mut ids: Vec<_> = docs.iter().map(|d| d.id).collect();
let mut files: Vec<_> = docs.iter().map(|d| d.doc_file).collect();
ids.sort_unstable();
files.sort_unstable();
let unique_ids: std::collections::BTreeSet<_> = ids.iter().collect();
let unique_files: std::collections::BTreeSet<_> = files.iter().collect();
assert_eq!(unique_ids.len(), docs.len(), "duplicate contract id");
assert_eq!(unique_files.len(), docs.len(), "duplicate doc file");
}
#[test]
fn frozen_set_covers_the_platform_promises() {
let docs = contract_docs();
for id in [
"http-mcp",
"team-server",
"context-ir",
"local-free-invariant",
"oss-plane-separation",
"billing-plane",
"wasm-abi",
"delivery-manifest",
"deployment-rehearsal",
"release-key-rotation",
] {
let entry = docs.iter().find(|d| d.id == id).expect("listed");
assert_eq!(
entry.status,
ContractStatus::Frozen,
"{id} must stay frozen"
);
}
}
#[test]
fn status_kv_matches_docs() {
let kv = status_kv();
assert_eq!(kv.len(), contract_docs().len());
assert_eq!(kv["http-mcp"], "frozen");
assert_eq!(kv["hosted-personal-index"], "experimental");
assert_eq!(kv["personal-cloud-encryption"], "experimental");
assert_eq!(kv["context-candidate-admission"], "experimental");
assert_eq!(kv["multi-agent-efficiency-benchmark"], "experimental");
assert_eq!(kv["test-deployment-evidence"], "experimental");
}
#[test]
fn doc_files_follow_versioned_naming() {
for d in contract_docs() {
if d.doc_file == "README.md" || d.doc_file == "DEPRECATION.md" {
continue;
}
assert!(
d.doc_file.ends_with(&format!("-v{}.md", d.version)),
"{} must end in -v{}.md",
d.doc_file,
d.version
);
}
}
}