chore: remove dead artifacts — send-notification queue (#170), dead metrics class + trace source (#171)#174
Conversation
…ned-counter + emitter-less trace source (#171) Closes #170. Closes #171. Both were found by the ultracode review of #159: things the docs presented as live that nothing actually used. Canon says speculative/dead coupling gets deleted (same rule that retired IRecipientResolver), so both go. #170 — send-notification was dead-end wiring: - NextAurora.Contracts.Commands.SendNotificationCommand had ZERO references — no handler, no publisher. The working path is unaffected: event handlers return SendNotificationRequest and Wolverine cascades it IN-PROCESS to SendNotificationHandler; it never touched the queue. - Worse than dead: event-catalog.md told any service it could publish there, and such a message would arrive unhandleable and be silently discarded. - Removed: the contract + Commands/ folder, MessagingQueues.SendNotification, the listener, the catalog row + command section, the architecture/README/observability entries, and the diagram box. #171 — two artifacts documented as live, incremented/emitted by nothing: - NextAuroraMetrics.MessagesAbandoned: declared, never .Add()-ed (the ASB processors that fed it died in the Wolverine migration). An operator alerting on it got a permanently-zero signal while Wolverine dead-lettered silently. - .AddSource("NextAurora.Messaging"): registered with no emitter. - ROOT CAUSE + real fix: only the "NextAurora" meter was registered, so Wolverine's OWN metrics were never collected. Now .AddMeter("Wolverine*") — wolverine-dead-letter-queue (the real DLQ alarm), -execution-failure, -messages-sent/-received, inbox depth. The dead counter is deleted and REPLACED by telemetry that actually fires. Identifier-move discipline applied: removed names tombstoned; swept to zero (the audit is the completion criterion, not memory). Documented a newly-found blind spot in the audit — line-broken identifiers in .excalidraw JSON evade the regex (found via the rendered PNG, not the grep), so diagram hits need a visual check too. Verified: build 0 warn/0 err; tombstone + messaging-topology audits clean; integration 40/40 (Order 11, Payment 6, Shipping 4, Catalog 19); unit 57/57; both diagrams re-rendered. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…g the very drift it audits The review of this branch caught a structural flaw in MY OWN control, plus a half-done deletion. Both Must-fixes applied. MUST-FIX 1 — the tombstone allowlist was FILE-scoped, so it silently exempted files from every FUTURE tombstone: docs/architecture.md was allowlisted for the ASB patterns (#159). That exemption then covered the send-notification and messages.abandoned tombstones added months later — so `check-tombstones.sh` reported "clean" while architecture.md still documented BOTH deleted artifacts as live (a publishable SendNotificationCommand row; messages.abandoned as the DLQ alarm). The control that exists to make "sweep to zero" mechanical was returning green on a sweep that wasn't. Found by architecture review, not by the control. FIX: tombstones are now GROUPED ([group-name] headings) and allowlist entries are `<group> <path>` — an exemption is scoped to ONE group, never the whole audit. Rewritten check-tombstones.sh enforces it. The fixed control immediately surfaced 6 hidden hits, all now swept (architecture.md ×6, performance-and-data-correctness.md). MUST-FIX 2 — #171 deleted 1 of 5 dead counters; the whole class was dead: NextAuroraMetrics was registered via AddSingleton but NEVER INJECTED anywhere — every real counter is created inline (`new Meter("NextAurora")`) in the handler that emits it. So all five of its counters were declared-and-never-incremented, i.e. the exact defect #171 exists to eliminate, in the file the PR was already editing. Deleted the class + its registration. Also (should-consider): - Extensions.cs now names the meter explicitly: Wolverine's is `Wolverine:{ServiceName}`, so AddMeter("Wolverine*") is LOAD-BEARING — a literal AddMeter("Wolverine") collects nothing. (Reviewer runtime-verified this against Wolverine 6.8.0 + OTel 1.15.3.) - Re-flowed two tier-1 comments left mid-sentence by the surgical edits; fixed a doubled `---` in event-catalog.md; framed the project-decisions OTel snippet as as-of-that-decision; noted the topology guard's direct-queue branch is now a forward-guard. Rules encoded (all three the review asked for): - CLAUDE.md: allowlist exemptions are group-scoped, never whole-audit. - architecture-reviewer: new "metrics / Meter / Counter" checklist section — a declared-but-never-incremented instrument is a DEFECT (it reads as a working alarm and never fires); prefer the framework's own instruments. - .coderabbit.yaml: **/Metrics/*.cs dead-instrument rule + the Wolverine meter-name rule for ServiceDefaults (don't "tidy" the wildcard). Verified: build 0 err; tombstone + messaging-topology audits clean; 145/145 tests (integration 40 — Order 11, Payment 6, Shipping 4, Catalog 19; unit 105). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 5 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (30)
WalkthroughThe PR removes the direct notification queue and dormant observability artifacts, registers Wolverine metrics, introduces group-scoped tombstone auditing, finalizes the OKL documentation, and updates architecture and operational references. ChangesArchitecture and observability cleanup
Identifier drift controls
Knowledge surface documentation
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
…path The 6th surface — a fail-closed, cross-repo knowledge layer — is built (the OKL), so the tracked ADR replaces the gitignored docs/post-ideas/ draft the canon had been pointing at (a dangling 404, itself the doc-orphan drift the method polices). - docs/decisions/2026-07-17-sixth-surface-okl.md: the decision record - CONTEXT.md: 6th-surface note "not built" -> "built as the OKL", ref repointed - .claude/commands/grid-infographic.md: ref repointed to the tracked path
…ifacts # Conflicts: # .claude/tombstones-allowlist.txt
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 @.claude/scripts/check-tombstones.sh:
- Around line 56-74: Update the allowlist parsing loop to use read -r with
separate group and path variables, preserving comment/blank-line skipping and
matching only the current group while supporting paths with spaces. In the git
grep execution around the status handling, pass the tombstone pattern through
-e, and append the excludes arguments only when the excludes array is non-empty
so Bash 3.2 with nounset enabled does not fail on an empty expansion.
In `@docs/decisions/2026-07-17-sixth-surface-okl.md`:
- Around line 62-67: In the discussion of OKL’s distinct wedge, replace the
adverb “exactly” with “precisely” while preserving the surrounding list and
meaning.
In `@docs/STATUS.md`:
- Line 19: Update the “Last updated” date near the top of docs/STATUS.md from
2026-07-12 to 2026-07-19, leaving the status content unchanged.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: bd2b53d6-7c55-4020-b0bc-bab51d1a10b5
⛔ Files ignored due to path filters (2)
docs/efcore-query-write.svgis excluded by!**/*.svgdocs/nextaurora-architecture.svgis excluded by!**/*.svg
📒 Files selected for processing (30)
.claude/agents/architecture-reviewer.md.claude/commands/grid-infographic.md.claude/scripts/check-messaging-topology.sh.claude/scripts/check-tombstones.sh.claude/tombstones-allowlist.txt.claude/tombstones.txt.coderabbit.yamlCLAUDE.mdCONTEXT.mdNextAurora.Contracts/Commands/SendNotificationCommand.csNextAurora.Contracts/Messaging/MessagingTopology.csNextAurora.ServiceDefaults/Extensions.csNextAurora.ServiceDefaults/Metrics/NextAuroraMetrics.csNotificationService/Features/SendNotification.csNotificationService/Program.csREADME.mddocs/STATUS.mddocs/architecture.mddocs/code-flows/notificationservice.mddocs/decisions/2026-07-17-sixth-surface-okl.mddocs/dotnet-10-features.mddocs/ef-core.mddocs/efcore-query-write.excalidrawdocs/event-catalog.mddocs/event-driven-observability.mddocs/event-replay.mddocs/nextaurora-architecture.excalidrawdocs/observability.mddocs/performance-and-data-correctness.mddocs/project-decisions.md
💤 Files with no reviewable changes (3)
- NextAurora.Contracts/Commands/SendNotificationCommand.cs
- NextAurora.ServiceDefaults/Metrics/NextAuroraMetrics.cs
- README.md
- check-tombstones.sh: git grep -e "$pattern" (a tombstone starting with '-' is no longer parsed as a flag); guard "${excludes[@]}" so an exemption-less group doesn't trip set -u on bash 3.2 (macOS default); read -r grp pth instead of set -- (handles spaces, drops the shellcheck disable). Verified: clean run + a leading-hyphen pattern in an empty-exemption group matches without crashing. - STATUS.md: Last-updated date + #170/#171/#174 state. Declined the LanguageTool 'exactly'->'precisely' nit on the ADR (subjective, no correctness or consistency impact). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
All three addressed in dddbd12:
|
|
@coderabbitai resolve |
|
@coderabbitai review |
✅ Action performedReview finished.
|
✅ Action performedComments resolved and changes approved. |
…tAuroraMetrics literal The tombstone CI audit correctly caught it (I edited STATUS after the last local audit run and didn't re-verify). A living status doc doesn't earn a permanent allowlist — reworded to 'business-metrics holder class'. Both audits re-run clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai full review |
✅ Action performedFull review finished. Your plan includes PR reviews subject to rate limits. More reviews will be available in 5 minutes. |
Closes #170. Closes #171.
Both artifacts were found by the ultracode review of #159: things the docs presented as live that nothing actually used. Canon says speculative/dead coupling gets deleted (same rule that retired
IRecipientResolver), so both go — and where a real signal was missing, it's replaced, not just removed.#170 —
send-notificationwas dead-end wiringSendNotificationCommandhad zero references: no handler, no publisher. The working path is untouched — event handlers return the internalSendNotificationRequestand Wolverine cascades it in-process toSendNotificationHandler; it never touched the queue.Worse than dead:
event-catalog.mdtold any service it could publish there, and such a message would arrive unhandleable and be silently discarded. Removed the contract (+ the now-emptyCommands/), the queue const, the listener, and every doc/diagram reference.#171 — dead observability artifacts, replaced with real telemetry
MessagesAbandoned: declared, never.Add()-ed (the ASB processors that fed it died in the Wolverine migration). An operator alerting on it got a permanently-zero signal while Wolverine dead-lettered silently..AddSource("NextAurora.Messaging"): registered with no emitter."NextAurora"meter was registered, so Wolverine's own metrics were never collected at all. NowAddMeter("Wolverine*")→wolverine-dead-letter-queue(the real DLQ alarm),-execution-failure,-messages-sent/-received, inbox depth. The wildcard is load-bearing: Wolverine's meter isWolverine:{ServiceName}, so a literalAddMeter("Wolverine")collects nothing.NextAuroraMetricsclass was dead (registered, never injected — every real counter is created inline in its handler). All five counters were declared-and-never-incremented. Class deleted.The control caught a flaw in itself — and it was mine
The architecture-review gate (#160's rule, run pre-PR) found that my tombstone allowlist was file-scoped:
docs/architecture.md, allowlisted for the ASB patterns in #159, was thereby exempt from every tombstone added afterward. Socheck-tombstones.shreported clean while architecture.md still documented both deleted artifacts as live. The control built to make "sweep to zero" mechanical was returning green on a sweep that wasn't.Fixed: tombstones are grouped, and allowlist entries are
<group> <path>— an exemption is scoped to one group, never the whole audit. The corrected control immediately surfaced 6 hidden hits, all now swept.Rules encoded (same PR as the fix, per the loop)
**/Metrics/*.csdead-instrument rule + the Wolverine meter-name rule (don't "tidy" the wildcard to a literal).Verification
.excalidrawJSON evade the regex (found via the rendered PNG, not the grep).🤖 Generated with Claude Code
Summary by CodeRabbit
Breaking Changes
Observability
Documentation