///|
pub(all) enum SafetyCheckKind {
NoBrokerExecutionPath
DecisionPolicyBoundary
ContextBudgetWithinWindow
BookCommitCompleteness
SecretRedactionBoundary
PublicExportRedaction
ReplayWithoutLiveMarket
SuiteOwnershipBoundary
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) enum SafetyStatus {
Pass
Fail
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct SafetyFinding {
run_id : @domain.RunId
kind : SafetyCheckKind
status : SafetyStatus
path : String
message : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct SafetyReport {
run_id : @domain.RunId
ok : Bool
findings : Array[SafetyFinding]
} derive(Debug, Eq, ToJson, FromJson)
///|
pub fn safety_finding(
run_id : @domain.RunId,
kind : SafetyCheckKind,
status : SafetyStatus,
path : String,
message : String,
) -> SafetyFinding {
{ run_id, kind, status, path, message }
}
///|
fn disallowed_tool_name(name : String) -> Bool {
name == "execute_order" ||
name == "place_order" ||
name == "submit_order" ||
name == "broker_order"
}
///|
fn no_broker_execution_finding(
run_id : @domain.RunId,
manifest : @pack.PackManifest,
) -> SafetyFinding {
let blocked = manifest.tools.any(fn(tool) { disallowed_tool_name(tool.name) })
if blocked {
safety_finding(
run_id,
NoBrokerExecutionPath,
Fail,
"pack.tools",
"pack declares a broker/order execution tool",
)
} else {
safety_finding(
run_id,
NoBrokerExecutionPath,
Pass,
"pack.tools",
"pack exposes analysis, review, replay, export, and view tools only",
)
}
}
///|
fn decision_policy_finding(
bundle : @workflow.AnalysisRunBundle,
) -> SafetyFinding {
let report = @policy.evaluate_decision_policy(
@policy.decision_policy_input(
bundle.request.run_id,
bundle.request.diagnosis,
bundle.request.decision,
),
)
if report.allowed {
safety_finding(
bundle.request.run_id,
DecisionPolicyBoundary,
Pass,
"decision-policy-report",
report.summary,
)
} else {
safety_finding(
bundle.request.run_id,
DecisionPolicyBoundary,
Fail,
"decision-policy-report",
report.summary,
)
}
}
///|
fn context_budget_finding(
bundle : @workflow.AnalysisRunBundle,
) -> SafetyFinding {
match bundle.projection {
Some(projection) =>
if projection.context_budget.ok {
safety_finding(
bundle.request.run_id,
ContextBudgetWithinWindow,
Pass,
"context-budget-report",
projection.context_budget.summary,
)
} else {
safety_finding(
bundle.request.run_id,
ContextBudgetWithinWindow,
Fail,
"context-budget-report",
projection.context_budget.summary,
)
}
None =>
safety_finding(
bundle.request.run_id,
ContextBudgetWithinWindow,
Pass,
"context-budget-report",
"context budget waits for prompt assembly",
)
}
}
///|
fn book_commit_finding(bundle : @workflow.AnalysisRunBundle) -> SafetyFinding {
match bundle.book_commit {
Some(report) =>
if report.status is CommitReady {
safety_finding(
bundle.request.run_id,
BookCommitCompleteness,
Pass,
"book-commit-report",
report.summary,
)
} else {
safety_finding(
bundle.request.run_id,
BookCommitCompleteness,
Fail,
"book-commit-report",
report.summary,
)
}
None =>
safety_finding(
bundle.request.run_id,
BookCommitCompleteness,
Pass,
"book-commit-report",
"book commit waits for completed run artifacts",
)
}
}
///|
fn secret_redaction_boundary_finding(
bundle : @workflow.AnalysisRunBundle,
) -> SafetyFinding {
let report = prepare_redaction_audit(bundle)
if report.ok {
safety_finding(
bundle.request.run_id,
SecretRedactionBoundary,
Pass,
"redaction-audit-report",
report.summary,
)
} else {
safety_finding(
bundle.request.run_id,
SecretRedactionBoundary,
Fail,
"redaction-audit-report",
report.summary,
)
}
}
///|
fn raw_model_schema(schema_id : String) -> Bool {
schema_id == "prompt-packet" ||
schema_id == "model-call-request" ||
schema_id == "model-call-response"
}
///|
fn public_export_redaction_finding(
bundle : @workflow.AnalysisRunBundle,
) -> SafetyFinding {
let manifest = @export.prepare_export_manifest(bundle, profile=PublicSummary)
let unsafe_item = manifest.items.any(fn(item) {
raw_model_schema(item.schema_id) || !item.public
})
if manifest.includes_raw_model_exchange || unsafe_item {
safety_finding(
bundle.request.run_id,
PublicExportRedaction,
Fail,
"export.public-summary",
"public export includes raw prompts, model exchange, or private items",
)
} else {
safety_finding(
bundle.request.run_id,
PublicExportRedaction,
Pass,
"export.public-summary",
"public export omits prompt packets, model requests, and model responses",
)
}
}
///|
fn replay_without_live_market_finding(
bundle : @workflow.AnalysisRunBundle,
) -> SafetyFinding {
let replay_plan = @replay.prepare_replay_plan(bundle)
if replay_plan.live_market_required {
safety_finding(
bundle.request.run_id,
ReplayWithoutLiveMarket,
Fail,
"replay-plan.live_market_required",
"replay requires live market data",
)
} else {
safety_finding(
bundle.request.run_id,
ReplayWithoutLiveMarket,
Pass,
"replay-plan.live_market_required",
"replay is planned over persisted MoonBook evidence",
)
}
}
///|
fn owner_allowed(owner : @pack.PackOwner) -> Bool {
owner is MoonGate ||
owner is MoonClaw ||
owner is MoonBook ||
owner is Moondesk ||
owner is PriceAction
}
///|
fn suite_ownership_finding(
run_id : @domain.RunId,
manifest : @pack.PackManifest,
) -> SafetyFinding {
let invalid = manifest.tools.any(fn(tool) { !owner_allowed(tool.owner) })
if invalid {
safety_finding(
run_id,
SuiteOwnershipBoundary,
Fail,
"pack.tools.owner",
"a tool is outside the declared MoonSuite ownership boundaries",
)
} else {
safety_finding(
run_id,
SuiteOwnershipBoundary,
Pass,
"pack.tools.owner",
"all tools are owned by MoonGate, MoonClaw, MoonBook, Moondesk, or PriceAction",
)
}
}
///|
fn report_ok(findings : Array[SafetyFinding]) -> Bool {
findings.all(fn(finding) { finding.status is Pass })
}
///|
pub fn prepare_safety_report(
bundle : @workflow.AnalysisRunBundle,
manifest? : @pack.PackManifest = @pack.price_action_manifest(),
) -> SafetyReport {
let run_id = bundle.request.run_id
let findings = [
no_broker_execution_finding(run_id, manifest),
decision_policy_finding(bundle),
context_budget_finding(bundle),
book_commit_finding(bundle),
secret_redaction_boundary_finding(bundle),
public_export_redaction_finding(bundle),
replay_without_live_market_finding(bundle),
suite_ownership_finding(run_id, manifest),
]
{ run_id, ok: report_ok(findings), findings }
}