@lcv-ideas-software/cross-review 4.2.0 → 4.2.1

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 (38) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/NOTICE +1 -1
  3. package/README.md +104 -82
  4. package/SECURITY.md +18 -37
  5. package/dist/scripts/runtime-smoke.js.map +1 -1
  6. package/dist/scripts/smoke.js +23 -23
  7. package/dist/scripts/smoke.js.map +1 -1
  8. package/dist/src/core/caller-tokens.js +3 -2
  9. package/dist/src/core/caller-tokens.js.map +1 -1
  10. package/dist/src/core/config.d.ts +3 -3
  11. package/dist/src/core/config.js +6 -7
  12. package/dist/src/core/config.js.map +1 -1
  13. package/dist/src/core/file-config.d.ts +1 -1
  14. package/dist/src/core/orchestrator.d.ts +45 -45
  15. package/dist/src/core/orchestrator.js +12 -2
  16. package/dist/src/core/orchestrator.js.map +1 -1
  17. package/dist/src/core/relator-lottery.js +5 -1
  18. package/dist/src/core/relator-lottery.js.map +1 -1
  19. package/dist/src/core/session-store.d.ts +9 -9
  20. package/dist/src/core/session-store.js +2 -2
  21. package/dist/src/core/session-store.js.map +1 -1
  22. package/dist/src/core/types.d.ts +164 -164
  23. package/dist/src/dashboard/server.js +12 -8
  24. package/dist/src/dashboard/server.js.map +1 -1
  25. package/dist/src/mcp/server.d.ts +13 -13
  26. package/dist/src/mcp/server.js.map +1 -1
  27. package/dist/src/peers/base.d.ts +6 -6
  28. package/dist/src/peers/errors.js +11 -9
  29. package/dist/src/peers/errors.js.map +1 -1
  30. package/dist/src/peers/gemini.js +2 -2
  31. package/dist/src/peers/gemini.js.map +1 -1
  32. package/dist/src/peers/model-selection.js +1 -1
  33. package/dist/src/peers/model-selection.js.map +1 -1
  34. package/dist/src/peers/perplexity.js +5 -2
  35. package/dist/src/peers/perplexity.js.map +1 -1
  36. package/dist/src/peers/text.d.ts +3 -3
  37. package/docs/evidence-preflight.md +1 -1
  38. package/package.json +7 -7
package/SECURITY.md CHANGED
@@ -1,52 +1,33 @@
1
1
  # Security Policy
2
2
 
3
- ## Reporting a Vulnerability
3
+ ## Supported status
4
4
 
5
- If you discover a security vulnerability in this repository, please do **not** open a public issue. Instead, please report it privately to the repository maintainer.
5
+ Latest supported release: v04.02.00 for npm package 4.2.0. The current main branch is also supported for security fixes until the next release is published.
6
6
 
7
- **Contact:** alert@lcvmail.com
7
+ ## Reporting a vulnerability
8
8
 
9
- Please include:
10
-
11
- - Description of the vulnerability
12
- - Steps to reproduce (if applicable)
13
- - Potential impact
14
- - Suggested fix (if you have one)
9
+ Please do not open a public issue for suspected vulnerabilities, credential leaks, private data exposure, authentication bypasses, payment-flow issues, supply-chain issues, or deployment misconfiguration.
15
10
 
16
- We will acknowledge your report within 24 hours and work to resolve the issue promptly.
11
+ Report privately by email:
17
12
 
18
- ## Supported Versions
13
+ - lcv@lcv.dev
19
14
 
20
- | Version | Supported |
21
- | ----------------- | ------------------------ |
22
- | Latest | ✅ |
23
- | Previous releases | ⚠️ Security updates only |
15
+ If GitHub private vulnerability reporting is enabled for this repository, that channel is also acceptable.
24
16
 
25
- ## Security Measures
26
-
27
- This repository employs:
17
+ Please include:
28
18
 
29
- - **Code Scanning (CodeQL)**: Automated static analysis on all commits
30
- - **Dependency Scanning (Dependabot)**: Automated dependency vulnerability detection
31
- - **Secret Scanning**: Detection and remediation of exposed secrets
32
- - **Branch Protection**: Required status checks before merge to main
19
+ - affected repository, component, route, package, workflow, or public surface;
20
+ - affected version, release tag, commit SHA, or deployment URL when known;
21
+ - impact and exploitability;
22
+ - reproduction steps or a safe proof of concept, if available;
23
+ - whether any credential, personal data, payment data, private editorial material, or operational secret may be involved.
33
24
 
34
- ## Threat Model
25
+ ## Scope
35
26
 
36
- `cross-review` is designed for a **single-user trusted host**. Inputs from operator and peers are not adversarial; the orchestrator holds API credentials in process memory and relies on local-only network bindings for the dashboard. Outside this model, the following caveats apply:
27
+ In scope: application code, Workers/Pages functions, package publication, GitHub Actions, dependency and supply-chain configuration, repository publication boundaries, security documentation, and public service configuration documented in this repository.
37
28
 
38
- - **Multi-host concurrency.** Running two MCP host instances of `cross-review` against the same `CROSS_REVIEW_DATA_DIR` is **not supported**. The per-session lock has TTL + PID-liveness fallbacks that close the common cases but leave a narrow TOCTOU window when two hosts contend for the same session. If you need multi-host operation, point each instance at a distinct `CROSS_REVIEW_DATA_DIR` (introduced in v2.0; tilde expansion since v2.4.0) or share one host across all clients.
39
- - **API keys in memory.** `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, `DEEPSEEK_API_KEY` are loaded into `AppConfig.api_keys` at boot. The persistence layer redacts secrets via [`redact()`](./src/security/redact.ts) before any meta.json/event log write, but the in-memory object is not opaque — do not log `config` directly. Stack traces from SDK errors are passed through `safeErrorMessage()` which redacts known key shapes.
40
- - **Stub adapters.** `CROSS_REVIEW_STUB=1` alone is **rejected fail-fast** since v2.4.0 — boot throws an explicit error referencing the missing confirmation flag, rather than silently demoting to real adapters. To deliberately activate stubs, set BOTH `CROSS_REVIEW_STUB=1` AND one of `NODE_ENV=test` OR `CROSS_REVIEW_STUB_CONFIRMED=1`. The double-confirmation prevents a stray dotenv variable from invalidating a cross-review used as a pre-commit gate.
41
- - **Dashboard HTTP.** The dashboard binds only to `127.0.0.1`. There is no authentication or rate-limit; same-machine processes can read all session metadata, costs and report markdown. Do not expose the dashboard port over a network without an authenticating reverse proxy.
42
- - **Untrusted callers.** The MCP `tools/list` schemas enforce per-field caps (`maxLength`, `pattern`) since v2.4.0 to defend against memory-exhaustion attempts via oversized `task`/`draft`/`prompt`. The trust boundary still assumes a cooperative caller — do not expose the stdio transport over a network socket without an authenticating proxy.
43
- - **Untrusted peers.** Peer streaming responses are capped at 16 MiB per call (`STREAM_TEXT_MAX_BYTES` since v2.4.0). The structured `<cross_review_status>` payload is rejected as malformed when it exceeds 64 KiB before `JSON.parse` runs.
44
- - **MCP schema transforms.** `SessionIdSchema` lowercases its input via a zod `.transform()`. JSON Schema does not have a native equivalent for transforms, so the JSON Schema published by the MCP SDK reflects only the regex validation, not the lowercasing. External clients see "uppercase UUIDv4 accepted" in the schema and the server still accepts it — the lowercasing happens server-side after parsing. The on-disk session_id and any value returned through MCP responses are always lowercase.
45
- - **Provider env-var precedence.** The DeepSeek adapter constructs the OpenAI SDK with `baseURL: "https://api.deepseek.com"`. The OpenAI SDK can also honor `OPENAI_BASE_URL` from the environment; the constructor argument takes precedence in current SDK versions, but operators should avoid setting `OPENAI_BASE_URL` globally to prevent any future SDK regression from redirecting DeepSeek traffic.
29
+ Out of scope: social engineering, physical attacks, denial-of-service testing without prior written authorization, spam, automated noisy scanning, and reports that rely only on outdated browser or dependency versions without a concrete vulnerable path in this repository.
46
30
 
47
- ## Best Practices
31
+ ## Coordinated disclosure
48
32
 
49
- - Keep dependencies up-to-date
50
- - Use strong authentication (SSH keys, personal access tokens)
51
- - Review pull requests carefully before merge
52
- - Report any suspicious activity immediately
33
+ LCV Ideas & Software will triage reports privately, request clarification when needed, and coordinate remediation before public disclosure. Public disclosure should wait until a fix or mitigation is available, unless there is an immediate user-safety reason to do otherwise.
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-smoke.js","sourceRoot":"","sources":["../../scripts/runtime-smoke.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime-smoke.js","sourceRoot":"","sources":["../../scripts/runtime-smoke.ts"],"names":[],"mappings":"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"}
@@ -2073,7 +2073,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2073
2073
  assert.equal(judgeResult.judged_count, 1);
2074
2074
  assert.equal(judgeResult.promoted.length, 1);
2075
2075
  assert.equal(judgeResult.skipped.length, 0);
2076
- assert.equal(judgeResult.promoted[0].item_id, seededItem.id);
2076
+ assert.equal(judgeResult.promoted[0]?.item_id, seededItem.id);
2077
2077
  // Verify durable promotion.
2078
2078
  const after = judgeOrch.store.read(sessionId);
2079
2079
  const promoted = after.evidence_checklist?.find((entry) => entry.id === seededItem.id);
@@ -2127,8 +2127,8 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2127
2127
  });
2128
2128
  assert.equal(inferredResult.promoted.length, 0);
2129
2129
  assert.equal(inferredResult.skipped.length, 1);
2130
- assert.equal(inferredResult.skipped[0].reason, "satisfied_but_unverified");
2131
- assert.equal(inferredResult.skipped[0].confidence, "inferred");
2130
+ assert.equal(inferredResult.skipped[0]?.reason, "satisfied_but_unverified");
2131
+ assert.equal(inferredResult.skipped[0]?.confidence, "inferred");
2132
2132
  const afterInferred = skipOrch.store.read(sessionId);
2133
2133
  assert.equal(afterInferred.evidence_checklist?.find((entry) => entry.id === seedItemId)?.status ?? "open", "open", "inferred judgment must NOT promote");
2134
2134
  // Pass 2: unknown — must skip with reason not_satisfied (stub maps unknown to satisfied=false).
@@ -2139,7 +2139,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2139
2139
  });
2140
2140
  assert.equal(unknownResult.promoted.length, 0);
2141
2141
  assert.equal(unknownResult.skipped.length, 1);
2142
- assert.equal(unknownResult.skipped[0].confidence, "unknown");
2142
+ assert.equal(unknownResult.skipped[0]?.confidence, "unknown");
2143
2143
  const afterUnknown = skipOrch.store.read(sessionId);
2144
2144
  assert.equal(afterUnknown.evidence_checklist?.find((entry) => entry.id === seedItemId)?.status ?? "open", "open", "unknown judgment must NOT promote");
2145
2145
  // No address_method set on either pass.
@@ -2247,7 +2247,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2247
2247
  // Only the open candidate is judged; queue capped at 1.
2248
2248
  assert.equal(result.judged_count, 1, "only open items are queued");
2249
2249
  assert.equal(result.promoted.length, 1);
2250
- assert.equal(result.promoted[0].item_id, "1000000000000001");
2250
+ assert.equal(result.promoted[0]?.item_id, "1000000000000001");
2251
2251
  // Verify all terminal items + the already-addressed item are unchanged.
2252
2252
  const after = tpOrch.store.read(sessionId);
2253
2253
  assert.equal(after.evidence_checklist?.find((entry) => entry.id === "1000000000000002")?.status, "satisfied", "satisfied terminal must remain satisfied");
@@ -2303,8 +2303,8 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2303
2303
  });
2304
2304
  assert.equal(result.promoted.length, 0, "malformed response must not promote");
2305
2305
  assert.equal(result.skipped.length, 1, "malformed response must produce 1 skip");
2306
- assert.equal(result.skipped[0].reason, "judge_failed", `expected reason=judge_failed, got ${result.skipped[0].reason}`);
2307
- assert.ok((result.skipped[0].message ?? "").includes("judge_response_missing_json_object"), "skipped.message must include the parser warning");
2306
+ assert.equal(result.skipped[0]?.reason, "judge_failed", `expected reason=judge_failed, got ${result.skipped[0]?.reason}`);
2307
+ assert.ok((result.skipped[0]?.message ?? "").includes("judge_response_missing_json_object"), "skipped.message must include the parser warning");
2308
2308
  // Item stays open on disk.
2309
2309
  const after = rmOrch.store.read(sessionId);
2310
2310
  assert.equal(after.evidence_checklist?.find((entry) => entry.id === seedItemId)?.status ?? "open", "open", "malformed judge response must leave item open");
@@ -2474,10 +2474,10 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2474
2474
  assert.equal(result.mode, "shadow");
2475
2475
  assert.equal(result.promoted.length, 0, "shadow mode must NOT populate promoted[]");
2476
2476
  assert.equal(result.shadow_decisions.length, 1, "shadow mode must populate shadow_decisions[]");
2477
- assert.equal(result.shadow_decisions[0].item_id, seedItemId);
2478
- assert.equal(result.shadow_decisions[0].would_promote, true);
2479
- assert.equal(result.shadow_decisions[0].satisfied, true);
2480
- assert.equal(result.shadow_decisions[0].confidence, "verified");
2477
+ assert.equal(result.shadow_decisions[0]?.item_id, seedItemId);
2478
+ assert.equal(result.shadow_decisions[0]?.would_promote, true);
2479
+ assert.equal(result.shadow_decisions[0]?.satisfied, true);
2480
+ assert.equal(result.shadow_decisions[0]?.confidence, "verified");
2481
2481
  // No mutation on disk.
2482
2482
  const after = orch.store.read(sessionId);
2483
2483
  const persisted = after.evidence_checklist?.find((entry) => entry.id === seedItemId);
@@ -2545,7 +2545,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2545
2545
  const tolerance = expected * 0.15; // ±60
2546
2546
  for (const peer of ["codex", "gemini", "deepseek", "grok", "perplexity"]) {
2547
2547
  const c = counts[peer];
2548
- assert.ok(Math.abs(c - expected) <= tolerance, `peer=${peer} count=${c} not within ±15% of ${expected} (range ${expected - tolerance}-${expected + tolerance}). Possible RNG bias.`);
2548
+ assert.ok(Math.abs((c ?? 0) - expected) <= tolerance, `peer=${peer} count=${c} not within ±15% of ${expected} (range ${expected - tolerance}-${expected + tolerance}). Possible RNG bias.`);
2549
2549
  }
2550
2550
  console.log("[smoke] relator_lottery_uniform_distribution_test: PASS");
2551
2551
  }
@@ -2605,7 +2605,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2605
2605
  });
2606
2606
  const relatorEvents = events.filter((e) => e.type === "session.relator_assigned");
2607
2607
  assert.equal(relatorEvents.length, 1, `expected 1 session.relator_assigned event, got ${relatorEvents.length}`);
2608
- const data = relatorEvents[0].data ?? {};
2608
+ const data = relatorEvents[0]?.data ?? {};
2609
2609
  assert.equal(data.caller, "claude");
2610
2610
  assert.ok(Array.isArray(data.candidate_pool));
2611
2611
  // Test passes peers=[codex,gemini,deepseek] explicitly; caller=claude
@@ -2692,7 +2692,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2692
2692
  });
2693
2693
  const relatorEvents = events.filter((e) => e.type === "session.relator_assigned");
2694
2694
  assert.equal(relatorEvents.length, 1);
2695
- const data = relatorEvents[0].data ?? {};
2695
+ const data = relatorEvents[0]?.data ?? {};
2696
2696
  const pool = data.candidate_pool;
2697
2697
  assert.ok(!pool.includes("claude"), "auto-recusal: pool não pode conter claude");
2698
2698
  assert.equal(pool.length, 2, `pool deve ter 2 peers (codex+gemini), got ${pool.length}`);
@@ -2931,7 +2931,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2931
2931
  });
2932
2932
  const driftEvents = events.filter((e) => e.type === "session.lead_drift_detected");
2933
2933
  assert.ok(driftEvents.length >= 1, `at least one session.lead_drift_detected event must fire (got ${driftEvents.length})`);
2934
- assert.equal(driftEvents[0].data?.lead_peer, "claude", "drift event must record lead_peer=claude");
2934
+ assert.equal(driftEvents[0]?.data?.lead_peer, "claude", "drift event must record lead_peer=claude");
2935
2935
  assert.equal(result.session.outcome, "aborted");
2936
2936
  assert.equal(result.session.outcome_reason, "lead_meta_review_drift");
2937
2937
  console.log("[smoke] lead_drift_detected_test: PASS");
@@ -2968,7 +2968,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
2968
2968
  });
2969
2969
  const driftEvents = events.filter((e) => e.type === "session.lead_drift_detected");
2970
2970
  assert.ok(driftEvents.length >= 1, `JSON-shape drift must be detected (got ${driftEvents.length} events)`);
2971
- const firstChars = driftEvents[0].data?.first_chars;
2971
+ const firstChars = driftEvents[0]?.data?.first_chars;
2972
2972
  assert.ok(firstChars?.startsWith('{"status":"NEEDS_EVIDENCE"'), `first_chars must show JSON shape (got ${firstChars?.slice(0, 40)})`);
2973
2973
  assert.equal(result.session.outcome, "aborted");
2974
2974
  assert.equal(result.session.outcome_reason, "lead_meta_review_drift");
@@ -3006,7 +3006,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
3006
3006
  });
3007
3007
  const driftEvents = events.filter((e) => e.type === "session.lead_drift_detected");
3008
3008
  assert.ok(driftEvents.length >= 1, `markdown-fenced JSON drift must be detected (got ${driftEvents.length} events)`);
3009
- const firstChars = driftEvents[0].data?.first_chars;
3009
+ const firstChars = driftEvents[0]?.data?.first_chars;
3010
3010
  assert.ok(firstChars?.startsWith("```json"), `first_chars must show markdown fence (got ${firstChars?.slice(0, 40)})`);
3011
3011
  assert.equal(result.session.outcome, "aborted");
3012
3012
  assert.equal(result.session.outcome_reason, "lead_meta_review_drift");
@@ -3579,12 +3579,12 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
3579
3579
  });
3580
3580
  assert.equal(consensus.judged_count, 1, "exactly 1 item judged");
3581
3581
  assert.equal(consensus.promoted.length, 1, "1 item promoted via consensus");
3582
- assert.equal(consensus.promoted[0].item_id, seedItemId);
3582
+ assert.equal(consensus.promoted[0]?.item_id, seedItemId);
3583
3583
  // All 3 peers must appear in rationales.
3584
- assert.ok(consensus.promoted[0].rationales.codex);
3585
- assert.ok(consensus.promoted[0].rationales.claude);
3586
- assert.ok(consensus.promoted[0].rationales.gemini);
3587
- assert.equal(consensus.consensus_decisions[0].unanimous_verified_satisfied, true);
3584
+ assert.ok(consensus.promoted[0]?.rationales.codex);
3585
+ assert.ok(consensus.promoted[0]?.rationales.claude);
3586
+ assert.ok(consensus.promoted[0]?.rationales.gemini);
3587
+ assert.equal(consensus.consensus_decisions[0]?.unanimous_verified_satisfied, true);
3588
3588
  // Disabled-peer rejection.
