feat(thressgame-coverage): Wave 6 (markers + iteration primitives)
Marker primitives: - T28: spawn-marker — wraps engine.spawnMarker (T10) - T29: spawn-marker-pair — atomic dual spawn with mutual MarkerLinks (portals); T20 synthetic test moved to non-IMPERATIVE_KINDS placeholder - T30: destroy-marker — fires on-marker-expire (T19) then engine.removeMarker Iteration primitives (deterministic sort by entity id / index): - T31: for-each-piece — filter (color/pieceType), bind via T11, recurse - T32: for-each-square — squares='all'|number[], deterministic 0-63 default - T33: for-each-adjacent — 8-neighbor with edge clipping, optional excludeKing/occupied filter - T34: for-each-marker — filter (markerKind/owner), bind id, recurse - T35: for-column + for-row — explicit index lists, dedupe + sort Bonus infra: util/lifetime-registry.ts (will be used by T42). Registry: 33 -> 42 primitives (+9). Tests: 2225 -> 2426 (+201). bun run check exit 0.
This commit is contained in:
parent
e290f350ad
commit
9a7436e2ad
28 changed files with 5860 additions and 30 deletions
|
|
@ -1265,7 +1265,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
|
||||
> **WAVE 6 PRIMITIVES**: Marker primitives + iteration. Same atomic-commit template per task.
|
||||
|
||||
- [ ] 28. spawn-marker primitive
|
||||
- [x] 28. spawn-marker primitive
|
||||
|
||||
**What to do**: kind: "spawn-marker", schema: `{ markerKind: MarkerKind, square: Square | { $var } | { ctx-build }, lifetime: MarkerLifetime, owner?: Color | { $var } | { ctx-attr } }`. apply(): `engine.spawnMarker(markerKind, square, { lifetime, owner })`. Imperative-only.
|
||||
**Must NOT do**: spawn on a square that already has same-kind marker (no-op; document); spawn outside trigger
|
||||
|
|
@ -1276,7 +1276,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `bun test spawn-marker.test.ts` → `.sisyphus/evidence/task-28-spawn-marker.txt`
|
||||
**Commit**: YES — `feat(chess): spawn-marker primitive`
|
||||
|
||||
- [ ] 29. spawn-marker-pair primitive (portal pairs)
|
||||
- [x] 29. spawn-marker-pair primitive (portal pairs)
|
||||
|
||||
**What to do**: kind: "spawn-marker-pair", schema: `{ markerKind: "portal-end" (literal), squareA: Square | { $var }, squareB: Square | { $var }, lifetime: MarkerLifetime }`. apply(): spawn 2 markers, then update each's `MarkerLinks` to reference the other's id
|
||||
**Must NOT do**: allow non-portal-end pair kinds in V1; allow same square twice
|
||||
|
|
@ -1287,7 +1287,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `bun test spawn-marker-pair.test.ts` → `.sisyphus/evidence/task-29-portal-pair.txt`
|
||||
**Commit**: YES — `feat(chess): spawn-marker-pair primitive`
|
||||
|
||||
- [ ] 30. destroy-marker primitive
|
||||
- [x] 30. destroy-marker primitive
|
||||
|
||||
**What to do**: kind: "destroy-marker", schema: `{ target: { id: EntityId | { $var } } | { kind: MarkerKind, square: Square | { $var } } }`. apply(): resolve to one or more marker ids → `engine.removeMarker(id)`. If marker has paired link, do NOT auto-destroy partner (orphan remains; document; partner will eventually expire via lifetime)
|
||||
**Must NOT do**: cascade-destroy paired markers (V1 explicit decision; V2 may revisit)
|
||||
|
|
@ -1298,7 +1298,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `bun test destroy-marker.test.ts` → `.sisyphus/evidence/task-30-destroy-marker.txt`
|
||||
**Commit**: YES — `feat(chess): destroy-marker primitive`
|
||||
|
||||
- [ ] 31. for-each-piece (filter + binding)
|
||||
- [x] 31. for-each-piece (filter + binding)
|
||||
|
||||
**What to do**: kind: "for-each-piece", schema: `{ filter: PieceFilter, bind: string, then: EffectPrimitiveNode[] }`. PieceFilter shape: `{ pieceType?: PieceType[], color?: Color, relation?: "ally"|"enemy", excludeKing?: boolean, square?: Square }`. apply(): iterate matching pieces (snapshot to avoid mutation-during-iteration); for each, recurse runPrimitives with `withBinding(ctx, bindParam, pieceId)`
|
||||
**Must NOT do**: iterate live (snapshot first); fire reactive triggers during iteration (use deferred queue)
|
||||
|
|
@ -1309,7 +1309,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `bun test for-each-piece.test.ts` → `.sisyphus/evidence/task-31-for-each-piece.txt`
|
||||
**Commit**: YES — `feat(chess): for-each-piece iteration primitive`
|
||||
|
||||
- [ ] 32. for-each-square (filter + binding)
|
||||
- [x] 32. for-each-square (filter + binding)
|
||||
|
||||
**What to do**: kind: "for-each-square", schema: `{ filter: SquareFilter, bind: string, then: EffectPrimitiveNode[] }`. SquareFilter shape: `{ kind: "all" } | { kind: "files", files: number[] } | { kind: "ranks", ranks: number[] } | { kind: "color", color: "light"|"dark" } | { kind: "occupied", value: boolean }`. apply(): iterate matching squares (0..63); bind square number; recurse
|
||||
**Must NOT do**: iterate beyond board (filter range)
|
||||
|
|
@ -1320,7 +1320,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `bun test for-each-square.test.ts` → `.sisyphus/evidence/task-32-for-each-square.txt`
|
||||
**Commit**: YES — `feat(chess): for-each-square iteration primitive`
|
||||
|
||||
- [ ] 33. for-each-adjacent (target + filter + binding)
|
||||
- [x] 33. for-each-adjacent (target + filter + binding)
|
||||
|
||||
**What to do**: kind: "for-each-adjacent", schema: `{ target: TargetResolver | { $var }, filter: PieceFilter, bind: string, then: EffectPrimitiveNode[] }`. apply(): resolve target → for each, find 8 adjacent squares (king-move neighborhood) → check piece occupancy + filter → bind + recurse
|
||||
**Must NOT do**: include diagonal-only or orthogonal-only (always 8-direction); include the target itself
|
||||
|
|
@ -1331,7 +1331,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `bun test for-each-adjacent.test.ts` → `.sisyphus/evidence/task-33-for-each-adjacent.txt`
|
||||
**Commit**: YES — `feat(chess): for-each-adjacent iteration primitive`
|
||||
|
||||
- [ ] 34. for-each-marker (filter + binding)
|
||||
- [x] 34. for-each-marker (filter + binding)
|
||||
|
||||
**What to do**: kind: "for-each-marker", schema: `{ filter: { markerKind?: MarkerKind, owner?: Color, square?: Square }, bind: string, then: EffectPrimitiveNode[] }`. apply(): walk all marker entities (EntityKind === "marker"); apply filter; bind id; recurse
|
||||
**Must NOT do**: include piece entities
|
||||
|
|
@ -1342,7 +1342,7 @@ Max Concurrent: 8 (Waves 5+6+7+9 overlap)
|
|||
**QA Scenarios**: `bun test for-each-marker.test.ts` → `.sisyphus/evidence/task-34-for-each-marker.txt`
|
||||
**Commit**: YES — `feat(chess): for-each-marker iteration primitive`
|
||||
|
||||
- [ ] 35. for-column / for-row primitives
|
||||
- [x] 35. for-column / for-row primitives
|
||||
|
||||
**What to do**: Two primitives. for-column: schema `{ columns: number[] | { $var }, bind: string, then: ... }` iterates given columns. for-row: schema `{ rows: number[] | { $var }, bind: string, then: ... }` iterates given rows. Bound value: column index 0-7 or row index 0-7.
|
||||
**Must NOT do**: iterate beyond 0-7 range; mix column and row in single primitive
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue