feat(rebind): foundation for RFC-0041 aliases#486
Draft
naxty wants to merge 2 commits into
Draft
Conversation
Adds the PKL `Alias` class (single `label` field) and the optional `alias: Alias?` field on Resource, Stack, and Target. Mirrors the surface in Go on the equivalent model structs. Introduces the `datastore.Tx` marker interface and `WithTx` method on `Datastore`; the marker has no methods yet so later PRs can extend it without churn. All datastore implementations pass-through. Adds `OperationRebind = "rebind"` to the API op-type enum. Creates `internal/metastructure/rebind` with `Rebinder.Run`, `Validate`, and `Execute`. PR 1 ships them as no-ops: Validate always returns an empty `RebindPlan` and Run short-circuits before opening a transaction. The rebinder is wired into the apply pipeline ahead of `FormaCommandFromForma`, so once later PRs add real validation logic the engine picks it up automatically. No behaviour change for existing formae (no alias declared = no-op). See RFC-0041 §Implementation Plan PR 1.
ResourceRebind now carries only Ksuid + NewLabel. Per-child writes generated by a stack rename move into a new ResourceStackCascade type with Ksuid + NewStack. Nothing in the plan can express "move this resource to a different stack via a ResourceAlias" because ResourceRebind has no NewStack field. Cross-stack moves are only possible through StackRebind plus the cascade slice, which is what the RFC scope allows. Target equivalents intentionally absent; tracked for the follow-up RFC.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lands the foundation for RFC-0041 (resource / stack rename via aliases). No behaviour change for existing formae — formae that do not declare
aliassee no DB writes from this code.Aliasclass with requiredlabel; optionalalias: Alias?onResource,Stack,Target.Aliasstruct (pkg/model/alias.go) mirrored asAlias *AliasonResource,Stack,Target.Txmarker interface andWithTx(ctx, fn) errormethod onDatastore. All impls (Aurora, Postgres, SQLite, mocks) pass-through; the marker carries no methods yet so later PRs can extend it without churn.OperationRebind = "rebind"constant.internal/metastructure/rebindpackage withRebinder.Run / Validate / Execute. All no-op.Runis wired into the apply path ahead ofFormaCommandFromForma; subsequent PRs add real rename behaviour without touching the wiring.Why
Subsequent PRs in the rename-aliases stack add real rename logic on top of this skeleton. Landing the surface up-front lets each follow-up PR stay small and focused.
Why
WithTxRebind is multi-row, atomic. A single rename like
stack: prod → productionwrites one newstacksrow plus N newresourcesrows (cascade-update ofresources.stack). If the cascade partially fails the metastructure is torn — stack renamed, children still pointing at the old label, downstream apply phase creates bogus resources.WithTxwraps the whole rebind in one DB transaction:The
Txinterface is intentionally empty in this PR. PR 2 (resource rebind) adds the real methods (StoreResource,CreateStack, …) toTx. Doing theDatastore-interface widening once now means PR 2 is purely additive onTx. All five implementations currently callfn(d)pass-through; real BEGIN/COMMIT plumbing is scoped to PR 2 where it is first exercised by a non-emptyRebindPlan.Test plan
go test ./pkg/model/...— 25 passed.go test ./internal/metastructure/rebind/...— 2 passed (no-op Run + Validate).go test ./internal/datastore/... ./internal/metastructure/...— green; pre-existing Postgres collation flake unrelated.make test-generator-pkl— 27/27 PKL tests pass after fixture refresh.