--- id: decide-log-facade-adoption name: Decide the log-facade posture (review 004 item 7, family-level) status: completed depends_on: [] scope: narrow risk: low impact: project level: implementation tags: [review-004-fixes, cross-cutting, decision] --- ## Description The family-level decision the review recorded rather than made, per `docs/reviews/004-pre-release-general-review.md` §"Findings recorded, not fixed" item 7: the workspace has no log facade — 17 library-path `eprintln!` sites carry the engines' diagnostics (verified secret-free: no DSN/password material ever printed). An operator currently sees nothing before wake loss in the arms `pg-fix-forwarder-diagnosability` will fix, and the fix's *output form* depends on this decision — which is why that task depends on this one. Decide, with the user (a family-level call): - **Adopt `log`** (facade-only; consumers wire the sink) — the light shape; check the family repos (alkcall/alktunnels/alksocks/alktty) for the house posture first and follow it if one exists. - **Adopt `tracing`** — richer, heavier; only if the family precedent supports it. - **Keep `eprintln!`** — document the discipline as the posture of record (what gets printed, the secret-free rule, the no-facade rationale). Considerations to weigh in the record: core's three-dependency posture (ADR-020 §4 — a facade dep on `alkstore` is a contract change; an engines-only adoption is the lighter shape and probably the right scope); published-crate consumer expectations (a facade that emits nothing until the consumer installs a sink vs stderr noise they didn't ask for); the 17 existing sites' disposition under whichever option lands. Output: a decision of record — a new ADR (or an amendment to an existing one) if adopting; a documented posture in `deployment.md` (or the engine specs) if declining. Either way, the user's sign-off is part of the record. ## Acceptance Criteria - [x] The family-precedent check is done and recorded (what alkcall/alktunnels/alksocks/alktty do, if anything) - [x] The decision of record landed: ADR (adoption) or documented posture (decline), with the rationale and the core-dep question answered explicitly - [x] The 17 existing `eprintln!` sites' disposition under the decision is named (migrated / kept / reduced) - [x] User sign-off recorded - [x] Doc gate green (whatever text landed) ## References - docs/reviews/004-pre-release-general-review.md §"Findings recorded, not fixed" item 7 (the finding, the family-level framing) - docs/architecture/decisions/020-payload-encoding.md §4 (core's dependency posture — the constraint on core-side adoption) - docs/architecture/deployment.md (where a declining posture would be documented) - tasks/pg-fix-forwarder-diagnosability.md (the consumer of this decision) ## Notes > Decisions of record the description didn't pin: - **The decision landed as ADR** ([ADR-025](../docs/architecture/decisions/025-log-facade.md)): `tracing` adopted, **engine crates only**; core keeps its dependency posture and stays emit-free — that is the explicit core-dep answer. No subscriber dep anywhere in `[dependencies]`; `tracing-subscriber` stays a `[dev-dependencies]` affair only if a test ever needs to assert on emitted events (none does yet). - **The user's sign-off was taken in-session via a choose-one question** with the three options of the description plus the family-precedent evidence table (recorded 2026-10-11; "Adopt tracing" chosen). It is part of the ADR's §Status. - **The site count moved under this task's feet**: the description and the review carried 17; the re-grep at decision time found **19** genuine library-path sites (sqlite 10, pg 9) — the delta came from review 004's own inline fixes re-structuring the tick/lease failure arms. The ADR records both numbers honestly; all 19 migrated, None kept, None deleted. - **The migration rode this task rather than a follow-up** — the description's letter asked only for the disposition to be *named*, but leaving 19 `eprintln!` sites next to a written adoption ADR would have made the record aspirational and re-verified a stale count later; the mechanical migration is small enough to land with the decision (levels: `warn` = retried/degraded ops, `error` = unrecoverable-loss events: watcher death, discarded pooled clients, panic-path rollback failures). - **Substrate-lineage sites** (8 of the sqlite 10 — `watcher.rs` ×6, `schema.rs` ×1, `ops.rs` ×1; the other two are engine-owned `tx.rs`) rode the PROVENANCE delta discipline: register entry **D-41** (port delta) in `alkstore-sqlite/src/substrate/PROVENANCE.md`, per ADR-018's format; message text and the `alkstore:` prefix carried over unchanged, only the macro swapped. - **No consumer-inventory row** was required (ADR-017 §2's row-first gate is on contract extensions; this touches no trait/type/error surface — the ADR states that explicitly). ## Summary > The family-precedent check found all four repos (alkcall, > alktunnels, alksocks, alktty) on `tracing = "0.1"` facade-only, with > `tracing-subscriber` (env-filter) as a dev-dependency where it > appears — silent by default. The user signed off on adopting > tracing (2026-10-11, in-session question). The decision of record > is ADR-025: `tracing` in the engine crates (`alkstore-sqlite`, > `alkstore-postgres` gain the dep; core and mem stay dep- and > emit-free), subscriber wiring on the consumer/binary, the > secret-free rule promoted to standing law. The disposition landed > with the decision: all 19 library-path `eprintln!` sites (17 at > review time; +2 from the review's own inline fixes) migrated to > `tracing::warn!/error!` with message text and secret-free > discipline unchanged; the four substrate-lineage sites carry > PROVENANCE delta D-41. deployment.md gained a "Diagnostics posture" > section (operator recipe: `RUST_LOG=warn`/`error` at the consuming > binary; silent-by-default honesty), the architecture README's ADR > index and the design-decisions table gained the ADR-025 row, and > the CHANGELOG's 0.1.0 body states the facade and the recipe. > Verified: `cargo build`, `cargo test --workspace` (green, > server-less), `cargo clippy --all-targets -- -D warnings` > (clean), `cargo fmt --check` (clean), the doc gate > (`RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --workspace`, > zero warnings), the fuzz corpus replay (6/6). The consumer task > `pg-fix-forwarder-diagnosability` now has its output form pinned: > `tracing::warn!` on the failed reconnect connects (with > attempt/backoff context), `tracing::error!` on the loop-exit poll > error.