Skip to content

Define canonical GeoArrow spatial values across GraphForge query, storage, and bindings #797

Description

@DecisionNerd

Problem

GraphForge is a consumer-neutral graph and knowledge workbench whose public data plane is Arrow, but it cannot yet represent, persist, query, and exchange standardized spatial values end to end. Ad hoc longitude/latitude columns cannot carry geometry type, CRS, edge interpretation, validity, or stable cross-language semantics.

GeoArrow is useful independently of any one renderer: notebooks, analytical consumers, dataframes, files, agents, and XYG should all receive the same typed spatial values. That does not make visualization behavior a GraphForge responsibility.

Objective

Define and ship strong, Rust-owned GeoArrow spatial values through GraphForge ontology, mutation, storage, query, Arrow interchange, and thin bindings while keeping rendering, viewport, projection UI, LOD, layers, paint, and interaction outside GraphForge.

Consumer-Neutral GeoArrow Contract

  • GraphForge preserves well-formed Arrow extension names, storage types, field metadata, buffers, offsets, validity, and nullability through IPC, Parquet, reopen, and bindings, including extension/CRS metadata that GraphForge cannot compute on.
  • The initial GraphForge-produced native geometry catalog is two-dimensional Point, LineString, Polygon, MultiPoint, MultiLineString, and MultiPolygon.
  • Geometry collections, mixed-geometry columns, Z/M coordinates, and arbitrary geometry unions are deferred from the initial producer profile but must not be silently corrupted when safely transported as recognized Arrow extensions.
  • CRS and edge interpretation are explicit field-level metadata. Canonical GraphForge construction and initial spatial computation are certified for a bounded documented profile beginning with EPSG:4326 and EPSG:3857.
  • Other well-formed CRS metadata may be stored, projected, exported, and reopened losslessly. An operation requiring unsupported CRS/edge semantics returns a typed unsupported-operation error; GraphForge does not reject otherwise preservable data.
  • Axis order follows the GeoArrow contract: canonical x/y, including longitude/latitude for geographic data and easting/northing for projected data. GraphForge never infers fields or silently swaps axes.
  • The canonical native path does not reconstruct row-wise WKB, WKT, or GeoJSON. Explicit import/export adapters may exist at boundaries, but canonical storage and results remain typed Arrow.
  • Spatial computation is Rust-owned and explicitly profiled. Initial work must freeze semantics for construction/type inspection and the documented point()/distance() surface; it must not create an unbounded GIS engine by implication.

Requirements

  • Audit and reconcile existing point/distance/spatial documentation against current Rust behavior.
  • Implement the GeoArrow profile through ontology, scalar and bulk construction, storage, query projection/filtering, Arrow IPC/Parquet, canonical fingerprints, Python, Node, and CLI/export.
  • Specify canonical field/storage types, extension metadata, nullability, precision, validation, deterministic ordering/fingerprints, and compatibility behavior.
  • Preserve accepted spatial values across commit, reopen, accepted batch boundaries, and language bindings without binding-owned geometry reconstruction.
  • Validate finite coordinates, offsets, rings/nesting, geometry sizes, metadata, and resource limits before mutation.
  • Separate transport support from computation support: safe unknown metadata is preserved; unsupported computation fails explicitly.
  • Keep coordinate values, geometries, and paths out of logs.
  • Introduce no dependency on XYG, map SDKs, renderers, basemap/tile providers, or foreign graph engines.

Acceptance Criteria

  • A normative specification identifies the supported producer profile, GeoArrow layouts and metadata, CRS/edge semantics, spatial-operation profile, and deferred forms.
  • Spatial properties survive scalar and bulk write, commit, reopen, query, Arrow IPC, Parquet, canonical fingerprinting, CLI export, Python, and Node without loss.
  • Well-formed but computationally unsupported CRS/extension metadata round-trips unchanged.
  • Unsupported spatial operations fail with stable typed errors before partial output or mutation.
  • Invalid coordinates, offsets, nesting, or over-budget geometry fail atomically without value-bearing diagnostics.
  • The documented point() and distance() behavior is either implemented with direct Rust execution evidence under the certified profile or corrected precisely; no false completeness claim remains.
  • Producer-neutral golden fixtures can be consumed without field renaming or WKB/WKT/GeoJSON reconstruction.
  • No GraphForge crate acquires visualization, map, tile, scene, or XYG behavior.
  • Relevant exact-head CI Gate is green.

BDD Completion Scenarios

Scenario: Spatial property crosses every GraphForge boundary

Given a node or edge with a canonical spatial property and explicit CRS
When it is committed, reopened, queried, and consumed through Python, Node, and CLI/export
Then every surface receives the same Arrow value, buffers, and metadata
And no binding reconstructs the geometry.

Scenario: Unknown computation profile remains transportable

Given a well-formed GeoArrow value whose CRS can be preserved but is not supported for a requested spatial operation
When the value is stored, queried, and exported
Then its extension and CRS metadata remain unchanged
And the unsupported operation returns a stable typed error without altering the value.

Scenario: Invalid spatial input fails atomically

Given malformed offsets/rings, non-finite coordinates, inconsistent metadata, or an over-budget geometry
When construction or query materialization validates it
Then GraphForge returns a stable typed error
And publishes no partial graph state or result.

Observability

Safe extension/geometry type, CRS-present flag or non-sensitive identifier, row/feature counts, byte counts, validation phase, and error code only. Never log coordinates, property values, queries, or paths.

Security And Privacy

Bound geometry sizes and nesting, validate metadata and offsets before allocation, preserve project/path containment, and perform no implicit network, tile, style, geocoding, or CRS-provider access.

Testing

Rust type/validation/property tests for every producer-profile geometry; scalar and bulk construction parity; create/query/reopen and accepted batch-boundary round trips; Arrow IPC and Parquet schema/buffer goldens; extension metadata and fingerprint checks; EPSG:4326/3857 operation cases; unsupported-but-preserved CRS cases; malformed offsets/rings, nulls, nesting, vertex/byte budgets; Python/Node/CLI parity; and producer-neutral fixtures.

Documentation

Update ontology/value, Cypher spatial function, Arrow, storage/project format, bindings, CLI/export, and compatibility documentation. Consumer-specific rendering instructions remain in the consumer repository.

Non-Goals

Maps, basemaps, tiles, viewport/projection UI, geographic LOD, layer geometry, paint, interaction, automatic geocoding, field inference, hidden CRS conversion, a full GIS/overlay engine, geometry collections, mixed geometry columns, Z/M production, or a GraphForge dependency on XYG.

Related Issues

Activity

  1. changed the title [-]Define canonical Arrow spatial values across GraphForge query, storage, and bindings[/-] [+]Define canonical GeoArrow spatial values across GraphForge query, storage, and bindings[/+] on Aug 18, 2026
  2. DecisionNerd commented on Aug 19, 2026

    @DecisionNerd
    ContributorAuthor

    Canonical GeoArrow close gate is complete.

    Native sub-issues and merge evidence:

    PR #823 merged from exact head 5d5aa56 after all 21 checks and CI Gate passed, merge state was CLEAN, and no review threads were unresolved. The complete diff remains Rust-owned with thin bindings and adds no visualization, XYG, map, tile, or foreign-engine dependency. This satisfies the canonical #797 acceptance outcomes and unblocks its native dependents.

  3. DecisionNerd commented on Aug 19, 2026

    @DecisionNerd
    ContributorAuthor

    Requirement-by-requirement close audit (merged-tree evidence):

    1. Normative producer profile/layout/metadata/CRS/edge/operation/deferred forms — feat: define canonical GeoArrow spatial contract #806 established the canonical value/profile contract; feat(spatial): certify GeoArrow producer portability #823 added docs/book/architecture/geoarrow-conformance.md and reconciled spatial-values.md plus the interchange contract.
    2. Lossless scalar/bulk → commit/reopen/query → IPC/Parquet/fingerprint/CLI/Python/Node — Persist and query canonical GeoArrow spatial properties #814 covers Rust scalar/bulk construction and persistence/reopen/query; feat(bindings): expose canonical GeoArrow interchange #817 executes thin Python, Node, and CLI paths; feat(spatial): certify GeoArrow producer portability #823 adds canonical Arrow IPC/Parquet artifacts, checksums, CLI export, and real binding conformance.
    3. Unsupported-but-well-formed extension/CRS round-trip — feat(spatial): certify GeoArrow producer portability #823 adds SpatialCrs::Preserved, retains exact extension name/metadata in storage decode/write and reopen/query/export, with direct preserved-profile tests.
    4. Stable typed unsupported-operation failures before partial output/mutation — Persist and query canonical GeoArrow spatial properties #814 establishes typed computation/resource failures; feat(spatial): certify GeoArrow producer portability #823 directly proves preserved-only distance() and unsupported-CRS point() reject explicitly.
    5. Atomic malformed/over-budget rejection without value-bearing diagnostics — feat: define canonical GeoArrow spatial contract #806/Persist and query canonical GeoArrow spatial properties #814 validate finite coordinates, layouts/nesting/metadata, point-distance and resource budgets before publish; feat(spatial): certify GeoArrow producer portability #823 adds malformed/adversarial conformance cases.
    6. Documented point() / distance() matches direct Rust behavior — Persist and query canonical GeoArrow spatial properties #814 implements and tests the certified 4326/3857 surface; feat(spatial): certify GeoArrow producer portability #823 adds direct Rust rejection evidence for noncomputable preserved profiles and updates documentation.
    7. Producer-neutral golden fixtures without renaming or row-wise reconstruction — feat(spatial): certify GeoArrow producer portability #823 adds deterministic canonical.arrow and canonical.parquet, SHA256SUMS, independent PyArrow reads, and exact metadata checks; canonical paths remain typed Arrow rather than WKB/WKT/GeoJSON.
    8. No visualization/map/tile/scene/XYG behavior in GraphForge — merged diffs are confined to core/API/storage/plan/rel, thin bindings/CLI, fixtures/build metadata, and architecture docs; no XYG, renderer, map SDK, tile, scene, or foreign graph-engine dependency was introduced.
    9. Relevant exact-head CI Gate green — feat: define canonical GeoArrow spatial contract #806, Persist and query canonical GeoArrow spatial properties #814, feat(bindings): expose canonical GeoArrow interchange #817, and feat(spatial): certify GeoArrow producer portability #823 each merged only after exact-head gates. Final feat(spatial): certify GeoArrow producer portability #823 head 5d5aa56f61f2a090c28fb219ab4927f70cc4a61b passed all 21 checks including CI Gate, both Bazel lanes, Rust Quality, Rust Benchmarks/CodSpeed, native Python/Node, concurrency, and storage platform lanes; merge state was CLEAN with zero unresolved threads.

    Native graph audit: #799–#802 are all CLOSED sub-issues and CLOSED blockers of #797. #797 is CLOSED/COMPLETED and remains the native dependency of CurateLabs/xyg#47, CurateLabs/graphforge-vscode#82, and #810; those consumers now observe #797 as CLOSED.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    coreCore source code changesenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions