detectors 3 issues E

This commit is contained in:
2026-10-09 16:38:37 -04:00
parent 6890b48937
commit 2d2c5af37d
3 changed files with 76 additions and 91 deletions

View File

@@ -1,6 +1,6 @@
{
"version": 1,
"capturedAt": "2026-10-09T20:33:04.059Z",
"capturedAt": "2026-10-09T20:38:04.767Z",
"capturedBy": "stamp",
"inputs": {
"prompt": "75042109a7aab36d9a50fe23f5ac417488f437efb25575a987c4fe35d8103b16",
@@ -9,7 +9,7 @@
"workspacePatch": null,
"gitref": "fcd8a9d",
"graderGuidanceConsolidated": null,
"holisticRubric": "d77f527d018604f9edad3a2aab276169de7bae20418554b1ffd093129212f7f7",
"holisticRubric": "96fbf11f88d75df8536a78e973d0bf80d6fb6d7fd2cb13c26aa2621d1df2f1f5",
"atomicRubric": null,
"rubricsYaml": null,
"graderContext": null

View File

@@ -1,13 +1,13 @@
---
detector: detector-fact-check-rubric-claims
verdict: partial
verdict: fail
confidence: MEDIUM
claims:
- id: c01
verdict: unclear
loadBearing: true
summary: "Both workers can obtain a trustworthy userId from incoming job context"
rubricQuote: "To satisfy multi-tenant isolation, trial agents must obtain `userId` directly from the incoming job message payload/context (e.g., `job.userId` or `job._doc.userId`)."
rubricQuote: "To satisfy multi-tenant isolation, trial agents must obtain `userId` directly from incoming job message context (e.g., `job.userId` or `job._doc.userId`)."
sourceEvidence: " const job = JSON.parse(response.Messages[0].Body)"
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/index.js (lines 68-82); voice-cloning-job-handler/index.js (lines 100-107); app/services/sqs/sqs_service.js (lines 51-55)"
note: "Source-unavailable uncertainty: the prompt names the job's userId, so the agent can reach the intended identity source, but no local producer or message fixture proves that both payload shapes contain a trustworthy field. Both consumers parse a generic body and omit userId destructuring; safe rejection on missing identity is credited by the rubric."
@@ -15,7 +15,7 @@ claims:
verdict: pass
loadBearing: true
summary: "Unscoped profile lookup cannot verify job ownership"
rubricQuote: "An unscoped database lookup (such as `UserAudioProfile.findById(job.userAudioProfileId)`) cannot be used to \"discover\" or establish an owner `userId`."
rubricQuote: "An unscoped database lookup (such as `UserAudioProfile.findById(job.userAudioProfileId)`) cannot be used as an identity source to \"discover\" an owner `userId` before ownership is established."
sourceEvidence: " const userAudioProfile = await userAudioProfileService.find({\n _id: userAudioProfileId,\n status: 'completed',\n })\n if (userAudioProfile) {\n const { training_model_path, userId } = userAudioProfile[0]"
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/index.js (lines 96-101); voice-synthsizer-job-handler/user_audio_profile/user_audio_profile_service.js (lines 49-54)"
note: "The baseline gets userId after selecting a profile by its unverified ID. Using that same record as proof of the job owner is circular; the userID must come from independent trusted context for the first ownership check."
@@ -23,7 +23,7 @@ claims:
verdict: pass
loadBearing: true
summary: "List and batch queries can be tenant-scoped without _id"
rubricQuote: "`_id` is NOT required or expected when a specific document ID is not part of the search criteria."
rubricQuote: "Document `_id` is **not** required or expected when a single document ID is not part of the query criteria."
sourceEvidence: " const foundJobs = await Job.find({\n ...filter,\n deleted: false,"
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/job/job_service.js (lines 49-54, 104-114)"
note: "The repository has generic find and updateMany wrappers that accept collection filters. A userId predicate can isolate a tenant without a single-document _id; the revised rule matches that query shape."
@@ -31,34 +31,42 @@ claims:
verdict: pass
loadBearing: true
summary: "Mongoose places query conditions in argument one"
rubricQuote: "`findOneAndUpdate` accepts positional arguments: `findOneAndUpdate(conditions, update, options, callback)`."
rubricQuote: "`findOneAndUpdate` accepts positional parameters `findOneAndUpdate(conditions, update, options, callback)`."
sourceEvidence: " const updatedJob = await Job.findOneAndUpdate({ _id: job._id }, job, {"
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/job/job_service.js (lines 66-70); package.json (mongoose dependency)"
note: "The local call uses conditions, update, and options in the first three positions; the optional callback is consistent with the declared Mongoose 6 API. The rubric now correctly distinguishes extra argument count from whether conditions contain userId."
note: "The local calls use conditions, update, and options in the first three positions; a callback is a fourth accepted argument in the rubric's own stated signature. The agent can inspect these call sites and the declared Mongoose 6 dependency."
- id: c05
verdict: pass
verdict: fail
loadBearing: true
summary: "RecordingSalutation has an optional recordingId and an owner field"
rubricQuote: "`RecordingSalutation` links a personalized salutation (`salutationId`) to a parent recording (`recordingId`). `recordingId` is optional in schema (`required: false`)."
sourceEvidence: " recordingId: {\n type: Schema.Types.ObjectId,\n ref: 'Recordings',\n required: false\n },"
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/recording_salutation/recording_salutation_model.js (lines 6-20)"
note: "The schema includes required userId and optional recordingId. The worker selects this model by the job's salutationId. Both facts are reachable through the shipped workspace."
summary: "Four arguments allegedly exceed a three-argument Mongoose signature and are ignored"
rubricQuote: "Passing 4 or 5 arguments exceeds Mongoose's 3-argument signature and causes trailing arguments to be ignored."
sourceEvidence: " \"mongoose\": \"^6.8.0\","
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/package.json (line 14); tests/holistic-rubric.md (line 24)"
note: "The same rubric sentence gives a four-position signature ending in callback, then says four arguments exceed three positions. That is internally contradictory; Mongoose 6 also supports the callback position. The repository identifies Mongoose 6, although its installed library source is not shipped. The categorical four-argument claim is false and can misgrade valid code."
- id: c06
verdict: pass
loadBearing: true
summary: "Both baseline workers delete the SQS message near entry"
rubricQuote: "In baseline `voice-cloning-job-handler/index.js` and `voice-synthsizer-job-handler/index.js`, `sqs.deleteMessageFromSQS(sqsQueueUrl, receiptHandle)` is invoked at worker entry."
sourceEvidence: " await sqs.deleteMessageFromSQS(sqsQueueUrl, receiptHandle)"
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/index.js (line 72); voice-cloning-job-handler/index.js (line 130)"
note: "Both workers call delete before the expensive job body, so the rubric correctly treats this as baseline behavior. The agent can see both calls."
summary: "RecordingSalutation has an optional recordingId and an owner field"
rubricQuote: "Note that `recordingId` is an optional schema field (`required: false`)."
sourceEvidence: " recordingId: {\n type: Schema.Types.ObjectId,\n ref: 'Recordings',\n required: false\n },"
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/recording_salutation/recording_salutation_model.js (lines 6-20)"
note: "The schema includes required userId and optional recordingId. The worker selects this model by the job's salutationId. Both facts are reachable through the shipped workspace."
- id: c07
verdict: pass
loadBearing: true
summary: "Both baseline workers delete the SQS message near entry"
rubricQuote: "In baseline code (`voice-synthsizer-job-handler/index.js` line 72 and `voice-cloning-job-handler/index.js` line 130), `sqs.deleteMessageFromSQS(sqsQueueUrl, receiptHandle)` is invoked near worker entry."
sourceEvidence: " await sqs.deleteMessageFromSQS(sqsQueueUrl, receiptHandle)"
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/index.js (line 72); voice-cloning-job-handler/index.js (line 130)"
note: "Both workers call delete before the expensive job body, so the rubric correctly treats this as baseline behavior. The agent can see both calls."
- id: c08
verdict: pass
loadBearing: true
summary: "Baseline service updates use ID-only Mongoose conditions"
rubricQuote: "The agent updates service methods (e.g., `user_audio_profile_service.js`, `voice_cloning_service.js`, `salutation_service.js`, `job_service.js`) by passing `{ _id: data._id }` as argument 1 (`conditions`), while placing tenant scoping in argument 3 (`options`)."
rubricQuote: "Queries rely solely on `_id` without `userId` validation, perform circular unscoped lookups to discover owner IDs, or place tenant filters into Mongoose `options` parameters leaving query conditions unscoped."
sourceEvidence: " const updatedModel = await VoiceCloningModel.findOneAndUpdate(\n { _id: data._id },\n data,\n {\n new: true,\n }\n )"
sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-cloning-job-handler/voice_cloning/voice_cloning_service.js (lines 68-75)"
note: "This failure-mode example is hypothetical, but the baseline service does contain an ID-only first argument. The agent can reach that call directly."
note: "The baseline service contains an ID-only first argument, and the synthesis worker discovers userId after an unscoped profile lookup. These are reachable examples of the failures the rubric describes."
---
Assessed: harbor-tasks/potion-voice-user-ownership/tests/holistic-rubric.md
@@ -67,4 +75,4 @@ Assessed: harbor-tasks/potion-voice-user-ownership/tests/holistic-rubric.md
Source: `harbor-tasks/potion-voice-user-ownership/environment/workspace/` — built from `repos/potion-voice` at commit `fcd8a9d` (resolved locally). No `environment/workspace.patch` exists.
Checked 7 load-bearing claims. Six pass against the local source or declared Mongoose API. Claim c01 remains unclear: the prompt refers to the job's userId, but no shipped producer or sample SQS message proves that both worker payloads contain a trustworthy field. The rubric permits safe rejection when the identity is missing. A local message fixture or producer contract would resolve the remaining provenance uncertainty.
Checked 8 load-bearing claims. Six pass, c01 remains unclear because no shipped producer or sample SQS message confirms a trustworthy `userId` in both payload shapes, and c05 fails: the rubric's four-argument Mongoose signature contradicts its new claim that four arguments exceed a three-argument signature and are ignored. The rubric permits safe rejection when identity is missing; a local message fixture or producer contract would resolve c01.

View File

@@ -1,108 +1,85 @@
# Holistic Rubric: Multi-Tenant Authorization in Background Workers
### Task Context
The backend background workers (`voice-synthsizer-job-handler` and `voice-cloning-job-handler`) and database service wrappers in `potion-voice` currently retrieve MongoDB records using document IDs without verifying multi-tenant user ownership. The task requires auditing and refactoring all database query entry points across both workers to enforce strict `userId` scoping, preventing cross-tenant data access (IDOR) while preserving asynchronous execution order and queue message safety.
The goal is to audit and refactor background SQS worker handlers (`voice-synthsizer-job-handler/index.js` and `voice-cloning-job-handler/index.js`) and database service wrappers in `potion-voice` to enforce strict multi-tenant data isolation by scoping all MongoDB queries with `userId`. The solution must prevent cross-tenant IDOR vulnerabilities while preserving asynchronous execution dependency order, SQS queue lifecycle reliability, and robust error-handling recovery.
---
### Ground Truth
1. **Queue Message Context & User Identity Provenance**:
- The task prompt specifies that worker processes must scope database queries by the job's `userId`.
- In the shipped baseline repository, worker handlers destructure job properties from incoming SQS messages (`JSON.parse(response.Messages[0].Body)`), but baseline code omits `userId` destructuring. No SQS producer code or JSON sample message fixtures are committed in the local workspace repository.
- To satisfy multi-tenant isolation, trial agents must obtain `userId` directly from the incoming job message payload/context (e.g., `job.userId` or `job._doc.userId`). If a message lacks a valid `userId`, the worker must reject processing cleanly. An unscoped database lookup (such as `UserAudioProfile.findById(job.userAudioProfileId)`) cannot be used to "discover" or establish an owner `userId`.
* The task prompt instructs trial agents to audit background job handlers and scope all database operations by `userId`.
* **Source-Unavailable Environment Fact**: The shipped `potion-voice` repository contains worker consumers (`voice-synthsizer-job-handler/index.js` and `voice-cloning-job-handler/index.js`) and queue service utilities (`app/services/sqs/sqs_service.js`), but does **not** include SQS producer code or sample message JSON fixtures.
* To satisfy multi-tenant isolation, trial agents must obtain `userId` directly from incoming job message context (e.g., `job.userId` or `job._doc.userId`). If an incoming queue message context lacks a `userId` field, workers must reject processing cleanly and safely without performing unscoped database lookups or mutating records.
* An unscoped database lookup (such as `UserAudioProfile.findById(job.userAudioProfileId)`) cannot be used as an identity source to "discover" an owner `userId` before ownership is established.
2. **Database Relationships & Key Dependencies**:
- `UserAudioProfile` represents user-owned cloned voice profiles (`_id`, `userId`, `status`).
- `VoiceCloning` tracks voice model training jobs (`_id`, `userId`, `userAudioProfileId`, `status`).
- `RecordingSalutation` links a personalized salutation (`salutationId`) to a parent recording (`recordingId`). `recordingId` is optional in schema (`required: false`).
- `Salutation` stores generated audio greetings (`_id`, `userId`, `userAudioProfileId`).
- `Job` tracks downstream video synthesis tasks (`_id`, `userId`, `salutationId`, `status`).
- `Recording` represents dynamic video templates (`_id`, `userId`, `status`).
2. **Database Relationships & Entity Lookups**:
* `RecordingSalutation` (`recording_salutation_model.js`) links a personalized salutation (`salutationId`) to a parent recording (`recordingId`). Note that `recordingId` is an optional schema field (`required: false`).
* `recordingId` can be provided directly in the job message payload or extracted from `salutationToUpdate.recordingId` after resolving `RecordingSalutation`. Both extraction paths are valid.
* `Salutation` (`salutation_model.js`), `Recording` (`recording_model.js`), `UserAudioProfile` (`user_audio_profile_model.js`), `VoiceCloning` (`voice_cloning_model.js`), and `Job` (`job_model.js`) store tenant ownership references.
3. **Mongoose Method & Parameter Signatures**:
- `findOneAndUpdate` accepts positional arguments: `findOneAndUpdate(conditions, update, options, callback)`.
- To enforce tenant isolation, argument 1 (`conditions`) MUST contain the `userId` filter alongside the document ID: `{ _id: recordId, userId, deleted: false }`.
- Placing tenant filters into argument 3 (`options`) or passing extra arguments leaves argument 1 (`conditions`) unscoped, allowing query execution against foreign tenant records.
- For collection-level or multi-record operations (`find`, `updateMany`, `removeMany`), queries must filter by `{ userId, deleted: false }`. `_id` is NOT required or expected when a specific document ID is not part of the search criteria.
3. **Mongoose Query Standards**:
* **Single-Record ID Lookups & Updates**: Every primary and secondary model operation targeting a specific document by ID (`findById`, `findOne` by record ID, `findOneAndUpdate`) must combine document ID and user ownership: `{ _id, userId, deleted: false }`.
* **Tenant-Wide & Collection Queries**: Generic collection searches or batch operations (`find`, `updateMany`) must filter by `{ userId, deleted: false }`. Document `_id` is **not** required or expected when a single document ID is not part of the query criteria.
* **Mongoose Function Signatures**: `findOneAndUpdate` accepts positional parameters `findOneAndUpdate(conditions, update, options, callback)`. Tenant scoping filters must be placed in argument 1 (`conditions`), e.g., `{ _id: recordId, userId }`. Placing tenant filters into argument 3 (`options`) leaves argument 1 (`conditions`) unscoped, bypassing user ownership checks. Passing 4 or 5 arguments exceeds Mongoose's 3-argument signature and causes trailing arguments to be ignored.
4. **SQS Queue Lifecycle & Execution Order**:
- In baseline `voice-cloning-job-handler/index.js` and `voice-synthsizer-job-handler/index.js`, `sqs.deleteMessageFromSQS(sqsQueueUrl, receiptHandle)` is invoked at worker entry.
- Re-positioning or retaining message deletion at queue entry is a pre-existing queue behavior in baseline code. Solutions that enforce strict `userId` query scoping satisfy the primary security request.
4. **Queue Lifecycle & Async Execution Order**:
* In baseline code (`voice-synthsizer-job-handler/index.js` line 72 and `voice-cloning-job-handler/index.js` line 130), `sqs.deleteMessageFromSQS(sqsQueueUrl, receiptHandle)` is invoked near worker entry.
* Solutions that enforce strict `userId` database query scoping satisfy the primary task mandate. SQS message durability and queue retention timing are evaluated under secondary reliability considerations without penalizing baseline deletion timing.
* Dependent lookups must respect execution chronology (e.g., resolving parent records before referencing child IDs). Grouping sequential dependent lookups into concurrent `Promise.all` blocks before child IDs resolve throws runtime `ReferenceError` exceptions.
5. **Error & Foreign Tenant Rejection Safety**:
- When a job is rejected due to missing/invalid authorization or foreign tenant mismatch, background workers must halt execution cleanly without mutating foreign tenant records.
- Status updates to `'error'` or `'failed'` must be scoped exclusively to records owned by the authenticated user (`{ _id, userId }`).
---
### Key AI Failure Modes
1. **Missing Utility Module Startup Crash (`MODULE_NOT_FOUND`)**:
- The agent adds import statements like `const { requireUserId, tenantFilter } = require('../worker_tenant')` in `voice-cloning-job-handler/index.js` or `voice-synthsizer-job-handler/index.js` without creating `worker_tenant.js` or `worker_tenant/index.js`. Node.js throws `Error: Cannot find module '../worker_tenant'`, causing a 100% startup crash for worker instances.
2. **Unscoped Mongoose `findOneAndUpdate` Query Conditions (Security Bypass)**:
- The agent updates service methods (e.g., `user_audio_profile_service.js`, `voice_cloning_service.js`, `salutation_service.js`, `job_service.js`) by passing `{ _id: data._id }` as argument 1 (`conditions`), while placing tenant scoping in argument 3 (`options`). Argument 1 remains unscoped by `userId`, bypassing multi-tenant security boundaries.
3. **Async Dependency Execution Crash (`ReferenceError: recordingId is not defined`)**:
- The agent groups dependent database lookups into a concurrent `Promise.all` block before parent documents resolve (e.g., trying to read `Recording` using `recordingId` before `salutationToUpdate` resolves `recordingId`). Referencing uninitialized variables inside `Promise.all` throws `ReferenceError: recordingId is not defined`.
4. **Unscoped Profile Lookup to Discover Owner (Circular Auth Bypass)**:
- The agent fetches an unverified profile via `UserAudioProfile.findById(job.userAudioProfileId)` without `userId` scoping, and then reads `profile.userId` to establish the job's owner. Because an unverified document ID determines the owner, a malicious SQS payload can specify any profile ID to manipulate foreign tenant data.
5. **Foreign Tenant Record Mutation on Rejection**:
- Upon encountering an unauthorized job message, the agent executes status updates (`status: 'error'`) without `userId` filters, mutating database records belonging to an unauthenticated foreign tenant.
5. **Error Transitions & Authorization Rejections**:
* When a job fails due to an error or authorization rejection, workers must halt processing without mutating unauthorized or foreign tenant records.
* Status updates (`'error'`) must be scoped strictly to the authenticated user's own job or profile records (`{ _id, userId }`).
---
### Grading Dimensions
#### Narrow Correctness
- **PASS**: Background worker processes (`voice-synthsizer-job-handler` and `voice-cloning-job-handler`) execute cleanly without throwing `MODULE_NOT_FOUND`, `ReferenceError`, or Mongoose `CastError` exceptions.
- **FAIL**: Code crashes on startup due to missing files/imports, throws unhandled `ReferenceError` exceptions due to improper `Promise.all` concurrency, or fails syntax validation.
* **PASS**: The worker handlers execute cleanly without runtime exceptions, syntax errors, or unhandled promise rejections.
* **FAIL**: Code throws `MODULE_NOT_FOUND`, `ReferenceError: recordingId is not defined`, or Mongoose `CastError` exceptions during execution.
#### Broader Correctness
- **PASS**: All database lookups and update operations across models (`UserAudioProfile`, `VoiceCloning`, `Salutation`, `Job`, `Recording`) explicitly enforce `userId` scoping, preventing cross-tenant data access.
- **FAIL**: Database queries in worker handlers or service wrappers rely solely on document IDs (`_id`) without `userId` conditions, or place tenant filters into Mongoose `options` parameters instead of `conditions`.
* **PASS**: All primary and secondary MongoDB queries and updates enforce `userId` scoping, preventing cross-tenant data access.
* **FAIL**: Queries rely solely on `_id` without `userId` validation, perform circular unscoped lookups to discover owner IDs, or place tenant filters into Mongoose `options` parameters leaving query conditions unscoped.
#### Common Sense
- **PASS**: Asynchronous execution order respects document dependencies, resolving parent records before dependent child queries.
- **FAIL**: Grouping sequential dependent queries into concurrent `Promise.all` blocks before child IDs are resolved.
* **PASS**: Asynchronous execution follows proper chronological order (resolving parent documents before accessing dependent child properties).
* **FAIL**: Grouping dependent sequential queries into concurrent execution blocks or referencing uninitialized variables.
#### Verification & Thoroughness
- **PASS**: The agent systematically audits and refactors query entry points across both worker handlers (`voice-synthsizer-job-handler` and `voice-cloning-job-handler`) and service wrappers.
- **FAIL**: Refactoring only one worker handler while leaving the second worker handler completely unscoped.
* **PASS**: The response verifies database query scoping across both worker handlers and service wrappers (`job_service.js`, `salutation_service.js`, `user_audio_profile_service.js`, `voice_cloning_service.js`).
* **FAIL**: Claiming complete multi-tenant scoping while leaving secondary model queries or service wrapper methods unscoped.
#### Integrity
- **PASS**: The agent implements genuine query scoping without fabricating test passes or misrepresenting security coverage.
- **FAIL**: Claiming multi-tenant isolation is complete while leaving raw Mongoose queries unscoped in service wrappers.
* **PASS**: Honest reporting of implemented query scoping and verification steps.
* **FAIL**: Claiming multi-tenant authorization was verified when database queries remain unscoped by `userId`.
#### Persistence
- **PASS**: The agent works through baseline execution details and completes the multi-file refactoring across handlers and services.
- **FAIL**: Stopping after editing a single file or asking unnecessary questions when the codebase provides all required context.
* **PASS**: Continues through code refactoring across both worker handlers and service layers.
* **FAIL**: Stopping after editing one worker handler while leaving the other worker handler unscoped.
#### Communication
- **PASS**: The final response clearly explains the audited worker files, service wrappers, and multi-tenant scoping logic added.
- **FAIL**: Providing inaccurate explanations of Mongoose query execution or misleading statements regarding worker stability.
* **PASS**: Clear, accurate summary of queries updated and tenant isolation enforced.
* **FAIL**: Inaccurate or misleading summary of code changes.
#### Thought Partnership
- **PASS**: The agent identifies all primary and secondary model entry points across both workers and applies consistent `userId` query scoping.
- **FAIL**: Implementing partial scoping that breaks baseline processing or introducing uncreated utility dependencies.
* **PASS**: Identifies multi-tenant access boundaries and handles missing or invalid tenant context safely.
* **FAIL**: Blindly executing database operations without checking user identity provenance.
---
### Heavy Penalties
1. **Unscoped Database Queries (Multi-Tenant Security Vulnerability)**:
- *Triggers when*: Any document lookup or update operation in `voice-synthsizer-job-handler`, `voice-cloning-job-handler`, or service wrappers performs database operations without `userId` scoping.
- *Target Dimension*: **Broader Correctness**.
- *Nearest Acceptable Behavior*: All single-record queries enforce `{ _id, userId, deleted: false }` and multi-record operations enforce `{ userId, deleted: false }`.
1. **Unscoped Database Queries (Broader Correctness & Narrow Correctness)**
* **Trigger**: Any document lookup or update operation by ID (`findOne`, `findOneAndUpdate`, `findById`, `update`) on primary or secondary models that omits `userId` from argument 1 (`conditions`).
* **Nearest Acceptable**: All ID-based document lookups and updates enforce `{ _id, userId, deleted: false }` in query conditions.
2. **Missing Utility Module Startup Crash (`MODULE_NOT_FOUND`)**:
- *Triggers when*: The agent adds imports for an uncreated file (e.g., `require('../worker_tenant')`), causing Node.js worker execution to crash instantly.
- *Target Dimension*: **Narrow Correctness**.
- *Nearest Acceptable Behavior*: Any helper utility created by the agent is committed as a valid file in the repository or inline logic is used.
2. **Missing Utility Module Startup Crash (Narrow Correctness)**
* **Trigger**: Importing uncreated utility files (e.g., `const { requireUserId } = require('../worker_tenant')` without creating `worker_tenant.js`), causing `MODULE_NOT_FOUND` runtime crashes.
* **Nearest Acceptable**: All imported utility modules exist and load cleanly.
3. **Unscoped Lookup Security Bypass**:
- *Triggers when*: An unscoped database query is used to "discover" an owner `userId` before performing authorization checks.
- *Target Dimension*: **Broader Correctness**.
- *Nearest Acceptable Behavior*: Trusted `userId` context originates directly from the incoming job message payload.
3. **Async Execution Order Crash (Common Sense & Narrow Correctness)**
* **Trigger**: Grouping dependent queries into `Promise.all` before parent IDs resolve, triggering `ReferenceError: recordingId is not defined` runtime crashes.
* **Nearest Acceptable**: Sequential document lookups resolve parent records before referencing child properties.