Skip to content

Bundle verifier rejects the schema_version 2 history exports that Server 2.5.14 produces #190

Closed

Description

@rmcdaniel

Problem

The published Python SDK's offline bundle verifier refuses every history export that published PHP Server 2.5.14 (Workflow 2.5.5) produces.

durable_workflow.history_bundle_verify (durable-workflow 2.7.0 from PyPI) supports only BUNDLE_SCHEMA_VERSION = 1. HistoryExport::forRun in Workflow 2.5.5 emits schema_version: 2. Every bundle therefore reports:

error bundle.schema_version_unsupported Bundle schema_version [2] is unsupported; expected 1.

and the overall status is failed, so a promotion gate built on the verifier rejects good bundles.

Reproduce

  1. Start ghcr.io/durable-workflow/server@sha256:28fa0f3968ea253c727aad7fe583bb61c788553f1e4b96ece6ea4570d20faf42 (2.5.14).
  2. Run any workflow to completion.
  3. GET /api/workflows/{id}/runs/{run}/history/export and save the body as bundle.json.
  4. pip install durable-workflow==2.7.0 && python -m durable_workflow.history_bundle_verify bundle.json

Expected

The verifier accepts the schema versions the published server emits, and keeps refusing only unknown future versions.

Found while qualifying the native server's history export (durable-workflow/server#325). The native export also emits schema_version 2, and apart from that rule it verifies cleanly.

Activity

  1. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    Duplicate of #173, which tracks the same hardcoded schema-version-1 refusal and already includes current published-runtime waiting/completed exports, preservation of version-1 behavior, integrity controls and installed-package acceptance. This report adds the Server 2.5.14 / Python 2.7.0 observation; retain it here as evidence. The defect is still open in #173; closing this duplicate does not claim a fix or authorize rewriting exported bundles.

  2. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    Reopening to retain this report’s distinct Server 2.5.14 / Python 2.7.0 and native-export compatibility observation alongside #173, which tracks the current-runtime waiting/completed exports and broader integrity/installed acceptance. They share the schema-version refusal, but verification must retain both artifact contexts. The earlier duplicate closure did not establish either context as fixed.

  3. rmcdaniel commented on Nov 2, 2026

    @rmcdaniel
    MemberAuthor

    Read-only status check (sdk-python-swarm), with no runtime evidence claimed:

    • The shared root cause is fixed in source and in a published release. history_bundle_verify.SUPPORTED_BUNDLE_SCHEMA_VERSIONS = {1, 2} has been in place since Python 2.10.0, which delivered Verify current schema-2 history export bundles without rewriting them #173 (registry acceptance #213).
    • The checked-in schema-2 corpus (tests/fixtures/history_bundles/schema2_published/provenance.json) comes only from published PHP Server 2.9.7 / Core 2.7.2 exports.
    • Still unverified: this issue's two retained contexts. (1) A published Server 2.5.14 export verifying under an installed SDK ≥ 2.10.0. (2) A native Rust Server history export verifying under the same. Both need a running Server, which this Mac can't host.

    Closing this needs one bounded run: export a completed run from each of those two producers, then run python -m durable_workflow.history_bundle_verify from a PyPI-installed SDK ≥ 2.10.0. Each must pass integrity checks and report no bundle.schema_version_unsupported. If either fails on another rule, that becomes a new defect rather than a reason to keep this one open.

  4. rmcdaniel commented on Nov 2, 2026

    @rmcdaniel
    MemberAuthor

    Bounded published-producer verification for #190: both retained contexts now pass. sdk-python ran this on lab3 (Docker 29.5.2 / Colima, linux/amd64). Each producer ran once on a disposable SQLite container. Containers, pulled images and anonymous volumes were removed afterwards.

    Identities

    PHP Server 2.5.14 native Server 3.0.0
    Tag → commit annotated 2.5.14 (e1a0177c…) → 152ee0f36df2e67e74c8997c573b3f9c68479eb2 annotated native-3.0.0 (9b79a21e…) → 741454251bba3b7667b7ada4f3b0884427b27abc
    GHCR index ghcr.io/durable-workflow/server:2.5.14 sha256:dc4f1372e0eeeccd3ced8e91feb3204e2120f8945ea8e18a16540342806d4dde ghcr.io/durable-workflow/server:3.0.0 sha256:ff1ea2167256c9f2a24b152e72f9a0c30e09710124c91a84442d3e9dc1b3996b
    linux/amd64 manifest run sha256:28fa0f3968ea253c727aad7fe583bb61c788553f1e4b96ece6ea4570d20faf42 (this issue's digest) sha256:79d1ba5fd70d9401f75fcdeb8dcf4c223830d922b147276dde5c4c1a9c408e59
    Image labels revision 152ee0f3…, release tag 2.5.14, Workflow 2.5.5 26a840f2… revision 741454…, release tag native-3.0.0
    /api/cluster/info version: 2.5.14 version: 3.0.0, implementation: rust, development: true, qualified_for_php_takeover: false

    The driver was a normal PyPI install in a fresh venv: SDK 2.7.0 for 2.5.14 (this issue's own version; wheel 40865e78…) and SDK 2.12.3 for native. Each driver ran one Worker with one activity (b190_greet) and one workflow (b190_greeter) to completed, with result {"greeting": "hello, world"}.

    The verifier was a normal PyPI 2.12.3 install in a fresh venv, using pip install --require-hashes with wheel f509643cce6bff4be695d70bc8e6315b7dbd9a0a454ff5d83dd4c43a1c3f7f03. It ran from outside any checkout with python -I -m durable_workflow.history_bundle_verify <bundle>.

    Exports

    The raw body is untouched, from GET /api/workflows/{id}/runs/{run}/history/export with X-Durable-Workflow-Control-Plane-Version: 2 → HTTP 200.

    Producer Run File sha256 / bytes Canonical checksum Schema Events / manifest entries
    PHP 2.5.14 b190-php2514-2f5243cff5 / 01m6etejc6vz8wtwm10bdcg372 f8f57968…6117c / 42,842 11b5783c…bec9 durable-workflow.v2.history-export v2 6 / 7
    native 3.0.0 b190-native300-e089c13f27 / 01M6ETBZ0CAK4QJ5148GVJKA61 9d9d8811…f16e / 41,769 a1f48c12…fa2e durable-workflow.v2.history-export v2 6 / 7

    Verifier results

    • Installed 2.12.3: both raw exports return status: ok, exit 0, 0 errors / 0 warnings / 0 findings, checksum_matches: true. The copies the SDK client fetched also verify ok; they differ from the raw bodies only in exported_at and its checksum.
    • Counterfactual, installed 2.7.0, same bytes: both producers return failed with exactly bundle.schema_version_unsupported. That reproduces this issue, with integrity still matching.
    • Negative controls, installed 2.12.3, on parsed copies of each fresh export: all refused (exit 1), with the same result for both producers:
      • schema_version: 3: bundle.schema_version_unsupported, also when re-checksummed with the verifier's own canonicalizer, so the schema rule fires independently.
      • String "2" schema version: schema_version_unsupported.
      • Tampered event or wrong checksum: integrity.checksum_mismatch.
      • history_events removed: bundle.section_missing + commands.history_event_missing.
      • payload_manifest removed: bundle.section_missing.
      • Re-checksummed manifest entry without a codec: payload_manifest.codec_missing.
      • Re-checksummed entry marked available with diagnostic: payload_missing: payload_manifest.payload_missing.
      • An unknown codec name with a valid checksum verifies ok. That is by design: the rule requires a declared codec, and codec names are open.
    • Checked-in published corpus, installed 2.12.3: the four schema2_published/bundles/* (Server 2.9.7) are ok. Both producer_invalid/* stay failed (workflow.memo_projection_mismatch, integrity.checksum_mismatch).

    Scope

    • Payloads: both exports carry inline Avro payloads with a 7-entry manifest; no external payload references were produced. Payload-reference and redaction behavior stays covered by the existing corpus and unit controls; this run doesn't extend it.
    • Not run: waiting-state exports and signed (HMAC) bundles.
    • No source change: this needed none. Every refusal above comes from a negative control, not from either producer or the runner.

    With both of this issue's contexts (published Server 2.5.14 and native Server 3.0.0) verified under an installed SDK ≥ 2.10.0, this issue is ready to close as fixed by 2.10.0 (#173). The separate #279 3.0.1 / 2.12.4 acceptance is unaffected.

  5. rmcdaniel commented on Nov 2, 2026

    @rmcdaniel
    MemberAuthor

    Both retained producer contexts are now verified with normally installed published SDK 2.12.3: the issue's exact PHP Server 2.5.14 platform image and native Server 3.0.0 exports pass unchanged schema-2 bundle verification. The same bytes reproduce the original refusal under installed 2.7.0, and unknown schemas, integrity errors and malformed/missing sections still refuse. Exact identities, commands, results and cleanup.

    Closing as delivered by 2.10.0 / #173, with the missing installed-producer acceptance completed. This adds no waiting-state, HMAC or external-payload claim and does not substitute for the separate native 3.0.1 / SDK 2.12.4 acceptance in durable-workflow/.github#279.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions