Repair delegated package audit dual writes - #1142
Conversation
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
…d1-0dbb # Conflicts: # docs/contributing/architecture/data-storage.md # packages/worker/src/app/admin-insights-data.ts # packages/worker/src/email/delivery-events.ts # packages/worker/src/email/inbound.ts # packages/worker/src/email/outbound.ts # packages/worker/src/email/service.ts # packages/worker/worker-configuration.d.ts Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
📝 WalkthroughWalkthrough
ChangesPackage owner environment flow
Audit event persistence
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
|
🔎 Preview deployed: https://kody-pr-1142.kody-a99.workers.dev Worker: Mocks:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@packages/worker/src/package-registry/package-owner.ts`:
- Line 86: Update logAuditEvent in audit-log.ts to handle Promise.all dual-write
partial failures explicitly: detect when either audit sink fails, preserve the
successful-write result, and surface the failure instead of swallowing it behind
only the audit-event-failed log. Add tests covering each sink failing while the
other succeeds, including the expected retry or failure propagation behavior.
🪄 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 Plus
Run ID: 7add499c-20b0-4aff-9b72-f688d204f797
📒 Files selected for processing (11)
packages/worker/src/mcp/capabilities/community/publish.tspackages/worker/src/mcp/capabilities/community/unpublish.tspackages/worker/src/mcp/capabilities/packages/delete-package.tspackages/worker/src/mcp/capabilities/packages/get-git-remote.tspackages/worker/src/mcp/capabilities/packages/get-package.tspackages/worker/src/mcp/capabilities/packages/list-packages.tspackages/worker/src/mcp/capabilities/packages/package-update.tspackages/worker/src/mcp/capabilities/packages/publish-external-push.tspackages/worker/src/mcp/capabilities/packages/save-package.tspackages/worker/src/package-registry/package-owner.tspackages/worker/src/package-registry/package-owner.workers.test.ts
|
@coderabbitai review |
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/worker/src/audit-log.ts (1)
104-130: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winMake retried audit inserts idempotent.
runD1WithRetry()can reissue the plainINSERT INTO audit_events ...after"D1_ERROR: Network connection lost"or similar transient failures. If D1 commits before the connection error reaches the Worker, the retry can create a second row becauseaudit_eventshas no event-identity constraint. Add a stable audit event ID and protect the insert withINSERT OR IGNORE/ON CONFLICT; simulate a committed first write before the connection failure in the retry test.🤖 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 `@packages/worker/src/audit-log.ts` around lines 104 - 130, Make audit-event writes idempotent across retries: update the audit insert in packages/worker/src/audit-log.ts (lines 104-130) to include a stable event identity and use INSERT OR IGNORE or an equivalent conflict-safe insert backed by the corresponding uniqueness constraint. Update the retry scenario in packages/worker/src/audit-log.node.test.ts (lines 75-145) to simulate the first write committing before the connection failure, then verify the retry leaves only one audit row.
🤖 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.
Outside diff comments:
In `@packages/worker/src/audit-log.ts`:
- Around line 104-130: Make audit-event writes idempotent across retries: update
the audit insert in packages/worker/src/audit-log.ts (lines 104-130) to include
a stable event identity and use INSERT OR IGNORE or an equivalent conflict-safe
insert backed by the corresponding uniqueness constraint. Update the retry
scenario in packages/worker/src/audit-log.node.test.ts (lines 75-145) to
simulate the first write committing before the connection failure, then verify
the retry leaves only one audit row.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4a1bbf7c-cfd2-483c-a511-a6136f7bb706
📒 Files selected for processing (2)
packages/worker/src/audit-log.node.test.tspackages/worker/src/audit-log.ts
Summary
package_scope_delegated_accessaudit events to both APP_DB and AUDIT_DB during the remaining expand phaseProduction evidence
NOT VERIFIED— closed-window APP_DB=275, AUDIT_DB=274; the missing row wasaccount/package_scope_delegated_accessat2026-08-01T20:09:48.495Z.VERIFIED— closed window2026-07-31T23:47:19Z–2026-08-01T21:22:36Zhad APP_DB=299, AUDIT_DB=299, missing=0, extra=0, exact multiset match.VERIFIED— a uniquely named 181-day-old AUDIT_DB canary inserted at 21:25Z had remaining=0 after the normal hourly retention run, checked at2026-08-01T22:06:29Z.Validation
CI=1 npm run validatepassedReview response
CodeRabbit correctly identified that
Promise.allplus a broad catch obscured partial writes and lacked retry coverage. The implementation now uses the shared transient D1 retry policy, waits for both sinks withPromise.allSettled, reports failed sink names, preserves successful writes, and has explicit partial-failure tests.System recap — extends existing primitives (medium risk)
Mode: recap · Base:
main@38f3be9d· Head:09e7d7deClassification: extends — delegated package ownership reaches both audit sinks, whose transient and partial failures are now detected explicitly.
Primitives touched
saved-packagescommunity-listingsaudit-d1System map
Delegated package and community operations resolve ownership and independently persist the resulting event to both expand-phase D1 sinks.
Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context (unchanged, included only when an edge crosses it).
Invariants
Conductor report
STATUS: done
What shipped: delegated package-scope audit events now dual-write correctly; known transient D1 failures retry independently and partial failures identify the failed sink. The one historical missing row was backfilled.
Production evidence: VERIFIED. Closed-window exact multiset parity is APP_DB=299 and AUDIT_DB=299 with zero missing/extra rows. AUDIT_DB retention is VERIFIED: the normal hourly lane removed a uniquely named 181-day-old canary by 22:06Z.
Risk self-assessment: medium — additive routing/retry repair and one evidence-driven backfill; no destructive schema change.
Merged/deployed: yes — PR #1142 / yes — production deploy.
Scope spill: package/community capability call sites and central audit sink only; no email, entitlements, vectorize, or index.ts changes.
Summary by CodeRabbit
Bug Fixes
Tests