3589
3589
  const prevs = {};
3590
3590
  for (const peer of ["GEMINI"]) {
@@ -6068,7 +6068,7 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
6068
6068
  // caller-supplied panel set-equals the enabled set, the lock must NOT
6069
6069
  // emit `session.caller_peer_selection_ignored`. Source pin.
6070
6070
  const serverSrcA2 = fs.readFileSync(path.join(process.cwd(), "src", "mcp", "server.ts"), "utf8");
6071
- assert.ok(/enabledPeers\?: readonly PeerId\[\];/.test(serverSrcA2), "v3.7.5 / A2: lockCallerPeerSelection ctx must accept optional `enabledPeers` snapshot");
6071
+ assert.ok(/enabledPeers\?: readonly PeerId\[\](?: \| undefined)?;/.test(serverSrcA2), "v3.7.5 / A2: lockCallerPeerSelection ctx must accept optional `enabledPeers` snapshot");
6072
6072
  assert.ok(/const callerPanelMatchesEnabled =[\s\S]*?ctx\.enabledPeers !== undefined &&[\s\S]*?callerSuppliedPeers !== undefined &&[\s\S]*?callerSuppliedPeers\.length === ctx\.enabledPeers\.length &&[\s\S]*?\[\.\.\.callerSuppliedPeers\]\.sort\(\)\.join\("\|"\) === \[\.\.\.ctx\.enabledPeers\]\.sort\(\)\.join\("\|"\)/m.test(serverSrcA2), "v3.7.5 / A2: lock must compare caller-supplied panel against enabled set via sorted set-equality before deciding peerPanelOverridden");
6073
6073
  assert.ok(/const peerPanelOverridden =\s*!!callerSuppliedPeers && callerSuppliedPeers\.length > 0 && !callerPanelMatchesEnabled;/.test(serverSrcA2), "v3.7.5 / A2: peerPanelOverridden must subtract callerPanelMatchesEnabled so the lock skips the emit when the panels match");
6074
6074
  // All 4 lock call sites must pass enabledPeers.