crtx-core 0.1.1

Core IDs, errors, and schema constants for Cortex.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
//! Typed Cortex / pai-axiom boundary envelopes.
//!
//! ADR 0040 requires cross-system exchanges to carry machine-readable
//! constraints and receipt state. These structs are shape-only: they do not
//! grant authority, persist records, or bypass the receiver's own gates.

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::{
    AxiomConstraint, ClaimCeiling, ContextPackId, ProofClosureReport, ProvenanceClass,
    SemanticTrustClass,
};

/// Current boundary envelope schema version.
pub const BOUNDARY_SCHEMA_VERSION: u16 = 1;

/// Stable type string for Cortex -> AXIOM constraint envelopes.
pub const CORTEX_TO_AXIOM_CONSTRAINT_ENVELOPE_V1: &str = "cortex.boundary.constraint_envelope.v1";

/// Stable type string for pai-axiom -> Cortex execution receipts.
pub const PAI_AXIOM_TO_CORTEX_EXECUTION_RECEIPT_V1: &str =
    "pai_axiom.boundary.execution_receipt.v1";

/// Contradiction state crossing the Cortex / pai-axiom boundary.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum BoundaryContradictionState {
    /// Contradictions were scanned and resolved for this use.
    Resolved,
    /// Multiple hypotheses remain intentionally represented.
    MultiHypothesis,
    /// Contradiction state is missing or not scanned.
    Unknown,
    /// An unresolved contradiction blocks authority-bearing use.
    Blocked,
}

/// Quarantine state crossing the Cortex / pai-axiom boundary.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum BoundaryQuarantineState {
    /// No quarantine or contamination is known.
    Clean,
    /// Material may be shown only for diagnostics.
    DiagnosticOnly,
    /// Material is quarantined and must not guide authority-bearing work.
    Quarantined,
    /// Material is contaminated by a failed or unsafe path.
    Contaminated,
}

/// Redaction state crossing the Cortex / pai-axiom boundary.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum BoundaryRedactionState {
    /// Raw operator-mode material is present under explicit opt-in.
    RawOperatorOptIn,
    /// Content has been redacted.
    Redacted,
    /// Content has been abstracted.
    Abstracted,
    /// Content is safe for the declared export posture.
    ExportSafe,
}

/// Claim language permitted to the receiving AXIOM runtime.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum AllowedClaimLanguage {
    /// Candidate claim only.
    CandidateClaim,
    /// Evidence reference only.
    EvidenceReference,
    /// Constraint or limit.
    Constraint,
    /// Residual risk.
    ResidualRisk,
    /// Request verification instead of asserting.
    VerificationRequest,
    /// Refusal or abstention.
    Refusal,
}

/// Authority-bearing use forbidden by a boundary envelope.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ForbiddenBoundaryUse {
    /// Principle or doctrine promotion.
    Promotion,
    /// Trusted run-history claim.
    TrustedHistory,
    /// Compliance evidence.
    ComplianceEvidence,
    /// Export as trusted material.
    Export,
    /// Release gate or release evidence.
    Release,
    /// External reporting.
    ExternalReporting,
    /// Execution authority or tool permission.
    ExecutionAuthority,
}

/// Cortex -> pai-axiom constraint envelope.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct CortexAxiomConstraintEnvelopeV1 {
    /// Schema version.
    pub schema_version: u16,
    /// Stable envelope type string.
    pub envelope_type: String,
    /// Context pack being constrained.
    pub context_pack_id: ContextPackId,
    /// Proof closure state and failing edges for the pack/use.
    pub proof_state: ProofClosureReport,
    /// Maximum claim strength permitted.
    pub truth_ceiling: ClaimCeiling,
    /// Semantic trust class for the selected context.
    pub semantic_trust: SemanticTrustClass,
    /// Weakest provenance class represented in selected context.
    pub provenance_class: ProvenanceClass,
    /// Contradiction posture.
    pub contradiction_state: BoundaryContradictionState,
    /// Quarantine posture.
    pub quarantine_state: BoundaryQuarantineState,
    /// Redaction posture.
    pub redaction_state: BoundaryRedactionState,
    /// Claim language the receiver may use.
    pub allowed_claim_language: Vec<AllowedClaimLanguage>,
    /// Authority-bearing uses forbidden by this envelope.
    pub forbidden_uses: Vec<ForbiddenBoundaryUse>,
    /// Detailed AXIOM constraints already understood by existing exports.
    pub constraints: Vec<AxiomConstraint>,
}

