Clarify CultNet receipt authority
This commit is contained in:
parent
361116b4bc
commit
dd5530ecb5
3 changed files with 74 additions and 1 deletions
|
|
@ -1387,6 +1387,7 @@ fn epiphany_mutation_contracts() -> Vec<CultNetDocumentMutationContract> {
|
|||
vec![RUNTIME_JOB_TYPE],
|
||||
vec![
|
||||
"Worker launch requests are typed task-intent documents; runtime jobs are lifecycle receipts, not the source of work intent.",
|
||||
"Core/coordinator policy owns the launch yes/no; transport bridges translate, gather host facts, execute side effects, and return receipts.",
|
||||
],
|
||||
),
|
||||
mutation_contract(
|
||||
|
|
@ -1597,6 +1598,7 @@ fn epiphany_mutation_contracts() -> Vec<CultNetDocumentMutationContract> {
|
|||
vec![
|
||||
"Reorientation policy is the typed resume/regather verdict surface.",
|
||||
"Launch and acceptance stay review-gated through explicit typed intents.",
|
||||
"The bridge may carry a reorient launch intent and report receipts, but the resume/regather verdict belongs to core.",
|
||||
],
|
||||
),
|
||||
read_only_surface_contract(
|
||||
|
|
@ -1618,6 +1620,7 @@ fn epiphany_mutation_contracts() -> Vec<CultNetDocumentMutationContract> {
|
|||
vec![
|
||||
"Job reflection over typed job bindings and runtime-spine lifecycle receipts.",
|
||||
"Heartbeat/runtime-spine owns activation; callers submit typed intents and watch receipts.",
|
||||
"Launch receipts must name decisionOwner and bridgeRole so transport never grows an unreadable second opinion.",
|
||||
],
|
||||
),
|
||||
coordinator_surface_contract(
|
||||
|
|
@ -2282,6 +2285,25 @@ mod tests {
|
|||
schema.document_type.as_deref() == Some("epiphany.swarm_control_receipt.v0")
|
||||
&& schema.schema_version.as_deref() == Some("epiphany.swarm_control_receipt.v0")
|
||||
}));
|
||||
let receipt_schema_path =
|
||||
epiphany_schema_root().join("epiphany.swarm-control-receipt.schema.json");
|
||||
let receipt_schema: serde_json::Value =
|
||||
serde_json::from_str(&fs::read_to_string(receipt_schema_path)?)?;
|
||||
let required = receipt_schema["required"]
|
||||
.as_array()
|
||||
.expect("receipt schema should list required fields");
|
||||
assert!(required.iter().any(|field| field == "decisionOwner"));
|
||||
assert!(required.iter().any(|field| field == "bridgeRole"));
|
||||
assert!(
|
||||
receipt_schema["properties"]["decisionOwner"]["description"]
|
||||
.as_str()
|
||||
.is_some_and(|description| description.contains("epiphany-core"))
|
||||
);
|
||||
assert!(
|
||||
receipt_schema["properties"]["bridgeRole"]["description"]
|
||||
.as_str()
|
||||
.is_some_and(|description| description.contains("transport"))
|
||||
);
|
||||
assert!(schemas.iter().any(|schema| {
|
||||
schema.document_type.as_deref() == Some(OPENAI_MODEL_REQUEST_TYPE)
|
||||
&& schema.schema_version.as_deref() == Some(OPENAI_MODEL_REQUEST_SCHEMA_VERSION)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://gamecult.dev/epiphany/cultnet/epiphany.swarm-control-receipt.schema.json",
|
||||
"title": "Epiphany Swarm Control Receipt",
|
||||
"description": "Generic receipt emitted after a coordinator-owned Epiphany control action.",
|
||||
"description": "Generic receipt emitted after a coordinator-owned Epiphany control action. The receipt names the authority that made the final yes/no decision and the transport role that carried it out.",
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
|
|
@ -18,6 +18,41 @@
|
|||
"authority": {
|
||||
"type": "string"
|
||||
},
|
||||
"decisionOwner": {
|
||||
"type": "string",
|
||||
"description": "Authority that made the final yes/no verdict. For Epiphany-owned launch and reorientation flows this is epiphany-core, not the transport bridge."
|
||||
},
|
||||
"bridgeRole": {
|
||||
"type": "string",
|
||||
"description": "What the bridge did for this action. Expected values are transport, translate, gatherHostFacts, executeSideEffects, and reportReceipt, alone or joined with '+'."
|
||||
},
|
||||
"intentDocumentType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"decision": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"verdict": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string"
|
||||
},
|
||||
"sourceDocumentType": {
|
||||
"type": "string"
|
||||
},
|
||||
"sourceRevision": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"targetDocumentType": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
@ -51,6 +86,20 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"hostFacts": {
|
||||
"type": "array",
|
||||
"description": "Host/runtime facts gathered by the bridge before execution, expressed as readable labels or artifact refs rather than private context.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"sideEffects": {
|
||||
"type": "array",
|
||||
"description": "Side effects the bridge performed after the core/coordinator verdict.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"note": {
|
||||
"type": "string"
|
||||
}
|
||||
|
|
@ -60,6 +109,8 @@
|
|||
"ok",
|
||||
"action",
|
||||
"authority",
|
||||
"decisionOwner",
|
||||
"bridgeRole",
|
||||
"targetDocumentType",
|
||||
"status",
|
||||
"summary"
|
||||
|
|
|
|||
Binary file not shown.
Reference in a new issue