fix: bind successful receipt wake boundary
Human-Responsibility: ICE-GL∞ / 冰朔 Persona-Author: ICE-P-ZY001 / 铸渊 Execution-Runtime: Codex desktop / DEV-20260810-014 Development-ID: DEV-20260810-014 Authorization-Scope: GH-PNCC persona runtime source and tests only; no UI, deployment, or execution limb Source-Anchor: user instruction to continue GH-PNCC from repository facts and verifiable receipts
This commit is contained in:
parent
869611962e
commit
b05d135707
7 changed files with 101 additions and 5 deletions
|
|
@ -180,6 +180,7 @@ failure_receipt_terminal_evidence_binding_source_implemented: 100
|
|||
successful_receipt_semantic_evidence_binding_source_implemented: 100
|
||||
successful_receipt_brain_entry_evidence_binding_source_implemented: 100
|
||||
successful_receipt_wake_checkpoint_evidence_binding_source_implemented: 100
|
||||
successful_receipt_wake_event_boundary_evidence_binding_source_implemented: 100
|
||||
general_purpose_persona_runtime_implemented: 0
|
||||
human_live_projection_implemented: 0
|
||||
hololake_integrated: 0
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ const MAX_FACT_SOURCE_BYTES: usize = 128_000;
|
|||
const MAX_FACT_CONTEXT_BYTES: usize = 512_000;
|
||||
const MAX_FACT_RESPONSE_BYTES: usize = 128_000;
|
||||
const MAX_SESSION_QUERY_LIMIT: usize = 100;
|
||||
const WAKE_EVENT_COUNT: usize = 3;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
@ -2736,9 +2737,12 @@ fn validate_persisted_lifecycle_terminal_evidence(
|
|||
.get("events")
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.ok_or("PERSONA_LIFECYCLE_COMPLETION_EVIDENCE_MISMATCH")?;
|
||||
if wake_events.len() != WAKE_EVENT_COUNT {
|
||||
return Err("PERSONA_LIFECYCLE_COMPLETION_EVIDENCE_MISMATCH".into());
|
||||
}
|
||||
let expected_wake_events = expected_events
|
||||
.as_array()
|
||||
.and_then(|all| all.get(..wake_events.len()))
|
||||
.and_then(|all| all.get(..WAKE_EVENT_COUNT))
|
||||
.ok_or("PERSONA_LIFECYCLE_COMPLETION_EVIDENCE_MISMATCH")?;
|
||||
let wake_terminal_hash = wake_events
|
||||
.last()
|
||||
|
|
@ -4378,6 +4382,57 @@ mod tests {
|
|||
assert!(error.contains("PERSONA_LIFECYCLE_COMPLETION_EVIDENCE_MISMATCH"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_a_rehashed_completed_receipt_with_truncated_wake_events() {
|
||||
let repo = persona_repo();
|
||||
let runtime = tempfile::TempDir::new().unwrap();
|
||||
let input = lifecycle_fact_input(repo.path());
|
||||
let first = run_idempotent_lifecycle_at(
|
||||
runtime.path(),
|
||||
input.clone(),
|
||||
"2026-08-11T00:00:00.000Z",
|
||||
"2026-08-11T00:00:01.000Z",
|
||||
|runtime_root, input, timestamp| {
|
||||
run_fact_task_at(runtime_root, input, timestamp, |_, _| {
|
||||
Ok(r#"{"summary":"Recoverable receipt.","facts":[{"statement":"The brain exists.","evidencePaths":["brain/CORE.hdlp"]}],"limitations":[]}"#.into())
|
||||
})
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let session_id = first.lifecycle["sessionId"].as_str().unwrap();
|
||||
let mut record = load_session_record(runtime.path(), session_id).unwrap();
|
||||
record.request_id = None;
|
||||
record.request_fingerprint = None;
|
||||
record.lifecycle_receipt_hash = None;
|
||||
write_session_record(runtime.path(), &record).unwrap();
|
||||
|
||||
let receipt_path = session_directory(runtime.path(), session_id)
|
||||
.unwrap()
|
||||
.join("lifecycle-receipt.json");
|
||||
let mut persisted: PersistedPersonaLifecycleReceipt =
|
||||
serde_json::from_slice(&fs::read(&receipt_path).unwrap()).unwrap();
|
||||
let first_wake_hash = persisted.lifecycle["wakeReceipt"]["events"][0]["eventHash"]
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.to_string();
|
||||
persisted.lifecycle["wakeReceipt"]["events"]
|
||||
.as_array_mut()
|
||||
.unwrap()
|
||||
.truncate(1);
|
||||
persisted.lifecycle["wakeReceipt"]["receiptId"] =
|
||||
format!("PNCC-WAKE-{}", &first_wake_hash[..20]).into();
|
||||
persisted.lifecycle_receipt_hash =
|
||||
hex_digest(&persisted_lifecycle_payload_bytes(&persisted).unwrap());
|
||||
fs::write(
|
||||
&receipt_path,
|
||||
serde_json::to_vec_pretty(&persisted).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let error = inspect_lifecycle_request_at(runtime.path(), &input).unwrap_err();
|
||||
assert!(error.contains("PERSONA_LIFECYCLE_COMPLETION_EVIDENCE_MISMATCH"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reconstructs_legacy_wake_checkpoint_evidence_from_the_wake_git_head() {
|
||||
let repo = persona_repo();
|
||||
|
|
|
|||
Loading…
Reference in a new issue