feat(core): fingerprint assembled system prompt with SHA-256 (#110)#129
feat(core): fingerprint assembled system prompt with SHA-256 (#110)#129web-dev0521 wants to merge 5 commits into
Conversation
…d#110) Add a real SHA-256 of the fully-assembled system prompt so the M1 exit criterion 'system prompt SHA is identical across full-stack restart' is provable and silent prompt drift between runs becomes a visible hash mismatch instead of an undetected behavior change. - New pure-Rust prompt_sha module (no crypto dependency, honoring the runtime_contract no-crypto policy), pinned to the FIPS-180 known-answer vectors so a transcription error fails CI. - genie-core logs system_prompt_sha at boot and serves it on /api/health. - genie-ctl status prints it as 'Prompt:'. - New prompt_sha_test boots prompt assembly twice from identical config + hydrated state and asserts an identical SHA, and asserts a prompt-assembly or hydration change shifts the digest.
|
Review note: not merging this in the current state because it is not mergeable against The core idea still looks aligned with M1, but the branch needs to be refreshed against current |
|
Hi, @ai-hpc , |
|
Reviewed and closed: this PR is now conflicting with current main and is not safe to merge as-is. Please reopen or resubmit a rebased branch if you want to continue it; thanks @web-dev0521. |
ai-hpc
left a comment
There was a problem hiding this comment.
Reviewed and reopened with changes requested: #110 is valid, but this branch is conflicting and only the PR-body check ran, so it is not merge-ready. Please rebase on current main, drop or rework stale README/CHANGELOG conflicts, and provide passing fmt/clippy/test proof; thanks @web-dev0521.
…; add missing blank line The real_server_client_disconnect_cancels_llm_producer test called ChatServer::new with 9 arguments; the system_prompt_sha parameter added in this branch's feature commit was never threaded through, causing a type-mismatch compile error that failed all four CI jobs (fmt, clippy, test, no-default-features). Also adds the blank line rustfmt requires between api_probe_addr and SKILL_RESTART_HINT in genie-ctl/src/main.rs (cargo fmt --check, exit 1).
cargo fmt --all --check broke the single-line assert_eq! because its argument list exceeds the fn_call_width heuristic; reformat across lines to match rustfmt output.
Summary
Adds a real SHA-256 fingerprint of the fully-assembled system prompt so the M1 exit criterion "system prompt SHA is identical across full-stack restart" is provable, and silent prompt drift between runs becomes a visible hash mismatch instead of an undetected behavior change. Closes #110.
Changes
prompt_shamodule computing a SHA-256 hex digest. No crypto dependency (honors the existingruntime_contractno-crypto policy); the digest is an operational determinism fingerprint, not a security primitive.Pinned to the FIPS-180 known-answer vectors so any transcription drift in the constants fails CI.
system_prompt_sha=…), and serves it assystem_prompt_shaon/api/health.genie-ctl statusprints it asPrompt: <sha>.prompt_sha_testintegration test: two prompt assemblies from identical config + hydrated state produce an identical SHA; a model-family (assembly) change or a hydration change shifts the SHA.Real Behavior Proof
What I ran
Environment: Windows 11 dev host, no Jetson available and no Rust toolchain installed on this box, so I could not run
cargo build/clippy/testlocally. The Rust build/clippy/test gates run in CI.To verify the hand-written SHA-256 is a genuine SHA-256 (not just internally consistent), I computed the same inputs through the OS crypto library and confirmed they equal the vectors hard-coded into the new unit test:
These are the canonical FIPS-180 single- and two-block vectors and match the
matches_published_sha256_vectorstest exactly.What I observed
prompt_sha_test: it assembles the system prompt twice (separate fresh SQLite memory files, same model + same hydrated identity facts — i.e. two simulated boots) and asserts the SHA is identical, and thata model-family change or an added household fact changes the SHA.
handle_healthunit test now asserts/api/healthreturns a 64-charsystem_prompt_shaequal to the SHA of the served prompt.A maintainer or reviewer with a toolchain can confirm with:
and on a running stack:
Test plan
curl -s 127.0.0.1:3000/api/health | jq .system_prompt_sha— note the digest.genie-ctl status— confirm thePrompt:line matches.restart, and confirm the SHA changes.
Notes for reviewers
runtime_contract::stable_hash). It is keyed to the FIPS-180 known-answer vectors so it cannot silently diverge from real SHA-256.runtime_contract.prompt_hash(FNV-1a operational fingerprint); M1 exit: system prompt SHA is identical across full-stack restart #110 specifically calls for a published "system prompt SHA", so a genuine SHA-256 is exposed as a distinct, top-level field.