Skip to content

refactor(NDNM): WarpRuntime decomposition + tech debt sweep#74

Merged
flyingrobots merged 73 commits intomainfrom
refactor/strand-service-decomposition
Apr 3, 2026
Merged

refactor(NDNM): WarpRuntime decomposition + tech debt sweep#74
flyingrobots merged 73 commits intomainfrom
refactor/strand-service-decomposition

Conversation

@flyingrobots
Copy link
Copy Markdown
Member

@flyingrobots flyingrobots commented Apr 2, 2026

Summary

Tech debt sweep + WarpRuntime decomposition + NDNM vassal liberation

Quick wins (6 items closed)

  • RECEIPT_OP_TYPE redundancy → OpStrategy.receiptName
  • SyncError for E_SYNC_DIVERGENCE (was raw Error)
  • AuditError class (16 raw Error throws replaced)
  • CLI import.meta.url (was __dirname polyfill)
  • ESLint dot-notation restored via @typescript-eslint
  • Broken test path fix (docs restructure)

WarpRuntime god class decomposition (phases 1-3)

Extracted 6 of 11 mixin method groups into independent service controllers:

  • StrandController (182 LOC) — strand lifecycle + conflict analysis
  • ComparisonController (1,155 LOC) — coordinate/strand comparison
  • SubscriptionController (244 LOC) — subscribe, watch, notifications
  • ProvenanceController (242 LOC) — patch lookups, causal cone, slicing
  • ForkController (274 LOC) — fork creation, wormhole, backfill rejection
  • QueryController (964 LOC) — all read queries, observer/worldline, content

3,061 LOC extracted. Remaining kernel (checkpoint, patch, materialize, materializeAdvanced — 2,115 LOC) deferred.

NDNM typedef-to-class liberation (11 promoted)

AuditReceipt, WarpStateV5, Dot, EventId, EffectEmission, EffectCoordinate, DeliveryObservation, TickReceipt, PatchDiff, LWWRegister, BTR, TrustState — all promoted from phantom @typedef to real JavaScript classes with constructors, validation, and instanceof support.

CBOR codec canonical key sorting

Both CborCodec and defaultCodec now sort keys for class instances (not just plain objects). Uses instanceof checks to skip built-in CBOR types. Decouples class field declaration order from wire format.

Also includes

  • NO_DOGS_NO_MASTERS legend (NDNM_)
  • AuditError domain error class
  • WarpStateV5 extracted to own module
  • Deno JSR panic fix (stale import paths + @import consolidation)
  • 4 broken link repairs from backlog migration
  • METHOD v2 review — 4 inbox items logged
  • Prior branch work: TSC zero campaign, OpStrategy, cycles 0001-0003

Zero public API surface changes — all 100+ methods remain on WarpRuntime.prototype.

Test plan

  • npm run lint — 0 errors
  • npm run typecheck — 0 errors
  • npm run test:local — 314 files, 5,157 tests pass
  • API surface snapshot test passes
  • node scripts/check-dts-surface.js — 248 exports, 0 errors
  • CI: all 7 checks green (lint, typecheck, test-node, test-bun, test-deno, links, preflight)

- Retrospective: TSC zero + JoinReducer OpStrategy
  (docs/archive/retrospectives/2026-04-01-*.md)
- CHANGELOG: TSC campaign, OpStrategy registry, dot-notation disable,
  EffectSinkPort widening
- Design alignment audit: all points aligned or accepted drift
- Playback: both hills achieved
- Lessons: agent over-refactoring, worktree leakage, test-per-merge
ROADMAP: added P1b tier with 4 high-priority items from TSC campaign drift:
- B171: audit 27 agent-authored files merged without review
- B172: restore dot-notation via @typescript-eslint/dot-notation
- B173: EffectSinkPort breaking change hygiene
- B174: @git-stunts/trailer-codec type declarations

