Migrated from Method backlog
GitHub Issues are now the live work tracker. Repository docs remain Method evidence.
| Field |
Value |
| Source backlog |
docs/method/backlog/bad-code/MODEL_incremental-index-updater-shape-sludge.md |
| Archived source |
docs/archive/backlog/github-issue-migration-2026-06-01/docs/method/backlog/bad-code/MODEL_incremental-index-updater-shape-sludge.md |
| Original lane |
bad-code |
| Original id |
BAD_IncrementalIndexUpdater-shape-sludge |
| Original legend |
MODEL |
| Original feature |
trie-state-storage |
| Original release home |
v17.0.0 |
Original backlog card
IncrementalIndexUpdater leans on Record<string, unknown> and a duck-typed WarpStateLike
Symptom
src/domain/services/index/IncrementalIndexUpdater.ts contains:
-
A duck-typed local alias:
type WarpStateLike = {
nodeAlive: { contains(key: string): boolean };
edgeAlive: ORSet;
};
This is shape-trust posing as a type. The method-set happens to
be compatible with WarpState, but nothing enforces that at
runtime.
-
At least eight Record<string, unknown> sites (lines
approximately 33, 34, 234, 244, 392, 394, 398, 409) used to carry
shard-prop data through the updater. Per SSTS, Record<string, unknown> is banned inside the domain — raw bags of untyped
fields do not correspond to a domain concept.
-
An as assertion decoding shard props:
this._codec.decode(buf) as Array<[string, Record<string, unknown>]>;
The decode should either return a typed runtime value via a
parser at the boundary, or throw.
Why it's not in cycle 0024's scope
Cycle 0024 (PROTO_orset-internal-encapsulation) fixes #1 — the
WarpStateLike duck type goes away as part of retyping consumers to
WarpState / ORSet. That's the only slice of this file touched by
0024.
Items #2 and #3 require a domain model for "shard props" (or
"indexed property bag"). That is a design decision: what are the
real concepts inside the index builder, and how do they cross the
codec boundary? Punting that to its own cycle so 0024 stays narrow.
Proposed fix
- Name the domain concept — probably something like
IndexShardProps or PropertyBag — and give it a runtime-backed
class with validated invariants.
- Move CBOR decoding to a parser method on that class (or to a
dedicated adapter-side parser) so raw Record<string, unknown>
never enters the domain.
- Audit the rest of
src/domain/services/index/ for the same
pattern — this file is unlikely to be the only offender.
Related
- Cycle 0024 retro (once it lands) should reference this item.
- Cycle 0023 retro surfaced the broader SSTS vigilance problem that
let this sludge accumulate.
Migrated from Method backlog
GitHub Issues are now the live work tracker. Repository docs remain Method evidence.
docs/method/backlog/bad-code/MODEL_incremental-index-updater-shape-sludge.mddocs/archive/backlog/github-issue-migration-2026-06-01/docs/method/backlog/bad-code/MODEL_incremental-index-updater-shape-sludge.mdbad-codeBAD_IncrementalIndexUpdater-shape-sludgeMODELtrie-state-storagev17.0.0Original backlog card
IncrementalIndexUpdater leans on
Record<string, unknown>and a duck-typedWarpStateLikeSymptom
src/domain/services/index/IncrementalIndexUpdater.tscontains:A duck-typed local alias:
This is shape-trust posing as a type. The method-set happens to
be compatible with
WarpState, but nothing enforces that atruntime.
At least eight
Record<string, unknown>sites (linesapproximately 33, 34, 234, 244, 392, 394, 398, 409) used to carry
shard-prop data through the updater. Per SSTS,
Record<string, unknown>is banned inside the domain — raw bags of untypedfields do not correspond to a domain concept.
An
asassertion decoding shard props:The decode should either return a typed runtime value via a
parser at the boundary, or throw.
Why it's not in cycle 0024's scope
Cycle 0024 (
PROTO_orset-internal-encapsulation) fixes #1 — theWarpStateLikeduck type goes away as part of retyping consumers toWarpState/ORSet. That's the only slice of this file touched by0024.
Items #2 and #3 require a domain model for "shard props" (or
"indexed property bag"). That is a design decision: what are the
real concepts inside the index builder, and how do they cross the
codec boundary? Punting that to its own cycle so 0024 stays narrow.
Proposed fix
IndexShardPropsorPropertyBag— and give it a runtime-backedclass with validated invariants.
dedicated adapter-side parser) so raw
Record<string, unknown>never enters the domain.
src/domain/services/index/for the samepattern — this file is unlikely to be the only offender.
Related
let this sludge accumulate.