impl CortexAxiomConstraintEnvelopeV1 {
    /// Construct an envelope with the stable v1 type string.
    #[must_use]
    pub fn new(
        context_pack_id: ContextPackId,
        proof_state: ProofClosureReport,
        truth_ceiling: ClaimCeiling,
        semantic_trust: SemanticTrustClass,
        provenance_class: ProvenanceClass,
    ) -> Self {
        Self {
            schema_version: BOUNDARY_SCHEMA_VERSION,
            envelope_type: CORTEX_TO_AXIOM_CONSTRAINT_ENVELOPE_V1.to_string(),
            context_pack_id,
            proof_state,
            truth_ceiling,
            semantic_trust,
            provenance_class,
            contradiction_state: BoundaryContradictionState::Unknown,
            quarantine_state: BoundaryQuarantineState::DiagnosticOnly,
            redaction_state: BoundaryRedactionState::Abstracted,
            allowed_claim_language: default_allowed_claim_language(),
            forbidden_uses: default_forbidden_boundary_uses(),
            constraints: Vec::new(),
        }
    }
}

/// Capability-token decision from pai-axiom.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum CapabilityTokenDecision {
    /// Token and policy allowed the operation.
    Allowed,
    /// Token allowed with warning.
    Warned,
    /// Token or policy rejected the operation.
    Rejected,
    /// Token was expired.
    Expired,
    /// Token was revoked.
    Revoked,
}

/// Capability-token state supplied by pai-axiom.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct CapabilityTokenState {
    /// Final token decision.
    pub decision: CapabilityTokenDecision,
    /// Token structure was valid.
    pub valid_structure: bool,
    /// Token audience matched Cortex.
    pub audience_bound: bool,
    /// Token scope matched the operation.
    pub scope_bound: bool,
    /// Token operation binding matched the receipt.
    pub operation_bound: bool,
    /// Token was not expired at execution time.
    pub not_expired: bool,
    /// Token was not revoked at execution time.
    pub not_revoked: bool,
    /// Policy allowed the operation.
    pub policy_allowed: bool,
    /// Attestation link was present and verified.
    pub attestation_linked: bool,
}

/// Runtime integrity state supplied by pai-axiom.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum RuntimeIntegrityState {
    /// Runtime integrity was not verified.
    Unverified,
    /// Release artifact was verified.
    VerifiedRelease,
    /// Release provenance was verified.
    VerifiedProvenance,
    /// Runtime is known or suspected compromised.
    Compromised,
}

/// Execution trust state supplied by pai-axiom.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ExecutionTrustState {
    /// Runtime integrity state.
    pub runtime_integrity: RuntimeIntegrityState,
    /// Optional release or provenance evidence ref.
    pub evidence_ref: Option<String>,
}

/// Operator approval state supplied by pai-axiom.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum OperatorApprovalState {
    /// Approval was not required.
    NotRequired,
    /// Approval was required but absent.
    RequiredMissing,
    /// Approval was supplied and operation-bound.
    ApprovedBound,
    /// Approval was supplied but not operation-bound.
    ApprovedUnbound,
}

/// Tool invocation outcome in a boundary receipt.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum BoundaryToolOutcome {
    /// Tool invocation succeeded.
    Succeeded,
    /// Tool invocation failed.
    Failed,
    /// Tool invocation was blocked.
    Blocked,
}

