Redact password from postgres connection errors - #433
Open
0-jake-0 wants to merge 5 commits into
Open
Conversation
postgres_read/write/sub embedded the full libpq connection string — including password=... — in anyhow error context, so credentials could reach logs and graph-abort errors. Add PostgresConnection::redacted(), which masks the password token while preserving every other field, and use it at all three connect() error sites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mNRkJnZZGC1QUULgbbwnA
Five-phase plan covering release-blocking bugs, operator/engine correctness, CI hardening, consolidation, bindings quality, and docs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mNRkJnZZGC1QUULgbbwnA
Records verified findings (CSV last-row drop repro, PyPI target bug, monotonic NanoTime, async channel unwraps), plan location, and next-session notes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mNRkJnZZGC1QUULgbbwnA
Two robustness gaps in the q-string write path:
- Non-finite float/real values rendered via {} as "NaN"/"inf", which are
not valid q and made the whole insert fail. Map them to q's native
null/infinity literals (0n/0w/-0w for float, 0Ne/0we/-0we for real);
multi-value columns with a non-finite entry use an explicit `float$(...)/
`real$(...) cast so the tokens parse as one vector.
- to_kdb_row() returning a non-compound list was silently turned into an
empty row (unwrap_or_default), and a ragged burst panicked on an
out-of-bounds column index during transpose. Extract the transpose into
k_rows_to_columns(), which errors on both instead.
Adds unit tests for the q-token formatting and the transpose validation.
Note: the multi-value non-finite cast forms are asserted at the string
level here but should be confirmed against a live KDB instance via the
kdb-integration-test suite before release.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mNRkJnZZGC1QUULgbbwnA
This was referenced Jul 25, 2026
0-jake-0
added a commit
that referenced
this pull request
Jul 25, 2026
…Wave 2 learnings) (#541) Two additions distilled from the Wave 2 ports (postgres/zmq): - Credential-redaction invariant in the fallibility section: never embed a password/token/DSN in error context; give the connection config a redacted() method and use it at every connect() error site, with a no-service test that the raw secret never leaks. Generalizes the classic postgres fix (#433) to every networked adapter. - Time-slicer cfg-gate reuse: the second time-partitioned adapter must WIDEN the shared slicer's #[cfg(any(feature = ...))] gate rather than duplicate it (postgres left compute_validated_time_slices gated postgres-only because a kdb cfg didn't exist yet), and postgres's query-at-wiring -> WindowFilter -> replay_results reader is named as the template. Directly unblocks the kdb port. Docs-only change to .claude/commands/new-adapter-next.md. Claude-Session: https://claude.ai/code/session_01SEQvysabaSKTnYyQDgPDTt Co-authored-by: Claude <noreply@anthropic.com>
0-jake-0
pushed a commit
that referenced
this pull request
Jul 25, 2026
Port the classic `postgres` adapter to wingfoil-next on the Op model: - `postgres_read` — time-partitioned historical replay. First time- partitioned adapter to port, so it lands the shared time slicer (`compute_time_slices` / `compute_validated_time_slices`) in `adapters::common` (feature-gated `postgres`; kdb adds its feature later) alongside the existing `WindowFilter`/`TimeWindow`. Queries every midnight-aligned slice at wiring time (`Handle::block_on`), clamps each row through `WindowFilter`, and feeds the finite rows to `replay_results`. - `postgres_sub` — realtime `LISTEN`/`NOTIFY` live tail on `produce_async`; rejects `RunMode::HistoricalFrom` at wiring (live, unbounded stream). - `PostgresSinkOps::postgres_write` — streaming insert sink over `consume_async`, connecting eagerly at wiring, per-burst pipelined. Password redaction (classic PR #433) is reproduced: `PostgresConnection::redacted()` masks the DSN `password=...` token at every `connect()` error site. Parity tests ported: no-service `tests/postgres_adapter.rs` (validation, connection-refused + redaction, historical rejection) and container-backed `tests/postgres_integration.rs` (gated `postgres-integration-test`, testcontainers). Classic example ported to `examples/postgres_adapter/`. CI wired into the integration-tests hub; port-plan updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEQvysabaSKTnYyQDgPDTt
0-jake-0
added a commit
that referenced
this pull request
Jul 25, 2026
Port the classic `postgres` adapter to wingfoil-next on the Op model: - `postgres_read` — time-partitioned historical replay. First time- partitioned adapter to port, so it lands the shared time slicer (`compute_time_slices` / `compute_validated_time_slices`) in `adapters::common` (feature-gated `postgres`; kdb adds its feature later) alongside the existing `WindowFilter`/`TimeWindow`. Queries every midnight-aligned slice at wiring time (`Handle::block_on`), clamps each row through `WindowFilter`, and feeds the finite rows to `replay_results`. - `postgres_sub` — realtime `LISTEN`/`NOTIFY` live tail on `produce_async`; rejects `RunMode::HistoricalFrom` at wiring (live, unbounded stream). - `PostgresSinkOps::postgres_write` — streaming insert sink over `consume_async`, connecting eagerly at wiring, per-burst pipelined. Password redaction (classic PR #433) is reproduced: `PostgresConnection::redacted()` masks the DSN `password=...` token at every `connect()` error site. Parity tests ported: no-service `tests/postgres_adapter.rs` (validation, connection-refused + redaction, historical rejection) and container-backed `tests/postgres_integration.rs` (gated `postgres-integration-test`, testcontainers). Classic example ported to `examples/postgres_adapter/`. CI wired into the integration-tests hub; port-plan updated. Claude-Session: https://claude.ai/code/session_01SEQvysabaSKTnYyQDgPDTt Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
postgres_read/write/sub embedded the full libpq connection string —
including password=... — in anyhow error context, so credentials could
reach logs and graph-abort errors. Add PostgresConnection::redacted(),
which masks the password token while preserving every other field, and
use it at all three connect() error sites.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_014mNRkJnZZGC1QUULgbbwnA