Skip to content

W-064: ecs-relations up traversal (REL-F04)

Type: feature · Size: S · Epic: E-relations-v0 · Target: packages/ecs-relations · Breaking: no Depends: W-060 Refs: spec REL-060..REL-067 (group REL-F04; KL3, KL6, KL8)

Goal

Implement up(world, entity, rel, trait, { self? }) in packages/ecs-relations: a depth-first walk along rel that returns the first entity with trait, visiting targets in ascending entity.id() order. Headless only.

Steps

  • S1 (REL-060, REL-061, REL-062, REL-063): depth-first walk over targetsFor(rel) sorted by entity.id(), returning the first match; { self: true } checks entity first; undefined when nothing matches; the result does not depend on the order of earlier adds and removes; files: packages/ecs-relations/src/up.ts, packages/ecs-relations/src/index.ts, packages/ecs-relations/tests/up.test.ts
  • S2 (REL-064, REL-065, REL-066, REL-067; changeset): a visited set makes cycles terminate; each call reads the current state and does not change the world; works for exclusive and non-exclusive relations and for tag, SoA, and AoS traits; throws naming up for an entity that is not alive in world; files: packages/ecs-relations/tests/up-edge.test.ts, packages/ecs-relations/src/up.ts, .changeset/w-064-ecs-relations-up.md (patch, @workspace/ecs-relations)

Log

  • 2026-11-01 created (Triage), split from the approved spec W-008
  • 2026-11-01 placed in Later (Depends W-060 not done; ready once the scaffold is done)
  • 2026-11-02 moved to Next (Triage): W-060 done, size S, target and Goal filled
  • 2026-11-02 moved down in Next behind the demo-critical items (Triage)