/// Tool provenance item in a boundary receipt.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct BoundaryToolInvocation {
    /// Tool name.
    pub tool_name: String,
    /// Invocation identifier.
    pub invocation_id: String,
    /// Stable input anchor.
    pub input_ref: Option<String>,
    /// Stable output anchor.
    pub output_ref: Option<String>,
    /// Invocation outcome.
    pub outcome: BoundaryToolOutcome,
}

/// Source anchor in a boundary receipt.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct BoundarySourceAnchor {
    /// Source reference.
    pub reference: String,
    /// Source kind.
    pub kind: String,
}

/// pai-axiom -> Cortex execution receipt.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct PaiAxiomExecutionReceiptV1 {
    /// Schema version.
    pub schema_version: u16,
    /// Stable receipt type string.
    pub receipt_type: String,
    /// Runtime/workloop identity.
    pub runtime_id: String,
    /// Capability-token state.
    pub capability_token_state: CapabilityTokenState,
    /// Execution trust state.
    pub execution_trust_state: ExecutionTrustState,
    /// Tool invocations and anchors.
    pub tool_provenance: Vec<BoundaryToolInvocation>,
    /// Operator approval state.
    pub operator_approval_state: OperatorApprovalState,
    /// Runtime quarantine state.
    pub quarantine_state: BoundaryQuarantineState,
    /// Source anchors for claims proposed to Cortex.
    pub source_anchors: Vec<BoundarySourceAnchor>,
    /// Explicit residual risk strings.
    pub residual_risk: Vec<String>,
    /// Must remain true for Cortex admission: receipt is not promotion.
    pub explicit_non_promotion: bool,
}

impl PaiAxiomExecutionReceiptV1 {
    /// Construct a v1 execution receipt.
    #[must_use]
    pub fn new(
        runtime_id: impl Into<String>,
        capability_token_state: CapabilityTokenState,
        execution_trust_state: ExecutionTrustState,
        operator_approval_state: OperatorApprovalState,
    ) -> Self {
        Self {
            schema_version: BOUNDARY_SCHEMA_VERSION,
            receipt_type: PAI_AXIOM_TO_CORTEX_EXECUTION_RECEIPT_V1.to_string(),
            runtime_id: runtime_id.into(),
            capability_token_state,
            execution_trust_state,
            tool_provenance: Vec::new(),
            operator_approval_state,
            quarantine_state: BoundaryQuarantineState::DiagnosticOnly,
            source_anchors: Vec::new(),
            residual_risk: Vec::new(),
            explicit_non_promotion: true,
        }
    }
}

/// Default claim language for constrained AXIOM work.
#[must_use]
pub fn default_allowed_claim_language() -> Vec<AllowedClaimLanguage> {
    vec![
        AllowedClaimLanguage::CandidateClaim,
        AllowedClaimLanguage::EvidenceReference,
        AllowedClaimLanguage::Constraint,
        AllowedClaimLanguage::ResidualRisk,
        AllowedClaimLanguage::VerificationRequest,
        AllowedClaimLanguage::Refusal,
    ]
}

/// Default forbidden authority-bearing uses for cross-boundary context.
#[must_use]
pub fn default_forbidden_boundary_uses() -> Vec<ForbiddenBoundaryUse> {
    vec![
        ForbiddenBoundaryUse::Promotion,
        ForbiddenBoundaryUse::TrustedHistory,
        ForbiddenBoundaryUse::ComplianceEvidence,
        ForbiddenBoundaryUse::Export,
        ForbiddenBoundaryUse::Release,
        ForbiddenBoundaryUse::ExternalReporting,
        ForbiddenBoundaryUse::ExecutionAuthority,
    ]
}

#[cfg(test)]
mod tests {
    use serde_json::json;

    use super::*;

