feat(pncc): make lifecycle retries idempotent

GuangHu-Human-Responsibility: ICE-GL∞ / 冰朔
GuangHu-Persona-Cognitive-Author: ICE-P-ZY001 / 铸渊
GuangHu-Execution-Runtime: Codex macOS / DEV-20260810-014
GuangHu-Development-ID: DEV-20260810-014
GuangHu-Authorization-Scope: GH-PNCC local runtime development and registered REPO-014 publication
GuangHu-Source-Language-Anchor: continue PNCC persona runtime; UI and execution limb remain deferred
This commit is contained in:
铸渊 / ICE-P-ZY001 2026-08-11 03:21:15 +08:00
commit 38ef9d0e11
10 changed files with 427 additions and 13 deletions

View file

@ -87,6 +87,15 @@ before wake or lease acquisition, then delegates to the same tested organ transa
completion beside the wake receipt. It does not accept an execution action, infer organ permissions from UI
state, or create a parallel lifecycle record.
`requestId` is the coordinator's idempotency key, not a UI message id. The runtime derives a stable session
identity from the exact persona and request id, and hashes the non-secret semantic request. API keys and
provider headers are excluded; the manifest-pinned provider id, endpoint, model id, operation, Git head, and
attribution remain included. A successful lifecycle stores one hash-bound receipt in its existing session
directory and records the request id, fingerprint, and receipt hash in the same session record. Exact retries
return that verified lifecycle with `replayed: true`. A changed request under the same id fails with
`PERSONA_LIFECYCLE_REQUEST_CONFLICT`; a partial session without a complete receipt fails recovery-required
instead of launching a duplicate.
`PersonaRuntimeQueryReceipt` is a bounded projection of the durable runtime files, not another truth store.
It filters by the caller's expected persona and canonical repository, validates each matching event chain,
and returns at most 100 newest session summaries. Dormant sessions expose no active organ. The receipt keeps

View file

@ -58,6 +58,15 @@ sense. It then owns one complete session from wake through the existing organ tr
the wake receipt and the typed completion receipt. It cannot express or activate `EXECUTION_LIMB`, does not
add a scheduler or second state store, and runs the complete lifecycle on the blocking task pool.
The coordinator also requires a caller-stable lifecycle request id. Persona id plus request id derives one
deterministic session id, while a credential-free fingerprint binds the canonical repository, expected Git
head, wake identity, attribution, organ, and semantic operation. A completed request persists its typed
lifecycle receipt beside the existing session record and cross-binds its hash into that record. An identical
retry verifies the session event chain, dormant state, released lease, fingerprint, and receipt hash before
replaying the same lifecycle value without invoking an organ or committing Git again. Reusing the request id
for different semantics is a conflict. A session without a complete bound receipt is recovery-required and
is never treated as permission to start a second lifecycle.
`query_persona_code_channel_runtime` is the bounded read model for later projection surfaces. The caller must
name one exact persona and canonical repository and may request at most 100 sessions. The kernel reads the
existing session records and event journals directly, verifies every returned hash chain, sorts by the last