From ae900589c3834a3d3f3e7406562b4b4480975254 Mon Sep 17 00:00:00 2001 From: implementer Date: Sun, 30 Aug 2026 03:52:55 +0000 Subject: [PATCH] docs: document the redacted resolved-configuration log in the non-container guide (E00-S04-T03) --- docs/development/non-container.md | 10 ++++++++-- packages/config/src/redact.ts | 8 ++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/development/non-container.md b/docs/development/non-container.md index a7c7459..9dba5c0 100644 --- a/docs/development/non-container.md +++ b/docs/development/non-container.md @@ -15,9 +15,9 @@ The workspace is a pnpm monorepo with three package groups: | Group | Path | Purpose | | --- | --- | --- | -| `apps/` | `apps/server` (`@personal-blog/server`) | Public server application. Serves the application health endpoint (E00-S02-T03) gated on the startup migration run (E00-S03-T06), and fails fast at startup with a field-specific error when a required setting is missing (E00-S04-T02); the Fastify 5 application shell lands in a later story. | +| `apps/` | `apps/server` (`@personal-blog/server`) | Public server application. Serves the application health endpoint (E00-S02-T03) gated on the startup migration run (E00-S03-T06), fails fast at startup with a field-specific error when a required setting is missing (E00-S04-T02), and redacts secret values from all log output (E00-S04-T03); the Fastify 5 application shell lands in a later story. | | `packages/` | `packages/core` (`@personal-blog/core`) | Application core (site identity, content primitives). Bootstrap placeholder. | -| `packages/` | `packages/config` (`@personal-blog/config`) | Configuration service. Owns the TypeBox/Ajv configuration schema for the validated config fields (E00-S04-T01) and the field-specific startup error for a missing required setting (E00-S04-T02); the environment adapter (E00-S04-T04) and secret redaction (E00-S04-T03) land in later tasks. | +| `packages/` | `packages/config` (`@personal-blog/config`) | Configuration service. Owns the TypeBox/Ajv configuration schema for the validated config fields (E00-S04-T01), the field-specific startup error for a missing required setting (E00-S04-T02) and the secret redaction layer (E00-S04-T03); the environment adapter (E00-S04-T04) and the `.env.example` template (E00-S04-T05) land in later tasks. | | `packages/` | `packages/database-postgres` (`@personal-blog/database-postgres`) | PostgreSQL database adapter package. Single owner of the `pg`/Kysely driver imports (E00-S03-T02); the migration ledger (`schema_migrations`, E00-S03-T03), the migration advisory lock (E00-S03-T04) and the migration runner with its failure diagnostic (E00-S03-T05) are implemented here. The server depends on this package to run the startup migrations behind its readiness gate (E00-S03-T06). | | `extensions/` | `extensions/example` (`@personal-blog/example-extension`) | Example extension exercising the `extensions/` group. Bootstrap placeholder. | @@ -113,6 +113,12 @@ compiled application entrypoint. Three things to know: answers 200 `{"status":"ok"}` from the start. The real Fastify 5 application shell — which turns this into the full serving API — lands in a later story; the `start` command shape stays the same once it does. +4. Since [E00-S04-T03], the server **logs its resolved configuration at + startup with secret values redacted**: the first log line is + `[config] resolved configuration: {"host":"0.0.0.0","port":3000, ..., + "sessionSecret":"[REDACTED]"}`, and every log line passes through the + redacting logger — the admin-session secret and the password embedded in a + `DATABASE_URL` connection string never appear in the log output. To run the compiled output of any other workspace package directly: diff --git a/packages/config/src/redact.ts b/packages/config/src/redact.ts index 8428bfd..302062a 100644 --- a/packages/config/src/redact.ts +++ b/packages/config/src/redact.ts @@ -17,10 +17,10 @@ * a secret value (e.g. an error message carrying a connection string) is * redacted even when the value was not redacted by field. * - * Both feed the server's redacting logger (`apps/server/src/logger.ts`), so - * secret values never reach stdout/stderr — the acceptance criteria: - * "secrets automatically redact from logs", "log output contains no secret - * values". + * Both feed the server's redacting logger (the `createLogger` in + * `apps/server/src/index.ts`), so secret values never reach stdout/stderr — + * the acceptance criteria: "secrets automatically redact from logs", "log + * output contains no secret values". * * Rollback note from the issue: revert the redaction changes. */