v1.0.7
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog,
and the project adheres to Semantic Versioning.
[1.0.7] — 2026-05-06
Closes 4 of 5 production-blocker findings from the v1.0.6 audit
(round 5). Audit's 5th finding (cargo-audit advisories on pyo3 0.22
- rustls-webpki 0.101) is documented and tracked for v1.0.8 — see
"Out of v1.0.7" below.
Security: env capture is no longer unsafe-by-default
pf snapshotruns a built-in regex ((?i)token|secret|password| passwd|pwd|api_?key|apikey|auth|bearer) that redacts secret-shaped
env-var names UNLESS the operator passes--no-default-scrub.
v1.0.6 captured every env var by default — operators with
OPENAI_API_KEY/GITHUB_TOKEN/ etc. in scope leaked them
into the .pfimg unless they remembered--scrub-env. 1
regression test (OPENAI_API_KEY+DATABASE_PASSWORDredacted,
non-secret var preserved).
ACRFence: ledger writes are HMAC-chained for real
- The CLI's
--effects-from-jsonlwrite path (and the snapshot
internal path) now route every entry through
pf_effects::ledger::Ledger::append, which computes a per-entry
session_hmac = HMAC(secret, prev_hash || this_hash). v1.0.6
wrote raw JSONL withsession_hmac = "", so tamper / reorder /
delete on the on-disk blob was undetectable. - A per-snapshot session secret is generated by default and
embedded in the blob header (tamper-detection mode). Operators
who want full ACRFence supplyPF_SESSION_SECRET=<hex>env var,
in which case the secret is NOT echoed back into the blob. pf verifynow walks every manifest's effects ledger, runs
Ledger::deserialize+verify(), and fails if the HMAC chain
is bad. 1 regression test (snapshot 2 entries → tamper one
entry's tool_id on disk →pf verifyfails).
vLLM / SGLang plugins now actually persist
_snapshotwrites every K/V page byte buffer + the per-snapshot
manifest into a real ProcessFork store via the new SDK
processfork.put_blob(). v1.0.6's hash was computed but never
stored — the returned CID resolved to nothing on disk._checkoutnow reads the manifest from the store and replays
every page viapager.write_page(). v1.0.6 just returned
{"ok": true}without any work.- New SDK surface:
processfork.put_blob(store, bytes) -> str. - Persistence works in both mock and live modes — the
_live()
gate that used to short-circuit was a usability filter, not a
correctness one, and made the persistence path untestable
without a real GPU. 4 new regression tests (vLLM + SGLang ×
mock-mode + persistence-round-trip + unknown-CID-errors).
Versions aligned across surfaces
processfork(Rust + Python wheel): 1.0.6 → 1.0.7processfork-vllm: 1.0.2 → 1.0.3 (real persistence)processfork-sglang: 1.0.2 → 1.0.3 (real persistence)@processfork/sdk(npm): 1.0.7 → 1.0.8- 8 Rust crates on crates.io: all → 1.0.7
Test count
196 → 199 cargo tests workspace-wide (+1 ledger HMAC tamper, +1
default-scrub, +1 quiesce-failure regression already in v1.0.6).
Plus 4 new vLLM/SGLang persistence regressions in adapters.
Out of v1.0.7 → tracked for v1.0.8
cargo auditignores remain:pyo3 0.22.6(RUSTSEC-2025-0020,
buffer-overflow inPyString::from_objectwe don't call) and
threerustls-webpki 0.101.7advisories (transitive via
aws-sdk-s3→aws-smithy-http-client→rustls 0.21) are
still indeny.toml'signorelist. Clearing them needs
pyo3 → 0.24 (Bound API rewrite, ~30 min mechanical) and
aws-sdk-s3 ≥1.135 (when it bumps its rustls floor, likely Q3
2026). Each ignore has a documented scope-of-impact comment;
none are exploitable in our use cases. v1.0.8 ships the bumps.