@moduna/qcp 0.1.3-alpha.2 → 0.1.3-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +67 -11
  2. package/dist/index.js +34584 -33797
  3. package/dist/qcp.js +34584 -33797
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -32,6 +32,7 @@ Safety:
32
32
  ✓ SELECT-only query
33
33
  ✓ LIMIT applied
34
34
  ✓ Query validated
35
+ ✓ Privacy checks active
35
36
 
36
37
  Results:
37
38
  ┌──────────────────────┬───────────────┐
@@ -53,12 +54,12 @@ Insight:
53
54
 
54
55
  ## Why qcp?
55
56
 
56
- Most data questions never get answered because they require SQL knowledge or data team availability. qcp bridges that gap — letting any developer or analyst query their PostgreSQL database using plain English, with full transparency into the generated SQL and a safety model that makes it impossible to accidentally modify data.
57
+ Most data questions never get answered because they require SQL knowledge or data team availability. qcp bridges that gap — letting any developer or analyst query their PostgreSQL database using plain English, with full transparency into the generated SQL and deterministic guardrails around database access.
57
58
 
58
59
  **Three principles:**
59
- 1. **Safety** — Read-only enforcement at the AST level. No string matching. Impossible to run INSERT, UPDATE, DELETE, or any write operation.
60
- 2. **Trust** — Every generated SQL query is shown before execution. You always know what ran against your database.
61
- 3. **Privacy** — No row data, schema metadata, SQL queries, or credentials are ever sent to telemetry. Your data stays yours.
60
+ 1. **Safety** — Read-only enforcement at the AST level plus read-only database transactions. `INSERT`, `UPDATE`, `DELETE`, DDL, and privilege changes are rejected before execution.
61
+ 2. **Trust** — Every generated SQL query is shown before execution. You always know what qcp intends to run against your database.
62
+ 3. **Privacy** — Telemetry never includes SQL, schema metadata, row data, connection URLs, or credentials. Database tool outputs are scrubbed before they are returned to an agent context.
62
63
 
63
64
  ---
64
65
 
@@ -168,6 +169,8 @@ qcp ask "question" --debug # Show raw LLM output and EXPLAIN plan
168
169
  qcp ask "question" --yes # Skip approval prompts
169
170
  ```
170
171
 
172
+ Use `--yes` only in trusted local workflows. It skips human approval prompts, but it does not disable SQL validation, read-only transactions, tenant isolation, or result scrubbing.
173
+
171
174
  ---
172
175
 
173
176
  ## Supported Providers
@@ -181,13 +184,13 @@ qcp ask "question" --yes # Skip approval prompts
181
184
 
182
185
  ---
183
186
 
184
- ## Safety Model
187
+ ## Safety and Security Model
185
188
 
186
- qcp enforces read-only access at **two independent layers**:
189
+ qcp treats LLM output as untrusted. The model can suggest SQL, but deterministic code decides whether that SQL is allowed to run.
187
190
 
188
- ### 1. SQL Safety (AST-based)
191
+ ### 1. SQL Safety (AST-Based)
189
192
 
190
- Every generated SQL is parsed into an Abstract Syntax Tree and validated before execution. This is **not string matching** — it's a structural parse of the SQL.
193
+ Every generated SQL statement is parsed into an Abstract Syntax Tree and validated before execution. The allowlist is structural, not prompt-based.
191
194
 
192
195
  **Allowed:** `SELECT`, `WITH` (CTEs), `EXPLAIN`
193
196
 
@@ -205,11 +208,47 @@ Safety:
205
208
  ✗ Query rejected — does not meet safety requirements.
206
209
  ```
207
210
 
211
+ `WITH` queries are also inspected internally, so a data-changing CTE such as `WITH deleted AS (DELETE ...) SELECT ...` is rejected.
212
+
208
213
  ### 2. Transaction-level enforcement
209
214
 