Retro updated with 3 additional drift items that were initially glossed:
- No design doc for TSC campaign (process skip)
- dot-notation disabled globally (implementation shortcut)
- 27 files merged via checkout --theirs (not aligned)
Process restructuring:
- BACKLOG/ is now a flat directory of markdown files (one per B-item)
- Cycles replace milestones: pull item → docs/design/cycles/<cycle>/
- The backlog file becomes the design doc for the cycle
- No more ROADMAP as planning registry (kept for reference only)

Migration:
- 38 incomplete B-items extracted from ROADMAP into individual files
- 13 completed OG-items moved to BACKLOG/done/
- 5 queued OG-items left in place
- CONTRIBUTING.md rewritten for cycle-based process
- CLAUDE.md updated (Task Tracking section)
- docs/ROADMAP.md marked as migrated
B176: WarpRuntime + warp/ god class decomposition (XL, HIGH)
B177: Cohesive WarpKernelPort — persistence union type cleanup (L, HIGH)
B178: CLI __dirname path traversal fragility (S, HIGH)

Origin: code quality audit findings (AUDIT_CODE_QUALITY.md,
AUDIT_THE_JANK.md). Note: 161 any casts and 172 TODO(ts-cleanup)
markers cited in the audit are already at zero — TSC campaign fixed
those. The structural issues (god class, fragmented ports, path
traversal) remain.
Replace B-number backlog system with The Method: lane-based backlog
directories, legend-prefixed filenames, sequential cycle numbering,
and dual-audience design docs.

- METHOD.md signpost at root
- docs/method/backlog/ with inbox, asap, up-next, cool-ideas, bad-code lanes
- 49 B-number/OG items migrated to named files in appropriate lanes
- 10 tech debt entries split from .claude/bad_code.md to bad-code/
- 13 cool ideas split from .claude/cool_ideas.md to cool-ideas/
- docs/method/process.md, release.md (moved from docs/)
- docs/method/retro/, graveyard/, legends/ directories
- BACKLOG/ directory removed
- CLAUDE.md, CHANGELOG.md, docs/ROADMAP.md updated
Covers god object decomposition, raw error purge, type boundary
cleanup, constructor hygiene, file size policy, and lint ratchets.
Legend code: CC. All bad-code/ items and several asap/ items fall
under this legend.
Design doc for @git-stunts/code-nav — a tree-sitter-powered tool
that lets LLM agents extract named symbols, view file outlines,
and find definitions without reading entire files. JS/TS + Rust.
CLI + MCP server. Phased: core extraction → MCP → Rust → polish.
Five real scenarios from git-warp sessions showing 53-96% context
reduction. Key insight: the compounding effect over a full session
saves 20K-90K tokens — the difference between hitting compression
mid-task and finishing cleanly.
Editor's Edition reframe: the product is not code-nav (a search
tool). It is safe-context (a context governor). AST-aware extraction
is one tooth of a policy-enforcing read layer grounded in empirical
data from 1,091 sessions showing Read at 96.2 GB of context burden.

Rewritten hill, 4-layer architecture (policy → structural extraction
→ transport → session hygiene), 7-command surface, phased delivery
(governor first, precision tools second, session intelligence third).
Design cycle that started as AST-aware symbol extraction and
pivoted to a full context governor after empirical data from
Blacklight (96.2 GB Read burden) reframed the problem. Remaining
work re-enters backlog as safe-context Phase 1.
Full design doc with command contracts, output shapes, test strategy,
project structure, and technology choices. Phase 1 scope: safe_read,
file_outline, read_range, run_capture, state_save/load. JS/TS only.
MCP + CLI. Tree-sitter for structural extraction.
Tree-sitter is the parser. WARP graphs are the memory of structural
truth over time — symbol lineage, structural deltas, observer-
relative views. Not for MVP, but the ramp from ephemeral extraction
to provenance-aware incremental context is clear.
Git has trees and branches. Grafting is attaching new growth onto
existing rootstock. CLI: git graft, MCP: graft-mcp, npm: @git-stunts/graft.
REJECT fixes:
- read_range bounded: max 250 lines, 20 KB, clipped with metadata
- state_save capped at 8 KB with recommended template
- safe_read uses lines + bytes (not lines alone), special-cases
  lockfiles and .min.js

MUST fixes:
- file_outline bounded: 60-char params, 200-entry cap
- Project root defined: .git detection, symlink resolution, path
  escaping refused, logs in .graft/logs/
- Machine-stable reason codes for all policy decisions
- intent documented as advisory only — never weakens policy
- Build path refusal: no source-path guessing

Repo: flyingrobots/graft (not git-stunts)
Two enforcement layers: MCP server (cross-LLM, voluntary) and
Claude Code hooks (enforced). PreToolUse hooks on Read and Bash
route through graft's policy gate — the agent never sees raw large
files or full test dumps.

New commands: graft doctor (diagnostic), graft stats (decision
metrics). NDJSON metrics log for Blacklight validation.

Agent ideas: parse cache, outline focus mode, smarter next-step
hints, estimated savings in every response.
User-defined patterns for paths that should always be refused.
Covers secrets (.env, credentials), large data files, project-
specific generated code. Optional — built-in bans still apply
without it. Reason code: graftignore.
REJECTs fixed:
- action: "error" distinct from "refused" (operational vs policy)
- Broken-file outline: best-effort with partial: true + parseErrors
- .graftignore uses picomatch (declared dep, not transitive)
- run_capture: cwd, env, timeout, max log size all specified

Promoted from COULD/SHOULD/COOL to MUST:
- Built-in secret file bans (.env, *.pem, *.key, id_rsa, etc.)
- Outline truncation metadata (entryCount, elidedCount)
- focus param on file_outline
- doctor --json, stats --json, stats --since-clear
- Log retention (metrics 1MB, logs 10MB, oldest pruned)
- Symlink escape test, broken-syntax test, secret-file tests
- Smart next-step hints with symbol names from outline
- Estimated savings in every response
- Parse cache (mtime-invalidated Map)
- Explicit CLI binary names (graft + git-graft)
- root param on safe_read, read_range, file_outline
- explain field (one-sentence human-readable reason)
graft pack, graft since, graft explain, graft init, focus auto,
capture handles, policy profiles (balanced/strict/feral), receipt
mode, symbol heatmap, and the line where graft becomes a WARP
substrate.
projection, focus, residual, receipt, witness. Not public CLI names
— internal architecture doctrine. Gives coherence: policy is not
arbitrary, projection is not truncation, focus is not slicing.

"Derive the smallest lawful view of the code that lets the agent
act without poisoning its own context."
Design cycle delivered a locked spec for Graft (context governor for
coding agents) through two APPROVE/REJECT/ENHANCE review rounds.
All escape hatches bounded, broken-file behavior specified, hooks
enforcement defined. Implementation begins as graft cycle 0001 at
flyingrobots/graft.
docs/release.md moved to docs/method/release.md during the Method
bootstrap (cycle 0001) but the test path was not updated.
Each OpStrategy object now carries its own TickReceipt-compatible
operation name (e.g. NodeRemove strategy has receiptName 'NodeTombstone').
This eliminates the redundant RECEIPT_OP_TYPE lookup tables that
duplicated knowledge already present in the strategy registry.

- Added `receiptName` property to all 8 strategy objects
- Added `receiptName` to OpStrategy typedef and load-time validation
- Deleted RECEIPT_OP_TYPE from JoinReducer.js
- Deleted duplicate RECEIPT_OP_TYPE from ConflictAnalyzerService.js
- ConflictAnalyzerService now imports OP_STRATEGIES (already imports
  from JoinReducer, so no new dependency direction)

Closes bad-code/PROTO_receipt-op-type-redundant
SyncProtocol.loadPatchRange() was constructing a plain Error and
manually attaching a code property. Now uses SyncError which provides
proper error typing, context serialization, and consistent error
hierarchy.

Also added E_SYNC_DIVERGENCE to the SyncError error code table.

Closes bad-code/PROTO_sync-protocol-raw-error
Introduced AuditError domain error class with four error codes:
- E_AUDIT_INVALID: receipt field validation failures
- E_AUDIT_CAS_FAILED: compare-and-swap ref update failures
- E_AUDIT_DEGRADED: service degraded after exhausting retries
- E_AUDIT_CHAIN_GAP: missing commit in audit chain ancestry

Replaced all 16 raw Error throws in AuditReceiptService with typed
AuditError instances carrying serializable context. Added AuditError
to package exports, index.d.ts, and type surface contract.

Closes bad-code/PROTO_audit-receipt-raw-error
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

- TrustState: frozen class constructed by buildState(). Holds Maps of
  active/revoked keys, writer bindings, errors, and record count.

- TrustRecord: remains a @typedef. It is Zod-parsed from external data
  and consumed as Record<string, unknown> throughout the trust chain —
  making it a class would break the index-signature compatibility that
  Zod parsing and signature verification depend on.

Closes bad-code/PROTO_typedef-truststate-to-class.
Not permanently blocked — Zod parse wrapping + consumer signature
widening is straightforward S-tier work, just more touch points
than the XS vassals.
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

…, unknown> pipeline

The typedef is the symptom. The disease is 20+ function signatures
across 5 trust files that accept Record<string, unknown> because
nobody introduced a concrete type at the CBOR decode boundary.
Effort upgraded from S to M.
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

1 similar comment
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

CHANGELOG updated with:
- 11 typedef-to-class promotions
- CBOR codec canonical key sorting fix
- WarpStateV5 class as new public export

Moved to ASAP for next cycle:
- PROTO_typedef-trustrecord-to-class (M — Record<string, unknown> pipeline cleanup)
- PROTO_typedef-orset-to-class (M — 10+ CRDT operations)
- PROTO_typedef-patchv2-to-class (M — core entity, deep integration)
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

Critical:
- CONTRIBUTING.md: fixed broken cycle path (docs/design/cycles/ →
  docs/design/<NNNN-slug>/), stale BACKLOG/ refs, and retro path
  mismatch (docs/archive/retrospectives/ → docs/method/retro/)

Major:
- ROADMAP.md: updated stale BACKLOG/ references to docs/method/backlog/
- AuditReceiptService: writer mismatch now throws with explicit
  E_AUDIT_WRITER_MISMATCH code instead of defaulting to E_AUDIT_INVALID

Minor:
- TickReceipt: added @throws annotation to constructor JSDoc
- METHOD.md: clarified structure diagram with <NNNN-slug> pattern
- DeliveryObservation: documented that reason field is omitted (not
  null) when absent

Nits acknowledged but deferred:
- WarpRuntime delegation boilerplate (DRY) — future cleanup
- WarpCore single-line JSDoc — cosmetic
- Em-dash inconsistency — cosmetic
- WarpStateV5 edgeBirthEvent default — intentional for old checkpoints
- BTR computeHmac guard — validated upstream
- DX_warpruntime-delegation-dry (XS): extract delegation boilerplate helper
- DX_warpcore-jsdoc-block-style (XS): expand single-line JSDoc to blocks
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

1 similar comment
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

Inline comments:
- ForkController: fork creation now rolls back ref on WarpRuntime.open
  failure (was non-atomic — dangling ref on error)
- ForkController._isAncestor: replaced MAX_WALK counter with visited
  Set for true cycle detection (was false-positive on deep histories)
- ForkController._validatePatchAgainstCheckpoint: backfill rejection
  and divergence now throw typed ForkError with E_FORK_BACKFILL_REJECTED
  and E_FORK_WRITER_DIVERGED codes (was raw Error)
- JoinReducer.cloneStateV5: restored structural fallback for plain
  objects from checkpoint deserialization (was strict instanceof-only)
- JoinReducer: receiptName load-time validation now checks against
  TickReceipt OP_TYPES allowlist (catches typos at module load)

Duplicate comments:
- ComparisonController: introduced ComparisonSideResolver class to
  hold graph + scope + liveFrontier as instance state, with role tag
  ('left'/'right'/'source'/'target') preventing side swaps.
  Live frontier captured once and shared across both sides.
- ComparisonController: added assertOptionsObject() validation for
  compareStrand() and planStrandTransfer() options params (was leaking
  raw TypeErrors on null/array/primitive input)
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

…mparisonSide class

ComparisonController:
- NormalizedSelector is now a base class with 4 subclasses:
  LiveSelector, CoordinateSelector, StrandSelector, StrandBaseSelector.
  Each implements resolve() directly — no dispatch switch, no resolver
  intermediary. The selector IS the resolver.
- ResolvedComparisonSide promoted from typedef to class.
- ComparisonSideResolver deleted (selectors resolve themselves).
- Live frontier captured once and shared via resolve() param.
- assertOptionsObject() guards on compareStrand/planStrandTransfer.

JoinReducer:
- OpOutcomeResult is now a base class with 3 subclasses:
  OpApplied, OpSuperseded, OpRedundant. OpSuperseded carries the
  winning EventId as a structured field instead of a formatted string.
- cloneStateV5 restored structural fallback for plain objects.
- receiptName load-time validation checks OP_TYPES allowlist.

BoundaryTransitionRecord:
- VerificationResult promoted from typedef to class.
- BTR.deserializeBTR returns class instance.

ForkController:
- _isAncestor uses visited Set for true cycle detection.
- Fork ref creation rolls back on WarpRuntime.open failure.
- Backfill rejection uses typed ForkError codes.

Logged asap/NDNM_comparison-pipeline-class-hierarchy for remaining
value object work (LamportCeiling, StrandId, WriterId, etc.).
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

Engineering standard for how JavaScript is written in git-warp.
Ten rules: classes not typedefs, validation in constructors,
subclasses not switches, instanceof for runtime checks, unknown
means the class hasn't been built yet, factory functions are shims,
serialization is the codec's problem, structured data not strings,
errors are domain classes, modules are the encapsulation boundary.

This is infrastructure. The code must be honest at runtime.
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

1 similar comment
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

Complete rewrite of the engineering standard. Not a style guide — a
doctrine for writing JavaScript infrastructure that remains honest
under execution, replay, migration, debugging, replication, failure,
and time.

Rule 0: Runtime Truth Wins. The Hierarchy of Truth. The Object Model.
Seven Principles. The Anti-Shape-Soup Doctrine. The Review Checklist.

Co-authored-by: James Ross <james@flyingrobots.dev>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

Refined structure, tightened language, added Hierarchy of Truth,
Language Policy (JS default, TS allowed not authoritative, Rust
escape hatch), Architecture section (browser-first, hexagonal
mandatory), four-category Object Model, cross-realm branding note,
Anti-Shape-Soup Doctrine, Review Checklist.

Co-authored-by: James Ross <james@flyingrobots.dev>
@flyingrobots
Copy link
Copy Markdown
Member Author

All three findings from this review round were already addressed in commit 23fbacb (pushed before this review completed):

  1. Fork atomicityWarpRuntime.open failure now triggers deleteRef rollback of the fork writer ref.
  2. _isAncestor MAX_WALK — Replaced with visited-Set cycle detection. No hard counter.
  3. cloneStateV5 structural fallback — restored for plain/deserialized objects. instanceof fast path for class instances, structural normalization for everything else.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

- CONTRIBUTING.md: ../../METHOD.md → ../METHOD.md (one level up from
  .github/, not two)
- SYSTEMS_STYLE_JAVASCRIPT.md: wrapped cross-realm branding snippet
  in a class body so the markdown code-sample linter can parse it
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 3, 2026

Release Preflight

  • package version: 16.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v16.0.0, release workflow will publish.

@flyingrobots flyingrobots merged commit 8c2de90 into main Apr 3, 2026
7 checks passed
@flyingrobots flyingrobots deleted the refactor/strand-service-decomposition branch April 3, 2026 03:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant