Repository navigation
Track activity with owner-side upsert folds - #5187
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The new serialized public enum members can break exhaustive consumers; use an open string vocabulary before approval.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
What changed in this PR
Moves activity tracking to an onboarding-gated owner-side upsert with serialized folds, replacing stale query-based create/update selection.
Changes:
- Adds real-mesh regression tests for stale indexes, onboarding guards, folds, and failure classification.
- Adds conflict and teardown rejection outcomes.
- Documents the new fold-based upsert pattern.
| File | Description |
|---|---|
test/MeshWeaver.Graph.Test/ActivityTrackingUpsertTest.cs |
Tests stale-index activity creation and folded tracking. |
test/MeshWeaver.Graph.Test/ActivityConflictSeverityTest.cs |
Tests response failure classification. |
src/MeshWeaver.Mesh.Contract/CreateNodeRequest.cs |
Adds upsert rejection outcomes and classification. |
src/MeshWeaver.Graph/MeshNodeExtensions.cs |
Implements root-gated folded upserts. |
src/MeshWeaver.Documentation/Data/Architecture/CqrsAndContentAccess.md |
Documents folded upserts. |
.claude/skills/mesh-data/SKILL.md |
Updates mesh-data guidance. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Pull request was converted to draft
|
#5187 replaces activity tracking's query/create/update split with the existing owner-side upsert and content folds, retaining caller identity, the onboarding guard, and the established failure policy. It merged as Production verification on memex.systemorph.com, image 3.0.0-ci.9162, core c55301f: the unchanged v2 The durable count advanced 3 → 4 → 5 → 6. First access stayed 2026-09-22 06:20:29.8520151 UTC; the three last-access values advanced to 09:57:40.4872116, 09:57:40.7613836, and 09:57:41.1025923 UTC. A separate final node read confirmed count 6, version 6, the preserved first access, and The deterministic real-mesh regression establishes the stale-query defect: the old handler persisted count 1000 from a stale query value of 999 when durable activity storage was empty, and allowed a stale positive to bypass the missing-user-root guard. Both regressions pass with the fix. The live run is a production smoke check of the delivered path; it does not reproduce the historical 30-second timeout or establish a cause for every earlier timeout. |

Activity tracking now uses the existing owner-side create-or-update operation with serialized content folds, so a stale search row cannot choose an unsafe update or supply a counter value. This replaces the query/create/update split implicated in #1174. The first visit seeds count one; later visits increment the stored count, preserve first access, and advance last access. The onboarding root guard now runs before either leg, and caller identity and detached-write lifetime tracking remain in place.
The real-mesh regression failed against the old handler in both cases: an absent stored activity became count 1000 from a stale query value of 999, and a stale positive allowed an activity to be persisted without an onboarded user root. The fix passes both. These are deterministic stale-index defects; the test does not claim to recreate the production 30-second timeout or add cluster-wide atomic counters.
The upsert response also retains structured conflict and hub-teardown classifications through an additive open-string
FailureKindproperty, preserving the existing serialized enum and activity tracking's failure policy. Read, create, and update failures carry the classification on the actual response path; unknown kinds remain named, loud failures. A teardown with an unknown write outcome is distinct from a recycling intake refusal; neither introduces a retry. The CQRS page and canonical mesh-data skill now document the shipped folds and remove the stale #4928 blocker.Validation: full solution Release build with CIRun=true and warnings as errors, zero warnings/errors; 59 focused activity, fold, refusal-wire and tracker tests plus the documentation link check passed, no skips. Coverage includes the real hub serializer and a future unknown failure kind. Independent review addressed failure-policy parity and evidence wording.
CI also exposed a race in the existing per-type bundle-hold fixture: it seeded an adoption after the source fingerprint appeared but before the initial compile completed, and that legitimate compile subsequently stamped Compiled. The fixture now waits for Ok, Compiled, and current/compiled source equality before seeding; every hold and provenance assertion is preserved. After that correction, the full Release solution again passed with zero warnings/errors, and 32 focused adoption/hold tests passed without skips.
Delivery: this is compiled core code and requires the supported platform image rollout. The rollout replaces the process-owned activity/_tracking hub; no NodeType content or per-node source recycle is required. Production verification will exercise repeated tracking and inspect the stored count and timestamps before closing #1174.