fix(migrate): add topological sorting and retry for dependent blueprint fields#75
Merged
EricFernandezPort merged 5 commits intoJun 5, 2026
Conversation
…nt fields The migrate module was applying aggregationProperties, mirrorProperties, and ownership concurrently without dependency ordering, while the import module already had these protections. This caused the Port API to silently nullify pathFilter in aggregation properties and drop inherited ownership when dependencies weren't ready yet. Changes: - Phase 2c (mirrorProperties): collect failures for retry after Phase 2d - Phase 2d (aggregationProperties): use TopologicalSortAggProps to ensure cross-blueprint agg prop dependencies are applied in order - Phase 2c retry: re-apply failed mirror props after agg props exist - Phase 2e (ownership): use TopologicalSortOwnership to ensure inherited ownership chains are applied in dependency order - Phase 3 retry: re-apply failed agg props after all other phases complete Fixes: aggregationProperties.pathFilter being silently nullified and inherited ownership being dropped during port migrate. Co-authored-by: Cursor <cursoragent@cursor.com>
Add missing tests for the page permissions feature introduced in PRs port-experimental#70 and port-experimental#71, following Eric's established test patterns: - TestCollector_CollectsPagePermissions: positive collection verification - TestLoader_LoadJSON_PagePermissions: JSON round-trip loading - TestComparePermissions_DetectsExtraFieldsAsChange: diff detection - TestComparePermissions_NormalizesStringSliceOrder: slice normalization - Updated TestDiffResult_PermissionsFields to include PagePermissions Co-authored-by: Cursor <cursoragent@cursor.com>
3 tasks
- TestImportToTarget_AggPropsAppliedInTopologicalOrder: verify cross- blueprint agg prop dependencies are applied in correct order - TestImportToTarget_FailedAggPropsRetried: verify failed agg prop updates are retried in a second pass - TestImportToTarget_OwnershipAppliedInTopologicalOrder: verify inherited ownership is applied after its dependency Co-authored-by: Cursor <cursoragent@cursor.com>
3c7747d to
86fb6a5
Compare
- Validate that page-permissions requires pages in --include (export, import, migrate, compare) to prevent silent empty export and idempotency-breaking force-overwrite - Fix invalidPermBodyPattern regex: add (?s) flag so multi-line JSON 422 bodies are matched - Fix migrate errors section mislabeled as "Warnings:" → "Errors:" - Add blueprint_permissions_updated and action_permissions_updated to migrate JSON output - Strengthen import_test retryBody nil guard: use t.Fatal instead of silent skip - Update ValidationWarning.Type comment to include "orphaned_permission_field" - Rewrite CHANGELOG 0.2.19 entry to describe features and fixes, not test names Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Entire-Checkpoint: a0896ec6ff15
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Entire-Checkpoint: 55a24cc72286
EricFernandezPort
approved these changes
Jun 5, 2026
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
aggregationProperties.pathFilterbeing silently nullified duringport migratewhen cross-blueprint dependencies aren't resolved in orderinherited ownershipbeing dropped when ownership chains require dependency orderingmigrate.go's dependent field handling in line withimport.go's proven phased approachRoot Cause
The
migrate.gomodule appliedaggregationProperties,mirrorProperties, andownershipconcurrently viarunBlueprintPhasewithout any dependency ordering or retry logic. Meanwhile,import.goalready had:import.gomigrate.go(before)TopologicalSortAggPropsTopologicalSortOwnershipWhen the Port API receives a blueprint update where
pathFilterreferences a relation path that doesn't exist yet, it returns 200 OK but silently nullifies the pathFilter. Similarly, inherited ownership referencing an unresolved relation path is silently dropped.Changes
TopologicalSortAggPropsto process levels sequentiallyTopologicalSortOwnershipto apply in dependency orderTest plan
make test— all existing tests passgo build ./...— compiles cleanport migratewith a dataset containing cross-blueprint aggregation properties withpathFilterport migratewith blueprints using inherited ownership chainsMade with Cursor