Repository navigation
fix(#1549): every NodeType release-failure class logs under its own EventId - #6326
Conversation
…ventId #4932 put each release-failure class into its own template, but the incident watcher folds every fingerprint of one log SITE into one issue, and a site is category + EventId + exception type. All classes shared category, EventId 0 and no exception, so NO NODE EXISTS (2026-09-24) and OWNING HUB REACHED NO VERDICT (2026-09-25) still arrived on #1549 as "a different fingerprint of the same log site" - causes that issue (silent forwards, fixed by #1990) was never about. LogReleaseRefusal now logs each class under EventId 7400 + class, named NodeTypeRelease<Class>; an undeclared value takes the Unclassified id. Test: EveryFailureClass_LogsUnderAnEventIdOfItsOwn. Negative control (ids removed): fails with one id shared by every class. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…currences fold by site Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Implicit enum ordinals can renumber or reuse deployed incident-site IDs when failure classes are inserted.
1 open finding
What changed in this PR
Separates NodeType release failures into distinct incident sites using per-class event IDs.
Changes:
- Adds event IDs to release-refusal logs.
- Tests event-ID uniqueness and naming.
- Documents incident-site folding behavior.
| File | Description |
|---|---|
src/MeshWeaver.Graph/NodeTypeRecompileExtensions.cs |
Assigns event IDs to failure logs. |
test/MeshWeaver.Graph.Test/ReleaseFailureClassIsInTheTemplateTest.cs |
Verifies IDs are nonzero and distinct. |
src/MeshWeaver.Documentation/Data/Architecture/ReleaseFailureClasses.md |
Documents event-ID-based separation. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| /// <returns>The event id that failure is logged under.</returns> | ||
| internal static EventId ReleaseFailureEventId(NodeTypeReleaseFailure failure) => | ||
| Enum.IsDefined(failure) | ||
| ? new EventId(ReleaseFailureEventIdBase + (int)failure, $"NodeTypeRelease{failure}") |
There was a problem hiding this comment.
Agreed: an id is a deployed incident site, so it can't be derived from an ordinal. Fixed in 7d673cc.
ReleaseFailureEventIdsis an explicit, append-only mapping from each class to a permanent code in 7400–7415 (Unclassified=7400 … HostLeaving=7415). These are the values the derived scheme would have produced, so nothing that has already shipped moves. An unlisted or undeclared value logs underUnclassified's id, the same way it takes that class's template.TheEventIdOfEveryClass_IsPinnedpins every class to its exact code and fails if any enum member has no entry. A class inserted mid-enum therefore can't take a historical site, and a new class has to be given its own code.EveryFailureClass_LogsUnderAnEventIdOfItsOwnstill checks that the ids are distinct.- Negative control: I removed
HostLeaving's row from the mapping, and both id tests fail. The suite passes 11/11 with the row restored, and the build is clean with-c Release -warnaserror. - The doc (
ReleaseFailureClasses) now says the codes are permanent and append-only, and that they are never the ordinal.
…inned by a test Review on #6326: an id derived from the enum ordinal renumbers every later class when one is inserted mid-enum, handing a new cause a deployed site. Each class now has an explicit append-only code (ReleaseFailureEventIds), and TheEventIdOfEveryClass_IsPinned pins the whole mapping. Negative control: a class with no code fails both id tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Test Results 14 files - 10 14 suites - 10 40m 49s ⏱️ - 8m 38s Results for commit 3adb660. ± Comparison against base commit 1007a35. This pull request removes 1501 and adds 9 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
…ure-classes-own-event-ids
…ure-classes-own-event-ids

Refs #1549.
#1549's original defect (per-node hubs silently forwarding for 2 h 20 m) was fixed by #1990 /
5cd54d3f2and verified on the deployed portal in August. The issue stayed open because later, unrelated release failures kept folding into it. This PR stops that folding.Root cause
NodeTypeReleaseFailureclass its own message template.StructuralLogIncidentIdentity.ComputeSiteFold) folds every fingerprint of one log site into one issue, and a site is category + EventId + exception type.NodeTypeRecompileExtensions.LogReleaseRefusallogged every class under one category, EventId 0 and no exception, so every class was the same site.NO NODE EXISTS(2026-09-24) andOWNING HUB REACHED NO VERDICT(2026-09-25 18:55:27Z) arrived on Per-node hubs stopped answering on memex-cloud for 2h20m — the NodeType release burst is the symptom that surfaced it #1549 as "a different fingerprint of the same log site48a398f36ff176dd", taking it to 459 occurrences of causes it was never about.Fix
LogReleaseRefusallogs each class underReleaseFailureEventId(failure)= an explicit, append-only code per class (ReleaseFailureEventIds, 7400–7415), namedNodeTypeRelease<Class>.Unclassified's id, the same way it takes that class's template.Test
test/MeshWeaver.Graph.Test/ReleaseFailureClassIsInTheTemplateTest.cs→EveryFailureClass_LogsUnderAnEventIdOfItsOwn.MeshWeaver.GraphandMeshWeaver.Graph.Testbuild clean with-c Release -warnaserror.Effect on incidents
Each class now opens its own incident site; ids are permanent explicit codes 7400–7415, pinned by
TheEventIdOfEveryClass_IsPinned. The classes that are not defects (NodeMissing,CompileDenied,OwnerRecycling) stay at Error. Deciding their levels is a separate question, as the remarks inLogReleaseRefusalsay.Doc:
Doc/Architecture/ReleaseFailureClasses→ "…and its own EVENT ID, because a recurrence folds by SITE".Pairs-with: none — no public surface removed (one internal helper and one internal const added).
🤖 Generated with Claude Code