    fn token_state(decision: CapabilityTokenDecision) -> CapabilityTokenState {
        CapabilityTokenState {
            decision,
            valid_structure: true,
            audience_bound: true,
            scope_bound: true,
            operation_bound: true,
            not_expired: true,
            not_revoked: true,
            policy_allowed: true,
            attestation_linked: true,
        }
    }

    #[test]
    fn boundary_type_strings_are_stable() {
        assert_eq!(
            CORTEX_TO_AXIOM_CONSTRAINT_ENVELOPE_V1,
            "cortex.boundary.constraint_envelope.v1"
        );
        assert_eq!(
            PAI_AXIOM_TO_CORTEX_EXECUTION_RECEIPT_V1,
            "pai_axiom.boundary.execution_receipt.v1"
        );
    }

    #[test]
    fn boundary_enum_wire_strings_are_stable() {
        assert_eq!(
            serde_json::to_value(BoundaryContradictionState::MultiHypothesis).unwrap(),
            json!("multi_hypothesis")
        );
        assert_eq!(
            serde_json::to_value(BoundaryQuarantineState::DiagnosticOnly).unwrap(),
            json!("diagnostic_only")
        );
        assert_eq!(
            serde_json::to_value(BoundaryRedactionState::RawOperatorOptIn).unwrap(),
            json!("raw_operator_opt_in")
        );
        assert_eq!(
            serde_json::to_value(AllowedClaimLanguage::VerificationRequest).unwrap(),
            json!("verification_request")
        );
        assert_eq!(
            serde_json::to_value(ForbiddenBoundaryUse::TrustedHistory).unwrap(),
            json!("trusted_history")
        );
        assert_eq!(
            serde_json::to_value(CapabilityTokenDecision::Revoked).unwrap(),
            json!("revoked")
        );
        assert_eq!(
            serde_json::to_value(RuntimeIntegrityState::VerifiedProvenance).unwrap(),
            json!("verified_provenance")
        );
        assert_eq!(
            serde_json::to_value(OperatorApprovalState::ApprovedBound).unwrap(),
            json!("approved_bound")
        );
        assert_eq!(
            serde_json::to_value(BoundaryToolOutcome::Blocked).unwrap(),
            json!("blocked")
        );
    }

    #[test]
    fn constraint_envelope_defaults_forbid_authority_bearing_uses() {
        let envelope = CortexAxiomConstraintEnvelopeV1::new(
            ContextPackId::new(),
            ProofClosureReport::full_chain_verified(Vec::new()),
            ClaimCeiling::LocalUnsigned,
            SemanticTrustClass::CandidateOnly,
            ProvenanceClass::RuntimeDerived,
        );

        assert_eq!(envelope.schema_version, BOUNDARY_SCHEMA_VERSION);
        assert_eq!(
            envelope.envelope_type,
            CORTEX_TO_AXIOM_CONSTRAINT_ENVELOPE_V1
        );
        assert!(envelope
            .forbidden_uses
            .contains(&ForbiddenBoundaryUse::ExecutionAuthority));
        assert!(envelope
            .allowed_claim_language
            .contains(&AllowedClaimLanguage::Refusal));
    }

    #[test]
    fn execution_receipt_defaults_to_candidate_only_non_promotion() {
        let receipt = PaiAxiomExecutionReceiptV1::new(
            "axiom-runtime:v3.1",
            token_state(CapabilityTokenDecision::Allowed),
            ExecutionTrustState {
                runtime_integrity: RuntimeIntegrityState::Unverified,
                evidence_ref: None,
            },
            OperatorApprovalState::NotRequired,
        );

        assert_eq!(receipt.schema_version, BOUNDARY_SCHEMA_VERSION);
        assert_eq!(
            receipt.receipt_type,
            PAI_AXIOM_TO_CORTEX_EXECUTION_RECEIPT_V1
        );
        assert!(receipt.explicit_non_promotion);
        assert_eq!(
            receipt.quarantine_state,
            BoundaryQuarantineState::DiagnosticOnly
        );
    }
}