Skip to content

feat(database): observeExit hook, span parameters and Redacted parameter redaction - #98

Merged
Makisuo merged 5 commits into
MapleTechLabs:mainfrom
artile:feat/observe-redaction
Nov 2, 2026
Merged

Makisuo merged 5 commits into
MapleTechLabs:mainfrom
artile:feat/observe-redaction

Conversation

@artile

@artile artile commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Statement spans give no hook for duration, rows and errors, and there is no rule for parameter values. A Redacted value in sql...`` was also bound as the Redacted object, so the database stored the text ``.

Closes #77.
Part of #52.

Changes

  • observeExit on fromSqlClient: called with a StatementObservation when each statement ends. It has sql, parameters, system, operation, collection, summary, tenantScope, route, durationMillis, rows and errorType.
  • spanParameters: true puts the bound values on the statement span as db.query.parameter.<index> (OpenTelemetry semconv). Off by default, so spans carry no values.
  • CompiledQuery.sensitiveParameters: the indexes of values given as Redacted. This covers compared values, param.* values, and values that an insert or update writes. Use a column such as PG.brand(PG.text, Schema.RedactedFromValue(Schema.String)). The driver gets the plain value. Spans write <redacted>. observeExit gets the value still Redacted.
  • sql...``: binds a Redacted value as its plain value and marks it (fix). On ClickHouse, which writes values into the text, it refuses a `Redacted` value.
  • Statement.sensitiveParameters, docs (database.md "Observing statements" and "Redaction", params-and-compilation.md, reference.md) and a minor changeset.

Left out

  • One span per transaction or batch: this needs a statement collector design of its own. Also, D1 batch() (D1 batch() as a typed atomic unit #55) is not in yet.
  • Redaction on ClickHouse: the dialect writes values into the SQL text. Effect's sql.execute span (db.query.text) and DatabaseError.sql carry that text. A fix needs bound params over HTTP.
  • in_ on a Redacted column fails to encode today (an array goes to the element codec). This is a separate issue in the builder.
  • CH.sql fragments inside a builder query do not mark Redacted values.
  • observeExit does not see BEGIN, COMMIT and ROLLBACK. Effect's withTransaction sends them, not Database.
  • observe (before the statement) is unchanged and still gets the plain values.
  • No SQLite, MySQL or D1 part.

Validation

With EFFECT_ORM_CLICKHOUSE_URL=http://127.0.0.1:8123 (ClickHouse 26.8.2.7, the CI version), EFFECT_ORM_CLICKHOUSE_USER=maple and EFFECT_ORM_CLICKHOUSE_PASSWORD=maple:

  • bun run build: ok.
  • bun run typecheck: ok, no errors.
  • bunx vitest run --testTimeout=60000 --hookTimeout=60000: 61 files passed, 1046 tests passed, 0 skipped. The longer timeouts are for local machine load only.
  • node scripts/check-doc-citations.mjs: ok (25 files). node scripts/check-exports-documented.mjs: ok. node scripts/check-doc-examples.mjs: ok (21 files).
  • bun scripts/check-package.ts: ok (tarball imports, types and CommonJS consumer).

New tests: src/pg/sensitive-parameters.test.ts (5), 4 in src/database/tracing.test.ts (observeExit, span parameters), and 2 in src/database/database.test.ts (sql with Redacted).

Upstream CI for fork PRs waits for a maintainer to approve the run.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 39 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9bc4b84b-f27f-4cbf-bcb9-5e64ebfdfa63
Commits

Reviewing files that changed from the base of the PR and between b57faf1 and eb5d284.

Files selected for processing: 14
  • .changeset/observe-exit-redaction.md
  • docs/database.md
  • docs/params-and-compilation.md
  • docs/reference.md
  • src/ch/compile.ts
  • src/ch/literal.ts
  • src/database.ts
  • src/database/database.test.ts
  • src/database/database.ts
  • src/database/sql.ts
  • src/database/tracing.test.ts
  • src/database/tracing.ts
  • src/pg/sensitive-parameters.test.ts
  • src/sql/literal-binder.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Resolves the import conflicts in compile.ts and tracing.ts. SQLite and D1
bind values, so they mark Redacted values like Postgres: tests compile both
dialects and run a node:sqlite Database with spanParameters and observeExit.
Docs and changeset say which dialects redact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Makisuo

Makisuo commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Merge-readiness pass (head eb5d284):

Changed

  • Merged main. The only conflicts were imports in src/ch/compile.ts (main's schemaOf next to isSensitive) and src/database/tracing.ts.
  • SQLite and D1 bind ? values and go through the same renderParams, withBoundLiterals and valueCells path, so they mark Redacted values the same way Postgres does. New tests: compiled selects and inserts on sqliteDialect and d1Dialect mark the right indexes. A node:sqlite Database with spanParameters and observeExit stores the plain value (builder insert and sql template), observes it still Redacted, and leaves no secret in the observations. system is sqlite.
  • Docs and changeset now say which dialects redact (Postgres, SQLite, D1). They also say that on ClickHouse a Redacted column value written by the builder is inlined into the statement text.

For the maintainer to decide

Verified

  • bun run typecheck and bun run build. bun run test with a live ClickHouse 26.8: 1443 of 1444 passed. The one failure was the known ClickHouse "Division by zero" flake in "generated fixtures: union results agree (clickhouse-join-nulls)", which test(fuzz): fix three flaky generated-data properties #131 fixes. Doc checks passed when run separately.
  • FUZZ_SCALE=0.3 vitest run tests/fuzz: 269 passed. tests/database.clickhouse.test.ts and src/database/tracing.test.ts live: green.
  • CI run 41474368094 was in progress when I posted this.

@Makisuo
Makisuo merged commit 4ad256c into MapleTechLabs:main Nov 2, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Observability: observe hook, span attributes, parameter redaction

2 participants