Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7fee358
feat(gen): migrate to gen-contract v4.0.1 / gen-sdk v2.0.0, adopt Sdk…
nikita-volkov Jul 11, 2026
a5b4530
feat(gen): rewrite compile.dhall/Gen.dhall as Interpret.dhall/package…
nikita-volkov Jul 11, 2026
b13e427
refactor(gen): rename gen/ to src/, move tests/Exhaustive.dhall to de…
nikita-volkov Jul 11, 2026
2c9073f
refactor(gen): update path references from gen/ to src/, tests/Exhaus…
nikita-volkov Jul 11, 2026
a30ac32
fix(gen): update gen/ path references in the pytest harness to src/
nikita-volkov Jul 11, 2026
ffea69f
docs(gen): add Task 7 CHANGELOG entry, fix stale Config.dhall comment
nikita-volkov Jul 11, 2026
9c33a23
refactor(gen): drop dead Run type-alias bindings in Query/Result/Resu…
nikita-volkov Jul 11, 2026
15c2836
The plan
nikita-volkov Jul 11, 2026
81ea82c
Revert "The plan"
nikita-volkov Jul 11, 2026
7b3ef57
Fix
nikita-volkov Jul 12, 2026
7625550
Drop the plans
nikita-volkov Jul 12, 2026
bd42d46
Add plans
nikita-volkov Jul 12, 2026
c30e212
python.gen: rename emitSync config field to sync (no behavior change)
nikita-volkov Jul 12, 2026
be51390
python.gen: make sync/async mutually exclusive at unified output paths
nikita-volkov Jul 12, 2026
cf6b165
python.gen: add python-sync fixture artifact, drop emitSync from main…
nikita-volkov Jul 12, 2026
fe5f82b
python.gen: add tests/golden_sync, regenerate both golden trees for e…
nikita-volkov Jul 12, 2026
3008b70
python.gen: split sync-surface tests onto their own golden fixture
nikita-volkov Jul 12, 2026
5bab734
python.gen: fix config-variant sync detection for unified output paths
nikita-volkov Jul 12, 2026
2892802
python.gen: document the exclusive sync/async config change
nikita-volkov Jul 12, 2026
a0b527e
Add demos to fixtures task
nikita-volkov Jul 12, 2026
82bd4ad
Drop the task doc
nikita-volkov Jul 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/build-contract-shell.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Wraps the Dhall-generated package (from tests/Exhaustive.dhall) in a minimal
# Wraps the Dhall-generated package (from demos/Exhaustive.dhall) in a minimal
# consumer shell, mirroring the hand-written tests/golden/ shell (pyproject.toml
# + py.typed) so basedpyright strict runs against the same layout a real
# consumer would import, per the full_package pattern in tests/conftest.py.
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ jobs:
with:
ref: ${{ inputs.ref || github.sha }}

