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
54 changes: 25 additions & 29 deletions bun.lock

Large diffs are not rendered by default.

30 changes: 1 addition & 29 deletions docs/BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ None of it is a GitHub issue.
- [Release pipeline](#release-pipeline) — REL1–REL4 · 4
- [Chart configuration surface](#chart-configuration-surface) — N1 · 1
- [Security Phase 1 deferrals](#security-phase-1-deferrals) — H1–H14 · 4
- [Security Phase 2 deferrals](#security-phase-2-deferrals) — C3–C11 · 7
- [Security Phase 2 deferrals](#security-phase-2-deferrals) — C3–C11 · 6
- [Security Phase 3 deferrals](#security-phase-3-deferrals) — K4
- [Security scanner triage](#security-scanner-triage) — SCAN1 · 1
- [Agent M1 deferrals (#328)](#agent-m1-deferrals-328) — A1–A8 · 7
Expand Down Expand Up @@ -3406,34 +3406,6 @@ a CC BY-SA database with no note connecting them.
tarballs, names the sample database's separate terms explicitly, and is regenerated from the lockfile
rather than hand-maintained.

### C10. The last DOMPurify advisories are held open by Monaco's pin

`dompurify` via `monaco-editor` is the only advisory chain that reaches a user. Everything else
`bun audit` reports — `minimatch`, `brace-expansion`, `flatted`, `picomatch`, `esbuild`, `@babel/core`,
`undici` — arrives through `eslint`, `typescript-eslint`, `knip`, `tsup`, `workflow` and `@ai-sdk/*`,
and none of it is in the image. `undici` was checked specifically, because the agent runtime sits in
`devDependencies` by design yet reaches the standalone build: building with `DOCKER_BUILD=true` shows
no `undici` anywhere under `.next/standalone`, since `@ai-sdk/provider-utils` reaches it through a
`createRequire` call that output tracing cannot follow.

#374 moved the shipped copy from 3.2.7 to 3.4.8 by upgrading Monaco itself, clearing 14 of the 17.
**Four remain** on GitHub Advanced Security's count, and none can be closed here: they need 3.4.9,
3.4.11, 3.4.12 and 3.4.13. Monaco pins dompurify exactly, and 0.56.0 is its newest release.

**Do not "fix" these with a `package.json` override.** Monaco ships DOMPurify inlined in its prebuilt
`min/vs` bundle and nothing in `src/` imports the package. An override would change a lockfile entry no
shipped code reads, leave the bundle byte-identical, and turn `bun audit` and Trivy green at once. The
GHAS findings land on `bun.lock:<line>`, which is the tell: every one of those tools reads the
manifest, not the artefact.

Two related non-findings, so they are not re-derived. `dompurify` is dual-licensed (MPL-2.0 OR
Apache-2.0), so the copyleft half can simply not be chosen. And the LGPL-3.0 `@img/sharp-libvips-*`
binaries never reach the runtime image, because the runner stage copies `node_modules` selectively and
nothing in `src/` uses `next/image`.

**Done when:** Monaco ships a dompurify at or past 3.4.13. Re-check on each Monaco release, and verify
by grepping the staged bundle for the version literal rather than trusting the lockfile.

### C11. The published SBOM carries no component for the bundled Node.js runtime

#584 gave `SECURITY.md` a hand-maintained **Bundled Node.js runtime** table: the pinned version, the
Expand Down
4 changes: 2 additions & 2 deletions docs/providers/cassandra.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
| **Status** | Implemented & shipped |
| **Database type id** | `cassandra` |
| **Family** | SQL (`src/lib/db/providers/sql/cassandra/`) |
| **Driver** | [`cassandra-driver`](https://www.npmjs.com/package/cassandra-driver) 4.9.0 — Apache-2.0, pure JS (no `binding.gyp`, no `.node`, no postinstall) ([§3.1](#31-a-driver-that-costs-no-distribution-channel-anything)) |
| **Driver** | [`cassandra-driver`](https://www.npmjs.com/package/cassandra-driver) 4.10.0 — Apache-2.0, pure JS (no `binding.gyp`, no `.node`, no postinstall) ([§3.1](#31-a-driver-that-costs-no-distribution-channel-anything)) |
| **Query language** | `sql` — CQL is SQL-*shaped*: no JOIN, no subquery, no OFFSET, no EXPLAIN ([§5.4](#54-dialect-traps-a-user-will-hit)) |
| **Default port** | `9042` — the native protocol. Thrift (9160) is gone from 4.0 onwards; 7000/7001 are internode and 7199 is JMX |
| **Connection pooling** | The driver's own, one session per connection: core 1 connection per local host, 2048 requests in flight per connection |
Expand Down Expand Up @@ -1465,7 +1465,7 @@ first and then the remaining columns alphabetically, with all twenty table optio
Nothing in the database holds the author's own bytes.

**`cql` IS NOT A MONACO LANGUAGE ID**, and every row above says `sql` because of it. The installed
monaco-editor 0.56.0 bundle registers 89 ids and `cql` is not among them; an unregistered id degrades
monaco-editor 0.57.0 bundle registers 89 ids and `cql` is not among them; an unregistered id degrades
to plain text with no throw and nothing observable. `sql` is the closest registered dialect, so a
`CREATE TABLE` renders correctly and the CQL-only spellings (`PRIMARY KEY ((a), b)`,
`frozen<address>`, a `$$ ... $$` function body) are highlighted as whatever the SQL tokenizer makes
Expand Down
2 changes: 1 addition & 1 deletion docs/providers/clickhouse.md
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ the author typed, so a reader must never be shown it as an original. The fixture
carrying a `SETTINGS index_granularity = 8192` clause nobody wrote.

`sql` is the right Monaco id and no part of it is a compromise: ClickHouse SQL is SQL, and the
installed monaco-editor 0.56.0 registers `sql`. The three ids this design had to refuse
installed monaco-editor 0.57.0 registers `sql`. The three ids this design had to refuse
elsewhere, `plsql`, `tsql` and `cql`, are not registered at all and are not needed here.

#### The read takes NO identifier position, and that is the security decision
Expand Down
2 changes: 1 addition & 1 deletion docs/providers/duckdb.md
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ Every declared kind publishes a definition text, so **all four declare `hasSourc
one object and answers a document of exactly one part.

`sql` is the honest Monaco id rather than a compromise. DuckDB's dialect is PostgreSQL-shaped, the
installed monaco-editor 0.56.0 registers no DuckDB id, and the text the engine publishes is ordinary
installed monaco-editor 0.57.0 registers no DuckDB id, and the text the engine publishes is ordinary
SQL. This is unlike Oracle, SQL Server and Cassandra, where `plsql`, `tsql` and `cql` are not
registrable ids in that bundle and `sql` really is a compromise those provider docs record.

Expand Down
9 changes: 6 additions & 3 deletions docs/providers/kafka.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
| **Status** | Implemented & shipped |
| **Database type id** | `kafka` |
| **Family** | Stream (`src/lib/db/providers/stream/kafka/`), the first provider in that family |
| **Driver** | `@platformatic/kafka` 2.11.0, pinned exactly, pure TypeScript, loaded under Bun and Node alike ([§2.5](#25-the-client-and-why)) |
| **Driver** | `@platformatic/kafka` 2.12.0, pinned exactly, pure TypeScript, loaded under Bun and Node alike ([§2.5](#25-the-client-and-why)) |
| **Query language** | `json` with `queryDialect: "kafka"`: a JSON read request of this product's own schema, not MongoDB's JSON ([§5.1](#51-the-read-request)) |
| **Default port** | `9092`, the port a stock broker listens on; the same number is the default under TLS, because a secured listener serves on whatever port its operator chose |
| **Connection pooling** | One `Admin`, one `Consumer` and one fetch `ConnectionPool` per connection, all closed by `disconnect()` ([§3.4](#34-one-client-per-connection-and-no-fetch-session)) |
Expand Down Expand Up @@ -102,7 +102,8 @@ A connect that fails after the client was built closes it again.

### 2.5 The client, and why

`@platformatic/kafka` 2.11.0, used fetch-only, was chosen by a broker-side measurement before any code was written (#1088, section 3.2 and Appendix B).
`@platformatic/kafka`, used fetch-only, was chosen at 2.11.0 by a broker-side measurement before any code was written (#1088, section 3.2 and Appendix B).
2.12.0 was taken only after the live read-only check passed on it ([§11.4](#114-the-live-read-only-check)).
Reading by partition, offset and timestamp through its `listOffsets`, `listOffsetsWithTimestamps` and a fetch registered no consumer group and never created `__consumer_offsets`, under Bun and Node.
Its `consume()` in MANUAL mode, with explicit offsets and `autocommit: false`, joins the group and leaves an `Empty` group registered after `close()`, so `consume()` is never called.
All four codecs, gzip, snappy, lz4 and zstd, decode with no native addon: snappy and lz4 come from WebAssembly, gzip and zstd from `node:zlib`, and the optional `@node-rs/crc32` falls back to WebAssembly.
Expand Down Expand Up @@ -629,6 +630,8 @@ With `--tripwire` it first reads every seeded topic on a broker never asked for
Its log searches for an automatic topic creation and for the never-joined group id are each paired with a control that finds that kind of line in the broker's whole log.

Measured on 2026-09-25: every check passed on `kafka` (57, with the tripwire), on `redpanda` (39), on `kafka-cluster` (47), and on `kafka-auth` as `reader` (7), and every snapshot after a run equalled the one before it.
Measured again on 2026-09-28 with `@platformatic/kafka` 2.12.0: the same four counts, eight of eight with `--failover`, and every snapshot after a run equalled the one before it.
The same day, under Node through `next start`, a connect, the topic listing and two reads on a broker never asked for a group coordinator left `__consumer_offsets` absent, and the group seed that followed created it.
Against the provider with one rule broken at a time, the check failed each time: a `disconnect()` that closes nothing, `autocreateTopics: true`, a `metadata([])` answered from the cache, lag that ignores the committed offset, a transaction filter that keeps aborted records, a group listing without the `consumer` type, and a lag listing that shows one partition twice.
A config write made during the run from outside the provider, setting `orders` to the `compression.type=gzip` line `codec-gzip` already holds, failed the check too; the check as first committed, which compared bare lines as a set, passed it.

Expand Down Expand Up @@ -732,7 +735,7 @@ See [`docs/API_DOCS.md`](../API_DOCS.md) for the full request and response contr

- Source: [`src/lib/db/providers/stream/kafka/`](../../src/lib/db/providers/stream/kafka/)
- Design: [#1088](https://github.com/libredb/libredb-studio/issues/1088)
- Client: [`@platformatic/kafka`](https://github.com/platformatic/kafka), version 2.11.0
- Client: [`@platformatic/kafka`](https://github.com/platformatic/kafka), version 2.12.0
- Kafka protocol: <https://kafka.apache.org/protocol>
- KIP-848, the consumer group protocol: <https://cwiki.apache.org/confluence/display/KAFKA/KIP-848%3A+The+Next+Generation+of+the+Consumer+Rebalance+Protocol>
- KIP-516, topic identifiers: <https://cwiki.apache.org/confluence/display/KAFKA/KIP-516%3A+Topic+Identifiers>
2 changes: 1 addition & 1 deletion docs/providers/mssql.md
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ sentence names the catalog view and the column the decision came from instead.
encryption at all.

**`sql` and not `tsql`.**
MEASURED in #789: `tsql` is not among the 89 language ids the installed monaco-editor 0.56.0 bundle
MEASURED in #789: `tsql` is not among the 89 language ids the installed monaco-editor 0.57.0 bundle
registers, and an unregistered id degrades to plain text silently.
So a T-SQL definition renders under the generic `sql` grammar, and T-SQL-only spellings
(`OUTER APPLY`, `MERGE ... OUTPUT`, `@variable`) draw as plain identifiers.
Expand Down
2 changes: 1 addition & 1 deletion docs/providers/mysql.md
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ CALL bulk26a1.seed();
parts. **Every kind either server declares can answer**, which makes this the one provider in the
fleet with no kind that declares nothing: MySQL's six and MariaDB's eight each have a `SHOW CREATE`
form. The Monaco language id is `mysql` on all eight; `mysql` is an id the installed monaco-editor
0.56.0 bundle really registers, unlike `plsql`, `tsql` and `cql`.
0.57.0 bundle really registers, unlike `plsql`, `tsql` and `cql`.

Measured 2026-09-13 on **MySQL 26.7.0** and **MariaDB 12.3.2** against the two committed fixtures.

Expand Down
2 changes: 1 addition & 1 deletion docs/providers/oracle.md
Original file line number Diff line number Diff line change
Expand Up @@ -1332,7 +1332,7 @@ The owner is the segment the DECLARATION assigns to the `schema` container level
is the LAST path segment; neither is read by a literal index.

**The Monaco language id is `sql`, and that is a compromise this provider states rather than hides.**
MEASURED on the installed monaco-editor 0.56.0: `plsql` is not among the 89 language ids the bundle
MEASURED on the installed monaco-editor 0.57.0: `plsql` is not among the 89 language ids the bundle
registers, and an unregistered id degrades to plain text SILENTLY, with no throw and nothing
observable. A PL/SQL body therefore renders under the SQL grammar, which highlights the DML and
misses `IS`, `BEGIN`, `EXCEPTION` and the block structure.
Expand Down
2 changes: 1 addition & 1 deletion docs/providers/postgres.md
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ One writer for both, because two copies are two chances for the read to answer "
`pg_get_function_identity_arguments()` is not used, for the reason [§3.1.4](#314-what-the-object-surface-declares-and-which-catalog-answers-for-it) gives: it renders parameter names.

**`pgsql` is a real Monaco language id and is no compromise here.**
It is among the ids the installed `monaco-editor` 0.56.0 registers, unlike `plsql` and `tsql`, which Oracle and SQL Server have to render under `sql`.
It is among the ids the installed `monaco-editor` 0.57.0 registers, unlike `plsql` and `tsql`, which Oracle and SQL Server have to render under `sql`.
A PL/pgSQL body inside a `$function$` dollar-quoted string is highlighted as PostgreSQL SQL rather than as a procedural language, which is the closest this bundle can come.

### 3.1.6 Object edit (#789)
Expand Down
2 changes: 1 addition & 1 deletion docs/providers/redis.md
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ reach this arm is a declaration somebody removed.
|---|---|---|
| `id` | `definition` | one part, always: a library has one Lua text |
| `label` | `Definition` | rendered as-is |
| `language` | the kind's declared `sourceLanguage`, which is `lua` | `lua` IS a Monaco language id the installed 0.56.0 bundle registers, unlike `plsql`, `tsql` and `cql` |
| `language` | the kind's declared `sourceLanguage`, which is `lua` | `lua` IS a Monaco language id the installed 0.57.0 bundle registers, unlike `plsql`, `tsql` and `cql` |
| `form` | `complete` | the text runs as given: it is what `FUNCTION LOAD` was handed |
| `origin` | `stored` | the author's own bytes. Measured on Redis 8.10.0: `WITHCODE` answers the shebang line and the body exactly as they were loaded, with no reformatting |

Expand Down
Loading
Loading