Skip to content

Fail retention-pruned history bundles in verification - #230

Merged
rmcdaniel merged 2 commits into
mainfrom
fix/228-pruned-bundle-verify
Nov 2, 2026
Merged

rmcdaniel merged 2 commits into
mainfrom
fix/228-pruned-bundle-verify

Conversation

@rmcdaniel

Copy link
Copy Markdown
Member

Closes #228.

Change

durable_workflow.history_bundle_verify now fails a retention-pruned bundle (workflow.details_state == "pruned") with the history.details_pruned error, matching PHP Core's BundleIntegrityVerifier.checkRetainedDetails from workflow#980 (merged 05ffc5794f8d554c4fb10c29a62da60e1a9e946c):

  • Finding: the same rule ID, severity, message text (including the optional at <details_pruned_at>), path workflow.details_state, and context {details_pruned_at, history_complete}. A missing, empty or non-string timestamp becomes null, as in PHP's stringValue.
  • Unchanged: bundles with details_state: "retained", and older exports without the field. Only the exact string "pruned" triggers the error.
  • Dedupe key: the pruned bundle's extended dedupe_key (…:details-pruned:<timestamp>) is accepted as exported. Python performs no dedupe-key check, so there's no new rule.
  • Simulation and CLIs: because the verdict is failed, simulate_bundles and durable-workflow-replay-verify --simulate-bundles block the bundle (block_and_investigate), and durable-workflow-history-bundle-verify exits nonzero. Bundle simulation doesn't execute workflow code; this is the integrity layer.

Regression fixture

tests/fixtures/history_bundles/retention_pruned/pruned-bundle.json holds the exact bytes from #228: a real TestGreetingWorkflow run, completed, pruned and exported by the workflow#980 head 2e562997. The merge 05ffc579 kept that head's files unchanged (the compare shows no file diff). File sha256 is 57f12ffb…bbf; the canonical checksum 8fa57d07…01ac still matches.

PHP's corpus entry tests/Fixtures/V2/ReplayRegression/retention-pruned-run-export.json (sha256 7016af05…) is a scenario descriptor that generates pruned exports at test time and carries no bundle bytes. provenance.json records that, along with PHP's expected verification result. The test asserts that Python's findings equal PHP's expected findings exactly.

Evidence (local, macOS, Python 3.12.4)

  • New tests: tests/test_history_bundle_pruned.py has 14 tests: fixture bytes untouched, exact PHP parity, dedupe key, a pruned marker without a timestamp, retained and absent unchanged, near-miss markers, and simulation plus both CLIs.
  • Counterfactual: with main's verifier, the 7 detection tests fail and the 7 unchanged-behavior controls pass.
  • Related suites: history-bundle and replay tests, 355 passed.
  • Lint and types: ruff and mypy pass.
  • Full suite: running; result posted below.

Expected to conflict with #229 only in CHANGELOG.md (both add under Unreleased).

🤖 Generated with Claude Code

A bundle exported after retention cleanup pruned the run's details
(workflow.details_state "pruned", history_complete false, no events) was
reported ok. Match PHP Core (workflow#980, 05ffc579): report the
history.details_pruned error at workflow.details_state with the pruned
timestamp and history_complete in the context. Bundle simulation and both
CLIs now block such bundles. Retained bundles and older exports without
the marker are unchanged, and the extended dedupe key is accepted as
exported.

The regression fixture is the exact pruned export from #228, produced by
the workflow#980 head whose tree the merge kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rmcdaniel rmcdaniel added the agent:sdk-python Work by the sdk-python repo agent label Nov 2, 2026
@rmcdaniel

Copy link
Copy Markdown
Member Author

Exact head fb97191c20bb8382b611573826dc65230d21f2ff: all 21 hosted checks pass. Clean local full unit suite on this branch: 3,730 passed, 4 skipped, with the 2 bash-3.2 scanner tests deselected. An earlier local run was discarded because the branch changed during it. Ready for review. Only CHANGELOG.md should conflict with #229 (both add under Unreleased); I'll resolve it on whichever branch lands second, if you want me to.

@sonarqubecloud

sonarqubecloud Bot commented Nov 2, 2026

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Merged main (8b95f28, which includes #229) normally into this branch. The only conflict was CHANGELOG Unreleased, now listing Added (#168) then Fixed (#228). Exact head 7d840977fa3d32b976dc5b44a7dca14b78266e46: all 21 hosted checks pass; local full unit suite 3,756 passed / 4 skipped (2 bash-3.2 scanner tests deselected).

@rmcdaniel
rmcdaniel marked this pull request as ready for review November 2, 2026 23:48
@rmcdaniel
rmcdaniel merged commit 1bb7e3d into main Nov 2, 2026
21 checks passed
@rmcdaniel
rmcdaniel deleted the fix/228-pruned-bundle-verify branch November 2, 2026 23:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:sdk-python Work by the sdk-python repo agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

history_bundle_verify accepts retention-pruned history bundles as ok

1 participant