Skip to content

fix: immediate standalone items + backlog reconciliation#56

Merged
flyingrobots merged 5 commits intomainfrom
chore/standalone-immediate
Feb 28, 2026
Merged

fix: immediate standalone items + backlog reconciliation#56
flyingrobots merged 5 commits intomainfrom
chore/standalone-immediate

Conversation

@flyingrobots
Copy link
Member

@flyingrobots flyingrobots commented Feb 28, 2026

Summary

  • B26: ED25519_SPKI_PREFIX constant with RFC 8410 reference in TrustCrypto.js
  • B46: ESLint no-restricted-syntax bans Date.now() in src/domain/**/*.js. Legitimate wall-clock uses annotated with eslint-disable. Fork name and verify seed switched to Math.random().
  • B47: orsetAdd() validates dot shape {writerId: string, counter: integer} before encodeDot().
  • B71: PatchBuilderV2.removeNode() warn mode routes through this._logger.warn() instead of console.warn. Writer now accepts and forwards logger to PatchBuilderV2.
  • B126: ESLint no-empty with allowEmptyCatch: false.
  • Backlog reconciliation: Promoted 11 items (B119–B129) from BACKLOG.md into ROADMAP.md standalone lane. BACKLOG.md cleared to skeleton.
  • M13 design: Added MIGRATION_PROBLEM.md documenting the edge property schema migration problem in detail.

Test plan

  • All 4,430 unit tests pass
  • ESLint clean
  • TypeScript strict mode clean (IRONCLAD gate)
  • noCoordination.test.js passes
  • Delete guard warn tests updated to inject mock logger instead of spying on console.warn
  • Fork name test regex updated for new random-only pattern

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced runtime validation for CRDT operations.
    • Improved logger fallback handling to prevent null pointer errors.
    • Strengthened error handling in domain code.
  • Documentation

    • Added comprehensive design document for edge property schema migration strategy.
    • Updated project roadmap with resolved backlog items.
  • Tests

    • Improved test verification mechanisms for logging behavior.
    • Updated fork naming test expectations.

- B46: ESLint `no-restricted-syntax` bans Date.now() in src/domain/.
  Legitimate wall-clock uses annotated with eslint-disable.
  fork.methods.js and MaterializedViewService.js switched to Math.random().
- B47: orsetAdd() validates dot shape before encodeDot().
- B26: ED25519_SPKI_PREFIX constant with RFC 8410 reference in TrustCrypto.
- B71: PatchBuilderV2.removeNode() warn mode routes through this._logger
  instead of console.warn. Writer now forwards logger to PatchBuilderV2.
- B126: ESLint no-empty rule with allowEmptyCatch: false.

Also includes BACKLOG→ROADMAP reconciliation (B119–B129 promoted)
and M13 design problem statement (MIGRATION_PROBLEM.md).
- patch.methods.js: coerce null logger to undefined for Writer constructor
- deleteGuardEnforce tests: add missing `child` method to mock loggers
@coderabbitai
Copy link

coderabbitai bot commented Feb 28, 2026

Warning

Rate limit exceeded

@flyingrobots has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 21 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 26a1bf7 and 7118b71.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • ROADMAP.md
  • docs/design/MIGRATION_PROBLEM.md
  • eslint.config.js
  • test/unit/domain/WarpGraph.deleteGuardEnforce.test.js
📝 Walkthrough

Walkthrough

The PR consolidates backlog items into ROADMAP, introduces ESLint rules enforcing domain purity (banning Date usage), refactors logging to use LoggerPort throughout the Writer/PatchBuilder flow, updates fork name generation from timestamp-based to random-based, adds a comprehensive design document for edge property schema migration, and includes validation enhancements and boundary safeguards.

Changes

Cohort / File(s) Summary
Backlog & Documentation Consolidation
BACKLOG.md, CHANGELOG.md, ROADMAP.md, docs/design/MIGRATION_PROBLEM.md
Moves backlog items B119–B129 into ROADMAP, updates reconciliation notes, and adds comprehensive design document on EdgePropSet migration strategy with schema versioning, compatibility concerns, and cross-module impact analysis.
Domain Purity ESLint Rules
eslint.config.js
Adds rules banning new Date() and Date.now() in domain code (directing to ClockPort), and enforces non-empty catch blocks via no-empty rule.
Logger Port Refactoring
src/domain/warp/Writer.js, src/domain/services/PatchBuilderV2.js, src/domain/warp/patch.methods.js
Introduces optional logger parameter to Writer constructor (defaults to nullLogger), narrows PatchBuilderV2 logger type from { warn: Function } to LoggerPort, and propagates logger through patch creation flows; replaces console.warn with logger.warn in patch-building warnings.
Wall-Clock Timestamp Annotations
src/domain/services/AuditReceiptService.js, src/domain/services/AuditVerifierService.js, src/domain/services/BoundaryTransitionRecord.js, src/domain/services/SyncAuthService.js, src/domain/utils/defaultClock.js
Adds ESLint disable comments and documentation notes around timestamp assignments; no functional logic changes, only commentary and linter suppression for wall-clock defaults.
Validation & Constants
src/domain/crdt/ORSet.js, src/domain/trust/TrustCrypto.js
Adds runtime validation in orsetAdd requiring dot parameter to be object with string writerId and integer counter; extracts ED25519_SPKI_PREFIX as a documented constant in TrustCrypto verification.
Fork Name & Seed Generation
src/domain/warp/fork.methods.js, src/domain/services/MaterializedViewService.js
Changes default fork name from timestamp + 4-char suffix to purely random 8-char suffix; replaces time-based sampling seed (Date.now()) with random-based seed (Math.random()).
Test Updates
test/unit/domain/WarpGraph.deleteGuardEnforce.test.js, test/unit/domain/WarpGraph.fork.test.js
Refactors delete-guard tests to use injected mockLogger instead of console.warn spy; updates fork name test pattern from timestamp-based to random 8-char format; preserves functional expectations with new verification mechanisms.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • PR #30 — Modifies Writer.js constructor and internal logger wiring; overlaps with this PR's logger parameter addition and propagation.
  • PR #36 — Updates TrustCrypto.js verification logic; directly related to the ED25519_SPKI_PREFIX constant refactoring in this PR.
  • PR #51 — Refactors PatchBuilderV2.js logging and type handling; shares code-level changes in the same patch-building instrumentation flow.

Poem

🐰 Loggers hop through the domain now,
Dates must bow—no new Date, no how!
Backlog's packed into ROADMAP's delight,
Forks dance random through the warp tonight!
Eight-char suffixes, migrations designed,
A cleaner warren, left chaos behind!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: immediate standalone items + backlog reconciliation' accurately describes the main changes: implementing immediate fixes (B26, B46, B47, B71, B126) and promoting backlog items into ROADMAP.md.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/standalone-immediate

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

Release Preflight

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

If you tag this commit as v12.2.1, release workflow will publish.

Ban new Date() in domain code, fix Writer logger fallback, fix
delete-guard test console.warn spy, pad fork name suffix, and
relocate MIGRATION_PROBLEM.md to docs/design/.
@github-actions
Copy link

Release Preflight

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

If you tag this commit as v12.2.1, release workflow will publish.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
eslint.config.js (1)

273-289: Close the Date() loophole in domain-purity rules.

Date.now() and new Date() are blocked, but Date() (function-call form) still allows wall-clock access in domain code.

🔧 Suggested rule addition
   "no-restricted-syntax": ["error",
     {
       "selector": "CallExpression[callee.object.name='Date'][callee.property.name='now']",
       "message": "Date.now() is banned in domain code. Use ClockPort / ClockAdapter instead.",
     },
+    {
+      "selector": "CallExpression[callee.name='Date']",
+      "message": "Date() is banned in domain code. Use ClockPort / ClockAdapter instead.",
+    },
     {
       "selector": "NewExpression[callee.name='Date']",
       "message": "new Date() is banned in domain code. Use ClockPort / ClockAdapter instead.",
     },
   ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eslint.config.js` around lines 273 - 289, Add a third restriction to the
existing "no-restricted-syntax" array to ban the function-call form Date() in
domain code: add an object with selector "CallExpression[callee.name='Date']"
and the same message "Date() is banned in domain code. Use ClockPort /
ClockAdapter instead." so the rule block that defines "no-restricted-syntax"
(around the files: ["src/domain/**/*.js"] entry) covers Date.now(), new Date(),
and Date().
test/unit/domain/WarpGraph.deleteGuardEnforce.test.js (1)

298-299: Consider using the mockLogger helper for consistency.

These inline logger objects duplicate the same structure as mockLogger. Using the helper would reduce duplication and ensure consistent mock structure across all tests.

♻️ Suggested refactor
 it('warn mode works through writer().commitPatch()', async () => {
   repo = await createGitRepo('delguard');
   const warnSpy = vi.fn();
-  const logger = { info: vi.fn(), warn: warnSpy, error: vi.fn(), debug: vi.fn(), child: () => logger };
+  const logger = mockLogger(warnSpy);
   const graph = await WarpGraph.open({

Note: You'd need to either move mockLogger to a shared scope or extract it to a test utility.

Also applies to: 333-334

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/domain/WarpGraph.deleteGuardEnforce.test.js` around lines 298 -
299, The test creates an inline logger (warnSpy and logger) duplicating the
existing mockLogger helper; replace the inline logger instances with the shared
mockLogger to reduce duplication and keep mocks consistent—locate uses of
warnSpy and logger in WarpGraph.deleteGuardEnforce.test.js (and the similar
occurrences around the other lines mentioned) and swap them to use the
mockLogger helper (or import/extract mockLogger into a shared test-utility if
not in scope), adjusting any expectations to reference mockLogger.warn or
mockLogger.child as needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/design/MIGRATION_PROBLEM.md`:
- Around line 197-205: The fenced code block in the MIGRATION_PROBLEM.md snippet
lacks a language tag (MD040); update the opening fence for that block to include
a language identifier (for example "text") so the block begins with ```text and
keep the closing fence unchanged, ensuring the fence uses three backticks and no
extra indentation; this will satisfy the linter and preserve the exact code
block contents in the Op normalization layer section.

In `@ROADMAP.md`:
- Around line 516-520: The inventory table in ROADMAP.md is inconsistent: the
"Standalone" row lists items including B26, B46, B47, B71, and B126 while the
"Standalone (done)" row still shows only three done items; update the table so
counts and ID lists match the DONE markers — increment the "Standalone (done)"
count and move the appropriate IDs (B26, B46, B47, B71, B126 as applicable) from
the "Standalone" list into the "Standalone (done)" list (or remove them if
already listed elsewhere), and then adjust the "Standalone" and "Total tracked"
counts to remain internally consistent with those ID lists.

---

Nitpick comments:
In `@eslint.config.js`:
- Around line 273-289: Add a third restriction to the existing
"no-restricted-syntax" array to ban the function-call form Date() in domain
code: add an object with selector "CallExpression[callee.name='Date']" and the
same message "Date() is banned in domain code. Use ClockPort / ClockAdapter
instead." so the rule block that defines "no-restricted-syntax" (around the
files: ["src/domain/**/*.js"] entry) covers Date.now(), new Date(), and Date().

In `@test/unit/domain/WarpGraph.deleteGuardEnforce.test.js`:
- Around line 298-299: The test creates an inline logger (warnSpy and logger)
duplicating the existing mockLogger helper; replace the inline logger instances
with the shared mockLogger to reduce duplication and keep mocks
consistent—locate uses of warnSpy and logger in
WarpGraph.deleteGuardEnforce.test.js (and the similar occurrences around the
other lines mentioned) and swap them to use the mockLogger helper (or
import/extract mockLogger into a shared test-utility if not in scope), adjusting
any expectations to reference mockLogger.warn or mockLogger.child as needed.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e319822 and 26a1bf7.

📒 Files selected for processing (19)
  • BACKLOG.md
  • CHANGELOG.md
  • ROADMAP.md
  • docs/design/MIGRATION_PROBLEM.md
  • eslint.config.js
  • src/domain/crdt/ORSet.js
  • src/domain/services/AuditReceiptService.js
  • src/domain/services/AuditVerifierService.js
  • src/domain/services/BoundaryTransitionRecord.js
  • src/domain/services/MaterializedViewService.js
  • src/domain/services/PatchBuilderV2.js
  • src/domain/services/SyncAuthService.js
  • src/domain/trust/TrustCrypto.js
  • src/domain/utils/defaultClock.js
  • src/domain/warp/Writer.js
  • src/domain/warp/fork.methods.js
  • src/domain/warp/patch.methods.js
  • test/unit/domain/WarpGraph.deleteGuardEnforce.test.js
  • test/unit/domain/WarpGraph.fork.test.js

- Ban Date() function-call form in domain ESLint rule
- Add text language tag to MIGRATION_PROBLEM.md fenced block
- Hoist mockLogger helper to outer describe scope
- Reconcile ROADMAP inventory table with DONE markers
@flyingrobots
Copy link
Member Author

All 4 review findings addressed in 7118b71:

  1. eslint.config.js (nit) — Added CallExpression[callee.name='Date'] selector to close the Date() function-call loophole.
  2. deleteGuardEnforce.test.js (nit) — Hoisted mockLogger to outer describe scope; replaced all inline logger objects in Writer API and cascade blocks.
  3. MIGRATION_PROBLEM.md (minor) — Added text language tag to fenced code block (MD040).
  4. ROADMAP.md (minor) — Reconciled inventory table: B26/B46/B47/B71/B126 moved to Standalone (done), counts updated.

All 4430 tests pass, lint clean, IRONCLAD gates green.

@coderabbitai review please 🥕

@coderabbitai
Copy link

coderabbitai bot commented Feb 28, 2026

@flyingrobots Thank you for addressing all 4 findings so thoroughly! 🎉

The commit 7118b71 looks comprehensive:

  • ✅ ESLint now catches both new Date() and Date() function calls
  • mockLogger properly scoped and reused across test blocks
  • ✅ Markdown linting resolved with language tag
  • ✅ ROADMAP inventory reconciled with completed items

With all tests passing and gates green, I'll review the changes now.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
Copy link

Release Preflight

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

If you tag this commit as v12.2.1, release workflow will publish.

@flyingrobots flyingrobots merged commit 2774dcf into main Feb 28, 2026
8 checks passed
@flyingrobots flyingrobots deleted the chore/standalone-immediate branch February 28, 2026 12:30
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