Skip to content

feat(pgpm-bundle): bundle envelope — versioned, content-addressed container for schema + data + fixtures#1435

Merged
pyramation merged 1 commit into
mainfrom
feat/bundle-envelope
Jul 23, 2026
Merged

feat(pgpm-bundle): bundle envelope — versioned, content-addressed container for schema + data + fixtures#1435
pyramation merged 1 commit into
mainfrom
feat/bundle-envelope

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

The bundle envelope — fn #3 exportMigrationBundle's artifact (constructive-planning#1225): one versioned, shippable container wrapping a schema MigrationBundle + data-dump SQL + fixtures, with a manifest, Merkle content digest, and provenance. New pgpm/bundle/src/envelope.ts, purely additive.

interface BundleEnvelope {
  manifest: EnvelopeManifest;   // { formatVersion, name, version, createdWith, parts[], digest, provenance? }
  schema: MigrationBundle;      // required; its part digest = the bundle's own manifest digest
  data: EnvelopeScriptPart[];   // ordered { name, deploy, revert|null, verify|null, digest }
  fixtures: EnvelopeScriptPart[];
}

createEnvelope({ version, schema, data?, fixtures?, provenance? })  // pure, deterministic
verifyEnvelope(envelope)              // re-hashes parts → inventory → envelope digest + verifyBundle(schema)
writeEnvelopeFile / readEnvelopeFile  // single JSON artifact (pgpm-envelope.json)
materializeEnvelope / envelopeFromDirectory
// envelope.json + schema/pgpm-bundle.json + data|fixtures/<name>/{deploy,revert,verify}.sql

Design decisions:

  • Lives in @pgpmjs/bundle, not a new package — same artifact layer, reuses hashString/verifyBundle/writeBundleFile. It cannot depend on @pgpmjs/export (export → core → bundle), so data/fixtures parts are caller-produced SQL (e.g. buildDataDeploy/Revert/VerifyScript from @pgpmjs/export): the envelope never generates SQL, just digests and ships it.
  • Merkle chain: manifest.digest = sha256(name, version, ordered part digests); the schema part digest is the bundle's own digest, so integrity extends down through every change/script. createdWith/provenance excluded from the digest (same rule as the bundle layer).
  • Directory layout instead of a tar dependency — deterministic, trivially tarred by callers.
  • Follow-up seams intact: snapshotDatabase = createEnvelope over slice/export outputs; applyMigrationBundle = existing applyBundle for schema then replay data/fixtures in order; ID-remap operates on part SQL pre-apply.

Also updates the pgpm-migration-bundle skill with the envelope surface.

Validated: bundle 33/33 (6 new envelope tests: determinism, tamper detection at part/inventory/schema levels, JSON + directory round-trips), core 356/356, builds green.

Link to Devin session: https://app.devin.ai/sessions/ad40d16f38a349b48eb7ce9375e27e6e
Requested by: @pyramation

@pyramation pyramation self-assigned this Jul 23, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit c72ba8c into main Jul 23, 2026
14 checks passed
@pyramation
pyramation deleted the feat/bundle-envelope branch July 23, 2026 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant