feat(spatial): bind derived spatial state to explicit derivation lineage
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
Start by reviewing the prerequisite contracts in #498, #528, and #520, then compare their boundaries with the proposed SpatialStateLineageV1 and SpatialDerivationRef shapes. Define the typed input and parent roles, separate state and lineage digests, and validate the listed replay invariants and qualification regressions, including missing parents, self-parenting, cycles, and unsupported schemas.
Written by the indexing model from the issue text.
Description
Purpose
Define one replayable, content-addressed provenance contract for derived spatial state.
This is intentionally broader than SpatialBelief<T>. The first deterministic mapper (#530) should produce a derived geometric evidence field, while a later separately qualified inference step may derive an actual physical occupancy belief from that evidence.
The lineage substrate should work for both without pretending they have the same epistemic meaning.
Core theorem
input evidence/state
+
exact derivation recipe
↓
derived spatial state
must retain enough identity to reconstruct what inputs were used, what procedure transformed them, and what exact output state resulted.
But:
derivation provenance
!=
truth
!=
confidence
!=
currentness
!=
belief authority
!=
action authority
Persistence of lineage is non-authorizing.
Why evidence references alone are insufficient
The same input evidence can yield different outputs under different algorithms, model revisions, transforms, calibration, parameters, or fusion rules:
same evidence
+ recipe A
-> state A
same evidence
+ recipe B
-> state B
Conversely, different valid histories can sometimes produce byte-identical state. State identity and history identity must therefore remain separate.
Proposed V1 shape
Conceptually:
SpatialStateLineageV1
├── state_kind
├── state_schema_version
├── derivation_ref
├── direct_input_refs[]
├── parent_state_refs[]
├── output_state_digest
└── lineage_digest
A small content-addressed derivation identity may be:
SpatialDerivationRef
├── namespace / producer identity
├── local derivation id
├── generation
└── derivation_digest
derivation_digest binds the canonical replay recipe/configuration. Depending on state kind, that record may include algorithm identity/version, implementation revision, grid specification, camera model, transform/calibration lineage, conflict rule, resource budget, uncertainty model, observation-likelihood model, or other replay-critical semantics.
Preserve input roles
Do not flatten all inputs into one untyped digest vector.
Direct inputs should preserve semantic role, conceptually:
DirectSpatialInputV1
├── SpatialStatement(ref)
├── Calibration(ref)
├── Transform(ref)
├── ClockScale(ref) // only if later introduced
└── OtherQualifiedInput(...)
Parent derived states belong in parent_state_refs[], not in the direct-observation list.
This prevents a prior map/belief digest from masquerading as fresh sensor evidence.
Recursive incremental updates
A realistic streaming update is:
State_t
+ newly admitted direct inputs
+ exact derivation recipe
-> State_t+1
so provenance is a DAG, not a repeatedly flattened evidence list.
Important invariants:
- prior states are not silently reclassified as fresh evidence;
- direct evidence remains separately addressable through graph depth;
- repeated evidence entering through an ancestor and again as a new direct input can be detected by the owning fusion/replay logic;
- missing/unresolved parents fail replay rather than being ignored;
- no state may directly name itself as a parent;
- replay resolution detects cycles rather than recursing indefinitely.
A small reference object alone does not prove global DAG validity; full graph validation belongs to the replay resolver/verifier.
Separate state and lineage identity
Use different identities for output bytes and derivation history:
output_state_digest = hash(canonical state bytes only)
lineage_digest = hash(
state kind/schema
+ derivation recipe identity
+ typed direct inputs
+ parent state refs
+ output_state_digest
)
This permits:
same output_state_digest
+ different valid history
-> different lineage_digest
which is expected for commutative streaming accumulators reached through different ingestion orders.
Likewise, identical recipe/input lineage with different stored output bytes is detectable because output_state_digest differs.
State-kind boundary
state_kind is descriptive/type identity, not authority.
Examples:
geometric_evidence_field
physical_occupancy_belief
object_relational_state
photometric_surface_field
A geometric evidence field must not become a belief merely by changing a string. The owning Rust type/constructor and qualified derivation transition establish the semantic boundary.
Intended sequence:
SpatialObservation
↓
SparseGeometricEvidenceFieldV1 (#530)
↓
qualified/calibrated belief extraction
↓
SpatialBelief<PhysicalOccupancyState>
↓
object / dynamic / semantic state
↓
photometric renderer
Every arrow may have lineage; the arrows do not grant one another authority automatically.
Replay / persistence
Persisted lineage cannot recreate runtime evidence admission, runtime belief authority, or currentness.
Reconstitution requires either:
- rerunning the exact qualified derivation from appropriately admitted/resolved inputs and comparing output identity; or
- a separately qualified replay/verifier boundary that establishes equivalent output and authority conditions.
A persisted derivation_ref + output_state_digest is evidence of recorded provenance, not a runtime capability.
Relationship to #530
#530 should use this lineage for SparseGeometricEvidenceFieldV1 without requiring BeliefSupport just to aggregate observations.
A later evidence-field -> occupancy-belief transition should produce a new state kind and new lineage and consume whatever bounded belief-support / calibrated inference authority is appropriate.
Qualification requirements
Require regressions proving at least:
- same direct evidence + different derivation recipe -> distinguishable lineage;
- changed recipe/config bytes -> changed derivation identity;
- same state bytes reached through different valid parent chains -> same state digest, different lineage digest;
- changed output bytes -> changed output state digest;
- parent state and direct observation roles cannot be substituted;
- repeated evidence through parent + direct input is detectable where the owning derivation forbids reuse;
- persisted lineage retains exact parents/inputs/recipe/output identity but grants no runtime authority;
- missing parent fails replay;
- direct self-parenting is rejected;
- cyclic lineage resolution fails closed;
- unknown/unsupported state/derivation schema fails closed;
- replay-critical transform/calibration/model/config revisions cannot be omitted by the owning derivation adapter.
Ordering
#495 protected spatial HDC
↓
#498 metric/frame/time/evidence foundation
↓
#528 generic observation admission
↓
#520 exact spatial statement binding
↓
#511 derived-state lineage
↓
#530 deterministic geometric evidence field
↓
qualified belief extraction
↓
objects / dynamics / Gaussian-surface renderer
This issue should remain a prerequisite for promoting the first persistent derived spatial state beyond a throwaway fixture, but should not expand #498 while #498 intentionally contains no fusion implementation.
- Dominant language
- Rust
- Stars
- 9
- Forks
- 1
- Avg merge
- 15m
- Merged PRs (30d)
- 8
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Luminous-Dynamics/symthaea
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Luminous-Dynamics/symthaea#3508 · 2 comments ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Luminous-Dynamics/symthaea#3137 · 1 comment ·
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
Luminous-Dynamics/symthaea#2464 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Luminous-Dynamics/symthaea#2452 · 1 comment ·
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
Luminous-Dynamics/symthaea#2424 ·
All issues in Luminous-Dynamics/symthaea
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100