Skip to content

Eliminate remaining runtime and maintenance debt - #108

Merged
AustinKelsay merged 27 commits into
stagingfrom
feature/cleanup-runtime-debt
Jul 18, 2026
Merged

Eliminate remaining runtime and maintenance debt#108
AustinKelsay merged 27 commits into
stagingfrom
feature/cleanup-runtime-debt

Conversation

@AustinKelsay

@AustinKelsay AustinKelsay commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary

Completes cleanup items 1–7 from #100:

  • unifies the public diagnostic logger contract without breaking NIP-specific aliases
  • makes the ephemeral Relay lifecycle quiet, deterministic, retryable, and cross-runtime
  • stabilizes NIP-57 receipt collection across timeout, EOSE, malformed-ID, and cleanup races
  • clears NIP-86 request timers on every terminal path
  • exercises public security limits at their exact inclusive boundaries
  • collapses command/README inventory duplication and verifies the command graph
  • removes stale NIP-04/NIP-44 surfaces and repairs maintained example references

Implementation tickets: #101, #102, #103, #104, #105, #106, #107.

Design and run artifacts

  • ADR: docs/adr/0002-unify-diagnostics-compatibly.md
  • Run ledger: docs/agents/runs/feature-cleanup-runtime-debt-ledger.md
  • Cross-runtime follow-up: docs/agents/runs/integrated-bun-compat-session.md
  • Final review: docs/agents/runs/final-cleanup-review-session.md

Verification

  • npm ci
  • command inventory verifier
  • ESLint
  • root and examples TypeScript checks
  • CJS/ESM build and examples build
  • package verification: 16 referenced targets, 304 packed files, 49 web modules, 3 guarded Node fallbacks
  • live example:basic and example:messaging groups
  • focused final matrix: Jest 103/103 and Bun 103/103
  • full Jest with open-handle detection: 72/72 suites, 991/991 tests
  • full Bun: 72/72 files, 991/991 tests
  • coverage: 72/72 suites, 991/991 tests
    • overall: 76.08% statements, 63.30% branches, 79.50% functions, 76.40% lines
    • security-validator.ts: 86.12% statements, 80.00% branches, 84.37% functions, 85.99% lines
  • branch diff secret scan and git diff --check

Review

  • independent Codex spec/behavior/security review: PASS, zero actionable findings
  • independent Codex standards/Fowler review: PASS, zero actionable findings
  • OpenCode GLM-5.2 max branch review: PASS, zero actionable findings
  • local CodeRabbit: two completed rounds; all nine findings fixed or evidence-rejected
  • a third local CodeRabbit confirmation was service-rate-limited, so this PR requests the required hosted full review
  • Grok was not substituted because the required Grok 4.5 xhigh routes were absent from the live catalog

Risks

  • npm ci retains the existing audit baseline of 13 dependency vulnerabilities (2 low, 3 moderate, 8 high). Dependency locks were intentionally not changed and no potentially breaking audit fix was applied.
  • This is a large cleanup diff, so hosted CI and CodeRabbit are required before merge.
  • No deployment is part of this PR.

Closes #100

Summary by CodeRabbit

  • New Features

    • Added shared diagnostic logger support with ConsoleLogger/DiagnosticLogger exports across platforms.
    • Introduced warn-only WarningLogger (kept as a deprecated alias for compatibility).
    • Enhanced NIP-57 clients with optional diagnostics while staying quiet by default.
    • Improved relay lifecycle shutdown/disconnect coordination and command-reference verification.
  • Bug Fixes

    • Hardened relay-management request timeout cleanup and zap-receipt collection edge cases.
  • Documentation

    • Consolidated README command documentation into a single command reference; removed outdated demos and examples.
  • Tests

    • Expanded multi-runtime (Jest/Bun) and type-compatibility coverage.

Server-side session shutdown did not prove that a same-process public Relay had observed its disconnect. Coordinate exact-URL observers at the WebSocket boundary, gate notification on owned transport shutdown, and make close finalization idempotent across natural, coordinated, manual, and late callback paths.
@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 60a1a554-5206-4928-aad2-f28eece8ad26

📥 Commits

Reviewing files that changed from the base of the PR and between 1dd8428 and 4c38d62.

📒 Files selected for processing (1)
  • tests/nip57/client.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/nip57/client.test.ts

📝 Walkthrough

Walkthrough

The PR consolidates command references, unifies diagnostic logger contracts, hardens relay and NIP client lifecycle cleanup, removes stale example surfaces, and adds public-behavior and compatibility tests across Node, Jest, and Bun.

Changes

Runtime debt cleanup

Layer / File(s) Summary
Command inventory and example cleanup
package.json, scripts/verify-commands.js, README.md, examples/*, tests/scripts/*
Removes redundant commands and stale examples, adds repository command verification, and centralizes the README command reference.
Shared diagnostic contracts
src/utils/logger.ts, src/index.ts, src/entries/index.web.ts, src/nip02/*, src/nip47/*
Adds the shared DiagnosticLogger contract, preserves deprecated NIP-specific aliases, and aligns root/web exports.
Relay lifecycle and disconnect coordination
src/utils/ephemeral-relay.ts, src/utils/websocket.ts, src/nip01/relay.ts, tests/utils/*, tests/nip01/*
Adds injected diagnostics, idempotent shutdown, session cleanup, URL-scoped disconnect observers, and connection-settlement coverage.
NIP client cleanup
src/nip57/*, src/nip86/index.ts, tests/nip57/*, tests/nip86/*
Centralizes NIP-57 subscription settlement and diagnostics, and clears NIP-86 request timers across all outcomes.
Public validation and run records
tests/security/*, tests/types/*, docs/adr/*, docs/agents/runs/*
Adds public security-boundary and logger-compatibility tests and records implementation, review, and verification sessions.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

Suggested labels: codex

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.58% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title broadly matches the cleanup-focused changes and is not misleading.
Linked Issues check ✅ Passed The changes cover all seven cleanup areas: diagnostics, Relay lifecycle, NIP-57, NIP-86, security limits, command inventory, and stale surface removal.
Out of Scope Changes check ✅ Passed I don't see material changes outside the linked cleanup scope; the docs, scripts, tests, and removals all support the stated objectives.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/cleanup-runtime-debt

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


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

@AustinKelsay

Copy link
Copy Markdown
Owner Author

@CodeRabbit full review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@AustinKelsay

Copy link
Copy Markdown
Owner Author

CI follow-up: the first hosted matrix exposed a Node 16-only test portability gap. Node 16 has no built-in globalThis.fetch, so three new NIP-57 tests could not spy on it. Commit 039ae8e installs a scoped mock property only when absent and removes it in teardown; production code is unchanged.

Fresh verification:

  • actual Node 16 Jest: NIP-57 client 14/14
  • current Node Jest: 14/14 with open-handle detection
  • Bun: 14/14
  • lint, TypeScript, and git diff --check: passed

The previous Node 20 job had already passed all 72 suites / 991 tests before the matrix was canceled by fail-fast from Node 16. The pushed fix has started a fresh hosted matrix.

@AustinKelsay

Copy link
Copy Markdown
Owner Author

Second CI portability follow-up: Node 16 lacks http.Server.closeAllConnections(), which the new native Relay test helper used as an extra sweep after it had already tracked, destroyed, and awaited every socket. Commit 1dd8428 makes that redundant modern-runtime call conditional.

Fresh verification:

  • actual Node 16 Jest with open-handle detection: 6/6
  • current Node Jest with open-handle detection: 6/6
  • Bun: 6/6
  • lint, TypeScript, and git diff --check: passed

Node 18's prior rerun completed all 72 suites / 991 tests before matrix fail-fast canceled the job. A fresh hosted matrix is starting from 1dd8428.

@AustinKelsay

Copy link
Copy Markdown
Owner Author

Final gate status:

  • Node 16: success
  • Node 18: success
  • Node 20: success, including coverage, library build, package verification, and examples build
  • Bun: success, including library build and package verification
  • hosted CodeRabbit full review: finished successfully with zero inline findings
  • independent final spec and standards re-reviews of both CI portability fixes: PASS

PR head 1dd8428 is clean and ready for maintainer review into staging.

@AustinKelsay

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/nip01/relay.ts (1)

243-264: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Invalidate the old attempt before emitting Disconnect.

triggerEvent() is synchronous. If a pre-connect disconnect handler calls connect(), Lines 259-262 subsequently clear and invalidate that new attempt. Complete the old attempt’s cleanup before invoking user callbacks.

Proposed ordering fix
           const wasConnected = this.connected;
           this.connected = false;
           this.clearBufferFlush();
-          this.triggerEvent(RelayEvent.Disconnect, this.url);
           this.clearRelayDisconnectObserver(attemptId);
           this.clearRelayDisconnectFinalizer(attemptId);

           if (!wasConnected) {
             this.detachSocketHandlers(socket);
             this.connectionPromise = null;
             this.connectionAttempt++;
             reject(new Error("connection closed"));
           }
+
+          this.triggerEvent(RelayEvent.Disconnect, this.url);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/nip01/relay.ts` around lines 243 - 264, In finalizeClose, complete all
old-attempt cleanup—including clearing connection state, detaching handlers,
nulling connectionPromise, and incrementing connectionAttempt—before calling
triggerEvent(RelayEvent.Disconnect, this.url). Preserve the existing guards and
rejection behavior, while ensuring a synchronous handler that calls connect() is
not affected by subsequent cleanup from the closed attempt.
🧹 Nitpick comments (1)
src/utils/websocket.ts (1)

14-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the shared relay URL normalizer for observer keys.

This local implementation creates a second relay canonicalization contract. Reuse the existing relay URL normalization utility so observer registration and notification remain consistent with the rest of the library.

As per coding guidelines, “Use the existing relay URL normalization utilities when working with relay URLs.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/websocket.ts` around lines 14 - 20, Replace the local
normalizeWebSocketUrl implementation with the existing shared relay URL
normalization utility, and update its callers to use that shared symbol for
observer keys. Remove the duplicate try/catch canonicalization logic while
preserving consistent normalization for registration and notification.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/nip02/nip02.test.ts`:
- Line 367: Remove the duplicate warnings constant near the nip02 test setup,
retaining only one declaration of the Array<{ message: string; value?: string }>
variable so the test compiles without changing its usage.

In `@tests/nip57/client.test.ts`:
- Around line 141-237: The setup in both tests should occur inside the
try/finally cleanup scope, before mutating globalThis.Bun or starting the relay,
so failures during setup are covered. Update the cleanup to conditionally
restore Bun and close/disconnect only initialized resources, including relay and
nostr; apply this to the empty-receipts test and “collects stored receipts
through every public receipt query.”

---

Outside diff comments:
In `@src/nip01/relay.ts`:
- Around line 243-264: In finalizeClose, complete all old-attempt
cleanup—including clearing connection state, detaching handlers, nulling
connectionPromise, and incrementing connectionAttempt—before calling
triggerEvent(RelayEvent.Disconnect, this.url). Preserve the existing guards and
rejection behavior, while ensuring a synchronous handler that calls connect() is
not affected by subsequent cleanup from the closed attempt.

---

Nitpick comments:
In `@src/utils/websocket.ts`:
- Around line 14-20: Replace the local normalizeWebSocketUrl implementation with
the existing shared relay URL normalization utility, and update its callers to
use that shared symbol for observer keys. Remove the duplicate try/catch
canonicalization logic while preserving consistent normalization for
registration and notification.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6b27be20-d36d-4805-a844-f95c04ff6fe1

📥 Commits

Reviewing files that changed from the base of the PR and between 697689d and 1dd8428.

📒 Files selected for processing (54)
  • CLAUDE.md
  • README.md
  • docs/adr/0002-unify-diagnostics-compatibly.md
  • docs/agents/runs/feature-cleanup-runtime-debt-ledger.md
  • docs/agents/runs/final-cleanup-review-session.md
  • docs/agents/runs/integrated-bun-compat-session.md
  • docs/agents/runs/issue-101-session.md
  • docs/agents/runs/issue-102-loaded-suite-followup-session.md
  • docs/agents/runs/issue-102-session.md
  • docs/agents/runs/issue-103-session.md
  • docs/agents/runs/issue-104-session.md
  • docs/agents/runs/issue-105-session.md
  • docs/agents/runs/issue-106-review-packet.md
  • docs/agents/runs/issue-106-session.md
  • docs/agents/runs/issue-107-session.md
  • examples/EXAMPLE_STANDARDIZATION.md
  • examples/README.md
  • examples/nip19/README.md
  • examples/nip44/nip44-demo.js
  • package.json
  • scripts/verify-commands.js
  • src/entries/index.web.ts
  • src/index.ts
  • src/nip01/relay.ts
  • src/nip02/README.md
  • src/nip02/index.ts
  • src/nip47/README.md
  • src/nip47/client.ts
  • src/nip47/service.ts
  • src/nip47/types.ts
  • src/nip57/README.md
  • src/nip57/client.ts
  • src/nip57/diagnostics.ts
  • src/nip57/index.ts
  • src/nip57/utils.ts
  • src/nip86/index.ts
  • src/shims/nip04-stub.ts
  • src/utils/ephemeral-relay.ts
  • src/utils/logger.ts
  • src/utils/websocket.ts
  • tests/README.md
  • tests/TEST_STANDARDIZATION.md
  • tests/entries/web-exports.test.ts
  • tests/nip01/relay/websocket-implementation.test.ts
  • tests/nip02/nip02.test.ts
  • tests/nip57/client.test.ts
  • tests/nip86/nip86.test.ts
  • tests/scripts/verify-commands.test.ts
  • tests/security/security-limits-public.test.ts
  • tests/types/logger-compatibility.ts
  • tests/utils/ephemeral-relay-close-ordering.test.ts
  • tests/utils/ephemeral-relay-lifecycle.test.ts
  • tests/utils/security-validator.test.ts
  • tests/utils/websocket.test.ts
💤 Files with no reviewable changes (2)
  • src/shims/nip04-stub.ts
  • examples/nip44/nip44-demo.js

Comment thread tests/nip02/nip02.test.ts
Comment thread tests/nip57/client.test.ts
@AustinKelsay

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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.

@AustinKelsay

Copy link
Copy Markdown
Owner Author

Three-pass CodeRabbit review complete:

  1. 6b27be20-d36d-4805-a844-f95c04ff6fe1 — full 54-file pass; two findings.
    • Valid cleanup-scope finding fixed in 4c38d62.
    • Duplicate-declaration finding verified false and withdrawn by CodeRabbit.
  2. 184fb58c-2c8e-4559-b630-b035b65e458d — incremental fix review; no new actionable finding, and CodeRabbit accepted both resolutions.
  3. 60a1a554-5206-4928-aad2-f28eece8ad26 — final confirmation; “No actionable comments were generated.”

Final CI is green on Node 16, Node 18, Node 20, and Bun. Focused Jest/Bun NIP-57 tests, lint, TypeScript, and diff checks also passed locally.

Grok orchestration was preflighted as requested, but the required grok-4.5-xhigh and grok-4.5-fast-xhigh routes were absent from the live CLI catalog, so no weaker model was substituted.

@AustinKelsay
AustinKelsay merged commit 1d07a4b into staging Jul 18, 2026
5 checks passed
@AustinKelsay
AustinKelsay deleted the feature/cleanup-runtime-debt branch July 18, 2026 16:05
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