fix: resolve log analysis findings (Ollama prefix, logging, init)#748
fix: resolve log analysis findings (Ollama prefix, logging, init)#748
Conversation
…, format_exc_info) - Remove `ollama/` prefix from `_parse_ollama_models()` -- the driver already prepends the provider name, causing double-prefixing that made LiteLLM send `ollama/model-name` to Ollama's API instead of bare name - Add faker and faker.factory to third-party logger taming list to suppress locale resolution DEBUG noise in Docker logs - Move `format_exc_info` from shared `_BASE_PROCESSORS` to per-sink processors (JSON sinks only) to eliminate structlog UserWarning when ConsoleRenderer handles exceptions natively - Remove log level selector from `synthorg init` wizard -- default is already `info` per architecture spec, runtime changes via web UI Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Pre-reviewed by 8 agents, 13 findings addressed: - Update docs/design/operations.md: add faker/faker.factory to tamed loggers list, document format_exc_info JSON-only behavior - Add tests for format_exc_info processor chain placement (console excludes, JSON includes) and Go config set log_level round-trip - Extract helpers to fix function length violations: _build_formatter, _ensure_log_dir, _handle_sink_failure, printInitSuccess - Remove format_exc_info from test_sinks._foreign_pre_chain to match production processor chain - Add CLAUDE.md carve-out for observability bootstrap logging Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
🧰 Additional context used📓 Path-based instructions (2){**/*.py,cli/**/*.go}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
cli/**/*_test.go📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (5)📓 Common learnings📚 Learning: 2026-03-22T16:44:15.487ZApplied to files:
📚 Learning: 2026-03-19T11:19:40.044ZApplied to files:
📚 Learning: 2026-03-19T11:30:29.217ZApplied to files:
📚 Learning: 2026-03-19T11:30:29.217ZApplied to files:
🧬 Code graph analysis (1)cli/cmd/config_test.go (2)
🔇 Additional comments (3)
WalkthroughLogging rules now allow stdlib 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request primarily focuses on refining the logging infrastructure and correcting a specific model naming issue. The changes aim to reduce log noise, ensure consistent and correct exception formatting across various log sinks, and streamline the initial setup experience by simplifying log level configuration. Additionally, the PR improves code maintainability through refactoring and updates documentation to reflect these enhancements. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request refactors the logging system to improve clarity and robustness, particularly around exception handling and sink initialization. Key changes include centralizing log sink failure handling and directory creation into dedicated helper functions, and conditionally applying format_exc_info based on the log sink type (JSON vs. console) to optimize exception rendering. The init command's interactive log level selection was removed, and new tests were added to validate config set log_level functionality. Additionally, the representation of Ollama model IDs was simplified by removing the 'ollama/' prefix, and faker loggers were added to the list of suppressed noisy loggers.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cli/cmd/config_test.go`:
- Around line 287-345: Add a native fuzz test named FuzzConfigSetLogLevel(f
*testing.F) that seeds valid and invalid log-level strings (e.g.,
"debug","info","warn","error","verbose","trace","", "INFO") via f.Add, then in
f.Fuzz create a temp dir, save config.DefaultState() with DataDir set, set
rootCmd output buffers, call
rootCmd.SetArgs([]string{"config","set","log_level", value, "--data-dir", dir})
and Execute(), and assert the command only succeeds (err == nil) when the input
equals one of the accepted values ("debug","info","warn","error") otherwise
expect an error; reference the existing tests and functions config.DefaultState,
config.Save, config.Load, rootCmd.SetArgs and rootCmd.Execute to locate and
mirror setup/teardown.
In `@tests/unit/observability/test_sinks.py`:
- Around line 169-182: Add a symmetric unit test that verifies non-JSON file
sinks do not include structlog.processors.format_exc_info: create a test named
like test_non_json_file_sink_excludes_format_exc_info that builds a SinkConfig
with sink_type=SinkType.FILE and json_format=False, call build_handler(sink,
tmp_path, _foreign_pre_chain()), assert the returned handler.formatter is a
ProcessorFormatter, and assert structlog.processors.format_exc_info is not in
handler.formatter.processors.
In `@tests/unit/providers/test_discovery.py`:
- Around line 82-83: The assertions use vendor-specific model IDs (result[0].id
== "llama3.2:latest", result[1].id == "codellama:7b"); update these to
vendor-agnostic test IDs (e.g., "test-provider:test-large-001",
"test-provider:test-small-001") so tests comply with the naming policy; change
the literal strings used in the assertions for result[0].id and result[1].id and
make the equivalent replacements noted for the other occurrences (the assertions
around lines 189-190) to keep consistency.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2465aafc-785b-47cf-917c-4418618b5cfe
📒 Files selected for processing (11)
CLAUDE.mdcli/cmd/config_test.gocli/cmd/init.godocs/design/operations.mdsrc/synthorg/observability/setup.pysrc/synthorg/observability/sinks.pysrc/synthorg/providers/probing.pytests/unit/api/controllers/test_providers.pytests/unit/observability/test_sinks.pytests/unit/providers/management/test_service_discovery.pytests/unit/providers/test_discovery.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Build Sandbox
- GitHub Check: Build Backend
- GitHub Check: Build Web
- GitHub Check: Test (Python 3.14)
- GitHub Check: CLI Test (windows-latest)
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Nofrom __future__ import annotations—Python 3.14 has PEP 649 native lazy annotations.
Useexcept A, B:(no parentheses) per PEP 758 except syntax for Python 3.14.
Type hints are required on all public functions; use mypy strict mode.
Use Google-style docstrings required on public classes and functions, enforced by ruff D rules.
Fordict/listfields in frozen Pydantic models, rely onfrozen=Truefor field reassignment prevention and usecopy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization).
Never mix static config fields with mutable runtime fields in one model. Use frozen Pydantic models for config/identity and separate mutable-via-copy models for runtime state that evolves.
Use Pydantic v2 (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values instead of storing redundant fields. UseNotBlankStrfor all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Files:
tests/unit/api/controllers/test_providers.pytests/unit/providers/management/test_service_discovery.pytests/unit/providers/test_discovery.pysrc/synthorg/providers/probing.pysrc/synthorg/observability/sinks.pytests/unit/observability/test_sinks.pysrc/synthorg/observability/setup.py
{**/*.py,cli/**/*.go}
📄 CodeRabbit inference engine (CLAUDE.md)
Line length is 88 characters (enforced by ruff).
Files:
tests/unit/api/controllers/test_providers.pytests/unit/providers/management/test_service_discovery.pytests/unit/providers/test_discovery.pysrc/synthorg/providers/probing.pycli/cmd/config_test.gosrc/synthorg/observability/sinks.pytests/unit/observability/test_sinks.pycli/cmd/init.gosrc/synthorg/observability/setup.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use test markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow.
Test timeout is 30 seconds per test globally inpyproject.toml—do not add per-filepytest.mark.timeout(30)markers; only non-default overrides liketimeout(60)are allowed.
Prefer@pytest.mark.parametrizefor testing similar cases.
In tests, usetest-provider,test-small-001, etc. instead of vendor-specific names.
Use Hypothesis for property-based testing in Python with@givenand@settingsdecorators. Use profiles:ci(50 examples, default) anddev(1000 examples).
For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()to make them deterministic instead of widening timing margins.
For tasks that must block indefinitely until cancelled (e.g., simulating slow providers), useasyncio.Event().wait()instead ofasyncio.sleep(large_number)—it is cancellation-safe and carries no timing assumptions.
Files:
tests/unit/api/controllers/test_providers.pytests/unit/providers/management/test_service_discovery.pytests/unit/providers/test_discovery.pytests/unit/observability/test_sinks.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Create new objects instead of mutating existing ones. For non-Pydantic internal collections (registries,BaseTool), usecopy.deepcopy()at construction andMappingProxyTypewrapping for read-only enforcement.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code (e.g., multiple tool invocations, parallel agent calls). Prefer structured concurrency over barecreate_task.
Functions should be less than 50 lines; files should be less than 800 lines.
Every module with business logic MUST import logger:from synthorg.observability import get_loggerthenlogger = get_logger(__name__).
Never useimport logging,logging.getLogger(), orprint()in application code.
Variable name for logger is alwayslogger(not_logger, notlog).
Always use constants from domain-specific modules undersynthorg.observability.eventsfor event names (e.g.,API_REQUEST_STARTEDfromevents.api,TOOL_INVOKE_STARTfromevents.tool). Import directly:from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Use structured logging: alwayslogger.info(EVENT, key=value)—neverlogger.info("msg %s", val).
All error paths must log at WARNING or ERROR with context before raising.
All state transitions must log at INFO.
DEBUG logging is for object creation, internal flow, and entry/exit of key functions.
Pure data models, enums, and re-exports do NOT need logging.
NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001,large/medium/smallas aliases.
Files:
src/synthorg/providers/probing.pysrc/synthorg/observability/sinks.pysrc/synthorg/observability/setup.py
src/synthorg/providers/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/providers/**/*.py: All provider calls go throughBaseCompletionProviderwhich applies retry and rate limiting automatically. Never implement retry logic in driver subclasses or calling code.
RetryConfig and RateLimiterConfig are set per-provider inProviderConfig; retryable errors (RateLimitError,ProviderTimeoutError,ProviderConnectionError,ProviderInternalError) are automatically retried; non-retryable errors raise immediately.
Rate limiter respectsRateLimitError.retry_afterfrom providers—automatically pauses future requests.
Files:
src/synthorg/providers/probing.py
src/synthorg/{providers,engine}/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
RetryExhaustedErrorsignals that all retries failed—the engine layer catches this to trigger fallback chains.
Files:
src/synthorg/providers/probing.py
cli/**/*_test.go
📄 CodeRabbit inference engine (CLAUDE.md)
Use property-based testing in Go with native
testing.Ffuzz functions.
Files:
cli/cmd/config_test.go
docs/design/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
When approved deviations occur, update the relevant
docs/design/page to reflect the new reality.
Files:
docs/design/operations.md
🧠 Learnings (26)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability includes structured logging via `get_logger(__name__)`, correlation tracking, and log sinks.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability must use structured logging with correlation tracking and log sinks
📚 Learning: 2026-03-22T16:44:15.487Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T16:44:15.487Z
Learning: Applies to tests/**/*.py : In tests, use `test-provider`, `test-small-001`, etc. instead of vendor-specific names.
Applied to files:
tests/unit/api/controllers/test_providers.pytests/unit/providers/management/test_service_discovery.pytests/unit/providers/test_discovery.py
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to tests/**/*.py : Tests must use test-provider, test-small-001, etc. for vendor-agnostic test data.
Applied to files:
tests/unit/api/controllers/test_providers.pytests/unit/providers/management/test_service_discovery.pytests/unit/providers/test_discovery.py
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/providers/**/*.py : Providers: LLM provider abstraction (LiteLLM adapter), auth types (api_key/oauth/custom_header/none), presets (PROVIDER_PRESETS), runtime CRUD (ProviderManagementService with asyncio.Lock serialization), hot-reload via AppState swap.
Applied to files:
tests/unit/api/controllers/test_providers.pytests/unit/providers/management/test_service_discovery.pysrc/synthorg/providers/probing.py
📚 Learning: 2026-03-22T16:44:15.487Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T16:44:15.487Z
Learning: Applies to src/synthorg/**/*.py : Never use `import logging`, `logging.getLogger()`, or `print()` in application code.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to src/**/*.py : Every module with business logic must import get_logger from ai_company.observability and define logger = get_logger(__name__); never use import logging or logging.getLogger() or print() in application code
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Never use `import logging`, `logging.getLogger()`, or `print()` in application code; use the injected logger instead
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Never use `import logging` / `logging.getLogger()` / `print()` in application code
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Never use `import logging`, `logging.getLogger()`, or `print()` in application code — use the synthorg logger instead
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-14T16:18:57.267Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T16:18:57.267Z
Learning: Applies to src/ai_company/!(observability)/**/*.py : Use DEBUG logging for object creation, internal flow, and entry/exit of key functions.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Never use `import logging` / `logging.getLogger()` / `print()` in application code. Variable name: always `logger` (not `_logger`, not `log`).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-17T06:43:14.114Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:43:14.114Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Never use `import logging` / `logging.getLogger()` / `print()` in application code. Variable name: always `logger`.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Never use import logging / logging.getLogger() / print() in application code.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-22T16:44:15.487Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T16:44:15.487Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST import logger: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`.
Applied to files:
CLAUDE.mdsrc/synthorg/observability/setup.py
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import logger via `from synthorg.observability import get_logger` and initialize with `logger = get_logger(__name__)`
Applied to files:
CLAUDE.mdsrc/synthorg/observability/setup.py
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import `from synthorg.observability import get_logger` and define `logger = get_logger(__name__)`
Applied to files:
CLAUDE.mdsrc/synthorg/observability/setup.py
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability includes structured logging via `get_logger(__name__)`, correlation tracking, and log sinks.
Applied to files:
docs/design/operations.mdsrc/synthorg/observability/sinks.pysrc/synthorg/observability/setup.py
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability must use structured logging with correlation tracking and log sinks
Applied to files:
docs/design/operations.mdsrc/synthorg/observability/sinks.pytests/unit/observability/test_sinks.pysrc/synthorg/observability/setup.py
📚 Learning: 2026-03-17T06:43:14.114Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:43:14.114Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions. Pure data models, enums, and re-exports do NOT need logging.
Applied to files:
docs/design/operations.mdsrc/synthorg/observability/setup.py
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Log all error paths at WARNING or ERROR with context before raising; log all state transitions at INFO; log object creation/internal flow/entry-exit at DEBUG
Applied to files:
docs/design/operations.mdsrc/synthorg/observability/setup.py
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability package (observability/): structured logging, correlation tracking, log sinks; event constants organized by domain under observability/events/ (e.g., events.api, events.tool, events.git, events.context_budget, events.backup)
Applied to files:
docs/design/operations.mdsrc/synthorg/observability/sinks.pysrc/synthorg/observability/setup.py
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions.
Applied to files:
docs/design/operations.mdsrc/synthorg/observability/setup.py
📚 Learning: 2026-03-15T16:55:07.730Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T16:55:07.730Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising.
Applied to files:
docs/design/operations.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Variable name for logger: always `logger` (not `_logger`, not `log`)
Applied to files:
docs/design/operations.md
📚 Learning: 2026-03-16T07:22:28.134Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T07:22:28.134Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, and key function entry/exit
Applied to files:
src/synthorg/observability/setup.py
🧬 Code graph analysis (6)
tests/unit/api/controllers/test_providers.py (2)
web/src/api/types.ts (1)
ProviderModelConfig(453-460)src/synthorg/config/schema.py (1)
ProviderModelConfig(44-83)
cli/cmd/config_test.go (2)
cli/internal/config/state.go (3)
DefaultState(36-48)Save(230-244)Load(65-103)cli/cmd/root.go (1)
Execute(101-107)
src/synthorg/observability/sinks.py (1)
src/synthorg/observability/config.py (1)
SinkConfig(51-113)
tests/unit/observability/test_sinks.py (2)
src/synthorg/observability/config.py (2)
SinkConfig(51-113)RotationConfig(22-48)src/synthorg/observability/sinks.py (1)
build_handler(202-235)
cli/cmd/init.go (2)
cli/internal/ui/ui.go (1)
UI(46-57)cli/internal/config/state.go (1)
StatePath(59-61)
src/synthorg/observability/setup.py (1)
src/synthorg/observability/config.py (1)
SinkConfig(51-113)
🔇 Additional comments (15)
CLAUDE.md (1)
162-162: LGTM!The carve-out is appropriately scoped to the bootstrap/handler-cleanup paths in
observability/setup.pyandobservability/sinks.py. These modules legitimately need stdlibloggingandprint(..., file=sys.stderr)because they run before or during logging system configuration.docs/design/operations.md (2)
1241-1244: LGTM!Documentation accurately reflects the new
format_exc_infoplacement: JSON sinks include it for serialization, console sinks omit it becauseConsoleRendererhandles exception rendering natively.
1336-1336: LGTM!Correctly documents the addition of
fakerandfaker.factoryto the third-party logger taming list.tests/unit/observability/test_sinks.py (1)
81-99: LGTM!Tests correctly verify the conditional
format_exc_infoplacement for console sinks: excluded for text format (ConsoleRenderer handles exceptions), included for JSON format (serialization needs string tracebacks).src/synthorg/observability/sinks.py (3)
116-129: LGTM!Clean extraction of directory creation logic with proper error handling. The
RuntimeErrorincludes context about which sink failed, aiding diagnostics.
175-199: LGTM!The formatter builder correctly applies
format_exc_infoonly for JSON sinks. The processor chain order is correct:remove_processors_meta→format_exc_info(JSON only) → renderer.
227-227: LGTM!Clean delegation to the extracted
_build_formatterhelper.src/synthorg/observability/setup.py (3)
56-57: LGTM!Adding
fakerandfaker.factoryto third-party logger taming appropriately suppresses the ~150 lines of locale-resolution DEBUG noise mentioned in the PR objectives.
138-172: LGTM!Clean extraction of sink failure handling with appropriate differentiation between critical sinks (
audit.log,access.log) that cause hard failures and non-critical sinks that are skipped with warnings. Thefrozensetprovides O(1) lookup and immutability.
204-204: LGTM!Clean delegation to the extracted
_handle_sink_failurehelper simplifies_attach_handlers.cli/cmd/init.go (1)
87-99: Canonicalized init output paths are now consistent — good change.Using the sanitized directory for “Data dir”, “Compose file”, and “Config” keeps the
success output aligned with what is actually persisted.src/synthorg/providers/probing.py (2)
190-199: Docstring update is clear and aligned with actual probing behavior.This wording now matches the implementation details (preset-registry resolution and single request per candidate).
259-259: Model ID normalization fix looks correct.Using
id=namehere correctly removes the duplicateollama/prefixing path.tests/unit/api/controllers/test_providers.py (1)
168-169: Test expectation update is correct.These IDs now align with the updated discovery output contract.
tests/unit/providers/management/test_service_discovery.py (1)
38-39: These expectation updates are consistent and correct.Good alignment with the non-prefixed discovered model IDs across service discovery paths.
Also applies to: 117-118, 141-141
- Fix operations.md sink count ("10 file sinks" -> "11 sinks (10 file +
1 console)") and format_exc_info note (gate on json_format, not sink
type)
- Replace vendor-specific model IDs in test_discovery.py with
vendor-agnostic names (test-large-001, test-small-001, test-model-*)
- Add test_non_json_file_sink_excludes_format_exc_info for symmetric
coverage of the format_exc_info processor chain placement
- Add FuzzConfigSetLogLevel fuzz test mirroring FuzzConfigSetAutoCleanup
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cli/cmd/config_test.go`:
- Around line 327-345: In TestConfigSetRejectsInvalidLogLevel, after saving the
initial state (state := config.DefaultState(); config.Save(state)), capture the
persisted log level (e.g., orig := state.LogLevel), and for each rejected
attempt inside the loop re-load the persisted state using the config package
load function (e.g., config.Load or the repository's equivalent) and assert that
the reloaded state's LogLevel still equals orig; add this check after each
failed rootCmd.Execute() to ensure invalid updates do not mutate the saved
value.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 7c416ee7-e83a-47a3-b8b2-889c53916a97
📒 Files selected for processing (4)
cli/cmd/config_test.godocs/design/operations.mdtests/unit/observability/test_sinks.pytests/unit/providers/test_discovery.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build Backend
- GitHub Check: Build Sandbox
- GitHub Check: CLI Test (windows-latest)
- GitHub Check: Test (Python 3.14)
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (5)
docs/design/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
When approved deviations occur, update the relevant
docs/design/page to reflect the new reality.
Files:
docs/design/operations.md
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Nofrom __future__ import annotations—Python 3.14 has PEP 649 native lazy annotations.
Useexcept A, B:(no parentheses) per PEP 758 except syntax for Python 3.14.
Type hints are required on all public functions; use mypy strict mode.
Use Google-style docstrings required on public classes and functions, enforced by ruff D rules.
Fordict/listfields in frozen Pydantic models, rely onfrozen=Truefor field reassignment prevention and usecopy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization).
Never mix static config fields with mutable runtime fields in one model. Use frozen Pydantic models for config/identity and separate mutable-via-copy models for runtime state that evolves.
Use Pydantic v2 (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values instead of storing redundant fields. UseNotBlankStrfor all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Files:
tests/unit/observability/test_sinks.pytests/unit/providers/test_discovery.py
{**/*.py,cli/**/*.go}
📄 CodeRabbit inference engine (CLAUDE.md)
Line length is 88 characters (enforced by ruff).
Files:
tests/unit/observability/test_sinks.pycli/cmd/config_test.gotests/unit/providers/test_discovery.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use test markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow.
Test timeout is 30 seconds per test globally inpyproject.toml—do not add per-filepytest.mark.timeout(30)markers; only non-default overrides liketimeout(60)are allowed.
Prefer@pytest.mark.parametrizefor testing similar cases.
In tests, usetest-provider,test-small-001, etc. instead of vendor-specific names.
Use Hypothesis for property-based testing in Python with@givenand@settingsdecorators. Use profiles:ci(50 examples, default) anddev(1000 examples).
For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()to make them deterministic instead of widening timing margins.
For tasks that must block indefinitely until cancelled (e.g., simulating slow providers), useasyncio.Event().wait()instead ofasyncio.sleep(large_number)—it is cancellation-safe and carries no timing assumptions.
Files:
tests/unit/observability/test_sinks.pytests/unit/providers/test_discovery.py
cli/**/*_test.go
📄 CodeRabbit inference engine (CLAUDE.md)
Use property-based testing in Go with native
testing.Ffuzz functions.
Files:
cli/cmd/config_test.go
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability includes structured logging via `get_logger(__name__)`, correlation tracking, and log sinks.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability must use structured logging with correlation tracking and log sinks
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability package (observability/): structured logging, correlation tracking, log sinks; event constants organized by domain under observability/events/ (e.g., events.api, events.tool, events.git, events.context_budget, events.backup)
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T16:18:57.267Z
Learning: Applies to src/ai_company/!(observability)/**/*.py : Use DEBUG logging for object creation, internal flow, and entry/exit of key functions.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:43:14.114Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Never use `import logging` / `logging.getLogger()` / `print()` in application code. Variable name: always `logger`.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Never use `import logging` / `logging.getLogger()` / `print()` in application code. Variable name: always `logger` (not `_logger`, not `log`).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to src/**/*.py : Every module with business logic must import get_logger from ai_company.observability and define logger = get_logger(__name__); never use import logging or logging.getLogger() or print() in application code
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Never use import logging / logging.getLogger() / print() in application code.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:43:14.114Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions. Pure data models, enums, and re-exports do NOT need logging.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import logger via `from synthorg.observability import get_logger` and initialize with `logger = get_logger(__name__)`
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability includes structured logging via `get_logger(__name__)`, correlation tracking, and log sinks.
Applied to files:
docs/design/operations.md
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability must use structured logging with correlation tracking and log sinks
Applied to files:
docs/design/operations.mdtests/unit/observability/test_sinks.py
📚 Learning: 2026-03-17T06:43:14.114Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:43:14.114Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions. Pure data models, enums, and re-exports do NOT need logging.
Applied to files:
docs/design/operations.md
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Log all error paths at WARNING or ERROR with context before raising; log all state transitions at INFO; log object creation/internal flow/entry-exit at DEBUG
Applied to files:
docs/design/operations.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability package (observability/): structured logging, correlation tracking, log sinks; event constants organized by domain under observability/events/ (e.g., events.api, events.tool, events.git, events.context_budget, events.backup)
Applied to files:
docs/design/operations.md
📚 Learning: 2026-03-22T16:44:15.487Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T16:44:15.487Z
Learning: Applies to cli/**/*_test.go : Use property-based testing in Go with native `testing.F` fuzz functions.
Applied to files:
cli/cmd/config_test.go
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to cli/**/*.go : Use native Go testing with `testing.F` fuzz functions (`Fuzz*`) for fuzz testing.
Applied to files:
cli/cmd/config_test.go
📚 Learning: 2026-03-19T11:30:29.217Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:30:29.217Z
Learning: Applies to cli/**/*.go : Use native `testing.F` fuzz functions (`Fuzz*`) for fuzz testing Go code
Applied to files:
cli/cmd/config_test.go
📚 Learning: 2026-03-19T11:30:29.217Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:30:29.217Z
Learning: Applies to cli/**/*.go : Run Go lint via `golangci-lint run`, vet via `go vet`, tests via `go test ./...`, and fuzz via `go test -fuzz=FuzzTarget -fuzztime=30s`
Applied to files:
cli/cmd/config_test.go
📚 Learning: 2026-03-22T16:44:15.487Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T16:44:15.487Z
Learning: Applies to tests/**/*.py : In tests, use `test-provider`, `test-small-001`, etc. instead of vendor-specific names.
Applied to files:
tests/unit/providers/test_discovery.py
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to tests/**/*.py : Tests must use test-provider, test-small-001, etc. for vendor-agnostic test data.
Applied to files:
tests/unit/providers/test_discovery.py
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to {src,tests,web,cli,site}/**/*.{py,ts,tsx,go,astro} : Vendor-agnostic everywhere: NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names: example-provider, example-large-001, example-medium-001, example-small-001. Vendor names may only appear in: (1) Operations design page provider list (docs/design/operations.md), (2) .claude/ skill/agent files, (3) third-party import paths/module names.
Applied to files:
tests/unit/providers/test_discovery.py
📚 Learning: 2026-03-22T16:44:15.487Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T16:44:15.487Z
Learning: Applies to src/synthorg/**/*.py : NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names: `example-provider`, `example-large-001`, `example-medium-001`, `example-small-001`, `large`/`medium`/`small` as aliases.
Applied to files:
tests/unit/providers/test_discovery.py
🧬 Code graph analysis (2)
tests/unit/observability/test_sinks.py (2)
src/synthorg/observability/config.py (2)
SinkConfig(51-113)RotationConfig(22-48)src/synthorg/observability/sinks.py (1)
build_handler(202-235)
cli/cmd/config_test.go (3)
cli/internal/config/state.go (3)
DefaultState(36-48)Save(230-244)Load(65-103)cli/internal/config/paths.go (1)
DataDir(18-31)cli/cmd/root.go (1)
Execute(101-107)
🔇 Additional comments (8)
tests/unit/providers/test_discovery.py (3)
68-69: Vendor-agnostic fixture names look correct.These updated mock model names are policy-compliant and keep the test intent intact.
As per coding guidelines:
In tests, use test-provider, test-small-001, etc. instead of vendor-specific names.
82-83: Assertions correctly match the new unprefixed Ollama IDs.Good update to validate raw discovered IDs after removing the extra
ollama/prefix behavior.
172-172: Malformed-entry coverage remains intact with normalized IDs.This keeps the malformed filtering behavior test clear while complying with naming policy.
Based on learnings:
Applies to tests/**/*.py : Tests must use test-provider, test-small-001, etc. for vendor-agnostic test data.Also applies to: 176-176, 189-190
tests/unit/observability/test_sinks.py (2)
81-100: Good branch coverage for console sink formatting behavior.These tests clearly validate both JSON and non-JSON console paths and protect the refactor intent.
169-198: Symmetric file-sink coverage looks solid.Nice addition of both include/exclude assertions for JSON vs non-JSON file formatting paths.
docs/design/operations.md (1)
1241-1245: Docs are correctly aligned with the observability changes.The updates accurately reflect JSON-only exception formatting, faker logger taming, and the corrected 11-sink layout.
Also applies to: 1336-1337, 1348-1350
cli/cmd/config_test.go (2)
287-325: Valid log-level round-trip coverage looks solid.Good positive-path assertions here: command execution plus persisted config verification.
347-379: Fuzz coverage is correctly added forlog_levelvalidation.This is a strong complement to table tests and improves resilience against edge inputs.
As per coding guidelines,
cli/**/*_test.go: Use property-based testing in Go with nativetesting.Ffuzz functions.
Add post-rejection config.Load assertion in TestConfigSetRejectsInvalidLogLevel to ensure invalid values leave the saved LogLevel unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #748 +/- ##
=======================================
Coverage 92.27% 92.28%
=======================================
Files 573 573
Lines 29655 29664 +9
Branches 2870 2871 +1
=======================================
+ Hits 27365 27374 +9
Misses 1810 1810
Partials 480 480 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🤖 I have created a release *beep* *boop* --- ## [0.4.8](v0.4.7...v0.4.8) (2026-03-22) ### Features * add auto_cleanup config and improve update UX ([#741](#741)) ([289638f](289638f)) * add reporting lines, escalation paths, and workflow handoffs to templates ([#745](#745)) ([c374cc9](c374cc9)) * differentiate template operational configs ([#742](#742)) ([9b48345](9b48345)) * diversify personality preset assignments across templates ([#743](#743)) ([15487a5](15487a5)) * improve template metadata -- skill taxonomy, descriptions, tags, and display names ([#752](#752)) ([f333f24](f333f24)) ### Bug Fixes * resolve log analysis findings (Ollama prefix, logging, init) ([#748](#748)) ([8f871a4](8f871a4)) * use git tag for dev release container image tags ([#749](#749)) ([f30d071](f30d071)) * use subordinate_id/supervisor_id in HierarchyResolver ([#751](#751)) ([118235b](118235b)) ### Performance * add long-lived cache headers for content-hashed static assets ([#747](#747)) ([4d350b5](4d350b5)) * use worksteal distribution for pytest-xdist ([#750](#750)) ([b7dd7de](b7dd7de)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Summary
_parse_ollama_models()-- the driver already prepends the provider name, so theollama/prefix in probing causedollama/ollama/model-nameto be sent to LiteLLMfakerandfaker.factoryto third-party logger taming to suppress 150+ lines of locale resolution DEBUG noise in Docker logsformat_exc_infofrom shared_BASE_PROCESSORSto per-sink processors (JSON sinks only) to eliminate structlog UserWarning conflict withConsoleRenderersynthorg initwizard -- default isinfoper architecture spec, runtime changes available via web UI andsynthorg config set log_level_build_formatter,_ensure_log_dir,_handle_sink_failure,printInitSuccessdocs/design/operations.mdto reflect faker taming and JSON-onlyformat_exc_infologging+printto stderr)format_exc_infoprocessor chain placement and Goconfig set log_levelround-tripTest plan
/analyse-logsto confirm no Ollama 404, no faker noise, no structlog warning, console at INFOPre-reviewed by 8 agents (docs-consistency, code-reviewer, python-reviewer, pr-test-analyzer, logging-audit, conventions-enforcer, go-reviewer, go-conventions-enforcer), 13 findings addressed.
🤖 Generated with Claude Code