Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions docs/EVOLUTION_STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,25 @@ images are digest-pinned. Measured on the release tree with `npm audit --omit=de
| Tree | info | low | moderate | high | critical |
| ------------------- | ---- | --- | -------- | ----- | -------- |
| Root production | 0 | 0 | 0 | **0** | **0** |
| Electron production | 0 | 0 | 0 | **1** | **0** |
| Electron production | 0 | 0 | 0 | **0** | **0** |

Re-measured on 2026-09-19 after the `js-yaml` fix below. The Electron tree is also clean in the
full run that includes dev dependencies (`npm audit --package-lock-only`: 0 across every
severity).

The verification round caught this claim being stale: a second, higher advisory on `adm-zip`
(GHSA-7q85-xj36-vmfc, high, fixed in 0.6.1) had appeared in the root production tree through the
optional `@huggingface/transformers` → `onnxruntime-node` chain, while the register still said there
was none. It was fixed rather than re-documented — a lockfile-only bump to 0.6.1 inside the existing
`^0.6.0` override, a three-line diff that took root production from `high: 1, moderate: 2` to zero.

The remaining `high` is accepted as residual: `js-yaml` 4.3.1, register id **R-10**, reachable only
from the Electron shell's update-check chain. It is not in the container image, the npm package or
the server runtime, and clearing it needs an Electron lockfile refresh that is out of scope here.
The last remaining `high` was then cleared the same way rather than carried: `js-yaml` 4.3.1, register
id **R-10**, reachable only from the Electron shell's update-check chain (`electron-updater` 6.8.9 →
`js-yaml`), never in the container image, the npm package or the server runtime. A lockfile-only bump
to 4.3.2 inside the existing `^4.2.0` override took Electron production from `high: 1` to zero, and
the shared hoisted copy meant it cleared the dev-tree `electron-builder` entries too. `package.json`
is unchanged; the diff is five lines of `electron/package-lock.json`. **No advisory is accepted as
residual in either shipped production tree.**

## Phase 11: documentation

Expand Down Expand Up @@ -265,7 +273,7 @@ have been irreversible or contract-breaking in a patch release.
| The in-memory decision store grows under a burst of wide candidate pools | Low | Memory pressure on the server process | Bounded by count, by a 32 MB byte budget and by a 30-minute TTL; candidates are compacted before storage |
| An operator enables SLO webhook alerts and gets paged by a breach that is really an idle provider | Low | Alert fatigue | An idle open breaker reports `insufficient_data` instead of breaching; alert state resets when alerting is toggled |
| A routing decision id is guessed and read by another caller | Low | Disclosure of routing metadata (never prompts or credentials) | Management auth on the lookup route; identical `404` for unknown and malformed ids |
| The Electron `js-yaml` advisory (R-10) is exploited | Low | Build-chain only; no server or dashboard exposure | Recorded in the vulnerability register; a lockfile-only refresh is planned |
| The Electron `js-yaml` advisory (R-10) is exploited | Closed | Build-chain only; no server or dashboard exposure | **Fixed** 2026-09-19: lockfile-only bump to `js-yaml` 4.3.2; Electron production audit is now clean |
| The 151 OpenAPI-covered routes without a contract test drift from the served contract | Medium | Documentation and SDKs disagree with the server | The governance baseline tracks them and cannot grow; the SDK drift test covers the documented surface |
| A gate or test run without isolated `DATA_DIR`/`HOME` touches a developer's real database | Medium | Unintended migration on a production install | Every command in this release exported isolated `DATA_DIR`, `HOME`, `USERPROFILE` and `APPDATA`; `tests/_setup/isolateDataDir.ts` enforces it in the test runner |

Expand All @@ -274,7 +282,9 @@ have been irreversible or contract-breaking in a patch release.
- The **workspace and budget hierarchy** is designed but not implemented (Phase 8 ADR).
- **151 routes** are covered by OpenAPI but have no contract test referencing them yet; the
governance baseline tracks them.
- The **`js-yaml` R-10** advisory in the Electron chain is accepted as residual.
- ~~The **`js-yaml` R-10** advisory in the Electron chain is accepted as residual.~~ Fixed
2026-09-19 — `js-yaml` 4.3.2, lockfile only. No advisory is accepted as residual in either
shipped production tree.
- A live **latency budget** is not enforced per candidate; the contract documents exactly what live
traffic does enforce, and the remaining work depends on decomposing `open-sse/services/combo.ts`.
- Accessibility was gated on login, dashboard, providers and settings; combos, logs and onboarding
Expand Down
87 changes: 70 additions & 17 deletions docs/security/VULNERABILITY_REGISTER.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ Result, as measured on 2026-09-14:
this run and made the same tree report `high: 1` without any dependency changing.
- Root dev-only: 4 high advisories (2 × extract-zip, js-yaml, smol-toml), 0 critical.
- Electron app (`electron/package-lock.json`): 1 high advisory in a production dependency
(R-10).
(R-10). **This statement expired.** R-10 was fixed on 2026-09-19 — see the
[Electron re-measurement](#electron-re-measurement--2026-09-19); that tree now reports no
advisory of any severity.

## Re-measurement — 2026-09-19

Expand All @@ -61,16 +63,61 @@ Result, as measured on 2026-09-14:

**Current result: the root production tree reports no advisory of any severity.** Both
adm-zip records (R-01 and R-11) are closed by the fix; the remaining 7 entries in the full run
are the dev-only records R-02 … R-09. The Electron app lockfile is unchanged (R-10 still open).
are the dev-only records R-02 … R-09. The Electron app lockfile was still unchanged at this
point (R-10 open); it was fixed later the same day — see the
[Electron re-measurement](#electron-re-measurement--2026-09-19).

The fix is item 2 of the [Proposed dependency PR](#proposed-dependency-pr-not-applied), applied
The fix is item 2 of the [dependency PR items](#dependency-pr-items), applied
as a lockfile-only change: `npm update adm-zip --package-lock-only --ignore-scripts` moved
`adm-zip` 0.6.0 → 0.6.1 inside the existing root override `^0.6.0`. `package.json` is
unchanged and the whole diff is three lines of `package-lock.json` (version, resolved,
integrity). `node_modules` was not touched. Verified afterwards:
`tests/unit/onnxruntime-single-copy.test.ts` (2/2 pass, the transformers/onnxruntime version
pair is intact) and `npm run check:lockfile` (OK).

## Electron re-measurement — 2026-09-19

- Toolchain: Node v24.16.0, npm 11.13.0. Electron lockfile: 285 packages audited.
- Trigger: R-10 was the last high advisory left in a shipped production tree, and it was the
only record still described as an accepted residual.

| Run | Command | Critical | High | Moderate | Low | Total |
| ------------------------------ | ------------------------------------------ | -------- | ----- | -------- | --- | ----- |
| electron prod (before the fix) | `npm audit --omit=dev --package-lock-only` | 0 | **1** | 0 | 0 | 1 |
| electron prod (after the fix) | `npm audit --omit=dev --package-lock-only` | 0 | 0 | 0 | 0 | 0 |
| electron full (after the fix) | `npm audit --package-lock-only` | 0 | 0 | 0 | 0 | 0 |
| root prod (unchanged by this) | `npm audit --omit=dev --package-lock-only` | 0 | 0 | 0 | 0 | 0 |

**Current result: both shipped production trees report no advisory of any severity, and the
Electron tree is clean in the full run too** — the dev-only `app-builder-lib`, `builder-util`
and `dmg-builder` copies deduplicate onto the same hoisted `js-yaml`, so the single bump
cleared them as well.

The fix is item 1 of the [dependency PR items](#dependency-pr-items), applied
as a lockfile-only change: `npm update js-yaml --package-lock-only --ignore-scripts` moved
`js-yaml` 4.3.1 → 4.3.2 inside the existing Electron override `^4.2.0` (and inside
`electron-updater`'s declared `^4.1.0`). `electron/package.json` is unchanged — the override
already permitted the fixed version, so no new `overrides` entry was needed. `node_modules` was
not touched.

The diff is five lines of `electron/package-lock.json`: three for `js-yaml` (version, resolved,
integrity) and two where npm synchronised the lockfile's own `version` field from the stale
`3.8.51` to the `3.8.54` already declared in `electron/package.json`. No other package changed
version.

Verified afterwards: `npm run check:lockfile` (OK) and the two commands behind
`audit:electron` — `npm --prefix electron audit --audit-level=critical` and
`--audit-level=high` — both exit 0, so the non-blocking high-severity warning that this script
used to print is gone. The `audit:electron` script itself was not run end to end on this
machine: its `(cmd || echo)` shell form is POSIX syntax that cmd.exe rejects before npm audit
runs, which is a pre-existing Windows-only limitation of the script and unrelated to this
change.

A full `electron-builder` packaging run was **not** executed here — it needs a download of the
Electron binaries and a code-signing environment this worktree does not have. What was checked
instead: `electron/package.json` parses, its `build` block is byte-for-byte unchanged by this
commit, and the only file this commit touches under `electron/` is `package-lock.json`.

## Summary

| ID | Advisory | Package | npm severity | Tree | Installed | First fixed | Action |
Expand All @@ -84,7 +131,7 @@ pair is intact) and `npm run check:lockfile` (OK).
| R-07 | GHSA-8cw4-87c7-c6xx | csv-parse | moderate | root dev | 7.0.1 | 7.0.2 | Lockfile refresh proposed |
| R-08 | GHSA-6w3j-5fw6-r9vr | joi | low | root dev | 18.2.3 | 18.2.5 | Lockfile refresh proposed |
| R-09 | GHSA-gg4h-3hg2-grpc | joi | low | root dev | 18.2.3 | 18.2.4 | Lockfile refresh proposed |
| R-10 | GHSA-2883-xcg3-v3hh | js-yaml | high | electron app production | 4.3.1 | 4.3.2 | Lockfile refresh proposed (priority) |
| R-10 | GHSA-2883-xcg3-v3hh | js-yaml | high | electron app production | 4.3.2 | 4.3.2 | **Fixed** 2026-09-19 (lockfile only) |
| R-11 | GHSA-7q85-xj36-vmfc | adm-zip | high | root production (optional) | 0.6.1 | 0.6.1 | **Fixed** 2026-09-19 (lockfile only) |

Propagation-only entries (no advisory of their own): `@huggingface/transformers` and
Expand All @@ -99,7 +146,7 @@ or `electron/package-lock.json`). This phase runs against a shared `node_modules
not regenerate lockfiles or mix dependency upgrades with other changes. The declared ranges in
the lockfiles show that each fixable record resolves by refreshing lock entries within the
existing ranges and overrides, with no `package.json` edit. See
[Proposed dependency PR](#proposed-dependency-pr-not-applied).
[dependency PR items](#dependency-pr-items).

## Records

Expand Down Expand Up @@ -311,15 +358,20 @@ existing ranges and overrides, with no `package.json` edit. See

### R-10 — js-yaml: merge-key CPU exhaustion (Electron app production tree)

- **Package:** `js-yaml` 4.3.1 (`electron/package-lock.json`, `node_modules/js-yaml`, not
marked dev).
**Status: fixed 2026-09-19** (lockfile only). `js-yaml` 4.3.1 → 4.3.2 in
`electron/package-lock.json`. The Electron production tree now reports no advisory of any
severity. Details below describe the advisory as it stood before the fix.

- **Package:** `js-yaml` 4.3.2 (`electron/package-lock.json`, `node_modules/js-yaml`, not
marked dev). Was 4.3.1 before the fix.
- **Advisory:** GHSA-2883-xcg3-v3hh / CVE-2026-84375 — high, CVSS 7.5, CWE-400/CWE-407,
published 2026-09-08. This is the same advisory as R-04, recorded separately because it
ships in a different artifact.
- **Dependency path:** Electron app dependency `electron-updater` 6.8.9 (declared
`^6.8.9` in `electron/package.json`; it declares `js-yaml ^4.1.0`) → `js-yaml` 4.3.1. The
`^6.8.9` in `electron/package.json`; it declares `js-yaml ^4.1.0`) → `js-yaml`. The
build-only packages `app-builder-lib`, `builder-util` and `dmg-builder` 26.15.3 (dev)
resolve the same copy.
resolve the same copy, so the single hoisted entry served both trees and one bump cleared
both.
- **Affected versions:** `>=4.0.0 <4.3.2`.
- **Fixed version:** 4.3.2.
- **Real exploitability in OmniRoute:** low.
Expand All @@ -332,19 +384,20 @@ existing ranges and overrides, with no `package.json` edit. See
- This does not affect the npm package or the Docker image.
- **Impact if exploited:** the Electron main process hangs or spikes CPU during an update
check, a denial of service of the desktop app.
- **Action taken:** none in code. Proposed: refresh the `electron/package-lock.json` entry to
4.3.2 (allowed by `^4.1.0`); this is the only high advisory in a shipped production tree.
- **Justification:** exploitation needs control of the release feed. The fix is a lockfile
change in a separate lockfile, out of scope for this phase. `audit:electron` blocks only on
critical, so it reports this as a warning.
- **Action taken:** fixed on 2026-09-19. `npm update js-yaml --package-lock-only
--ignore-scripts` refreshed the `electron/package-lock.json` entry to 4.3.2, allowed by both
`electron-updater`'s declared `^4.1.0` and the existing `^4.2.0` override in
`electron/package.json`. No `package.json` change and no new override were needed.
`audit:electron` no longer emits its non-blocking high-severity warning.

## Proposed dependency PR (not applied)
## Dependency PR items

This should be a dedicated PR that changes only `package-lock.json` and
`electron/package-lock.json`, with no mass upgrade:

1. `electron/package-lock.json`: `js-yaml` 4.3.1 → 4.3.2 (R-10), within `^4.1.0`. Do this
first: it is the only high advisory in a shipped production tree.
1. ~~`electron/package-lock.json`: `js-yaml` 4.3.1 → 4.3.2 (R-10), within `^4.1.0`.~~
**Applied 2026-09-19** — lockfile only, via `npm update js-yaml --package-lock-only
--ignore-scripts`. It was the last high advisory in a shipped production tree.
2. ~~`adm-zip` 0.6.0 → 0.6.1 (R-01), within the root override `^0.6.0`.~~ **Applied
2026-09-19** — lockfile only, via `npm update adm-zip --package-lock-only`. It also closes
R-11, the high advisory that appeared later on the same package.
Expand Down
10 changes: 5 additions & 5 deletions electron/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading