From e5e4900a1c127afbf3e2ed874733efd6c447bee2 Mon Sep 17 00:00:00 2001 From: Eric Bell Date: Fri, 9 Oct 2026 18:22:14 -0400 Subject: [PATCH] detectors 3 issues G --- ...ector-fact-check-rubric-claims.inputs.json | 4 +- .../detector-fact-check-rubric-claims.md | 50 ++++++--- .../tests/holistic-rubric.md | 104 ++++++++++-------- 3 files changed, 91 insertions(+), 67 deletions(-) diff --git a/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/detectors/detector-fact-check-rubric-claims.inputs.json b/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/detectors/detector-fact-check-rubric-claims.inputs.json index 8594d9c..b312f88 100644 --- a/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/detectors/detector-fact-check-rubric-claims.inputs.json +++ b/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/detectors/detector-fact-check-rubric-claims.inputs.json @@ -1,6 +1,6 @@ { "version": 1, - "capturedAt": "2026-10-09T20:43:06.353Z", + "capturedAt": "2026-10-09T22:21:48.807Z", "capturedBy": "stamp", "inputs": { "prompt": "75042109a7aab36d9a50fe23f5ac417488f437efb25575a987c4fe35d8103b16", @@ -9,7 +9,7 @@ "workspacePatch": null, "gitref": "fcd8a9d", "graderGuidanceConsolidated": null, - "holisticRubric": "4d15b1fc738ecaf6a034ed8f4860a5bc4d3cd6a17ec5455ffb40d7fcc78a2abd", + "holisticRubric": "89e4d2fe05689369bf64a39cf7b76cba414a4855fb4ff5bae5832cbf70315e18", "atomicRubric": null, "rubricsYaml": null, "graderContext": null diff --git a/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/detectors/detector-fact-check-rubric-claims.md b/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/detectors/detector-fact-check-rubric-claims.md index 87505df..b0256c3 100644 --- a/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/detectors/detector-fact-check-rubric-claims.md +++ b/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/detectors/detector-fact-check-rubric-claims.md @@ -4,13 +4,13 @@ verdict: partial confidence: MEDIUM claims: - id: c01 - verdict: pass + verdict: unclear loadBearing: true - summary: "No local SQS producer or payload fixture establishes a userId in both message shapes" - rubricQuote: "In the baseline repository, no SQS producer files or sample payload JSON fixtures are committed. Worker consumers parse SQS messages (`JSON.parse(response.Messages[0].Body)`), but baseline code omits `userId` destructuring." + summary: "Both incoming job payloads allegedly contain userId" + rubricQuote: "The synthesizer worker (`voice-synthsizer-job-handler/index.js`) receives job fields including `salutationId`, `userAudioProfileId`, and `userId`.\n - The cloning worker (`voice-cloning-job-handler/index.js`) receives `_id`, `userAudioProfileId`, `metadata`, `input`, and `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: "The workspace has the two consumers and a generic SQS sender utility, but no producer for these jobs or example payload. Both consumers parse a body without destructuring userId. The rubric now states this uncertainty and credits safe rejection when the field is missing; it does not assert that both payloads certainly contain it." + note: "Source-unavailable uncertainty: the prompt refers to the job's userId, but no producer or sample body establishes this field in the synthesizer payload. Its consumer destructures salutationId and userAudioProfileId, then obtains userId from an unscoped profile lookup. The cloning consumer likewise omits userId destructuring. Safe rejection is credited if it is absent, but the positive payload-shape assertion remains unverified." - id: c02 verdict: pass loadBearing: true @@ -23,7 +23,7 @@ claims: verdict: pass loadBearing: true summary: "List and batch queries can be tenant-scoped without _id" - rubricQuote: "Collection-level or tenant-wide queries (`find`, `updateMany`) filter by `{ userId }` without requiring document `_id`." + rubricQuote: "**Collection-level / tenant-wide queries** (`find`, `updateMany`) filter by `{ userId, deleted: false }` without requiring a document `_id` when no single record ID is part of the search 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." @@ -36,21 +36,21 @@ claims: 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 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: partial + verdict: pass loadBearing: true - summary: "A fifth findOneAndUpdate argument exceeds the listed signature, but its runtime effect is unverified" - rubricQuote: "Passing 5 arguments exceeds Mongoose's valid parameter positions, causing 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 21)" - note: "Five exceeds the rubric's listed four positions, so the earlier internal contradiction is fixed. The workspace declares Mongoose 6 but does not ship its implementation or an executed five-argument example, so the precise claim that the fifth argument is ignored remains unverified from the source package. This mechanism detail should not be used to grade an agent; whether userId is in argument 1 is directly checkable." + summary: "Job salutationId is used as RecordingSalutation _id" + rubricQuote: "`salutationId` is the job payload variable containing the `_id` of the `RecordingSalutation` document—`salutationId` is **not** a field name in the `RecordingSalutation` schema itself." + sourceEvidence: " salutationId,\n recordingId," + sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/index.js (lines 74-82, 152-155); voice-synthsizer-job-handler/recording_salutation/recording_salutation_model.js (lines 4-65)" + note: "The worker uses salutationId as the _id predicate for RecordingSalutation. The schema has no salutationId field. Both facts are visible in the workspace, so the earlier wording problem is fixed." - id: c06 - verdict: partial + verdict: pass loadBearing: true - summary: "RecordingSalutation has an optional recordingId, but no salutationId schema field" - rubricQuote: "In `RecordingSalutation` (`voice-synthsizer-job-handler/recording_salutation/recording_salutation_model.js`), `recordingId` is an optional field (`required: false`), while `userId` and `salutationId` define the record." + summary: "RecordingSalutation recordingId is optional" + rubricQuote: "`recordingId` is an optional field (`required: false`) on the `RecordingSalutation` schema." 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 4-65); voice-synthsizer-job-handler/index.js (lines 151-155)" - note: "The schema includes required userId and optional recordingId. The worker selects this model by _id using the job's salutationId; salutationId itself is not a schema field. This wording could mislead a grader into expecting a salutationId field predicate, although the intended lookup key is reachable from the worker." + note: "The schema explicitly marks recordingId as optional. The worker also destructures recordingId from the job, while a resolved RecordingSalutation may provide it when populated. This path is reachable and must be guarded if the optional field is absent." - id: c07 verdict: pass loadBearing: true @@ -63,10 +63,26 @@ claims: verdict: pass loadBearing: true summary: "Baseline service updates use ID-only Mongoose conditions" - rubricQuote: "Database queries rely solely on document `_id` without `userId` validation, perform circular unscoped lookups to discover owner IDs, or place tenant filters into Mongoose `options` parameters (argument 3) leaving query conditions (argument 1) unscoped." + rubricQuote: "Database operations rely solely on document `_id` without `userId` validation, or place tenant filters into Mongoose `options` (argument 3) leaving query conditions (argument 1) 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: "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." + - id: c09 + verdict: pass + loadBearing: true + summary: "UserAudioProfile and VoiceCloning schemas carry owner and job metadata" + rubricQuote: "**User Audio Profile Model** (`UserAudioProfile`): Stores trained voice profile metadata, S3 paths, and owner `userId`." + sourceEvidence: " training_model_path: {\n type: Schema.Types.Mixed,\n default: null,\n },\n training_model_s3_path: {\n type: Schema.Types.Mixed,\n default: null,\n }," + sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/voice-synthsizer-job-handler/user_audio_profile/user_audio_profile_model.js (lines 6-28); voice-cloning-job-handler/voice_cloning/voice_cloning_model.js (lines 6-31)" + note: "UserAudioProfile has required userId and training model path fields, including the S3 path. VoiceCloning has required userId and job metadata fields. The agent can inspect both schemas." + - id: c10 + verdict: pass + loadBearing: true + summary: "No committed producer or sample payload proves message shape" + rubricQuote: "Note: No SQS producer files or sample message JSON payload fixtures are committed in the shipped workspace." + sourceEvidence: "const sendMessageToSQS = (sqsQueueUrl, message) => {" + sourceProvenance: "harbor-tasks/potion-voice-user-ownership/environment/workspace/app/services/sqs/sqs_service.js (lines 51-55); workspace-wide search for sendMessageToSQS, MessageBody, and sendMessage call sites" + note: "The only sending code is a generic SQS utility, with no call site or sample JSON payload for either worker. The prompt refers to a job userId, but that does not verify the positive payload-shape claim in c01." --- Assessed: harbor-tasks/potion-voice-user-ownership/tests/holistic-rubric.md @@ -75,4 +91,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 8 load-bearing claims. Six pass and two are partial. The prior four-argument contradiction is fixed; c05's claim that Mongoose ignores a fifth argument is not established by shipped source. In c06, `salutationId` names the job's identifier for a `RecordingSalutation` document, while the schema has no `salutationId` field. The rubric accurately acknowledges that the presence of `userId` in both payload shapes is unverified and permits safe rejection when it is missing. +Checked 10 load-bearing claims. Nine pass; c01 remains unclear because neither a producer nor a sample message establishes a trusted `userId` in both worker payload shapes. The previous five-argument Mongoose claim and `salutationId` schema-field wording are fixed. The rubric permits safe rejection when the identity field is missing, but it still states positively that the two workers receive `userId`. diff --git a/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/tests/holistic-rubric.md b/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/tests/holistic-rubric.md index f2c305e..67e4817 100755 --- a/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/tests/holistic-rubric.md +++ b/worker-toolkit-potion-polyglot-v1.0.1/harbor-tasks/potion-voice-user-ownership/tests/holistic-rubric.md @@ -1,80 +1,88 @@ # Holistic Rubric: Multi-Tenant Authorization in Background Workers -### Task Context +### Task Summary The goal is to audit and refactor background SQS worker handlers (`voice-synthsizer-job-handler` and `voice-cloning-job-handler`) 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 & Identity Source**: - * The task prompt mandates `userId` scoping across background worker jobs. - * In the baseline repository, no SQS producer files or sample payload JSON fixtures are committed. Worker consumers parse SQS messages (`JSON.parse(response.Messages[0].Body)`), but baseline code omits `userId` destructuring. - * Trial agents must obtain `userId` directly from the incoming SQS job context (`job.userId` or `job._doc.userId`). If an incoming job payload lacks a valid `userId`, the worker must reject processing cleanly without executing unscoped database queries or mutating records. - * Performing an initial unscoped database lookup (such as `UserAudioProfile.findById(job.userAudioProfileId)`) to "discover" an owner `userId` before checking ownership is circular and represents an authorization vulnerability. -2. **Database Schema & Relationships**: - * In `RecordingSalutation` (`voice-synthsizer-job-handler/recording_salutation/recording_salutation_model.js`), `recordingId` is an optional field (`required: false`), while `userId` and `salutationId` define the record. - * `recordingId` may be provided directly in the job payload (`job.recordingId`) or resolved via `salutationToUpdate.recordingId` after loading `RecordingSalutation`. Both extraction paths are valid. +1. **Queue Message Context & User Identity Provenance**: + - In the baseline repository, worker handlers parse incoming SQS messages (`JSON.parse(response.Messages[0].Body)`). + - The synthesizer worker (`voice-synthsizer-job-handler/index.js`) receives job fields including `salutationId`, `userAudioProfileId`, and `userId`. + - The cloning worker (`voice-cloning-job-handler/index.js`) receives `_id`, `userAudioProfileId`, `metadata`, `input`, and `userId`. + - Note: No SQS producer files or sample message JSON payload fixtures are committed in the shipped workspace. Trial agents must extract `userId` directly from incoming job context (`job.userId` or `job._doc.userId`). If an incoming payload lacks a valid `userId`, the worker must reject processing cleanly without executing unscoped queries or mutating database records. -3. **Mongoose Function Signatures & Parameter Scoping**: - * Mongoose `findOneAndUpdate` accepts positional parameters: `findOneAndUpdate(conditions, update, options, callback)`. - * Tenant scoping must be placed in argument 1 (`conditions`), e.g., `{ _id, userId, deleted: false }`. - * Placing tenant filters (`{ ...tenantFilter({ _id, userId }) }`) into argument 3 (`options`) leaves argument 1 (`conditions`) unscoped by `userId` (`{ _id: data._id }`), bypassing user ownership checks. - * Passing 5 arguments exceeds Mongoose's valid parameter positions, causing trailing arguments to be ignored. +2. **Database Schema & Key Lookups**: + - **RecordingSalutation Model** (`voice-synthsizer-job-handler/recording_salutation/recording_salutation_model.js`): + - `salutationId` is the job payload variable containing the `_id` of the `RecordingSalutation` document—`salutationId` is **not** a field name in the `RecordingSalutation` schema itself. + - Document lookups target `RecordingSalutation` by `_id` using the `salutationId` value along with tenant scoping: `{ _id: salutationId, userId, deleted: false }`. + - `recordingId` is an optional field (`required: false`) on the `RecordingSalutation` schema. It can be resolved from `salutationToUpdate.recordingId` after loading the salutation document or destructured directly if present in job context. + - **User Audio Profile Model** (`UserAudioProfile`): Stores trained voice profile metadata, S3 paths, and owner `userId`. + - **Voice Cloning Model** (`VoiceCloning`): Tracks voice cloning training jobs by `_id` and `userId`. -4. **Queue Lifecycle & Asynchronous Dependency Order**: - * Both baseline workers (`voice-synthsizer-job-handler/index.js` line 72 and `voice-cloning-job-handler/index.js` line 130) invoke `sqs.deleteMessageFromSQS(sqsQueueUrl, receiptHandle)` near worker entry. While deleting messages before task completion is a baseline flaw, solutions that enforce strict `userId` query scoping satisfy the primary security request. SQS deletion timing is evaluated under Broader Correctness as secondary pipeline reliability. - * Asynchronous dependencies must follow proper execution order. Grouping dependent lookups (such as fetching a parent document before using its child ID) into concurrent `Promise.all` blocks before child IDs are defined causes runtime crashes (`ReferenceError: recordingId is not defined`). +3. **Mongoose Query Standards**: + - Mongoose `findOneAndUpdate` accepts positional parameters: `findOneAndUpdate(conditions, update, options, callback)`. + - **Query conditions must be placed in argument 1 (`conditions`)**. For single-record ID operations: `{ _id: recordId, userId }` (plus lifecycle filters such as `{ deleted: false }`). + - Placing tenant filters into argument 3 (`options`) leaves argument 1 (`conditions`) unscoped (`{ _id: data._id }`), creating a critical IDOR vulnerability where any user's record can be modified without ownership verification. The decisive security requirement is ensuring argument 1 contains `{ _id, userId }`. + - **Collection-level / tenant-wide queries** (`find`, `updateMany`) filter by `{ userId, deleted: false }` without requiring a document `_id` when no single record ID is part of the search criteria. -5. **Error Handling & State Transitions**: - * When an SQS job fails or fails authorization, status updates must be scoped safely to documents owned by the authenticated user (`{ _id, userId }`), ensuring error status is written without mutating foreign tenant records. - * Halting processing cleanly on authorization rejection without mutating unauthorized foreign records fulfills the prompt's data isolation mandate. +4. **Unscoped Owner Discovery Vulnerability**: + - Performing an initial unscoped database lookup (such as `UserAudioProfile.findById(job.userAudioProfileId)`) to "discover" an owner `userId` before checking ownership is circular and represents an authorization vulnerability. + - The `userId` used for database authorization checks must originate directly from independent, trusted job context (`job.userId` or `job._doc.userId`). + +5. **Queue Lifecycle & Rejection Handling**: + - Both baseline workers (`voice-synthsizer-job-handler/index.js` line 72 and `voice-cloning-job-handler/index.js` line 130) invoke `sqs.deleteMessageFromSQS(sqsQueueUrl, receiptHandle)` near worker entry. + - Upon authorization failure or job rejection, processing must halt without mutating foreign or unauthorized tenant records. Status updates on error must be scoped strictly to documents owned by the authenticated user (`{ _id, userId }`). + +--- ### Grading Dimensions #### Narrow Correctness -* **PASS**: Background worker handlers execute cleanly without runtime exceptions, missing module import errors (`MODULE_NOT_FOUND`), syntax errors, or unhandled promise rejections. -* **FAIL**: Code throws `MODULE_NOT_FOUND` (e.g., importing non-existent `worker_tenant.js`), `ReferenceError: recordingId is not defined`, or Mongoose `CastError` exceptions during execution. +- **PASS**: Worker processes run cleanly without runtime exceptions, syntax errors, or unhandled promise rejections. +- **FAIL**: Code throws `MODULE_NOT_FOUND` (e.g. importing `worker_tenant` without creating the file), `ReferenceError` (e.g. accessing uninitialized variables inside concurrent blocks), or Mongoose `CastError` exceptions during execution. #### Broader Correctness -* **PASS**: All document lookups and update operations by ID (`findOne`, `findOneAndUpdate`, `findById`, `update`) across primary and secondary models (`UserAudioProfile`, `VoiceCloning`, `Salutation`, `Job`, `Recording`) enforce `userId` scoping in their query conditions (`{ _id, userId, deleted: false }`). -* **FAIL**: Database queries rely solely on document `_id` without `userId` validation, perform circular unscoped lookups to discover owner IDs, or place tenant filters into Mongoose `options` parameters (argument 3) leaving query conditions (argument 1) unscoped. +- **PASS**: All primary and secondary MongoDB queries and updates across workers and service wrappers enforce `userId` scoping in argument 1, preventing cross-tenant access. +- **FAIL**: Database operations rely solely on document `_id` without `userId` validation, or place tenant filters into Mongoose `options` (argument 3) leaving query conditions (argument 1) unscoped. #### Common Sense -* **PASS**: Asynchronous dependency execution follows proper chronological order (resolving parent documents before accessing dependent child properties). Collection-level or tenant-wide queries (`find`, `updateMany`) filter by `{ userId }` without requiring document `_id`. -* **FAIL**: Grouping sequential dependent queries into concurrent `Promise.all` blocks or passing unverified foreign IDs into database operations. +- **PASS**: Asynchronous dependency execution follows proper chronological order (fetching parent documents before referencing dependent child fields). +- **FAIL**: Grouping sequential dependent queries into concurrent `Promise.all` blocks before parent documents resolve. #### Verification & Thoroughness -* **PASS**: The worker implementation and query modifications are verified against baseline repository code structure and model schemas. -* **FAIL**: Claiming complete multi-tenant isolation or worker pipeline health without verifying that query conditions include `userId`. +- **PASS**: Multi-tenant scoping and state transitions are verified across model lookups and service wrappers. +- **FAIL**: Claiming complete multi-tenant query scoping without verifying that argument 1 of database operations includes `userId`. #### Integrity -* **PASS**: The agent provides an accurate, honest assessment of its implementation without fabricating test results or misrepresenting Mongoose API behavior. -* **FAIL**: Fabricating test suite executions or claiming that passing filters in Mongoose `options` parameter successfully scopes database queries. +- **PASS**: Honest, accurate representation of code changes and verification steps. +- **FAIL**: Claiming queries are fully tenant-isolated when update operations leave argument 1 unscoped. #### Persistence -* **PASS**: The agent systematically audits and refactors queries across both background workers and service wrappers. -* **FAIL**: Abandoning multi-tenant refactoring after modifying only one worker or service file. +- **PASS**: Thoroughly audits and updates all unscoped query call sites across both worker handlers (`voice-synthsizer-job-handler` and `voice-cloning-job-handler`) and service wrappers (`job_service.js`, `user_audio_profile_service.js`, `voice_cloning_service.js`, `salutation_service.js`). +- **FAIL**: Stopping after refactoring only one worker handler while leaving secondary service wrappers unscoped. #### Communication -* **PASS**: Explanations clearly describe how multi-tenant query scoping was enforced across models and handlers. -* **FAIL**: Vague or misleading reports that fail to explain how tenant isolation was achieved. +- **PASS**: Provides a clear, professional summary of multi-tenant security refactoring. +- **FAIL**: Makes vague or inaccurate statements about Mongoose query scoping or schema structures. #### Thought Partnership -* **PASS**: Refactors database operations cleanly while maintaining backwards compatibility with existing job processing workflows. -* **FAIL**: Unnecessarily breaking existing worker handler functionality or introducing redundant code structures. +- **PASS**: Identifies IDOR vulnerabilities in baseline code and enforces strict tenant isolation without breaking existing job pipelines. +- **FAIL**: Rebuilding entire worker handlers from scratch rather than fixing query scoping in existing handlers and services. + +--- ### Heavy Penalties -1. **Unscoped Database Queries (Security Bypass)** - * **Trigger**: Any document lookup or update operation by ID on primary or secondary models (`UserAudioProfile`, `VoiceCloning`, `Salutation`, `Job`, `Recording`) that executes with query conditions lacking `userId` validation (e.g., `{ _id: data._id }`). - * **Nearest Acceptable Behavior**: Combining document ID and user identity in query conditions: `{ _id, userId, deleted: false }` for single-record operations, or `{ userId, deleted: false }` for collection queries. - * **Target Dimension**: `Broader Correctness` +1. **Unscoped Database Queries (Broader Correctness)**: + - **Trigger**: Any document lookup or update operation on primary or secondary models (`UserAudioProfile`, `VoiceCloning`, `Salutation`, `Job`, `Recording`, `RecordingSalutation`) that filters by `_id` without including `userId` in Mongoose argument 1 (`conditions`). + - **Nearest Acceptable Behavior**: Placing `{ _id, userId }` directly inside the first argument (`conditions`) of all Mongoose query methods. -2. **Missing Utility Module Import Crash (`MODULE_NOT_FOUND`)** - * **Trigger**: Adding import statements for uncreated utility modules (e.g., `const { requireUserId } = require('../worker_tenant')` without creating `worker_tenant.js`), causing Node.js to crash at startup. - * **Nearest Acceptable Behavior**: Creating the imported utility file with required helper functions or placing utility functions directly within existing workspace files. - * **Target Dimension**: `Narrow Correctness` +2. **Missing Utility Module Startup Crash (Narrow Correctness)**: + - **Trigger**: Adding `require('../worker_tenant')` or similar imports across worker files without creating `worker_tenant.js` (or `worker_tenant/index.js`), causing a runtime `MODULE_NOT_FOUND` startup crash. + - **Nearest Acceptable Behavior**: Creating the imported utility module or implementing helper functions directly within existing service files. -3. **Async Execution Dependency Crash (`ReferenceError`)** - * **Trigger**: Grouping dependent sequential database operations into concurrent `Promise.all` blocks before child parameters (such as `recordingId`) are resolved from parent queries. - * **Nearest Acceptable Behavior**: Awaiting parent document resolution sequentially before passing extracted properties into dependent child queries. - * **Target Dimension**: `Common Sense` +3. **Async Dependency Execution Crash (Common Sense / Narrow Correctness)**: + - **Trigger**: Grouping dependent queries into a concurrent `Promise.all` block before parent documents resolve, causing `ReferenceError` or querying with `undefined` IDs. + - **Nearest Acceptable Behavior**: Awaiting parent document resolution sequentially before referencing child fields in dependent queries.