Build-configuration-driven logging so debugging is rich locally while the installed app stays quiet.
New ClaudeDo.Logging library: BuildConfig.IsDebug (runtime DebuggableAttribute check, no #if DEBUG), DefaultTaskIdEnricher, and LoggingSetup.Configure (the single shared Serilog setup both processes call).
Worker + App/Ui now write ONE shared rolling file ~/.todo-app/logs/claudedo-.log (retain 2), each line tagged with a Process and SourceContext. The App/Ui were previously log-silent.
TaskId correlation rides Serilog LogContext: pushed in TaskRunner.RunAsync/ContinueAsync (Worker) and in WorkerClient.InvokeForTaskAsync (UI). Grep one TaskId to follow a task UI -> Worker -> UI.
IWorkerClient / WorkerHub contracts unchanged; only the concrete WorkerClient ctor gained an ILogger param, so test fakes are unaffected.
Test plan
dotnet build App + Worker (Release): 0 errors
Worker.Tests: 419 pass (incl. 4 new logging tests)
Manual (visual-verification gap): run App + Worker from Rider (Debug), confirm both log to one claudedo-*.log + console; run a task and confirm UI and Worker lines share the same [TaskId]
Manual: install Release build, confirm log is Warning+ only and no console output
Review notes (non-blocking)
BuildConfig.IsDebug uses GetEntryAssembly(), which is null under the test host -> the BuildConfigTests assertion is effectively a tautology. This is correct for production (entry assembly = the App/Worker exe) and the spec already accepted that the branch can't be flipped within one test run.
InvokeForTaskAsync's LogContext scope currently only decorates the single debug trace line; kept as a forward-looking hook for future UI log lines on that path.
See docs/superpowers/specs/2026-06-04-debug-logging-traceability-design.md and the matching plan in docs/superpowers/plans/.
## Summary
Build-configuration-driven logging so debugging is rich locally while the installed app stays quiet.
- New `ClaudeDo.Logging` library: `BuildConfig.IsDebug` (runtime `DebuggableAttribute` check, no `#if DEBUG`), `DefaultTaskIdEnricher`, and `LoggingSetup.Configure` (the single shared Serilog setup both processes call).
- **Debug builds** (Rider run button): `Debug` level, console + file. **Release builds** (installed app): `Warning` level, file only.
- Worker + App/Ui now write ONE shared rolling file `~/.todo-app/logs/claudedo-.log` (retain 2), each line tagged with a `Process` and `SourceContext`. The App/Ui were previously log-silent.
- `TaskId` correlation rides Serilog `LogContext`: pushed in `TaskRunner.RunAsync`/`ContinueAsync` (Worker) and in `WorkerClient.InvokeForTaskAsync` (UI). Grep one TaskId to follow a task UI -> Worker -> UI.
- `IWorkerClient` / `WorkerHub` contracts unchanged; only the concrete `WorkerClient` ctor gained an `ILogger` param, so test fakes are unaffected.
## Test plan
- [x] `dotnet build` App + Worker (Release): 0 errors
- [x] Worker.Tests: 419 pass (incl. 4 new logging tests)
- [ ] **Manual (visual-verification gap):** run App + Worker from Rider (Debug), confirm both log to one `claudedo-*.log` + console; run a task and confirm UI and Worker lines share the same `[TaskId]`
- [ ] **Manual:** install Release build, confirm log is `Warning`+ only and no console output
## Review notes (non-blocking)
- `BuildConfig.IsDebug` uses `GetEntryAssembly()`, which is null under the test host -> the `BuildConfigTests` assertion is effectively a tautology. This is correct for production (entry assembly = the App/Worker exe) and the spec already accepted that the branch can't be flipped within one test run.
- `InvokeForTaskAsync`'s `LogContext` scope currently only decorates the single debug trace line; kept as a forward-looking hook for future UI log lines on that path.
See `docs/superpowers/specs/2026-06-04-debug-logging-traceability-design.md` and the matching plan in `docs/superpowers/plans/`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Build-configuration-driven logging so debugging is rich locally while the installed app stays quiet.
ClaudeDo.Logginglibrary:BuildConfig.IsDebug(runtimeDebuggableAttributecheck, no#if DEBUG),DefaultTaskIdEnricher, andLoggingSetup.Configure(the single shared Serilog setup both processes call).Debuglevel, console + file. Release builds (installed app):Warninglevel, file only.~/.todo-app/logs/claudedo-.log(retain 2), each line tagged with aProcessandSourceContext. The App/Ui were previously log-silent.TaskIdcorrelation rides SerilogLogContext: pushed inTaskRunner.RunAsync/ContinueAsync(Worker) and inWorkerClient.InvokeForTaskAsync(UI). Grep one TaskId to follow a task UI -> Worker -> UI.IWorkerClient/WorkerHubcontracts unchanged; only the concreteWorkerClientctor gained anILoggerparam, so test fakes are unaffected.Test plan
dotnet buildApp + Worker (Release): 0 errorsclaudedo-*.log+ console; run a task and confirm UI and Worker lines share the same[TaskId]Warning+ only and no console outputReview notes (non-blocking)
BuildConfig.IsDebugusesGetEntryAssembly(), which is null under the test host -> theBuildConfigTestsassertion is effectively a tautology. This is correct for production (entry assembly = the App/Worker exe) and the spec already accepted that the branch can't be flipped within one test run.InvokeForTaskAsync'sLogContextscope currently only decorates the single debug trace line; kept as a forward-looking hook for future UI log lines on that path.See
docs/superpowers/specs/2026-06-04-debug-logging-traceability-design.mdand the matching plan indocs/superpowers/plans/.🤖 Generated with Claude Code
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.