///|
pub(all) enum ReadinessState {
Ready
NeedsEvidence
Blocked
Planned
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) enum BuildLane {
DataLane
TerrainLane
MissionLane
ViewerLane
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct KernelLayer {
layer_id : String
label : String
owns : String
source_contract : String
current_artifact : String
readiness : ReadinessState
next_output : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct EvidenceGate {
gate_id : String
label : String
owner_package : String
readiness : ReadinessState
proof_artifact : String
blocker : String
next_action : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct BuildTask {
task_id : String
priority : Int
lane : BuildLane
title : String
outcome : String
depends_on : Array[String]
evidence : Array[String]
done_when : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct MoonMoonKernel {
kernel_id : String
product_name : String
current_site_id : String
thesis : String
operating_rule : String
layers : Array[KernelLayer]
evidence_gates : Array[EvidenceGate]
build_queue : Array[BuildTask]
} derive(Debug, Eq, ToJson, FromJson)
///|
pub fn readiness_state_label(state : ReadinessState) -> String {
match state {
Ready => "ready"
NeedsEvidence => "needs-evidence"
Blocked => "blocked"
Planned => "planned"
}
}
///|
pub fn build_lane_label(lane : BuildLane) -> String {
match lane {
DataLane => "data"
TerrainLane => "terrain"
MissionLane => "mission"
ViewerLane => "viewer"
}
}
///|
fn source_gate(dossier : @site.SiteDossier) -> EvidenceGate {
let ready = dossier.validations.length() == dossier.datasets.length() &&
dossier.catalog_evidence.length() >= 4
{
gate_id: "catalog-backed-source-evidence",
label: "Cataloged lunar source evidence backs the model",
owner_package: "src/data_core + src/lunar_data + src/terrain",
readiness: if ready {
Ready
} else {
Blocked
},
proof_artifact: "indexes/catalog.json + terrain fixture validation",
blocker: if ready {
"none"
} else {
"catalog evidence or terrain fixture validation is incomplete"
},
next_action: if ready {
"connect more product labels directly to catalog refs"
} else {
"repair catalog evidence before changing terrain claims"
},
}
}
///|
fn route_gate(dossier : @site.SiteDossier) -> EvidenceGate {
let best = dossier.corridor_scan[0]
let promoted = best.selected_route_id != ""
{
gate_id: "promoted-corridor-route",
label: "Best measured corridor window is promoted into route evidence",
owner_package: "src/mission",
readiness: if promoted {
Ready
} else {
NeedsEvidence
},
proof_artifact: "src/mission/generated_first_trusted_square_corridor_scan.mbt#\{best.window_id}",
blocker: if promoted {
"none"
} else {
"best measured corridor has no selected route"
},
next_action: if promoted {
"tighten the selected route blockers"
} else {
"bind the best corridor window to a named route candidate"
},
}
}
///|
fn energy_gate(dossier : @site.SiteDossier) -> EvidenceGate {
let power = dossier.power_window_evidence
{
gate_id: "time-windowed-energy",
label: "Power-window evidence is attached to route scoring",
owner_package: "src/mission",
readiness: if power.has_time_window_ephemeris {
Ready
} else {
Blocked
},
proof_artifact: power.local_source_path,
blocker: if power.has_time_window_ephemeris {
"none"
} else {
"missing time-windowed ephemeris evidence"
},
next_action: "review energy margin before allowing the selected traverse",
}
}
///|
fn ui_gate(_dossier : @site.SiteDossier) -> EvidenceGate {
{
gate_id: "standalone-ui",
label: "MoonBit-owned standalone operator UI renders from the view model",
owner_package: "src/ui",
readiness: Ready,
proof_artifact: "src/ui/page.mbt",
blocker: "none",
next_action: "move to a Rabbita-style app only when interaction needs justify it",
}
}
///|
fn kernel_layers(dossier : @site.SiteDossier) -> Array[KernelLayer] {
[
{
layer_id: "source-registry",
label: "Source registry",
owns: "catalog refs, source manifests, checksums, acquisition notes, extraction candidates",
source_contract: "lunar_data -> data_core catalog evidence -> product views",
current_artifact: "src/site/catalog_evidence.mbt",
readiness: Ready,
next_output: "route remaining product evidence labels through catalog refs",
},
{
layer_id: "terrain-world",
label: "Terrain world",
owns: "DEM cells, metrics, roughness, slope, hazard classification",
source_contract: "LOLA evidence -> TerrainGrid -> TerrainMetrics",
current_artifact: "src/terrain",
readiness: if dossier.terrain.hazard_class ==
@terrain.HazardClass::Blocked {
Blocked
} else {
Ready
},
next_output: "promote a smoother corridor tile before expanding the world",
},
{
layer_id: "mission-constraints",
label: "Mission constraints",
owns: "traverse scoring, corridor ranking, horizon, terrain remediation, energy gates",
source_contract: "terrain metrics + power evidence -> route decision",
current_artifact: "src/mission",
readiness: if dossier.energy.decision == @mission.TraverseDecision::Allow {
Ready
} else {
Blocked
},
next_output: "make the selected route clearance checklist smaller and stricter",
},
{
layer_id: "site-dossier",
label: "Site dossier",
owns: "one inspectable lunar site model assembled from the domain packages",
source_contract: "core + data_core + lunar_data + terrain + mission -> SiteDossier",
current_artifact: "src/site/site.mbt",
readiness: Ready,
next_output: "add a second site only after the first site gates are clean",
},
{
layer_id: "operator-view",
label: "Operator view",
owns: "renderer-neutral view model and standalone HTML inspection surface",
source_contract: "SiteDossier -> TrustedSquareViewModel -> HTML/JSON",
current_artifact: "src/ui",
readiness: Ready,
next_output: "Rabbita-style UI package when live controls outgrow static HTML",
},
]
}
///|
fn catalog_artifact_ids(dossier : @site.SiteDossier) -> Array[String] {
let ids : Array[String] = []
for evidence in dossier.catalog_evidence {
ids.push(
"\{evidence.artifact.artifact_kind}/\{evidence.artifact.artifact_id}",
)
}
ids
}
///|
fn build_queue(dossier : @site.SiteDossier) -> Array[BuildTask] {
let best = dossier.corridor_scan[0]
[
{
task_id: "clear-selected-route-blockers",
priority: 100,
lane: MissionLane,
title: "Clear or explain the selected northeast-stepout route blockers",
outcome: "the product can answer why the selected route is blocked without suite-side artifacts",
depends_on: ["src/mission", "src/site/site.mbt"],
evidence: [best.window_id, best.selected_route_id],
done_when: "selected route blockers are represented by small MoonBit data structures and tests",
},
{
task_id: "catalog-backed-product-evidence",
priority: 80,
lane: DataLane,
title: "Keep product source evidence wired through catalog refs",
outcome: "source labels and authority in the product come from catalog evidence, not standalone fixture constants",
depends_on: ["src/data_core", "src/lunar_data", "src/site"],
evidence: catalog_artifact_ids(dossier),
done_when: "the UI source panel and kernel source gate name catalog artifacts and tests prove the refs",
},
{
task_id: "moonmoon-ui-package",
priority: 50,
lane: ViewerLane,
title: "Keep the live terrain viewer in the Rabbita UI package",
outcome: "MoonMoon keeps browser behavior in an explicit Rabbita package without hiding assets in domain packages",
depends_on: ["src/ui", "ui/rabbita-moon/main"],
evidence: ["cd ui/rabbita-moon && moon build --target js"],
done_when: "ui/rabbita-moon owns live browser behavior and src/ui remains renderer-neutral data",
},
]
}
///|
pub fn system_kernel() -> MoonMoonKernel {
let dossier = @site.first_trusted_square_dossier()
{
kernel_id: "moonmoon/kernel/standalone-v1",
product_name: "MoonMoon",
current_site_id: dossier.site.site_id,
thesis: "MoonMoon is a MoonBit-native lunar terrain and mission model, not a generated artifact bundle.",
operating_rule: "Domain claims live in typed MoonBit packages; generated outputs are build products, not source architecture.",
layers: kernel_layers(dossier),
evidence_gates: [
source_gate(dossier),
route_gate(dossier),
energy_gate(dossier),
ui_gate(dossier),
],
build_queue: build_queue(dossier),
}
}
///|
pub fn top_priority_task(kernel : MoonMoonKernel) -> BuildTask {
let mut best = kernel.build_queue[0]
for task in kernel.build_queue {
if task.priority > best.priority {
best = task
}
}
best
}
///|
pub fn render_markdown(kernel : MoonMoonKernel) -> String {
let mut text = "# \{kernel.product_name} Kernel\n\n"
text += "\{kernel.thesis}\n\n"
text += "Operating rule: \{kernel.operating_rule}\n\n"
text += "## Layers\n\n"
for layer in kernel.layers {
text += "- \{layer.layer_id}: \{readiness_state_label(layer.readiness)}\n"
text += " - owns: \{layer.owns}\n"
text += " - artifact: \{layer.current_artifact}\n"
text += " - next: \{layer.next_output}\n"
}
text += "\n## Evidence Gates\n\n"
for gate in kernel.evidence_gates {
text += "- \{gate.gate_id}: \{readiness_state_label(gate.readiness)}\n"
text += " - owner: \{gate.owner_package}\n"
text += " - proof: \{gate.proof_artifact}\n"
text += " - blocker: \{gate.blocker}\n"
text += " - next: \{gate.next_action}\n"
}
text += "\n## Build Queue\n\n"
for task in kernel.build_queue {
text += "- P\{task.priority} \{task.task_id} [\{build_lane_label(task.lane)}]\n"
text += " - \{task.title}\n"
text += " - done: \{task.done_when}\n"
}
text
}
///|
pub fn render_json(kernel : MoonMoonKernel) -> Json {
kernel.to_json()
}
///|
pub fn system_kernel_markdown() -> String {
render_markdown(system_kernel())
}
///|
pub fn system_kernel_json() -> Json {
render_json(system_kernel())
}