///|
/// Evidence gates for the systematic long-form production lifecycle.
pub(all) enum ProductionGate {
G0Brief
G1RightsBible
G2Creative
G3ProductionAuthorization
G4Assets
G5Master
G6ClientAcceptance
G7Delivery
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) enum ProductionStage {
Draft
BriefReady
RightsReady
CreativeApproved
ProductionAuthorized
AssetsReady
MasterApproved
ClientAccepted
DeliveryAuthorized
Delivered
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct GateReceipt {
gate : ProductionGate
actor : String
evidence_digest : String
decided_at : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct ProductionReadiness {
brief_complete : Bool
rights_cleared : Bool
bible_locked : Bool
script_approved : Bool
storyboard_approved : Bool
animatic_approved : Bool
route_authorized : Bool
budget_authorized : Bool
shots_complete : Bool
provenance_complete : Bool
qc_approved : Bool
editorial_approved : Bool
client_accepted : Bool
delivery_planned : Bool
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct ProductionProjectSummary {
project_id : String
stage : ProductionStage
target_duration_seconds : Int
episode_count : Int
scene_count : Int
shot_count : Int
budget_cny : Double
spent_cny : Double
gate_receipts : Array[GateReceipt]
} derive(Debug, Eq, ToJson, FromJson)
///|
pub fn production_gate_sequence() -> Array[ProductionGate] {
[
G0Brief,
G1RightsBible,
G2Creative,
G3ProductionAuthorization,
G4Assets,
G5Master,
G6ClientAcceptance,
G7Delivery,
]
}
///|
pub fn production_gate_ready(
gate : ProductionGate,
readiness : ProductionReadiness,
) -> Bool {
match gate {
G0Brief => readiness.brief_complete
G1RightsBible => readiness.rights_cleared && readiness.bible_locked
G2Creative =>
readiness.script_approved &&
readiness.storyboard_approved &&
readiness.animatic_approved
G3ProductionAuthorization =>
readiness.route_authorized && readiness.budget_authorized
G4Assets => readiness.shots_complete && readiness.provenance_complete
G5Master => readiness.qc_approved && readiness.editorial_approved
G6ClientAcceptance => readiness.client_accepted
G7Delivery => readiness.delivery_planned
}
}
///|
pub fn next_production_gate(receipts : Array[GateReceipt]) -> ProductionGate? {
for gate in production_gate_sequence() {
if !receipts.any(receipt => receipt.gate == gate) {
return Some(gate)
}
}
None
}
///|
pub fn systematic_delivery_ready(
summary : ProductionProjectSummary,
readiness : ProductionReadiness,
) -> Bool {
summary.target_duration_seconds >= 180 &&
summary.target_duration_seconds <= 480 &&
summary.shot_count > 0 &&
summary.spent_cny <= summary.budget_cny &&
production_gate_sequence().all(gate => production_gate_ready(gate, readiness)) &&
next_production_gate(summary.gate_receipts) is None
}