# The `as Source` import mode on gen/Deps only changes how pgn loads the
# The `as Source` import mode on src/Deps only changes how pgn loads the
# remote packages (unnormalized, to save RAM), not what they evaluate to.
# The pinned action below bundles a dhall fork that predates the mode, so
# strip it here; the evaluation is semantically identical either way. The
Expand All @@ -132,16 +132,16 @@ jobs:
shell: bash
run: |
set -euo pipefail
sed -i -e 's/^[[:space:]]*as Source$//' -e 's/^[[:space:]]*sha256:[0-9a-f]\{64\}$//' gen/Deps/*.dhall
sed -i -e 's/^[[:space:]]*as Source$//' -e 's/^[[:space:]]*sha256:[0-9a-f]\{64\}$//' src/Deps/*.dhall

# A plain, standard-Dhall evaluator cannot run this: gen/Interpreters/Project.dhall's
# A plain, standard-Dhall evaluator cannot run this: src/Interpreters/Project.dhall's
# buildLookup and gen-sdk's own Fixtures.Exhaustive both use Text/equal, a builtin
# from pgn's forked Dhall, absent from the upstream dhall-lang Prelude. This action
# bundles that same fork.
- name: Generate output from Dhall
uses: nikita-volkov/dhall-directory-tree.github-action@60a18dc647d6daea805263ea0fed7bb8011f3bcd # v2
with:
dhall_file: tests/Exhaustive.dhall
dhall_file: demos/Exhaustive.dhall
output_dir: contract-output

- name: Assert the compile did not fail
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ jobs:
id: resolve
uses: nikita-volkov/dhall-resolve.github-action@7caaf1fdb40ac864bc02e37575f577ee084713a8 # v3
with:
file: gen/Gen.dhall
file: src/package.dhall
minify: true

- name: Prepare changelog for release
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ already says.

## Dhall

`gen/` pins its remote imports by sha256 (`gen/Deps/*.dhall`). Bump those
`src/` pins its remote imports by sha256 (`src/Deps/*.dhall`). Bump those
deliberately, one at a time, and re-run the harness before committing a pin
change.
65 changes: 65 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,70 @@
# Upcoming

- **Breaking:** `emitSync` is gone. In its place, `sync : Optional Bool`
(default `False`) picks exactly one surface per generate — async or sync —
emitted at the same unified paths either way (no more `sync/` subdirectory,
no more second package-root facade). Previously `emitSync: true` added a
second, nested sync tree alongside the always-emitted async one; a project
that needs both surfaces now generates two artifacts against this same
`gen:` with different `packageName`s, one with `sync: true` and one
without. See `docs/plans/2026-07-12-configurable-sync-output.md` for the
full rationale and migration shape. `tests/golden_sync/` is a new committed
golden fixture (`specimen_sync_client`) exercising the sync surface
end-to-end (basedpyright strict + round-trip), alongside the existing
`tests/golden/` (`specimen_client`, now async-only).

- `buildLookup` (`Interpreters/Project.dhall`) and, with it, this generator's
last dependency on pgn's fork-only `Text/equal` builtin are removed from
`src/`: custom-type decode/encode now dispatches through named
`_decode`/`_encode` methods generated onto each custom type's own Python
class (`CompositeModule.dhall`/`EnumModule.dhall`), called by name from
every reference site, instead of resolving classification and fields via a
project-wide structural search (`grep -rn "Text/equal" src` now returns
only two explanatory comments, zero invocations). Array (dims > 0)
decode/encode is built at the call site (`Member.dhall`/
`ParamsMember.dhall`) instead of a third per-type method, delegating only
the per-element transform to `_decode`/`_encode`: an earlier draft this
session added a per-type `_decode_array` to `EnumModule.dhall`, but it
could not express `elementIsNullable` (a per-column fact, not a per-type
one) and silently broke nullable-element enum-array decode and
enum-array param encode — both working, corpus-exercised paths — caught
by the final whole-branch review and fixed before merge. Behavior change:
because the call site is now kind-uniform, a 1-D composite-array column
or param is no longer rejected at Dhall-generation time the way it used
to be, and — unlike the `_decode_array` design it replaces — no longer
depends on `basedpyright strict` catching a missing method either, since
`_decode`/`_encode` genuinely exist on a composite class too. **This path
has not been exercised against real Postgres, and `tests/golden/` has NOT
been regenerated for this change this session** — the composite-array
fixture addition, its golden regeneration, and confirming actual Postgres
round-trip behavior are a known, deliberate gap in this commit, deferred
to a follow-up pass on a properly provisioned machine (see
`docs/plans/2026-07-11-reusable-custom-type-codecs.md`).
Separately, a composite field nesting another custom type is *also* no
longer rejected at generation time: the `nestedLookup = Absent` stub that
used to force it down the same loud-fail path is gone (it only existed
to satisfy `Member.run`'s old signature). This is not the same kind of
change as the composite-array case above, though — `CompositeModule.dhall`'s
`_decode`/`_encode` still do a blind flat `cast(tuple[...], src)`/splat,
unchanged by this refactor, and never recurse into the nested type's own
codec, so the field silently decodes/encodes wrong rather than being
caught by a type checker. Because the failure mode is `cast()`, which
suppresses type-checking on its argument by design, this is **not**
expected to be caught by `basedpyright strict`. It is a real, silent
architecture gap, flagged here as an open follow-up design question, not
a shipped or backstopped behavior change.
- Migrated the generator's internal dependencies to `gen-contract` v4.0.1
and `gen-sdk` v2.0.0, adopting `Sdk.Sigs` in place of the local
`Algebras/` module, and restructured the repository layout to match the
pGenie generator architecture: implementation moved from `gen/` to
`src/`, the public entry point renamed from `gen/Gen.dhall` to
`src/package.dhall`, and the fixture driver moved from
`tests/Exhaustive.dhall` to `demos/Exhaustive.dhall`. No change to
generated output or the public Dhall interface (`artifacts.<name>.gen`
URLs pointing at a previously-released `resolved.dhall` are unaffected;
only the next release's URL path changes, from `.../gen/Gen.dhall` — the
unresolved source path some projects may reference directly instead of a
frozen release — to `.../src/package.dhall`).
- The test harness now runs every pgn subprocess in its own process group under
an RSS watchdog: a thread polls `ps -o rss=` every 2 s and, on breach of
`PGN_MAX_RSS_GB` (default 40 GB), kills the whole group and fails the test with
Expand Down
Loading
Loading