You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The #1218 public mixed exploratory/qualified route fixture now constructs and replays after #1219/#1222, but exposes a separate property publication bug: composite SetNodeProperty succeeds for a qualified entity, then the correctly labelled query MATCH (n:mixed:NewNode) WHERE n.score IS NOT NULL RETURN n.node_uuid, n.score returns zero rows immediately, expected exactly that node/123. Compaction is not needed. The earlier unlabelled query was insufficient evidence because ontology-mode unlabelled property union is not supported; it does not establish a runtime-owner regression.
At current main cba602d, composite_publish::eligible_delta_operations hard-codes _untyped for all four node/edge property set/remove variants. apply_graph_mutations repeats the same routing in canonical staging. Query/construction use active runtime/semantic property ownership. Switching publication backends alone cannot repair this mismatch. Corrected baseline: /tmp/gf1224-qualified-baseline.log, test composite_qualified_property_publishing_preserves_values, current main cba602d plus test only: immediate qualified-property assertion 0 versus1. Earlier source discussion: #1221 (comment).
This is a focused verified blocker split from #1221's complete publishing-contract assessment so #1218 can finish its mixed-route replay proof without a dependency cycle. Native child of #1194; blocks #1194, #1218, #1213 and #1221. #1221 retains broader topology support, adoption/clearing authority and cross-path contract work and reuses this repair. No overlap with #1218 edge ordering/schema or #1213 encoding policy.
Acceptance
Resolve supported composite property set/remove ownership from authenticated current node/edge identity and active runtime/semantic bindings. Share the resolved operation routing between prepared delta publication and canonical composite staging, including optimistic publication and same-request creates where applicable. Preserve correct pure exploratory behavior. Refuse ambiguous/unsupported ownership before publication; never silently select an unrelated route.
Public tests cover node and edge set/remove, qualified and runtime/advisory owners, existing values and newly added properties, nullable/typed values and latest-value/tombstone semantics. Prove immediate query, reopen, compaction, export/full verify/clean import and subsequent mutation. Include a mixed exploratory/qualified graph with exact property values. fix(api): preserve property ownership in composite publishing routes #1224 verifies its canonical publishing route; fix(storage): replay valid exploratory edge fragments without losing route semantics #1218 retains the exact mixed-graph GFDR/compaction regression and runs it after this prerequisite merges. Neither may replace the failed value assertion with topology-only proof.
Preserve semantic metadata and complete publication participants, authentication/corruption refusal, parent conflicts, idempotency, cancellation and active snapshots. Reject invalid operations without advancing CURRENT or changing published authorities.
Keep route resolution bounded to required identities/owners; reuse current indexes/catalog/bindings and avoid a new full-graph scan/copy. Measure deterministic lookup/read/write work and temporary/memory exposure across representative cardinalities, with source-bound CPU/RSS evidence appropriate to the changed path. Retain all existing encoding settings; fix(storage): unify permanent encoding policy across all Parquet publishing paths #1213 owns policy changes.
Add focused direct regression coverage, document route ownership and applicable error behavior using existing content-free errors, independently review, pass required exact-head CI Gate, and squash merge.
Completion scenarios
Given a graph containing runtime and qualified owners, when public composite property changes publish through delta or canonical staging, then exact values and removals are visible immediately and after reopen/compaction/portable round trip.
Given an invalid or ambiguous owner, when the mutation is admitted, then it refuses before authoritative publication and preserves the prior graph and active snapshots.
Given increasing unrelated graph size, when a bounded property request resolves routes, then deterministic resource evidence bounds the newly retained owner map and changed payload work. The existing composite validation snapshot already materializes topology and all identity sets; this repair must add no further full-graph scan or copy, and must disclose that existing cost rather than claim the complete transaction is request-sized.
Backward compatibility, migrations, a generic writer abstraction, topology-journal support and unrelated query optimization remain out of scope.
Verified implementation boundary
First writes to an absent qualified property route need canonical staging to establish authenticated semantic schema authority; GFDR carries values, not that authority. Later supported property writes may use GFDR. Optimistic publication remains canonical. Public fixtures separately prove actual GFDR compaction and mixed-owner canonical values; a no-run compaction refusal is not counted as compaction proof.
The first CAS-backed optimistic property publication also exposed a stale-path check: durability promotes the attempt directory, but final CAS closure authentication read its former location. The bounded fix authenticates the installed generation before CURRENT, preserving the lease and cancellation boundary.
The previously recorded CAS UUID-membership authority defect is repaired by merged #1228; current regression coverage also creates topology on a constructed CAS parent. The same-request qualified create/set fixture uses an empty parent and tests node/edge values and portable removal. No UUID authentication is relaxed here.
Reopened current-production edge case
The first qualified-node repair remains merged. On main 1aea7a8b823f5e79ba890c80f822cc50ba06f85f, composite SET/removal on exploratory edges produced by public construction returns success but immediate exact queries retain old values. Construction stores those properties under _exploratory; ordinary public CREATE stores them under the logical relation name. Topology stems alone cannot identify both property owners. The repair must check authenticated row presence in the relevant candidates, including a newest tombstone, and refuse multiple owners. Public unnamed CREATE is rejected by the binder and is not an additional supported publishing path.
A combined construction/ordinary regression also exposed the same removal contract at query time: removing the last string value from one owner leaves a Null-typed route; fixed and variable traversals chose that Null union field before another route's Utf8 field. The resulting query fails on incompatible Null/Utf8 arrays. The bounded correction must retain a concrete union type and null contributions, while preserving errors for incompatible concrete types.
Completed through #1235: exact public construction + ordinary CREATE (including an edge with no properties), composite SET/removal, fixed and variable traversal, compaction, retained stream, reopen, export/full verify/clean import. Representative sizes are 33 and 4,097 original nodes, 129 constructed edges and two ordinary-created edges. Deterministic targeted probe cases cover 1/16/129 targets and 33/4,097 unrelated property rows. Final measurements and independent review are complete; all required exact-head CI passed before squash merge.
Closure evidence
Merged #1235 as 525b29c36250ca09f5ce1ae5422b9a98c17ecb49; exact-head Test Suite/CI Gate 34476237237 succeeded at 6c48a942a988eb11d4021777b3f65ab0e3cdc6e5. Merge was CLEAN, the sole closing reference was #1224, and no review thread remained unresolved. Independent source review found no actionable findings.
Local evidence: cargo test -p graphforge-api --lib --test permanent_storage_budgets produced 737 passing API unit tests and 33 passing publishing tests; the new all-removed relationship-struct assertion was corrected to the verified public schema and passed separately. Final cargo test -p graphforge-api --lib --test permanent_storage_budgets composite_ -- --nocapture passed 79 unit and nine integration tests. The final imported-mutation lifecycle extension passed, as did the Null-order/all-removed/incompatible-type regression and all 24 property_overlay::tests. Workspace clippy, formatting, gate registry and make pre-push-fast passed. Final authoritative Bazel CI covers the merged implementation and tests.
Measured source d30ac7553a6825246333d7f815d6b8fa680b5914: full lifecycle elapsed/user/system 14.46/14.36/1.62 seconds; peak RSS 156,492 KiB; traced reads/writes 232,819,358/42,417,574 bytes; 5,942 fsync calls; no traced errors. Sampled unique-inode allocation peak 10,649,600 bytes, with explicit sampling/overlap limitations. Deterministic selected-route and fragment budgets, exact semantics and unchanged permanent encoding are recorded in the assessment and raw evidence. No migration, compatibility reader or generic writer abstraction was added.
Reopened named-query ownership case (main c481cc1)
The prior repairs remain merged. Canonical #1221 conformance now reproduces a remaining exact-query acceptance failure on merged main c481cc1539b94b0dba7e9092b443408a331ae749: public exploratory construction with 33 nodes / 129 edges / two routes, followed immediately by a named REL0 traversal, returns correct UUIDs/endpoints but null integer/string edge properties. The same fixture's wildcard traversal passes its exact oracle. Main-only runtime reproduction: TMPDIR=/home/ubuntu/graphforge-native-tmp-1195 CARGO_TARGET_DIR=/home/ubuntu/code/graphforge-1229/target cargo test -p graphforge-api --test permanent_storage_budgets baseline_named_exploratory_edge_properties_1224 -- --test-threads=1: 0 passed, 1 failed, 0.50s. Test-only patch/log retained at /tmp/gf1224-main-named-edge-reproducer.patch and /tmp/gf1224-main-named-edge.log; runtime sources were unchanged from main.
The complete safe #1221 four-case census passed both ontology-promoted cases (33 and 4,097 nodes), including actual property GFDR, compaction, node/edge deletion→reopen→CREATE, export/full verify/import and further node/edge mutation. Both exploratory cases fail at initial named-property verification, before any GFDR boundary change executes. Initial helper-path mistakes are retained in earlier diagnostic logs and are not product defects.
Independent source review found one owner-selection cause: construction stores properties under _exploratory; named schema discovery in graphforge-rel/src/lowerer.rs (fixed provider, variable traversal and relational joins) and execution graphforge-exec/src/lib.rs::build_edge_prop_children select only the logical relation name. Existing #1224 mutation ownership handles both candidates, but the named query readers do not. No overlapping issue is created. This issue remains a native blocker of #1221 and #1194.
Finish the existing exact-query criterion with named fixed/variable and applicable already-bound traversal coverage across constructed and ordinary-created edges of the same relation, nullable typed values, property filters, removal/compaction/reopen/portable import and subsequent mutation. Resolve authenticated candidate owners without widening unrelated route reads, losing conflict refusal or undoing the Null/concrete union correction. Retain deterministic work budgets, source-bound resource evidence where changed, independent review and exact-head CI before squash merge and closure. No compatibility path or new topology GFDR support is authorized.
Current main 5fc68e568893110cca97b0eb2c797d306b264e27 still fails a minimal public construction → ordinary Cypher edge SET → immediate exact query. Production files were restored to main for the regression run; only test harness additions differed. Command: TMPDIR=/home/ubuntu/graphforge-native-tmp-1195 CARGO_TARGET_DIR=/home/ubuntu/code/graphforge-target-1195 CARGO_BUILD_JOBS=4 cargo test -p graphforge-api --test permanent_storage_budgets constructed_edge_cypher_set_has_one_authenticated_owner. Result: 0 passed, 1 failed, 0 ignored; ProjectCorrupt: edge properties have multiple authenticated owners.
Fixture: 33 deterministic random-UUID nodes, 129 edges, two routes, nullable node/edge properties, adjacency. Public construction and exact initial query pass. MATCH ()-[r]->() WHERE r.weight IS NOT NULL SET r.weight = r.weight + 1 succeeds, then exact UUID/endpoints/type/weight/text query refuses duplicate owners. No empty REMOVE, import, or predicate optimizer change is involved.
Source cause: ordinary execution WriteCol::stem_for_row selects logical relationship type; SetAccumulator forwards that route to storage. Constructed properties remain under authenticated _exploratory; ordinary mutation inserts a second route owner. The merged composite ownership resolver does not cover this Cypher path. Preserve the previous composite repair and its evidence; this is a remaining canonical acceptance boundary, not an overlapping new issue.
Remaining acceptance: ordinary Cypher edge SET and REMOVE resolve the unique authenticated owner for constructed and ordinary graphs; preserve exact properties, IDs and corruption refusal; prove immediate query, active snapshots, reopen, export/full verification, clean import and subsequent mutation. Include flat/sharded and relevant ontology/exploratory cases. This blocks the new #1242 full lifecycle fixture as well as #1194. No production repair has started; the current three-change WIP limit remains in force.
Verified blocker
The #1218 public mixed exploratory/qualified route fixture now constructs and replays after #1219/#1222, but exposes a separate property publication bug: composite SetNodeProperty succeeds for a qualified entity, then the correctly labelled query
MATCH (n:mixed:NewNode) WHERE n.score IS NOT NULL RETURN n.node_uuid, n.scorereturns zero rows immediately, expected exactly that node/123. Compaction is not needed. The earlier unlabelled query was insufficient evidence because ontology-mode unlabelled property union is not supported; it does not establish a runtime-owner regression.At current main cba602d,
composite_publish::eligible_delta_operationshard-codes_untypedfor all four node/edge property set/remove variants.apply_graph_mutationsrepeats the same routing in canonical staging. Query/construction use active runtime/semantic property ownership. Switching publication backends alone cannot repair this mismatch. Corrected baseline:/tmp/gf1224-qualified-baseline.log, testcomposite_qualified_property_publishing_preserves_values, current main cba602d plus test only: immediate qualified-property assertion 0 versus1. Earlier source discussion: #1221 (comment).This is a focused verified blocker split from #1221's complete publishing-contract assessment so #1218 can finish its mixed-route replay proof without a dependency cycle. Native child of #1194; blocks #1194, #1218, #1213 and #1221. #1221 retains broader topology support, adoption/clearing authority and cross-path contract work and reuses this repair. No overlap with #1218 edge ordering/schema or #1213 encoding policy.
Acceptance
Completion scenarios
Backward compatibility, migrations, a generic writer abstraction, topology-journal support and unrelated query optimization remain out of scope.
Verified implementation boundary
First writes to an absent qualified property route need canonical staging to establish authenticated semantic schema authority; GFDR carries values, not that authority. Later supported property writes may use GFDR. Optimistic publication remains canonical. Public fixtures separately prove actual GFDR compaction and mixed-owner canonical values; a no-run compaction refusal is not counted as compaction proof.
The first CAS-backed optimistic property publication also exposed a stale-path check: durability promotes the attempt directory, but final CAS closure authentication read its former location. The bounded fix authenticates the installed generation before CURRENT, preserving the lease and cancellation boundary.
The previously recorded CAS UUID-membership authority defect is repaired by merged #1228; current regression coverage also creates topology on a constructed CAS parent. The same-request qualified create/set fixture uses an empty parent and tests node/edge values and portable removal. No UUID authentication is relaxed here.
Reopened current-production edge case
The first qualified-node repair remains merged. On main
1aea7a8b823f5e79ba890c80f822cc50ba06f85f, composite SET/removal on exploratory edges produced by public construction returns success but immediate exact queries retain old values. Construction stores those properties under_exploratory; ordinary public CREATE stores them under the logical relation name. Topology stems alone cannot identify both property owners. The repair must check authenticated row presence in the relevant candidates, including a newest tombstone, and refuse multiple owners. Public unnamed CREATE is rejected by the binder and is not an additional supported publishing path.A combined construction/ordinary regression also exposed the same removal contract at query time: removing the last string value from one owner leaves a Null-typed route; fixed and variable traversals chose that Null union field before another route's Utf8 field. The resulting query fails on incompatible Null/Utf8 arrays. The bounded correction must retain a concrete union type and null contributions, while preserving errors for incompatible concrete types.
Completed through #1235: exact public construction + ordinary CREATE (including an edge with no properties), composite SET/removal, fixed and variable traversal, compaction, retained stream, reopen, export/full verify/clean import. Representative sizes are 33 and 4,097 original nodes, 129 constructed edges and two ordinary-created edges. Deterministic targeted probe cases cover 1/16/129 targets and 33/4,097 unrelated property rows. Final measurements and independent review are complete; all required exact-head CI passed before squash merge.
Closure evidence
Merged #1235 as
525b29c36250ca09f5ce1ae5422b9a98c17ecb49; exact-head Test Suite/CI Gate 34476237237 succeeded at6c48a942a988eb11d4021777b3f65ab0e3cdc6e5. Merge was CLEAN, the sole closing reference was #1224, and no review thread remained unresolved. Independent source review found no actionable findings.Local evidence:
cargo test -p graphforge-api --lib --test permanent_storage_budgetsproduced 737 passing API unit tests and 33 passing publishing tests; the new all-removed relationship-struct assertion was corrected to the verified public schema and passed separately. Finalcargo test -p graphforge-api --lib --test permanent_storage_budgets composite_ -- --nocapturepassed 79 unit and nine integration tests. The final imported-mutation lifecycle extension passed, as did the Null-order/all-removed/incompatible-type regression and all 24property_overlay::tests. Workspace clippy, formatting, gate registry andmake pre-push-fastpassed. Final authoritative Bazel CI covers the merged implementation and tests.Measured source
d30ac7553a6825246333d7f815d6b8fa680b5914: full lifecycle elapsed/user/system 14.46/14.36/1.62 seconds; peak RSS 156,492 KiB; traced reads/writes 232,819,358/42,417,574 bytes; 5,942 fsync calls; no traced errors. Sampled unique-inode allocation peak 10,649,600 bytes, with explicit sampling/overlap limitations. Deterministic selected-route and fragment budgets, exact semantics and unchanged permanent encoding are recorded in the assessment and raw evidence. No migration, compatibility reader or generic writer abstraction was added.Reopened named-query ownership case (main c481cc1)
The prior repairs remain merged. Canonical #1221 conformance now reproduces a remaining exact-query acceptance failure on merged main
c481cc1539b94b0dba7e9092b443408a331ae749: public exploratory construction with 33 nodes / 129 edges / two routes, followed immediately by a namedREL0traversal, returns correct UUIDs/endpoints but null integer/string edge properties. The same fixture's wildcard traversal passes its exact oracle. Main-only runtime reproduction:TMPDIR=/home/ubuntu/graphforge-native-tmp-1195 CARGO_TARGET_DIR=/home/ubuntu/code/graphforge-1229/target cargo test -p graphforge-api --test permanent_storage_budgets baseline_named_exploratory_edge_properties_1224 -- --test-threads=1: 0 passed, 1 failed, 0.50s. Test-only patch/log retained at/tmp/gf1224-main-named-edge-reproducer.patchand/tmp/gf1224-main-named-edge.log; runtime sources were unchanged from main.The complete safe #1221 four-case census passed both ontology-promoted cases (33 and 4,097 nodes), including actual property GFDR, compaction, node/edge deletion→reopen→CREATE, export/full verify/import and further node/edge mutation. Both exploratory cases fail at initial named-property verification, before any GFDR boundary change executes. Initial helper-path mistakes are retained in earlier diagnostic logs and are not product defects.
Independent source review found one owner-selection cause: construction stores properties under
_exploratory; named schema discovery ingraphforge-rel/src/lowerer.rs(fixed provider, variable traversal and relational joins) and executiongraphforge-exec/src/lib.rs::build_edge_prop_childrenselect only the logical relation name. Existing #1224 mutation ownership handles both candidates, but the named query readers do not. No overlapping issue is created. This issue remains a native blocker of #1221 and #1194.Finish the existing exact-query criterion with named fixed/variable and applicable already-bound traversal coverage across constructed and ordinary-created edges of the same relation, nullable typed values, property filters, removal/compaction/reopen/portable import and subsequent mutation. Resolve authenticated candidate owners without widening unrelated route reads, losing conflict refusal or undoing the Null/concrete union correction. Retain deterministic work budgets, source-bound resource evidence where changed, independent review and exact-head CI before squash merge and closure. No compatibility path or new topology GFDR support is authorized.
Reopened ordinary Cypher publishing boundary (2026-09-10)
Current main
5fc68e568893110cca97b0eb2c797d306b264e27still fails a minimal public construction → ordinary Cypher edge SET → immediate exact query. Production files were restored to main for the regression run; only test harness additions differed. Command:TMPDIR=/home/ubuntu/graphforge-native-tmp-1195 CARGO_TARGET_DIR=/home/ubuntu/code/graphforge-target-1195 CARGO_BUILD_JOBS=4 cargo test -p graphforge-api --test permanent_storage_budgets constructed_edge_cypher_set_has_one_authenticated_owner. Result: 0 passed, 1 failed, 0 ignored;ProjectCorrupt: edge properties have multiple authenticated owners.Fixture: 33 deterministic random-UUID nodes, 129 edges, two routes, nullable node/edge properties, adjacency. Public construction and exact initial query pass.
MATCH ()-[r]->() WHERE r.weight IS NOT NULL SET r.weight = r.weight + 1succeeds, then exact UUID/endpoints/type/weight/text query refuses duplicate owners. No empty REMOVE, import, or predicate optimizer change is involved.Source cause: ordinary execution
WriteCol::stem_for_rowselects logical relationship type; SetAccumulator forwards that route to storage. Constructed properties remain under authenticated_exploratory; ordinary mutation inserts a second route owner. The merged composite ownership resolver does not cover this Cypher path. Preserve the previous composite repair and its evidence; this is a remaining canonical acceptance boundary, not an overlapping new issue.Remaining acceptance: ordinary Cypher edge SET and REMOVE resolve the unique authenticated owner for constructed and ordinary graphs; preserve exact properties, IDs and corruption refusal; prove immediate query, active snapshots, reopen, export/full verification, clean import and subsequent mutation. Include flat/sharded and relevant ontology/exploratory cases. This blocks the new #1242 full lifecycle fixture as well as #1194. No production repair has started; the current three-change WIP limit remains in force.