///|
pub(all) enum RecordIntegrityCheck {
AnalysisRecordSelfContained
WritePlanDeclaresRecord
BookCommitReady
ReplayAnchorsRecord
ExportAnchorsRecord
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) enum RecordIntegrityStatus {
Pass
NeedsWork
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct RecordIntegrityFinding {
run_id : @domain.RunId
check : RecordIntegrityCheck
status : RecordIntegrityStatus
path : String
message : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct RecordIntegrityReport {
run_id : @domain.RunId
ready : Bool
artifact_count : Int
findings : Array[RecordIntegrityFinding]
summary : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub fn record_integrity_finding(
run_id : @domain.RunId,
check : RecordIntegrityCheck,
status : RecordIntegrityStatus,
path : String,
message : String,
) -> RecordIntegrityFinding {
{ run_id, check, status, path, message }
}
///|
fn completed_record_finding(
bundle : @workflow.AnalysisRunBundle,
) -> RecordIntegrityFinding {
match bundle.projection {
Some(projection) => {
let record = projection.result.record
let snapshot = record.snapshot
if record.run_id == bundle.request.run_id &&
snapshot.symbol == bundle.request.market.symbol &&
snapshot.timeframe == bundle.request.market.timeframe &&
record.stage1 is Some(_) &&
record.stage2 is Some(_) &&
record.validation.length() > 0 &&
record.status is Persisted {
record_integrity_finding(
bundle.request.run_id,
AnalysisRecordSelfContained,
Pass,
"records/analyses/\{bundle.request.run_id}.json",
"analysis record carries run id, market snapshot, stage outputs, validation, and persisted status",
)
} else {
record_integrity_finding(
bundle.request.run_id,
AnalysisRecordSelfContained,
NeedsWork,
"records/analyses/\{bundle.request.run_id}.json",
"analysis record is missing self-contained run, market, stage, validation, or status evidence",
)
}
}
None =>
record_integrity_finding(
bundle.request.run_id,
AnalysisRecordSelfContained,
NeedsWork,
"analysis-run-bundle.projection",
"analysis projection is unavailable, so record integrity cannot be proven",
)
}
}
///|
fn artifact_declared(
plan : @book.BookWritePlan,
schema_id : String,
path : String,
) -> Bool {
plan.artifacts.any(fn(artifact) {
artifact.schema_id == schema_id && artifact.path == path
})
}
///|
fn write_plan_finding(
bundle : @workflow.AnalysisRunBundle,
) -> RecordIntegrityFinding {
match bundle.write_plan {
Some(plan) => {
let run_id = bundle.request.run_id
if artifact_declared(
plan,
"analysis-record",
"records/analyses/\{run_id}.json",
) &&
artifact_declared(
plan,
"kline-snapshot",
"raw/market-data/\{run_id}.json",
) {
record_integrity_finding(
run_id,
WritePlanDeclaresRecord,
Pass,
"book-write-plan",
"MoonBook write plan declares the analysis record and raw market snapshot",
)
} else {
record_integrity_finding(
run_id,
WritePlanDeclaresRecord,
NeedsWork,
"book-write-plan",
"MoonBook write plan is missing the analysis record or raw snapshot artifact",
)
}
}
None =>
record_integrity_finding(
bundle.request.run_id,
WritePlanDeclaresRecord,
NeedsWork,
"book-write-plan",
"MoonBook write plan is unavailable",
)
}
}
///|
fn ready_analysis_commit(
report : @book.BookCommitReport,
run_id : @domain.RunId,
) -> Bool {
report.commits.any(fn(commit) {
commit.artifact.schema_id == "analysis-record" &&
commit.artifact.path == "records/analyses/\{run_id}.json" &&
commit.status is ArtifactReady &&
commit.idempotency_key ==
"\{run_id}|analysis-record|records/analyses/\{run_id}.json"
})
}
///|
fn book_commit_finding(
bundle : @workflow.AnalysisRunBundle,
) -> RecordIntegrityFinding {
match bundle.book_commit {
Some(report) =>
if report.status is CommitReady &&
ready_analysis_commit(report, bundle.request.run_id) {
record_integrity_finding(
bundle.request.run_id,
BookCommitReady,
Pass,
"book-commit-report",
"analysis record commit is ready with a stable idempotency key",
)
} else {
record_integrity_finding(
bundle.request.run_id,
BookCommitReady,
NeedsWork,
"book-commit-report",
"analysis record commit is missing, blocked, or lacks a stable idempotency key",
)
}
None =>
record_integrity_finding(
bundle.request.run_id,
BookCommitReady,
NeedsWork,
"book-commit-report",
"book commit report is unavailable",
)
}
}
///|
fn replay_finding(
bundle : @workflow.AnalysisRunBundle,
) -> RecordIntegrityFinding {
let plan = @replay.prepare_replay_plan(bundle)
if plan.can_replay &&
plan.steps.any(fn(step) {
step.kind is LoadAnalysisRecord &&
step.path == "records/analyses/\{bundle.request.run_id}.json"
}) {
record_integrity_finding(
bundle.request.run_id,
ReplayAnchorsRecord,
Pass,
"replay-plan",
"replay plan anchors the durable analysis record",
)
} else {
record_integrity_finding(
bundle.request.run_id,
ReplayAnchorsRecord,
NeedsWork,
"replay-plan",
"replay plan does not anchor a replayable analysis record",
)
}
}
///|
fn export_finding(
bundle : @workflow.AnalysisRunBundle,
) -> RecordIntegrityFinding {
let manifest = @export.prepare_export_manifest(bundle)
if manifest.items.any(fn(item) {
item.schema_id == "analysis-record" &&
item.path == "records/analyses/\{bundle.request.run_id}.json" &&
item.required
}) {
record_integrity_finding(
bundle.request.run_id,
ExportAnchorsRecord,
Pass,
"export-manifest",
"audit export includes the durable analysis record",
)
} else {
record_integrity_finding(
bundle.request.run_id,
ExportAnchorsRecord,
NeedsWork,
"export-manifest",
"audit export does not include the durable analysis record",
)
}
}
///|
fn report_ready(findings : Array[RecordIntegrityFinding]) -> Bool {
findings.all(fn(finding) { finding.status is Pass })
}
///|
fn report_summary(report : RecordIntegrityReport) -> String {
let pass_count = report.findings.fold(init=0, fn(count, finding) {
if finding.status is Pass {
count + 1
} else {
count
}
})
if report.ready {
"record integrity report passed \{pass_count}/\{report.findings.length()} checks with \{report.artifact_count} artifact(s)"
} else {
"record integrity report has \{report.findings.length() - pass_count} check(s) needing work"
}
}
///|
fn artifact_count(bundle : @workflow.AnalysisRunBundle) -> Int {
match bundle.write_plan {
Some(plan) => plan.artifacts.length()
None => 0
}
}
///|
pub fn prepare_record_integrity_report(
bundle : @workflow.AnalysisRunBundle,
) -> RecordIntegrityReport {
let findings = [
completed_record_finding(bundle),
write_plan_finding(bundle),
book_commit_finding(bundle),
replay_finding(bundle),
export_finding(bundle),
]
let report : RecordIntegrityReport = {
run_id: bundle.request.run_id,
ready: report_ready(findings),
artifact_count: artifact_count(bundle),
findings,
summary: "",
}
{ ..report, summary: report_summary(report) }
}