///|
pub fn wiki_maintainer_skill_path() -> String {
"skills/wiki-maintainer/SKILL.md"
}
///|
pub fn default_keeper_skill_paths() -> Array[String] {
[wiki_maintainer_skill_path()]
}
///|
pub fn default_keeper_context_pages() -> Array[String] {
["wiki/index.md", "wiki/log.md"]
}
///|
pub fn fallback_keeper_policy_lines() -> Array[String] {
[
"Keep all memory and durable artifacts inside this book unless the task explicitly names a repository patch.",
"Return explicit blockers instead of fake completion when required tools or sources are missing.",
"Preserve MoonTown, MoonBook, and MoonClaw responsibility boundaries.",
]
}
///|
pub fn fallback_keeper_routine_lines() -> Array[String] {
[
"Read task context pages first.", "Create or update target pages listed in the task when applicable.",
"Report changed files, artifacts, blockers, and validation results.",
]
}
///|
pub fn fallback_keeper_memory_summary(
book_id : String,
task_id : String,
) -> String {
"Fallback MoonBook context for externally planned task `\{task_id}` in book `\{book_id}`."
}
///|
pub fn fallback_keeper_output_contract_lines() -> Array[String] {
[
"result_id", "summary", "artifacts", "memory_candidates", "requires_review",
"notify_town",
]
}
///|
pub fn executable_book_event_protocol() -> String {
"moonbook.executable_event.v1"
}
///|
pub struct ExecutableBookLifecycleProof {
contract_id : String
owner : String
session_id : String
book_root : String
ready : Bool
status : String
completed_step_count : Int
step_count : Int
blocked_step_count : Int
first_blocker_id : String
first_blocker_label : String
first_blocker_evidence : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub struct ExecutableBookEvent {
protocol : String
id : String
source : String
book_id : String
result_id : String
run_id : String?
event_type : String
accepted : Bool
requires_review : Bool
notify_town : Bool
summary : String
artifacts : Array[String]
evidence_id : String?
review_path : String?
lifecycle_proof : ExecutableBookLifecycleProof?
} derive(Debug, Eq, ToJson, FromJson)
///|
pub fn ExecutableBookEvent::new(
id~ : String,
book_id~ : String,
result_id~ : String,
summary~ : String,
artifacts? : Array[String] = [],
run_id? : String? = None,
event_type? : String = "knowledge_accepted",
accepted? : Bool = true,
requires_review? : Bool = false,
notify_town? : Bool = false,
evidence_id? : String? = None,
review_path? : String? = None,
lifecycle_proof? : ExecutableBookLifecycleProof? = None,
) -> ExecutableBookEvent {
{
protocol: executable_book_event_protocol(),
id,
source: "moonbook",
book_id,
result_id,
run_id,
event_type,
accepted,
requires_review,
notify_town,
summary,
artifacts,
evidence_id,
review_path,
lifecycle_proof,
}
}
///|
pub struct ExecutableBookEventRoute {
town_event : @core.TownEvent
notify_operator : Bool
lifecycle_status : String
lifecycle_ready : Bool
first_blocker_id : String
route_reason : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub fn ExecutableBookEvent::lifecycle_status(
self : ExecutableBookEvent,
) -> String {
match self.lifecycle_proof {
Some(proof) => proof.status
None => "unknown"
}
}
///|
pub fn ExecutableBookEvent::lifecycle_ready(self : ExecutableBookEvent) -> Bool {
match self.lifecycle_proof {
Some(proof) => proof.ready
None => true
}
}
///|
pub fn ExecutableBookEvent::first_lifecycle_blocker_id(
self : ExecutableBookEvent,
) -> String {
match self.lifecycle_proof {
Some(proof) => proof.first_blocker_id
None => ""
}
}
///|
pub fn ExecutableBookEvent::has_lifecycle_blocker(
self : ExecutableBookEvent,
) -> Bool {
match self.lifecycle_proof {
Some(proof) => !proof.ready
None => false
}
}
///|
pub fn ExecutableBookEvent::should_notify_town(
self : ExecutableBookEvent,
) -> Bool {
self.notify_town ||
self.accepted ||
self.requires_review ||
self.has_lifecycle_blocker()
}
///|
pub fn ExecutableBookEvent::town_event_kind(
self : ExecutableBookEvent,
) -> String {
if self.requires_review {
"book.review_required"
} else if self.has_lifecycle_blocker() {
"book.lifecycle_blocked"
} else if self.accepted {
"book.knowledge_accepted"
} else {
"book.result"
}
}
///|
pub fn ExecutableBookEvent::route_reason(self : ExecutableBookEvent) -> String {
if self.requires_review {
"review_required"
} else if self.has_lifecycle_blocker() {
"lifecycle_blocked"
} else if self.accepted {
"knowledge_accepted"
} else if self.notify_town {
"notify_requested"
} else {
"record_only"
}
}
///|
pub fn ExecutableBookEvent::to_town_event(
self : ExecutableBookEvent,
index : Int,
proposal_id? : String? = None,
) -> @core.TownEvent {
let kind = self.town_event_kind()
let evidence = self.evidence_id.unwrap_or("none")
let lifecycle = self.lifecycle_status()
let blocker = self.first_lifecycle_blocker_id()
let lifecycle_detail = if blocker == "" {
"lifecycle=\{lifecycle}"
} else {
"lifecycle=\{lifecycle}; blocker=\{blocker}"
}
@core.TownEvent::new(
id="event-book-\{index}-\{self.id}",
kind~,
detail="\{self.book_id} / \{self.result_id}: \{self.event_type}; artifacts=\{self.artifacts.length()}; evidence=\{evidence}; \{lifecycle_detail}; \{self.summary}",
related_task_id=Some(self.result_id),
related_book_id=Some(self.book_id),
related_proposal_id=proposal_id,
related_run_id=self.run_id,
)
}
///|
pub fn ExecutableBookEvent::route_to_town(
self : ExecutableBookEvent,
index : Int,
proposal_id? : String? = None,
) -> ExecutableBookEventRoute {
{
town_event: self.to_town_event(index, proposal_id~),
notify_operator: self.should_notify_town(),
lifecycle_status: self.lifecycle_status(),
lifecycle_ready: self.lifecycle_ready(),
first_blocker_id: self.first_lifecycle_blocker_id(),
route_reason: self.route_reason(),
}
}
///|
pub fn executable_book_event_core_fields() -> Array[String] {
[
"protocol", "id", "source", "book_id", "result_id", "event_type", "accepted",
"requires_review", "notify_town", "summary", "artifacts",
]
}
///|
pub fn executable_book_event_optional_fields() -> Array[String] {
["run_id", "evidence_id", "review_path", "lifecycle_proof"]
}