Skip to content

feat(pgpm-core): shared SQL header model + control-only cross-package dep mode#1401

Merged
pyramation merged 1 commit into
mainfrom
feat/pgpm-header-model
Jul 20, 2026
Merged

feat(pgpm-core): shared SQL header model + control-only cross-package dep mode#1401
pyramation merged 1 commit into
mainfrom
feat/pgpm-header-model

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Atom 1 of the schema-transformation platform plan (constructive-io/constructive-planning#1226, design in #1225): a single shared model for pgpm SQL script headers, plus the control-only cross-package dependency mode for slicePlan.

New files/sql/header.ts (exported via files/sql):

  • parsePgpmHeader(content) → { header: PgpmHeader, body } — structured, lossless parse of -- Deploy|Revert|Verify + -- requires: header blocks. Handles all three formats in the wild: legacy -- Deploy proj:change to pg, modern -- Deploy change, and the writer's -- Deploy: change. header.lines + body reassemble the file byte-exactly (writePgpmScript).
  • renameInHeader(script, renames) — rewrites header identity and matching -- requires: refs (package-qualified refs handled; tag refs untouched). This is the primitive the rename/move atom (Atom 3) and bundle transpilation build on.
  • scanDeployScript(content, { key, extname, makeKey }) — the resolver's historical whole-file line scan, extracted verbatim from resolution/deps.ts (same regexes, same identity-mismatch errors). resolveDependencies now consumes it; behavior unchanged, all 390 existing tests pass.
  • verifyPlanMatchesHeaders(moduleDir) → HeaderDriftIssue[] — new read-only drift gate comparing pgpm.plan changes/deps against deploy scripts (missing-file / identity-mismatch / requires-drift).

Slice: crossPackageDepMode: 'change' | 'tag' | 'control-only' on SliceConfig:

  • 'change' (default) and 'tag' are today's behaviors (useTagsForCrossPackageDeps still honored as an alias for 'tag').
  • 'control-only' drops per-change cross-package refs from sliced plan lines entirely; the dependency is carried only by the control file's requires = '<pkg>'. Extension install ordering deploys the whole dependency package first, which subsumes any per-change ordering constraint — this is the "abstract the detail, depend on the module" mode from the modularization discussion (chore: update schemas from constructive-db #1225 deep dive 4).

No breaking changes: all additions are opt-in; generateSinglePackage's trailing param accepts the old boolean or the new mode.

Note: pnpm lint currently fails repo-wide on main (ESLint 9 installed but only .eslintrc.json present) — unrelated to this change; typecheck via pnpm build and full pnpm test (390/390) pass.

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

@pyramation pyramation self-assigned this Jul 20, 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 30717c3 into main Jul 20, 2026
38 checks passed
@pyramation
pyramation deleted the feat/pgpm-header-model branch July 20, 2026 21:54
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