210
- All queries run inside a `BEGIN READ ONLY` transaction. Even if the safety parser were somehow bypassed, the database itself would reject any write operation.
215
+ All database reads run inside a `BEGIN READ ONLY` transaction. Even if application-level validation were bypassed, PostgreSQL should reject write operations inside the transaction.
216
+
217
+ ### 3. Mastra Tool Containment
218
+
219
+ The Prisma/Mastra database tools route execution through one security pipeline:
220
+
221
+ 1. Validate read-only SQL.
222
+ 2. Require trusted Mastra `requestContext.tenantId` and `requestContext.userId`.
223
+ 3. Inject tenant/user predicates into supported `SELECT`/`WITH` queries.
224
+ 4. Execute only the rewritten SQL.
225
+ 5. Scrub sensitive output before it reaches the LLM/tool transcript.
226
+ 6. Return sanitized errors without raw stack traces or schema dumps.
227
+
228
+ Direct `qcp ask` execution does not invent a tenant boundary. If the Prisma tool path has no trusted Mastra request context, query execution fails closed instead of relying on the LLM to add tenant filters.
229
+
230
+ ### 4. Tenant Isolation
231
+
232
+ For Mastra database tool execution, qcp deterministically scopes queries using schema metadata:
233
+
234
+ - `tenantId` maps to `organization_id`, `tenant_id`, `org_id`, `workspace_id`, or `account_id`.
235
+ - `userId` maps to `user_id` or `owner_id`.
236
+ - Tables without a supported scope column are rejected.
237
+ - Unknown tables, ambiguous unqualified tables, unsafe outer joins, table functions, lateral queries, and unsupported nested-query shapes are rejected.
238
+
239
+ Tenant predicates are injected by AST rewriting and serialization, not by string concatenation and not by LLM instructions.
240
+
241
+ ### 5. Privacy Scrubbing
211
242
 
212
- ### 3. Human-in-the-loop approval
243
+ Database tool outputs are recursively scrubbed before they are returned to an agent/model-facing context. qcp masks common sensitive values including:
244
+
245
+ - Email addresses
246
+ - Phone numbers
247
+ - SSNs
248
+ - Bearer tokens and JWT-like tokens
249
+ - API keys, secrets, passwords, and long secret-like strings
250
+
251
+ ### 6. Human-in-the-loop approval
213
252
 
214
253
  When `safeMode` is enabled (default), qcp prompts for confirmation before executing queries that:
215
254
  - Access potentially sensitive tables (`users`, `customers`, `payments`, etc.)
@@ -224,10 +263,23 @@ When `safeMode` is enabled (default), qcp prompts for confirmation before execut
224
263
  ? Execute this query? (y/N)
225
264
  ```
226
265
 
266
+ Mastra execution tools also use tool-level approval hooks for sensitive or high-cost reads.
267
+
268
+ ### 7. Error Hygiene
269
+
270
+ Raw database errors are not returned to the agent as-is. qcp suppresses driver stack traces, raw SQL, and schema-revealing database messages in model-facing tool responses.
271
+
272
+ For more detail, see [SECURITY.md](SECURITY.md).
273
+
227
274
  ---
228
275
 
229
276
  ## Privacy Model
230
277
 
278
+ qcp has two different data flows:
279
+
280
+ 1. **LLM provider flow** — To generate SQL and summaries, qcp sends your question and local schema context to your configured provider unless you use a local provider such as Ollama. Query results may be sent to the configured provider for summarization.
281
+ 2. **Telemetry flow** — Anonymous product telemetry is separate and intentionally excludes database content.
282
+
231
283
  ### What qcp sends to telemetry (PostHog)
232
284
 
233
285
  - qcp version
@@ -250,7 +302,11 @@ qcp telemetry off
250
302
 
251
303
  ### Schema scanning
252
304
 
253
- `qcp schema scan` reads **structure only** — table names, column names, types, and relationships. It never reads row data. The schema is stored locally in `.qcp/schema.json` and never sent to any external service.
305
+ `qcp schema scan` reads **structure only** — table names, column names, types, and relationships. It never reads row data. The schema is stored locally in `.qcp/schema.json`. When you ask questions with a hosted LLM provider, qcp may send relevant schema context to that configured provider so it can generate SQL.
306
+
307
+ ### Logs and support bundles
308
+
309
+ qcp logging and support tooling are designed to avoid credentials, SQL text, schema content, and row data. If you share logs or support bundles publicly, review them first as you would with any developer diagnostic artifact.
254
310
 
255
311
  ---
256
312