Skip to content

Fix: Zero mutators OCR/transcript missed follow-ups#431

Merged
capy-ai[bot] merged 2 commits into
mainfrom
capy/apply-zero-mutators-followup
Apr 22, 2026
Merged

Fix: Zero mutators OCR/transcript missed follow-ups#431
capy-ai[bot] merged 2 commits into
mainfrom
capy/apply-zero-mutators-followup

Conversation

@urjitc

@urjitc urjitc commented Apr 22, 2026

Copy link
Copy Markdown
Member

This PR applies the follow-up missed by PR #425's merge, addressing a race condition where concurrent user edits could overwrite workflow-owned ocrStatus/processingStatus fields, and adds coverage for when syncExtractedRow runs on items without existing extracted rows.

Mutator fixes

  • src/lib/zero/mutators.ts: Strip ocrStatus and processingStatus from upsertItem payload; these are workflow-owned and should not be clobbered by client-side mutators that can't see workspace_item_extracted.
  • src/lib/zero/server-mutators.ts: Hoist updatedAt in syncExtractedRow to avoid duplicate timestamp generation.

Test coverage

  • src/lib/zero/tests/mutator-extracted-regressions.test.ts: Verify client mutator doesn't send ocrStatus/processingStatus to Zero and that user-editable fields flow through correctly; add test for syncExtractedRow creating extracted row when missing.

Open ENG-048 ENG-048

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Enhanced extraction workflow data handling to ensure client-side mutations properly preserve server-managed fields and prevent unintended overwrites during concurrent operations.
  • Tests

    • Added regression tests for extraction synchronization edge cases, verifying proper field initialization and data consistency.
    • Enhanced existing mutation tests to confirm correct field handling during updates.

@urjitc urjitc added the capy Generated by capy.ai label Apr 22, 2026 — with Capy AI
@github-project-automation github-project-automation Bot moved this to Backlog in Dev Board Apr 22, 2026
@vercel

vercel Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
thinkex Ready Ready Preview, Comment Apr 22, 2026 5:41am

Request Review

@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@urjitc has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 53 minutes and 52 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 53 minutes and 52 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 868fc1e8-ada3-4d7c-9522-764f5e628fc9

📥 Commits

Reviewing files that changed from the base of the PR and between 14c8a21 and 72d0bd5.

📒 Files selected for processing (2)
  • src/lib/zero/__tests__/mutator-extracted-regressions.test.ts
  • src/lib/zero/mutators.ts
📝 Walkthrough

Walkthrough

The changes enhance mutator field handling by excluding workflow-derived shell fields (ocrStatus, processingStatus) from client-safe payloads in upsertItem, stabilize timestamp generation in syncExtractedRow, and add regression tests verifying correct behavior when extracted rows are deleted and recreated with proper null initialization.

Changes

Cohort / File(s) Summary
Test Regression Coverage
src/lib/zero/__tests__/mutator-extracted-regressions.test.ts
Updated shell flag assertion to verify ocrStatus and processingStatus are excluded from shared update calls; added new regression test ensuring syncExtractedRow correctly initializes extracted rows with null-equivalent extraction fields and false/0 shell flags when extracted row is missing.
Mutator Field Stripping
src/lib/zero/mutators.ts
Expanded clientSafeShell destructuring in upsertItem to additionally exclude ocrStatus and processingStatus (workflow-derived fields) from the mutation payload, ensuring only client-owned shell fields are persisted.
Server Mutator Optimization
src/lib/zero/server-mutators.ts
Stabilized timestamp generation in syncExtractedRow by computing updatedAt once and reusing the value across both insert and conflict-update operations instead of calling new Date().toISOString() multiple times.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 A hop through the fields, both safe and derived,
Where workflow-born states are gently deprived,
Timestamps now steady, extracted rows mend,
The shell keeps its secrets from start to the end! 🌱

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR objectives focus on fixing OCR/transcript race conditions and test coverage, but the linked issue #39 concerns folder deletion cascading to items, which is unrelated to the actual code changes. Review and verify the linked issue is correct, or link the PR to issues related to OCR/transcript handling and upsertItem behavior instead.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix: Zero mutators OCR/transcript missed follow-ups' accurately describes the main changes, which involve fixing OCR and transcript handling in Zero mutators.
Out of Scope Changes check ✅ Passed All changes (mutator stripping of workflow-owned fields, timestamp hoisting, and regression tests) are directly aligned with the PR objectives of fixing OCR/transcript race conditions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch capy/apply-zero-mutators-followup

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.

❤️ Share

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

@greptile-apps

greptile-apps Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a race condition where concurrent user edits via upsertItem could overwrite workflow-owned ocrStatus/processingStatus fields on the shell row, and ensures syncExtractedRow uses a single consistent updatedAt timestamp across its insert and conflict-update branches. Test coverage is added for both the field-stripping behaviour and the previously untested "no existing extracted row" path in syncExtractedRow.

Confidence Score: 5/5

Safe to merge — all changes are targeted, well-justified, and covered by new tests.

No P0/P1 findings. The destructuring fix in upsertItem is minimal and correct. The updatedAt hoist is a pure consistency improvement. The new tests exercise both changed behaviours directly.

No files require special attention.

Important Files Changed

Filename Overview
src/lib/zero/mutators.ts Strips ocrStatus and processingStatus from the client-side upsertItem payload to prevent concurrent user edits from clobbering workflow-owned shell fields.
src/lib/zero/server-mutators.ts Hoists updatedAt before the insert/upsert so both the values and onConflictDoUpdate.set branches use the same timestamp, eliminating a potential clock-skew inconsistency.
src/lib/zero/tests/mutator-extracted-regressions.test.ts Adds assertions that ocrStatus/processingStatus are absent from the client mutator payload, verifies user-editable fields still flow through, and adds a new test for syncExtractedRow creating an extracted row when none exists.

Reviews (1): Last reviewed commit: "Add missed OCR/transcript Zero mutator f..." | Re-trigger Greptile

@capy-ai capy-ai 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.

Added 1 comment

Comment thread src/lib/zero/mutators.ts Outdated

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 3 files

Requires human review: This PR modifies core data synchronization logic (mutators) and field-level persistence, which constitutes a business logic change in a core path requiring human review.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/lib/zero/mutators.ts">

<violation number="1" location="src/lib/zero/mutators.ts:359">
P1: Keeping `processingStatus` in the shared upsert payload allows unrelated audio edits to overwrite workflow-owned status during concurrent updates. Restrict this field to explicit status-transition paths instead of writing it on every upsert.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/lib/zero/mutators.ts
// A concurrent user edit whose mutator tx snapshots a pre-completion
// `"processing"` value before the workflow commits `"complete"` would
// otherwise overwrite the workflow's write when the mutator upserts the
// shell. `processingStatus` is intentionally *not* stripped here because

@cubic-dev-ai cubic-dev-ai Bot Apr 22, 2026

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.

P1: Keeping processingStatus in the shared upsert payload allows unrelated audio edits to overwrite workflow-owned status during concurrent updates. Restrict this field to explicit status-transition paths instead of writing it on every upsert.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/zero/mutators.ts, line 359:

<comment>Keeping `processingStatus` in the shared upsert payload allows unrelated audio edits to overwrite workflow-owned status during concurrent updates. Restrict this field to explicit status-transition paths instead of writing it on every upsert.</comment>

<file context>
@@ -351,20 +351,23 @@ export async function upsertItem(
   // otherwise overwrite the workflow's write when the mutator upserts the
-  // shell. `syncExtractedRow` rebuilds all derived fields server-side from
-  // the real extracted row.
+  // shell. `processingStatus` is intentionally *not* stripped here because
+  // the audio retry flow (WorkspaceContent.tsx handleAudioComplete) goes
+  // through this path to flip audio back to `"processing"` after a user
</file context>
Fix with Cubic

@capy-ai
capy-ai Bot merged commit d2afce7 into main Apr 22, 2026
8 checks passed
@capy-ai
capy-ai Bot deleted the capy/apply-zero-mutators-followup branch April 22, 2026 05:51
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Dev Board Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capy Generated by capy.ai

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant