Skip to main content

contract_schema_gen/
lib.rs

1use schemars::schema_for;
2use serde_json::Value;
3use std::fs;
4use std::path::{Path, PathBuf};
5
6type SchemaWriter = fn(&Path, &str) -> Result<(), Box<dyn std::error::Error>>;
7
8#[derive(Clone, Copy)]
9struct SchemaSpec {
10    name: &'static str,
11    writer: SchemaWriter,
12}
13
14fn write_schema<T: schemars::JsonSchema>(
15    dir: &Path,
16    name: &str,
17) -> Result<(), Box<dyn std::error::Error>> {
18    let schema = schema_for!(T);
19    let value: Value = serde_json::to_value(&schema)?;
20    let path = dir.join(name);
21    fs::write(path, serde_json::to_string_pretty(&value)? + "\n")?;
22    Ok(())
23}
24
25const SCHEMA_SPECS: &[SchemaSpec] = &[
26    SchemaSpec {
27        name: "export-envelope-v3.schema.json",
28        writer: write_schema::<semantic_memory_forge::ExportEnvelopeV3>,
29    },
30    SchemaSpec {
31        name: "projection-import-batch-v3.schema.json",
32        writer: write_schema::<forge_memory_bridge::ProjectionImportBatchV3>,
33    },
34    SchemaSpec {
35        name: "compile-output.schema.json",
36        writer: write_schema::<constraint_compiler::CompileOutput>,
37    },
38    SchemaSpec {
39        name: "execution-report.schema.json",
40        writer: write_schema::<kernel_execution::ExecutionReport>,
41    },
42    SchemaSpec {
43        name: "oracle-assessment.schema.json",
44        writer: write_schema::<kernel_oracles::OracleAssessment>,
45    },
46    SchemaSpec {
47        name: "forge-tool-receipt-v2.schema.json",
48        writer: write_schema::<semantic_memory_forge::ForgeToolReceiptV2>,
49    },
50    SchemaSpec {
51        name: "episode-bundle-v1.schema.json",
52        writer: write_schema::<semantic_memory_forge::EpisodeBundleV1>,
53    },
54    SchemaSpec {
55        name: "evidence-bundle-v1.schema.json",
56        writer: write_schema::<semantic_memory_forge::EvidenceBundle>,
57    },
58    SchemaSpec {
59        name: "execution-context-v1.schema.json",
60        writer: write_schema::<semantic_memory_forge::ExecutionContextV1>,
61    },
62    SchemaSpec {
63        name: "semantics-profile-v1.schema.json",
64        writer: write_schema::<semantic_memory_forge::SemanticsProfileV1>,
65    },
66    SchemaSpec {
67        name: "claim-state-v1.schema.json",
68        writer: write_schema::<semantic_memory_forge::ClaimStateV1>,
69    },
70    SchemaSpec {
71        name: "support-set-v1.schema.json",
72        writer: write_schema::<semantic_memory_forge::SupportSetV1>,
73    },
74    SchemaSpec {
75        name: "contradiction-witness-v1.schema.json",
76        writer: write_schema::<semantic_memory_forge::ContradictionWitnessV1>,
77    },
78    SchemaSpec {
79        name: "retraction-record-v1.schema.json",
80        writer: write_schema::<semantic_memory_forge::RetractionRecordV1>,
81    },
82    SchemaSpec {
83        name: "claim-state-v13.schema.json",
84        writer: write_schema::<semantic_memory_forge::ClaimStateV13>,
85    },
86    SchemaSpec {
87        name: "witness-artifact-v1.schema.json",
88        writer: write_schema::<semantic_memory_forge::WitnessArtifactV1>,
89    },
90    SchemaSpec {
91        name: "certificate-artifact-v1.schema.json",
92        writer: write_schema::<semantic_memory_forge::CertificateArtifactV1>,
93    },
94    SchemaSpec {
95        name: "refutation-artifact-v1.schema.json",
96        writer: write_schema::<semantic_memory_forge::RefutationArtifactV1>,
97    },
98    SchemaSpec {
99        name: "semantic-diff-v1.schema.json",
100        writer: write_schema::<semantic_memory_forge::SemanticDiffV1>,
101    },
102    SchemaSpec {
103        name: "oracle-slice-contract-v1.schema.json",
104        writer: write_schema::<semantic_memory_forge::OracleSliceContractV1>,
105    },
106    SchemaSpec {
107        name: "causal-attribution-bundle-v1.schema.json",
108        writer: write_schema::<semantic_memory_forge::CausalAttributionBundleV1>,
109    },
110    SchemaSpec {
111        name: "degradation-record-v1.schema.json",
112        writer: write_schema::<semantic_memory_forge::DegradationRecordV1>,
113    },
114    SchemaSpec {
115        name: "exactness-budget-v1.schema.json",
116        writer: write_schema::<semantic_memory_forge::ExactnessBudgetV1>,
117    },
118    SchemaSpec {
119        name: "intervention-bundle-v1.schema.json",
120        writer: write_schema::<semantic_memory_forge::InterventionBundleV1>,
121    },
122    SchemaSpec {
123        name: "outcome-schema-v1.schema.json",
124        writer: write_schema::<semantic_memory_forge::OutcomeSchemaV1>,
125    },
126    SchemaSpec {
127        name: "experiment-case-v1.schema.json",
128        writer: write_schema::<verification_control::ExperimentCaseV1>,
129    },
130    SchemaSpec {
131        name: "cohort-contract-v1.schema.json",
132        writer: write_schema::<semantic_memory_forge::CohortContractV1>,
133    },
134    SchemaSpec {
135        name: "comparability-matrix-v1.schema.json",
136        writer: write_schema::<verification_control::ComparabilityMatrixV1>,
137    },
138    SchemaSpec {
139        name: "counterfactual-slice-v1.schema.json",
140        writer: write_schema::<semantic_memory_forge::CounterfactualSliceV1>,
141    },
142    SchemaSpec {
143        name: "decision-trace-v1.schema.json",
144        writer: write_schema::<verification_control::DecisionTraceV1>,
145    },
146    SchemaSpec {
147        name: "refuter-suite-v1.schema.json",
148        writer: write_schema::<verification_policy::RefuterSuiteV1>,
149    },
150    SchemaSpec {
151        name: "refuter-result-v1.schema.json",
152        writer: write_schema::<verification_control::RefuterResultV1>,
153    },
154    SchemaSpec {
155        name: "rollout-decision-v1.schema.json",
156        writer: write_schema::<verification_adjudication::RolloutDecisionV1>,
157    },
158    SchemaSpec {
159        name: "rollback-decision-v1.schema.json",
160        writer: write_schema::<verification_adjudication::RollbackDecisionV1>,
161    },
162    SchemaSpec {
163        name: "experiment-budget-v1.schema.json",
164        writer: write_schema::<verification_policy::ExperimentBudgetV1>,
165    },
166    SchemaSpec {
167        name: "attestation-envelope-v1.schema.json",
168        writer: write_schema::<attestation_exchange::AttestationEnvelopeV1>,
169    },
170    SchemaSpec {
171        name: "trust-root-set-v1.schema.json",
172        writer: write_schema::<attestation_exchange::TrustRootSetV1>,
173    },
174    SchemaSpec {
175        name: "artifact-admission-policy-v1.schema.json",
176        writer: write_schema::<verification_policy::ArtifactAdmissionPolicyV1>,
177    },
178    SchemaSpec {
179        name: "transparency-receipt-v1.schema.json",
180        writer: write_schema::<attestation_exchange::TransparencyReceiptV1>,
181    },
182    SchemaSpec {
183        name: "attestation-revocation-v1.schema.json",
184        writer: write_schema::<remote_oracle_admission::AttestationRevocationV1>,
185    },
186    SchemaSpec {
187        name: "attestation-supersession-v1.schema.json",
188        writer: write_schema::<remote_oracle_admission::AttestationSupersessionV1>,
189    },
190    SchemaSpec {
191        name: "remote-oracle-lease-v1.schema.json",
192        writer: write_schema::<remote_oracle_admission::RemoteOracleLeaseV1>,
193    },
194    SchemaSpec {
195        name: "remote-slice-request-v1.schema.json",
196        writer: write_schema::<remote_oracle_admission::RemoteSliceRequestV1>,
197    },
198    SchemaSpec {
199        name: "remote-slice-result-v1.schema.json",
200        writer: write_schema::<remote_oracle_admission::RemoteSliceResultV1>,
201    },
202    SchemaSpec {
203        name: "cross-runtime-replay-ticket-v1.schema.json",
204        writer: write_schema::<remote_oracle_admission::CrossRuntimeReplayTicketV1>,
205    },
206    SchemaSpec {
207        name: "effect-intent-v1.schema.json",
208        writer: write_schema::<effect_runtime::EffectIntentV1>,
209    },
210    SchemaSpec {
211        name: "effect-preflight-report-v1.schema.json",
212        writer: write_schema::<effect_runtime::EffectPreflightReportV1>,
213    },
214    SchemaSpec {
215        name: "effect-window-v1.schema.json",
216        writer: write_schema::<effect_runtime::EffectWindowV1>,
217    },
218    SchemaSpec {
219        name: "effect-commit-decision-v1.schema.json",
220        writer: write_schema::<effect_runtime::EffectCommitDecisionV1>,
221    },
222    SchemaSpec {
223        name: "effect-execution-receipt-v1.schema.json",
224        writer: write_schema::<effect_runtime::EffectExecutionReceiptV1>,
225    },
226    SchemaSpec {
227        name: "effect-observation-bundle-v1.schema.json",
228        writer: write_schema::<effect_runtime::EffectObservationBundleV1>,
229    },
230    SchemaSpec {
231        name: "compensation-plan-v1.schema.json",
232        writer: write_schema::<effect_runtime::CompensationPlanV1>,
233    },
234    SchemaSpec {
235        name: "compensation-execution-receipt-v1.schema.json",
236        writer: write_schema::<effect_runtime::CompensationExecutionReceiptV1>,
237    },
238    SchemaSpec {
239        name: "external-effect-ledger-entry-v1.schema.json",
240        writer: write_schema::<effect_runtime::ExternalEffectLedgerEntryV1>,
241    },
242    SchemaSpec {
243        name: "capability-class-v1.schema.json",
244        writer: write_schema::<authority_delegation::CapabilityClassV1>,
245    },
246    SchemaSpec {
247        name: "authority-lease-v1.schema.json",
248        writer: write_schema::<authority_delegation::AuthorityLeaseV1>,
249    },
250    SchemaSpec {
251        name: "delegation-bundle-v1.schema.json",
252        writer: write_schema::<authority_delegation::DelegationBundleV1>,
253    },
254    SchemaSpec {
255        name: "authority-chain-v1.schema.json",
256        writer: write_schema::<authority_delegation::AuthorityChainV1>,
257    },
258    SchemaSpec {
259        name: "separation-of-duties-policy-v1.schema.json",
260        writer: write_schema::<authority_delegation::SeparationOfDutiesPolicyV1>,
261    },
262    SchemaSpec {
263        name: "dual-control-approval-v1.schema.json",
264        writer: write_schema::<authority_delegation::DualControlApprovalV1>,
265    },
266    SchemaSpec {
267        name: "break-glass-grant-v1.schema.json",
268        writer: write_schema::<authority_delegation::BreakGlassGrantV1>,
269    },
270    SchemaSpec {
271        name: "delegation-revocation-v1.schema.json",
272        writer: write_schema::<authority_delegation::DelegationRevocationV1>,
273    },
274    SchemaSpec {
275        name: "acting-on-behalf-receipt-v1.schema.json",
276        writer: write_schema::<authority_delegation::ActingOnBehalfReceiptV1>,
277    },
278    SchemaSpec {
279        name: "conflict-disclosure-v1.schema.json",
280        writer: write_schema::<authority_delegation::ConflictDisclosureV1>,
281    },
282    SchemaSpec {
283        name: "deployment-profile-v1.schema.json",
284        writer: write_schema::<assurance_runtime::DeploymentProfileV1>,
285    },
286    SchemaSpec {
287        name: "operating-envelope-v1.schema.json",
288        writer: write_schema::<assurance_runtime::OperatingEnvelopeV1>,
289    },
290    SchemaSpec {
291        name: "assurance-case-v1.schema.json",
292        writer: write_schema::<assurance_runtime::AssuranceCaseV1>,
293    },
294    SchemaSpec {
295        name: "hazard-register-v1.schema.json",
296        writer: write_schema::<assurance_runtime::HazardRegisterV1>,
297    },
298    SchemaSpec {
299        name: "control-mapping-v1.schema.json",
300        writer: write_schema::<assurance_runtime::ControlMappingV1>,
301    },
302    SchemaSpec {
303        name: "residual-risk-acceptance-v1.schema.json",
304        writer: write_schema::<assurance_runtime::ResidualRiskAcceptanceV1>,
305    },
306    SchemaSpec {
307        name: "release-readiness-decision-v1.schema.json",
308        writer: write_schema::<assurance_runtime::ReleaseReadinessDecisionV1>,
309    },
310    SchemaSpec {
311        name: "field-monitoring-plan-v1.schema.json",
312        writer: write_schema::<assurance_runtime::FieldMonitoringPlanV1>,
313    },
314    SchemaSpec {
315        name: "certification-bundle-v1.schema.json",
316        writer: write_schema::<assurance_runtime::CertificationBundleV1>,
317    },
318    SchemaSpec {
319        name: "recertification-trigger-v1.schema.json",
320        writer: write_schema::<assurance_runtime::RecertificationTriggerV1>,
321    },
322    SchemaSpec {
323        name: "service-level-profile-v1.schema.json",
324        writer: write_schema::<continuity_runtime::ServiceLevelProfileV1>,
325    },
326    SchemaSpec {
327        name: "error-budget-ledger-v1.schema.json",
328        writer: write_schema::<continuity_runtime::ErrorBudgetLedgerV1>,
329    },
330    SchemaSpec {
331        name: "incident-case-v1.schema.json",
332        writer: write_schema::<continuity_runtime::IncidentCaseV1>,
333    },
334    SchemaSpec {
335        name: "containment-decision-v1.schema.json",
336        writer: write_schema::<continuity_runtime::ContainmentDecisionV1>,
337    },
338    SchemaSpec {
339        name: "forensic-freeze-v1.schema.json",
340        writer: write_schema::<continuity_runtime::ForensicFreezeV1>,
341    },
342    SchemaSpec {
343        name: "recovery-plan-v1.schema.json",
344        writer: write_schema::<continuity_runtime::RecoveryPlanV1>,
345    },
346    SchemaSpec {
347        name: "recovery-replay-slice-v1.schema.json",
348        writer: write_schema::<continuity_runtime::RecoveryReplaySliceV1>,
349    },
350    SchemaSpec {
351        name: "continuity-exception-v1.schema.json",
352        writer: write_schema::<continuity_runtime::ContinuityExceptionV1>,
353    },
354    SchemaSpec {
355        name: "postmortem-bundle-v1.schema.json",
356        writer: write_schema::<continuity_runtime::PostmortemBundleV1>,
357    },
358    SchemaSpec {
359        name: "resilience-exercise-v1.schema.json",
360        writer: write_schema::<continuity_runtime::ResilienceExerciseV1>,
361    },
362    SchemaSpec {
363        name: "dispute-bundle-v1.schema.json",
364        writer: write_schema::<verification_control::DisputeBundleV1>,
365    },
366    SchemaSpec {
367        name: "disclosure-policy-v1.schema.json",
368        writer: write_schema::<verification_policy::DisclosurePolicyV1>,
369    },
370    SchemaSpec {
371        name: "disclosure-budget-v1.schema.json",
372        writer: write_schema::<verification_policy::DisclosureBudgetV1>,
373    },
374    SchemaSpec {
375        name: "pilot-loop-receipt-v1.schema.json",
376        writer: write_schema::<forge_pilot::LoopReceipt>,
377    },
378    SchemaSpec {
379        name: "verification-case-v1.schema.json",
380        writer: write_schema::<verification_control::VerificationCase>,
381    },
382    SchemaSpec {
383        name: "check-plan-v1.schema.json",
384        writer: write_schema::<verification_control::CheckPlan>,
385    },
386    SchemaSpec {
387        name: "verification-attempt-v1.schema.json",
388        writer: write_schema::<verification_control::VerificationAttempt>,
389    },
390    SchemaSpec {
391        name: "effect-review-case-v1.schema.json",
392        writer: write_schema::<verification_control::EffectReviewCaseV1>,
393    },
394    SchemaSpec {
395        name: "effect-block-receipt-v1.schema.json",
396        writer: write_schema::<verification_control::EffectBlockReceiptV1>,
397    },
398    SchemaSpec {
399        name: "delegation-review-case-v1.schema.json",
400        writer: write_schema::<verification_control::DelegationReviewCaseV1>,
401    },
402    SchemaSpec {
403        name: "release-gate-case-v1.schema.json",
404        writer: write_schema::<verification_control::ReleaseGateCaseV1>,
405    },
406    SchemaSpec {
407        name: "continuity-review-case-v1.schema.json",
408        writer: write_schema::<verification_control::ContinuityReviewCaseV1>,
409    },
410    SchemaSpec {
411        name: "control-receipt-v1.schema.json",
412        writer: write_schema::<verification_control::ControlReceipt>,
413    },
414    SchemaSpec {
415        name: "ledger-entry-v1.schema.json",
416        writer: write_schema::<verification_control::LedgerEntry>,
417    },
418    SchemaSpec {
419        name: "scheduler-decision-v1.schema.json",
420        writer: write_schema::<verification_control::SchedulerDecision>,
421    },
422    SchemaSpec {
423        name: "boundary-repair-record-v1.schema.json",
424        writer: write_schema::<verification_control::BoundaryRepairRecord>,
425    },
426    SchemaSpec {
427        name: "region-artifact-transport-v1.schema.json",
428        writer: write_schema::<verification_control::RegionArtifactTransport>,
429    },
430    SchemaSpec {
431        name: "syndrome-route-record-v1.schema.json",
432        writer: write_schema::<verification_control::SyndromeRouteRecord>,
433    },
434    SchemaSpec {
435        name: "policy-snapshot-v1.schema.json",
436        writer: write_schema::<verification_policy::PolicySnapshot>,
437    },
438    SchemaSpec {
439        name: "approval-record-v1.schema.json",
440        writer: write_schema::<verification_policy::ApprovalRecord>,
441    },
442    SchemaSpec {
443        name: "policy-decision-v1.schema.json",
444        writer: write_schema::<verification_policy::PolicyDecision>,
445    },
446    SchemaSpec {
447        name: "calibration-snapshot-v1.schema.json",
448        writer: write_schema::<verification_calibration::CalibrationSnapshot>,
449    },
450    SchemaSpec {
451        name: "nuisance-state-artifact-v1.schema.json",
452        writer: write_schema::<verification_calibration::NuisanceStateArtifact>,
453    },
454    SchemaSpec {
455        name: "promotion-decision-v1.schema.json",
456        writer: write_schema::<verification_adjudication::PromotionDecision>,
457    },
458    SchemaSpec {
459        name: "verification-disposition-v1.schema.json",
460        writer: write_schema::<verification_adjudication::VerificationDisposition>,
461    },
462    SchemaSpec {
463        name: "refutation-decision-v1.schema.json",
464        writer: write_schema::<verification_adjudication::RefutationDecision>,
465    },
466    SchemaSpec {
467        name: "rollback-plan-v1.schema.json",
468        writer: write_schema::<verification_adjudication::RollbackPlan>,
469    },
470    SchemaSpec {
471        name: "effect-adjudication-receipt-v1.schema.json",
472        writer: write_schema::<verification_adjudication::EffectAdjudicationReceiptV1>,
473    },
474    SchemaSpec {
475        name: "release-rollback-decision-v1.schema.json",
476        writer: write_schema::<verification_adjudication::ReleaseRollbackDecisionV1>,
477    },
478    SchemaSpec {
479        name: "adjudication-result-v1.schema.json",
480        writer: write_schema::<verification_adjudication::AdjudicationResult>,
481    },
482    SchemaSpec {
483        name: "loop-iteration-report-v1.schema.json",
484        writer: write_schema::<forge_pilot::LoopIterationReport>,
485    },
486    SchemaSpec {
487        name: "loop-report-v1.schema.json",
488        writer: write_schema::<forge_pilot::LoopReport>,
489    },
490    SchemaSpec {
491        name: "verification-plan-artifact-v1.schema.json",
492        writer: write_schema::<forge_pilot::VerificationPlanArtifact>,
493    },
494    SchemaSpec {
495        name: "repair-record-v1.schema.json",
496        writer: write_schema::<forge_pilot::RepairRecordV1>,
497    },
498    SchemaSpec {
499        name: "runtime-query-provenance-v1.schema.json",
500        writer: write_schema::<knowledge_runtime::RuntimeQueryProvenanceV1>,
501    },
502    SchemaSpec {
503        name: "inference-advisory-v1.schema.json",
504        writer: write_schema::<knowledge_runtime::InferenceAdvisory>,
505    },
506    SchemaSpec {
507        name: "inference-explanation-v1.schema.json",
508        writer: write_schema::<knowledge_runtime::InferenceExplanation>,
509    },
510    SchemaSpec {
511        name: "risk-gate-decision-v1.schema.json",
512        writer: write_schema::<knowledge_runtime::RiskGateDecision>,
513    },
514    SchemaSpec {
515        name: "import-failure-record-v1.schema.json",
516        writer: write_schema::<semantic_memory::ProjectionImportFailureReceiptEntry>,
517    },
518    SchemaSpec {
519        name: "treaty-bundle-v1.schema.json",
520        writer: write_schema::<federated_settlement::TreatyBundleV1>,
521    },
522    SchemaSpec {
523        name: "runtime-identity-set-v1.schema.json",
524        writer: write_schema::<federated_settlement::RuntimeIdentitySetV1>,
525    },
526    SchemaSpec {
527        name: "cross-runtime-equivalence-bundle-v1.schema.json",
528        writer: write_schema::<federated_settlement::CrossRuntimeEquivalenceBundleV1>,
529    },
530    SchemaSpec {
531        name: "shared-disposition-v1.schema.json",
532        writer: write_schema::<federated_settlement::SharedDispositionV1>,
533    },
534    SchemaSpec {
535        name: "local-dissent-record-v1.schema.json",
536        writer: write_schema::<federated_settlement::LocalDissentRecordV1>,
537    },
538    SchemaSpec {
539        name: "shared-view-downgrade-v1.schema.json",
540        writer: write_schema::<federated_settlement::SharedViewDowngradeV1>,
541    },
542    SchemaSpec {
543        name: "settlement-case-v1.schema.json",
544        writer: write_schema::<federated_settlement::SettlementCaseV1>,
545    },
546    SchemaSpec {
547        name: "settlement-receipt-v1.schema.json",
548        writer: write_schema::<federated_settlement::SettlementReceiptV1>,
549    },
550    SchemaSpec {
551        name: "shared-replay-slice-v1.schema.json",
552        writer: write_schema::<federated_settlement::SharedReplaySliceV1>,
553    },
554    SchemaSpec {
555        name: "shared-divergence-report-v1.schema.json",
556        writer: write_schema::<federated_settlement::SharedDivergenceReportV1>,
557    },
558    SchemaSpec {
559        name: "treaty-suspension-v1.schema.json",
560        writer: write_schema::<federated_settlement::TreatySuspensionV1>,
561    },
562    SchemaSpec {
563        name: "mechanism-bundle-v1.schema.json",
564        writer: write_schema::<mechanism_runtime::MechanismBundleV1>,
565    },
566    SchemaSpec {
567        name: "theory-version-v1.schema.json",
568        writer: write_schema::<mechanism_runtime::TheoryVersionV1>,
569    },
570    SchemaSpec {
571        name: "theory-library-v1.schema.json",
572        writer: write_schema::<mechanism_runtime::TheoryLibraryV1>,
573    },
574    SchemaSpec {
575        name: "hypothesis-library-v1.schema.json",
576        writer: write_schema::<mechanism_runtime::HypothesisLibraryV1>,
577    },
578    SchemaSpec {
579        name: "simulation-contract-v1.schema.json",
580        writer: write_schema::<mechanism_runtime::SimulationContractV1>,
581    },
582    SchemaSpec {
583        name: "fit-run-v1.schema.json",
584        writer: write_schema::<mechanism_runtime::FitRunV1>,
585    },
586    SchemaSpec {
587        name: "theory-refuter-suite-v1.schema.json",
588        writer: write_schema::<mechanism_runtime::TheoryRefuterSuiteV1>,
589    },
590    SchemaSpec {
591        name: "rollout-stability-report-v1.schema.json",
592        writer: write_schema::<mechanism_runtime::RolloutStabilityReportV1>,
593    },
594    SchemaSpec {
595        name: "discovery-program-v1.schema.json",
596        writer: write_schema::<discovery_portfolio::DiscoveryProgramV1>,
597    },
598    SchemaSpec {
599        name: "program-hypothesis-set-v1.schema.json",
600        writer: write_schema::<discovery_portfolio::ProgramHypothesisSetV1>,
601    },
602    SchemaSpec {
603        name: "portfolio-plan-v1.schema.json",
604        writer: write_schema::<discovery_portfolio::PortfolioPlanV1>,
605    },
606    SchemaSpec {
607        name: "experiment-campaign-v1.schema.json",
608        writer: write_schema::<discovery_portfolio::ExperimentCampaignV1>,
609    },
610    SchemaSpec {
611        name: "campaign-decision-trace-v1.schema.json",
612        writer: write_schema::<discovery_portfolio::CampaignDecisionTraceV1>,
613    },
614    SchemaSpec {
615        name: "information-value-estimate-v1.schema.json",
616        writer: write_schema::<discovery_portfolio::InformationValueEstimateV1>,
617    },
618    SchemaSpec {
619        name: "verification-load-budget-v1.schema.json",
620        writer: write_schema::<discovery_portfolio::VerificationLoadBudgetV1>,
621    },
622    SchemaSpec {
623        name: "charter-bundle-v1.schema.json",
624        writer: write_schema::<constitutional_memory::CharterBundleV1>,
625    },
626    SchemaSpec {
627        name: "doctrine-snapshot-v1.schema.json",
628        writer: write_schema::<constitutional_memory::DoctrineSnapshotV1>,
629    },
630    SchemaSpec {
631        name: "amendment-proposal-v1.schema.json",
632        writer: write_schema::<constitutional_memory::AmendmentProposalV1>,
633    },
634    SchemaSpec {
635        name: "amendment-decision-v1.schema.json",
636        writer: write_schema::<constitutional_memory::AmendmentDecisionV1>,
637    },
638    SchemaSpec {
639        name: "archive-manifest-v1.schema.json",
640        writer: write_schema::<constitutional_memory::ArchiveManifestV1>,
641    },
642    SchemaSpec {
643        name: "compaction-receipt-v1.schema.json",
644        writer: write_schema::<constitutional_memory::CompactionReceiptV1>,
645    },
646    SchemaSpec {
647        name: "historical-query-guarantee-v1.schema.json",
648        writer: write_schema::<constitutional_memory::HistoricalQueryGuaranteeV1>,
649    },
650    SchemaSpec {
651        name: "deprecation-bundle-v1.schema.json",
652        writer: write_schema::<constitutional_memory::DeprecationBundleV1>,
653    },
654    SchemaSpec {
655        name: "retirement-bundle-v1.schema.json",
656        writer: write_schema::<constitutional_memory::RetirementBundleV1>,
657    },
658    SchemaSpec {
659        name: "spec-bundle-v1.schema.json",
660        writer: write_schema::<spec_execution::SpecBundleV1>,
661    },
662    SchemaSpec {
663        name: "normative-ast-v1.schema.json",
664        writer: write_schema::<spec_execution::NormativeASTV1>,
665    },
666    SchemaSpec {
667        name: "generated-schema-bundle-v1.schema.json",
668        writer: write_schema::<spec_execution::GeneratedSchemaBundleV1>,
669    },
670    SchemaSpec {
671        name: "generated-interpreter-bundle-v1.schema.json",
672        writer: write_schema::<spec_execution::GeneratedInterpreterBundleV1>,
673    },
674    SchemaSpec {
675        name: "generated-conformance-corpus-v1.schema.json",
676        writer: write_schema::<spec_execution::GeneratedConformanceCorpusV1>,
677    },
678    SchemaSpec {
679        name: "generated-migration-plan-v1.schema.json",
680        writer: write_schema::<spec_execution::GeneratedMigrationPlanV1>,
681    },
682    SchemaSpec {
683        name: "proof-obligation-set-v1.schema.json",
684        writer: write_schema::<spec_execution::ProofObligationSetV1>,
685    },
686    SchemaSpec {
687        name: "proof-evaluation-receipt-v1.schema.json",
688        writer: write_schema::<spec_execution::ProofEvaluationReceiptV1>,
689    },
690    SchemaSpec {
691        name: "human-veto-bundle-v1.schema.json",
692        writer: write_schema::<spec_execution::HumanVetoBundleV1>,
693    },
694    SchemaSpec {
695        name: "meta-challenge-bundle-v1.schema.json",
696        writer: write_schema::<spec_execution::MetaChallengeBundleV1>,
697    },
698    SchemaSpec {
699        name: "self-hosting-build-receipt-v1.schema.json",
700        writer: write_schema::<spec_execution::SelfHostingBuildReceiptV1>,
701    },
702    SchemaSpec {
703        name: "effect-policy-profile-v1.schema.json",
704        writer: write_schema::<verification_policy::EffectPolicyProfileV1>,
705    },
706    SchemaSpec {
707        name: "delegation-policy-profile-v1.schema.json",
708        writer: write_schema::<verification_policy::DelegationPolicyProfileV1>,
709    },
710    SchemaSpec {
711        name: "release-policy-profile-v1.schema.json",
712        writer: write_schema::<verification_policy::ReleasePolicyProfileV1>,
713    },
714    SchemaSpec {
715        name: "continuity-policy-profile-v1.schema.json",
716        writer: write_schema::<verification_policy::ContinuityPolicyProfileV1>,
717    },
718    SchemaSpec {
719        name: "applicability-context-v1.schema.json",
720        writer: write_schema::<profile_runtime::ApplicabilityContextV1>,
721    },
722    SchemaSpec {
723        name: "profile-set-v1.schema.json",
724        writer: write_schema::<profile_runtime::ProfileSetV1>,
725    },
726    SchemaSpec {
727        name: "composition-rule-set-v1.schema.json",
728        writer: write_schema::<profile_runtime::CompositionRuleSetV1>,
729    },
730    SchemaSpec {
731        name: "composition-receipt-v1.schema.json",
732        writer: write_schema::<profile_runtime::CompositionReceiptV1>,
733    },
734    SchemaSpec {
735        name: "effective-constitution-v1.schema.json",
736        writer: write_schema::<profile_runtime::EffectiveConstitutionV1>,
737    },
738    SchemaSpec {
739        name: "compiled-obligation-set-v1.schema.json",
740        writer: write_schema::<profile_runtime::CompiledObligationSetV1>,
741    },
742    SchemaSpec {
743        name: "composition-conflict-set-v1.schema.json",
744        writer: write_schema::<profile_runtime::CompositionConflictSetV1>,
745    },
746    SchemaSpec {
747        name: "profile-exception-bundle-v1.schema.json",
748        writer: write_schema::<profile_runtime::ProfileExceptionBundleV1>,
749    },
750    SchemaSpec {
751        name: "policy-impact-diff-v1.schema.json",
752        writer: write_schema::<profile_runtime::PolicyImpactDiffV1>,
753    },
754    SchemaSpec {
755        name: "access-purpose-matrix-v1.schema.json",
756        writer: write_schema::<verification_policy::AccessPurposeMatrixV1>,
757    },
758    SchemaSpec {
759        name: "approval-matrix-v1.schema.json",
760        writer: write_schema::<authority_delegation::ApprovalMatrixV1>,
761    },
762    SchemaSpec {
763        name: "audit-extraction-policy-v1.schema.json",
764        writer: write_schema::<verification_policy::AuditExtractionPolicyV1>,
765    },
766    SchemaSpec {
767        name: "conflict-class-catalog-v1.schema.json",
768        writer: write_schema::<authority_delegation::ConflictClassCatalogV1>,
769    },
770    SchemaSpec {
771        name: "cross-boundary-transfer-class-v1.schema.json",
772        writer: write_schema::<verification_policy::CrossBoundaryTransferClassV1>,
773    },
774    SchemaSpec {
775        name: "delegation-matrix-v1.schema.json",
776        writer: write_schema::<authority_delegation::DelegationMatrixV1>,
777    },
778    SchemaSpec {
779        name: "escalation-clock-policy-v1.schema.json",
780        writer: write_schema::<continuity_runtime::EscalationClockPolicyV1>,
781    },
782    SchemaSpec {
783        name: "evidence-collection-plan-v1.schema.json",
784        writer: write_schema::<assurance_runtime::EvidenceCollectionPlanV1>,
785    },
786    SchemaSpec {
787        name: "hazard-library-v1.schema.json",
788        writer: write_schema::<assurance_runtime::HazardLibraryV1>,
789    },
790    SchemaSpec {
791        name: "hazard-scenario-v1.schema.json",
792        writer: write_schema::<assurance_runtime::HazardScenarioV1>,
793    },
794    SchemaSpec {
795        name: "incident-taxonomy-v1.schema.json",
796        writer: write_schema::<continuity_runtime::IncidentTaxonomyV1>,
797    },
798    SchemaSpec {
799        name: "locality-exception-v1.schema.json",
800        writer: write_schema::<verification_policy::LocalityExceptionV1>,
801    },
802    SchemaSpec {
803        name: "mitigation-playbook-v1.schema.json",
804        writer: write_schema::<assurance_runtime::MitigationPlaybookV1>,
805    },
806    SchemaSpec {
807        name: "monitor-catalog-v1.schema.json",
808        writer: write_schema::<assurance_runtime::MonitorCatalogV1>,
809    },
810    SchemaSpec {
811        name: "pager-route-profile-v1.schema.json",
812        writer: write_schema::<continuity_runtime::PagerRouteProfileV1>,
813    },
814    SchemaSpec {
815        name: "privacy-retention-profile-v1.schema.json",
816        writer: write_schema::<verification_policy::PrivacyRetentionProfileV1>,
817    },
818    SchemaSpec {
819        name: "recertification-schedule-v1.schema.json",
820        writer: write_schema::<assurance_runtime::RecertificationScheduleV1>,
821    },
822    SchemaSpec {
823        name: "redaction-rule-set-v1.schema.json",
824        writer: write_schema::<verification_policy::RedactionRuleSetV1>,
825    },
826    SchemaSpec {
827        name: "regulatory-regime-profile-v1.schema.json",
828        writer: write_schema::<assurance_runtime::RegulatoryRegimeProfileV1>,
829    },
830    SchemaSpec {
831        name: "requirement-control-map-v1.schema.json",
832        writer: write_schema::<assurance_runtime::RequirementControlMapV1>,
833    },
834    SchemaSpec {
835        name: "residency-policy-profile-v1.schema.json",
836        writer: write_schema::<verification_policy::ResidencyPolicyProfileV1>,
837    },
838    SchemaSpec {
839        name: "role-catalog-v1.schema.json",
840        writer: write_schema::<authority_delegation::RoleCatalogV1>,
841    },
842    SchemaSpec {
843        name: "severity-matrix-v1.schema.json",
844        writer: write_schema::<continuity_runtime::SeverityMatrixV1>,
845    },
846    SchemaSpec {
847        name: "tenant-boundary-profile-v1.schema.json",
848        writer: write_schema::<verification_policy::TenantBoundaryProfileV1>,
849    },
850    SchemaSpec {
851        name: "vendor-certification-adapter-v1.schema.json",
852        writer: write_schema::<attestation_exchange::VendorCertificationAdapterV1>,
853    },
854    SchemaSpec {
855        name: "vendor-evidence-translation-v1.schema.json",
856        writer: write_schema::<attestation_exchange::VendorEvidenceTranslationV1>,
857    },
858    SchemaSpec {
859        name: "vendor-revocation-handling-v1.schema.json",
860        writer: write_schema::<attestation_exchange::VendorRevocationHandlingV1>,
861    },
862    SchemaSpec {
863        name: "vendor-trust-root-binding-v1.schema.json",
864        writer: write_schema::<attestation_exchange::VendorTrustRootBindingV1>,
865    },
866    SchemaSpec {
867        name: "bridge-import-failure-artifact-v1.schema.json",
868        writer: write_schema::<forge_memory_bridge::BridgeImportFailureArtifact>,
869    },
870];
871
872/// Generates every registered schema into the supplied output directory.
873pub fn generate_schemas(out_dir: &Path) -> Result<Vec<PathBuf>, Box<dyn std::error::Error>> {
874    fs::create_dir_all(out_dir)?;
875
876    let mut written = Vec::with_capacity(SCHEMA_SPECS.len());
877    for spec in SCHEMA_SPECS {
878        (spec.writer)(out_dir, spec.name)?;
879        written.push(out_dir.join(spec.name));
880    }
881
882    Ok(written)
883}
884
885/// Returns the canonical checked-in schema directory.
886pub fn canonical_schema_dir() -> PathBuf {
887    PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../schemas")
888}
889
890/// Verifies that a directory exactly matches the generated canonical schema set.
891pub fn check_against_dir(expected_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
892    if !expected_dir.is_dir() {
893        return Err(format!(
894            "schema compatibility check failed: missing canonical schemas directory '{}'",
895            expected_dir.display()
896        )
897        .into());
898    }
899
900    let temp_dir = tempfile::tempdir()?;
901    let generated = generate_schemas(temp_dir.path())?;
902
903    for generated_path in generated {
904        let file_name = generated_path.file_name().ok_or_else(|| {
905            format!(
906                "generated schema path '{}' has no filename",
907                generated_path.display()
908            )
909        })?;
910        let expected_path = expected_dir.join(file_name);
911        if !expected_path.is_file() {
912            return Err(format!("missing canonical schema '{}'", expected_path.display()).into());
913        }
914
915        let expected = fs::read_to_string(&expected_path)?;
916        let actual = fs::read_to_string(&generated_path)?;
917        if expected != actual {
918            return Err(format!("schema drift detected for '{}'", expected_path.display()).into());
919        }
920    }
921
922    let mut canonical_entries = fs::read_dir(expected_dir)?
923        .map(|entry| entry.map(|entry| entry.path()))
924        .collect::<Result<Vec<_>, _>>()?;
925    canonical_entries.sort();
926
927    if canonical_entries.len() != SCHEMA_SPECS.len() {
928        return Err(format!(
929            "schema directory '{}' contains {} files but generator owns {}",
930            expected_dir.display(),
931            canonical_entries.len(),
932            SCHEMA_SPECS.len()
933        )
934        .into());
935    }
936
937    for expected in canonical_entries {
938        if !SCHEMA_SPECS
939            .iter()
940            .any(|spec| expected.ends_with(spec.name))
941        {
942            return Err(format!("unexpected canonical schema '{}'", expected.display()).into());
943        }
944    }
945
946    Ok(())
947}
948
949#[cfg(test)]
950mod tests {
951    use super::*;
952
953    #[test]
954    fn generates_expected_schema_set() {
955        let temp = tempfile::tempdir().unwrap();
956        let written = generate_schemas(temp.path()).unwrap();
957
958        assert_eq!(written.len(), SCHEMA_SPECS.len());
959        for spec in SCHEMA_SPECS {
960            assert!(
961                temp.path().join(spec.name).is_file(),
962                "expected '{}' to be generated",
963                spec.name
964            );
965        }
966    }
967
968    #[test]
969    fn canonical_schemas_match_generator_output() {
970        check_against_dir(&canonical_schema_dir()).unwrap();
971    }
972
973    #[test]
974    fn check_fails_when_schema_file_drifts() {
975        let temp = tempfile::tempdir().unwrap();
976        generate_schemas(temp.path()).unwrap();
977        let drifted = temp.path().join(SCHEMA_SPECS[0].name);
978        fs::write(&drifted, "{\n  \"drifted\": true\n}\n").unwrap();
979
980        let err = check_against_dir(temp.path()).unwrap_err();
981        assert!(err.to_string().contains("schema drift detected"));
982    }
983
984    #[test]
985    fn execution_evidence_schema_family_is_registered() {
986        let required = [
987            "forge-tool-receipt-v2.schema.json",
988            "episode-bundle-v1.schema.json",
989            "execution-context-v1.schema.json",
990            "control-receipt-v1.schema.json",
991            "loop-iteration-report-v1.schema.json",
992            "verification-plan-artifact-v1.schema.json",
993        ];
994
995        for name in required {
996            assert!(
997                SCHEMA_SPECS.iter().any(|spec| spec.name == name),
998                "missing execution-evidence schema registration for {name}"
999            );
1000        }
1001    }
1002
1003    // ─── LIB-C004: v9 constitutional artifact families must all have registered schemas ───
1004
1005    #[test]
1006    fn v9_canonical_bundle_schemas_are_registered() {
1007        // LIB-C001: Freeze canonical episode/claim/evidence package law.
1008        // Every wire-visible v9 bundle artifact must be governed by contract-schema-gen.
1009        let required = [
1010            "episode-bundle-v1.schema.json",
1011            "evidence-bundle-v1.schema.json",
1012            "execution-context-v1.schema.json",
1013            "export-envelope-v3.schema.json",
1014            "projection-import-batch-v3.schema.json",
1015        ];
1016        for name in required {
1017            assert!(
1018                SCHEMA_SPECS.iter().any(|spec| spec.name == name),
1019                "LIB-C001: missing canonical bundle schema registration for {name}"
1020            );
1021        }
1022    }
1023
1024    #[test]
1025    fn v9_execution_evidence_schemas_are_complete() {
1026        // LIB-C002: Freeze execution evidence artifacts.
1027        // All execution-evidence families must be governed.
1028        let required = [
1029            "forge-tool-receipt-v2.schema.json",
1030            "episode-bundle-v1.schema.json",
1031            "execution-context-v1.schema.json",
1032            "control-receipt-v1.schema.json",
1033            "scheduler-decision-v1.schema.json",
1034            "loop-iteration-report-v1.schema.json",
1035            "loop-report-v1.schema.json",
1036            "verification-plan-artifact-v1.schema.json",
1037            "repair-record-v1.schema.json",
1038            "runtime-query-provenance-v1.schema.json",
1039            "import-failure-record-v1.schema.json",
1040        ];
1041        for name in required {
1042            assert!(
1043                SCHEMA_SPECS.iter().any(|spec| spec.name == name),
1044                "LIB-C002: missing execution-evidence schema registration for {name}"
1045            );
1046        }
1047    }
1048
1049    #[test]
1050    fn v9_repair_law_schema_is_registered() {
1051        // LIB-C008: Repair law hardening.
1052        // RepairRecordV1 must be a governed schema, not folkloric.
1053        assert!(
1054            SCHEMA_SPECS
1055                .iter()
1056                .any(|spec| spec.name == "repair-record-v1.schema.json"),
1057            "LIB-C008: RepairRecordV1 must be a governed schema"
1058        );
1059    }
1060
1061    #[test]
1062    fn v9_runtime_provenance_schema_is_registered() {
1063        // LIB-C009: Runtime provenance completeness.
1064        // RuntimeQueryProvenanceV1 must be a governed schema.
1065        assert!(
1066            SCHEMA_SPECS
1067                .iter()
1068                .any(|spec| spec.name == "runtime-query-provenance-v1.schema.json"),
1069            "LIB-C009: RuntimeQueryProvenanceV1 must be a governed schema"
1070        );
1071    }
1072
1073    #[test]
1074    fn v9_bridge_atomicity_schemas_are_registered() {
1075        // LIB-C005: Bridge atomicity proofs.
1076        // Bridge failure and region transport artifacts must be governed schemas.
1077        let required = [
1078            "import-failure-record-v1.schema.json",
1079            "boundary-repair-record-v1.schema.json",
1080            "region-artifact-transport-v1.schema.json",
1081            "syndrome-route-record-v1.schema.json",
1082            "bridge-import-failure-artifact-v1.schema.json",
1083        ];
1084        for name in required {
1085            assert!(
1086                SCHEMA_SPECS.iter().any(|spec| spec.name == name),
1087                "LIB-C005: missing bridge atomicity schema registration for {name}"
1088            );
1089        }
1090    }
1091
1092    #[test]
1093    fn v9_governance_review_schemas_are_registered() {
1094        // LIB-C004: Schema governance enforcement.
1095        // All governance review case families must be governed schemas.
1096        let required = [
1097            "effect-review-case-v1.schema.json",
1098            "effect-block-receipt-v1.schema.json",
1099            "delegation-review-case-v1.schema.json",
1100            "release-gate-case-v1.schema.json",
1101            "continuity-review-case-v1.schema.json",
1102            "verification-case-v1.schema.json",
1103            "check-plan-v1.schema.json",
1104            "verification-attempt-v1.schema.json",
1105        ];
1106        for name in required {
1107            assert!(
1108                SCHEMA_SPECS.iter().any(|spec| spec.name == name),
1109                "LIB-C004: missing governance review schema registration for {name}"
1110            );
1111        }
1112    }
1113}