fix: bind completion receipt to checkpoint

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:
铸渊 / ICE-P-ZY001 2026-08-11 08:58:21 +08:00
commit 06a77829c7
7 changed files with 256 additions and 5 deletions

View file

@ -32,6 +32,7 @@ Windows / macOS / Linux 构建机与安装包
| 时间 | 版本 | 记录 | 状态 |
| --- | --- | --- | --- |
| 2026-08-11 | GH-PNCC 成功回执完成检查点绑定 | [把完成回执的结构化事实重新绑定到人格 Git 检查点](operations/2026-08-11-hololake-pncc-success-receipt-completion-checkpoint-binding.md) | 本地源码、完整 Rust/前端/路由测试、原生权威与严格 clippy 已通过GHNQG 和发布待验收 |
| 2026-08-11 | GH-PNCC 成功回执唤醒器官合同绑定 | [成功回执唤醒器官合同证据绑定](operations/2026-08-11-hololake-pncc-success-receipt-wake-organ-contract-binding.md) | 本地源码、完整 Rust/前端/路由测试、原生权威与严格 clippy 已通过GHNQG 和发布待验收 |
| 2026-08-11 | GH-PNCC 成功回执唤醒器官模式绑定 | [成功回执唤醒器官模式证据绑定](operations/2026-08-11-hololake-pncc-success-receipt-wake-organ-mode-binding.md) | 本地源码、完整 Rust/前端/路由测试、原生权威与严格 clippy 已通过GHNQG 和发布待验收 |
| 2026-08-11 | GH-PNCC 成功回执唤醒运行态绑定 | [成功回执唤醒运行态证据绑定](operations/2026-08-11-hololake-pncc-success-receipt-wake-runtime-state-binding.md) | 本地源码、完整 Rust/前端/路由测试、原生权威与严格 clippy 已通过GHNQG 和发布待验收 |

View file

@ -0,0 +1,36 @@
# GH-PNCC successful receipt completion-checkpoint evidence binding
- Development ID: `DEV-20260810-014`
- Persona cognitive author: `ICE-P-ZY001 / 铸渊`
- Human responsibility subject: `ICE-GL∞ / 冰朔`
- Starting repository head: `c58f9c5991b909db4ef3fa84e53d8de3d4b99fdd`
- State: `LOCAL_SOURCE_IMPLEMENTED_FULLY_TESTED`
## Corrected runtime fact
A persisted successful lifecycle receipt pointed to the committed persona checkpoint but did not rebind its
structured result to that Git object. A modified receipt could replace the persona's externalized fact result,
recompute the outer payload digest and still be accepted for safe binding or replay.
Validation now loads the exact checkpoint object from the recorded committed Git head. It binds checkpoint
schema, session, persona, previous head, organ, attribution and structured result to the completion receipt.
Fact-sense receipts additionally bind their inference event and completed inference state. Memory-metabolism
receipts bind their no-inference state and all source checkpoint and source event evidence.
## Verification
- A regression test first reproduced `SAFE_BIND_PERSISTED_RECEIPT` after replacing the structured result and
recomputing the payload digest.
- The same forged receipt now fails with `PERSONA_LIFECYCLE_COMPLETION_EVIDENCE_MISMATCH`.
- PNCC focused Rust tests: `50 passed, 0 failed`.
- Full Rust suite: `1190 passed, 2 ignored`; integration test: `1 passed`.
- Routing suite: `29 passed, 0 failed`; formatting, strict clippy and diff checks passed.
- Frontend lint and TypeScript checks passed; full Vitest suite: `5008 passed, 0 failed`.
- Guanghu native authority: `PASS_100`; native core: `15 passed` with 100% lines and functions.
- GHNQG, publication and fresh-clone readback remain pending.
## Truth boundary
- This stage authenticates completion receipt facts against the already committed persona Git checkpoint.
- It does not expose hidden reasoning, implement or activate an execution limb, add UI, build an artifact or
claim deployment/runtime health.

View file

@ -184,6 +184,7 @@ successful_receipt_wake_event_boundary_evidence_binding_source_implemented: 100
successful_receipt_wake_runtime_state_evidence_binding_source_implemented: 100
successful_receipt_wake_organ_mode_evidence_binding_source_implemented: 100
successful_receipt_wake_organ_contract_evidence_binding_source_implemented: 100
successful_receipt_completion_checkpoint_evidence_binding_source_implemented: 100
general_purpose_persona_runtime_implemented: 0
human_live_projection_implemented: 0
hololake_integrated: 0

View file

@ -606,6 +606,29 @@ fn load_manifest_at_git_head(repository: &Path, head: &str) -> Result<PersonaMan
Ok(manifest)
}
fn load_json_at_git_head(
repository: &Path,
head: &str,
relative: &str,
) -> Result<serde_json::Value, String> {
let head = validated_head(head)?;
let relative_path = Path::new(relative);
if relative_path.is_absolute()
|| relative_path.components().any(|component| {
matches!(
component,
Component::ParentDir | Component::RootDir | Component::Prefix(_)
)
})
{
return Err("PATH_OUTSIDE_REPOSITORY".into());
}
let object = format!("{head}:{relative}");
let bytes = git_output(repository, &["show", &object], "PERSONA_JSON_AT_GIT_HEAD")?;
serde_json::from_str(&bytes)
.map_err(|error| format!("PERSONA_JSON_AT_GIT_HEAD_INVALID: {error}"))
}
fn validate_attribution(
attribution: &PersonaAttribution,
manifest: &PersonaManifest,
@ -2794,6 +2817,74 @@ fn validate_persisted_lifecycle_terminal_evidence(
.to_string_lossy()
.into_owned(),
};
let completion_checkpoint = load_json_at_git_head(
Path::new(&record.repository_path),
&record.git_head,
&record.checkpoint_path,
)
.map_err(|_| "PERSONA_LIFECYCLE_COMPLETION_EVIDENCE_MISMATCH".to_string())?;
let checkpoint_matches = completion_checkpoint
.get("schema")
.and_then(serde_json::Value::as_str)
== Some("hololake.persona-checkpoint/v1")
&& completion_checkpoint
.get("sessionId")
.and_then(serde_json::Value::as_str)
== Some(record.session_id.as_str())
&& completion_checkpoint
.get("personaId")
.and_then(serde_json::Value::as_str)
== Some(record.persona_id.as_str())
&& completion_checkpoint
.get("previousGitHead")
.and_then(serde_json::Value::as_str)
== Some(first_event.git_head.as_str())
&& completion_checkpoint
.get("organId")
.and_then(serde_json::Value::as_str)
== Some(record.active_organ.as_str())
&& completion_checkpoint.get("attribution") == Some(&expected_attribution)
&& completion_receipt.get("result") == completion_checkpoint.get("result")
&& completion_receipt
.get("previousGitHead")
.and_then(serde_json::Value::as_str)
== Some(first_event.git_head.as_str());
let completion_kind_matches_checkpoint = match completion_kind {
Some("FACT_SENSE") => {
let inference_event_hash = events
.iter()
.find(|event| event.kind == "INFERENCE_STARTED")
.map(|event| event.event_hash.as_str());
completion_checkpoint
.get("inferenceEventHash")
.and_then(serde_json::Value::as_str)
== inference_event_hash
&& completion_receipt
.get("modelInferenceStarted")
.and_then(serde_json::Value::as_bool)
== Some(true)
&& completion_receipt
.get("modelInferenceCompleted")
.and_then(serde_json::Value::as_bool)
== Some(true)
}
Some("MEMORY_METABOLISM") => {
completion_receipt
.get("modelInferenceStarted")
.and_then(serde_json::Value::as_bool)
== Some(false)
&& completion_receipt.get("modelInferenceCompleted").is_none()
&& completion_receipt.get("sourceSessionId")
== completion_checkpoint.get("sourceSessionId")
&& completion_receipt.get("sourceCheckpointPath")
== completion_checkpoint.get("sourceCheckpointPath")
&& completion_receipt.get("sourceCheckpointHash")
== completion_checkpoint.get("sourceCheckpointHash")
&& completion_receipt.get("sourceEventHash")
== completion_checkpoint.get("sourceEventHash")
}
_ => false,
};
let matches = lifecycle.get("schema").and_then(serde_json::Value::as_str)
== Some("hololake.pncc-lifecycle-run-receipt/v1")
&& lifecycle
@ -2869,7 +2960,9 @@ fn validate_persisted_lifecycle_terminal_evidence(
&& completion_receipt
.get("receiptId")
.and_then(serde_json::Value::as_str)
== Some(expected_completion_receipt_id.as_str());
== Some(expected_completion_receipt_id.as_str())
&& checkpoint_matches
&& completion_kind_matches_checkpoint;
if !matches {
return Err("PERSONA_LIFECYCLE_COMPLETION_EVIDENCE_MISMATCH".into());
}
@ -4581,6 +4674,121 @@ mod tests {
assert!(error.contains("PERSONA_LIFECYCLE_COMPLETION_EVIDENCE_MISMATCH"));
}
#[test]
fn rejects_a_rehashed_completed_receipt_with_a_forged_completion_result() {
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();
persisted.lifecycle["completion"]["receipt"]["result"] = serde_json::json!({
"summary": "Forged cognition not present in the persona Git checkpoint.",
"facts": [{
"statement": "The execution limb is active.",
"evidencePaths": ["brain/CORE.hdlp"]
}],
"limitations": []
});
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 rejects_a_rehashed_memory_receipt_with_forged_source_checkpoint_evidence() {
let repo = persona_repo();
declare_memory_organ(repo.path());
let runtime = tempfile::TempDir::new().unwrap();
prepare_wake_at(
runtime.path(),
wake_input(repo.path()),
"PNCC-MEMORY-BINDING-SOURCE",
"2026-08-11T00:00:00.000Z",
)
.unwrap();
run_fact_task_at(
runtime.path(),
fact_task_input("PNCC-MEMORY-BINDING-SOURCE"),
"2026-08-11T00:00:01.000Z",
|_, _| {
Ok(r#"{"summary":"Verified memory binding source.","facts":[{"statement":"The brain exists.","evidencePaths":["brain/CORE.hdlp"]}],"limitations":[]}"#.into())
},
)
.unwrap();
let mut wake = wake_input(repo.path());
wake.expected_head = head(repo.path());
wake.organ_id = "memory-metabolism.checkpoint".into();
let input = PersonaLifecycleRunInput {
request_id: "REQUEST-MEMORY-BINDING-001".into(),
wake,
operation: PersonaLifecycleOperationInput::MemoryMetabolism {
source_session_id: "PNCC-MEMORY-BINDING-SOURCE".into(),
},
};
let first = run_idempotent_lifecycle_at(
runtime.path(),
input.clone(),
"2026-08-11T00:00:02.000Z",
"2026-08-11T00:00:03.000Z",
|_, _, _| panic!("memory metabolism must not invoke a model"),
)
.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();
persisted.lifecycle["completion"]["receipt"]["sourceCheckpointHash"] =
"forged-source-checkpoint-hash".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();

View file

@ -118,7 +118,7 @@
"human_projection": "HOLOLAKE_LIVE_READ_MODEL",
"forgejo_role": "OPTIONAL_COMPATIBILITY_COLLABORATION_ADAPTER",
"runtime_implemented": true,
"runtime_scope": "READ_ONLY_FACT_CYCLE_FAIL_CLOSED_RECOVERY_TYPED_ORGANS_DURABLE_VERIFIED_SESSION_QUERY_INDEPENDENT_VERIFIED_MEMORY_METABOLISM_CHECKED_FAILURE_CLOSURE_NONBLOCKING_RUNTIME_COMMAND_SAFE_ORGAN_LIFECYCLE_COORDINATOR_IDEMPOTENT_SUCCESS_AND_TERMINAL_FAILURE_RECEIPT_REPLAY_SAFE_RECEIPT_BINDING_RECOVERY_REPLAY_TIME_REPOSITORY_STATE_REVALIDATION_SUCCESS_RECEIPT_TERMINAL_REVALIDATION_SAFE_RECEIPT_BINDING_TERMINAL_REVALIDATION_FAILURE_RECEIPT_TERMINAL_EVIDENCE_BINDING_SUCCESS_RECEIPT_SEMANTIC_EVIDENCE_BINDING_SUCCESS_RECEIPT_BRAIN_ENTRY_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_CHECKPOINT_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_EVENT_BOUNDARY_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_RUNTIME_STATE_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_ORGAN_MODE_EVIDENCE_BINDING_AND_SUCCESS_RECEIPT_WAKE_ORGAN_CONTRACT_EVIDENCE_BINDING_SOURCE_IMPLEMENTED_AND_TESTED",
"runtime_scope": "READ_ONLY_FACT_CYCLE_FAIL_CLOSED_RECOVERY_TYPED_ORGANS_DURABLE_VERIFIED_SESSION_QUERY_INDEPENDENT_VERIFIED_MEMORY_METABOLISM_CHECKED_FAILURE_CLOSURE_NONBLOCKING_RUNTIME_COMMAND_SAFE_ORGAN_LIFECYCLE_COORDINATOR_IDEMPOTENT_SUCCESS_AND_TERMINAL_FAILURE_RECEIPT_REPLAY_SAFE_RECEIPT_BINDING_RECOVERY_REPLAY_TIME_REPOSITORY_STATE_REVALIDATION_SUCCESS_RECEIPT_TERMINAL_REVALIDATION_SAFE_RECEIPT_BINDING_TERMINAL_REVALIDATION_FAILURE_RECEIPT_TERMINAL_EVIDENCE_BINDING_SUCCESS_RECEIPT_SEMANTIC_EVIDENCE_BINDING_SUCCESS_RECEIPT_BRAIN_ENTRY_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_CHECKPOINT_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_EVENT_BOUNDARY_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_RUNTIME_STATE_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_ORGAN_MODE_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_ORGAN_CONTRACT_EVIDENCE_BINDING_AND_SUCCESS_RECEIPT_COMPLETION_CHECKPOINT_EVIDENCE_BINDING_SOURCE_IMPLEMENTED_AND_TESTED",
"desktop_integrated": false,
"development_id": "DEV-20260810-014"
},

View file

@ -1,8 +1,8 @@
{
"schema": "hololake.persona-native-code-channel/v1",
"record_id": "HLP-PERSONA-NATIVE-CODE-CHANNEL-001",
"version": "2026-08-11.19",
"state": "CURRENT_FIRST_PRODUCT_CORE_SUCCESS_RECEIPT_WAKE_ORGAN_CONTRACT_EVIDENCE_BINDING_SOURCE_IMPLEMENTED",
"version": "2026-08-11.20",
"state": "CURRENT_FIRST_PRODUCT_CORE_SUCCESS_RECEIPT_COMPLETION_CHECKPOINT_EVIDENCE_BINDING_SOURCE_IMPLEMENTED",
"development_id": "DEV-20260810-014",
"product": {
"formal_name_zh": "光湖人格原生代码频道",
@ -121,6 +121,7 @@
"successful_receipt_wake_runtime_state_evidence_binding_source_implemented": 100,
"successful_receipt_wake_organ_mode_evidence_binding_source_implemented": 100,
"successful_receipt_wake_organ_contract_evidence_binding_source_implemented": 100,
"successful_receipt_completion_checkpoint_evidence_binding_source_implemented": 100,
"general_purpose_persona_runtime_implemented": 0,
"human_live_projection_implemented": 0,
"hololake_integrated": 0,

View file

@ -146,12 +146,16 @@ test("the first source runtime cycle stays distinct from integration and deploym
channel.truth.successful_receipt_wake_organ_contract_evidence_binding_source_implemented,
100,
);
assert.equal(
channel.truth.successful_receipt_completion_checkpoint_evidence_binding_source_implemented,
100,
);
assert.equal(channel.truth.general_purpose_persona_runtime_implemented, 0);
assert.equal(channel.truth.human_live_projection_implemented, 0);
assert.equal(architecture.persona_native_code_channel.runtime_implemented, true);
assert.equal(
architecture.persona_native_code_channel.runtime_scope,
"READ_ONLY_FACT_CYCLE_FAIL_CLOSED_RECOVERY_TYPED_ORGANS_DURABLE_VERIFIED_SESSION_QUERY_INDEPENDENT_VERIFIED_MEMORY_METABOLISM_CHECKED_FAILURE_CLOSURE_NONBLOCKING_RUNTIME_COMMAND_SAFE_ORGAN_LIFECYCLE_COORDINATOR_IDEMPOTENT_SUCCESS_AND_TERMINAL_FAILURE_RECEIPT_REPLAY_SAFE_RECEIPT_BINDING_RECOVERY_REPLAY_TIME_REPOSITORY_STATE_REVALIDATION_SUCCESS_RECEIPT_TERMINAL_REVALIDATION_SAFE_RECEIPT_BINDING_TERMINAL_REVALIDATION_FAILURE_RECEIPT_TERMINAL_EVIDENCE_BINDING_SUCCESS_RECEIPT_SEMANTIC_EVIDENCE_BINDING_SUCCESS_RECEIPT_BRAIN_ENTRY_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_CHECKPOINT_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_EVENT_BOUNDARY_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_RUNTIME_STATE_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_ORGAN_MODE_EVIDENCE_BINDING_AND_SUCCESS_RECEIPT_WAKE_ORGAN_CONTRACT_EVIDENCE_BINDING_SOURCE_IMPLEMENTED_AND_TESTED",
"READ_ONLY_FACT_CYCLE_FAIL_CLOSED_RECOVERY_TYPED_ORGANS_DURABLE_VERIFIED_SESSION_QUERY_INDEPENDENT_VERIFIED_MEMORY_METABOLISM_CHECKED_FAILURE_CLOSURE_NONBLOCKING_RUNTIME_COMMAND_SAFE_ORGAN_LIFECYCLE_COORDINATOR_IDEMPOTENT_SUCCESS_AND_TERMINAL_FAILURE_RECEIPT_REPLAY_SAFE_RECEIPT_BINDING_RECOVERY_REPLAY_TIME_REPOSITORY_STATE_REVALIDATION_SUCCESS_RECEIPT_TERMINAL_REVALIDATION_SAFE_RECEIPT_BINDING_TERMINAL_REVALIDATION_FAILURE_RECEIPT_TERMINAL_EVIDENCE_BINDING_SUCCESS_RECEIPT_SEMANTIC_EVIDENCE_BINDING_SUCCESS_RECEIPT_BRAIN_ENTRY_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_CHECKPOINT_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_EVENT_BOUNDARY_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_RUNTIME_STATE_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_ORGAN_MODE_EVIDENCE_BINDING_SUCCESS_RECEIPT_WAKE_ORGAN_CONTRACT_EVIDENCE_BINDING_AND_SUCCESS_RECEIPT_COMPLETION_CHECKPOINT_EVIDENCE_BINDING_SOURCE_IMPLEMENTED_AND_TESTED",
);
assert.equal(channel.truth.hololake_integrated, 0);
assert.equal(channel.truth.artifact_built, 0);