Skip to content

feat: replace hardcoded name pools with Faker multi-locale name generation#714

Merged
Aureliolo merged 11 commits intomainfrom
fix/fix-setup-wizard
Mar 22, 2026
Merged

feat: replace hardcoded name pools with Faker multi-locale name generation#714
Aureliolo merged 11 commits intomainfrom
fix/fix-setup-wizard

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

  • Replace hardcoded _AUTO_NAMES role-based name pools with Faker multi-locale name generation across 57 Latin-script locales
  • Add "Name Generation" step to setup wizard (locale/region selection between Provider and Company steps)
  • Add NameLocaleSelector shared component with All toggle, region groups, and locale chips
  • Add GET/PUT /setup/name-locales and GET /setup/name-locales/available API endpoints
  • Add name_locales setting definition (company namespace) with SettingsNameLocales component on Settings page
  • Add explicit diverse names to all 7 built-in template YAMLs
  • Thread locale preferences through renderer for locale-aware auto-name generation
  • Add faker==40.11.0 as production dependency

Pre-PR review fixes (15 agents, 29 findings)

  • Fix Faker.seed() global state mutation: use local random.Random + seed_instance() with lru_cache for performance
  • Fix broken v-if/v-else chain in SettingsPage.vue (GUI + code views rendered simultaneously on non-company tabs)
  • Add missing except Exception handler in _check_has_name_locales (prevents TaskGroup crash)
  • Add WARNING logging for corrupt JSON in _read_name_locales
  • Add mixed sentinel validation (__all__ cannot combine with explicit locales)
  • Create AvailableLocalesResponse Pydantic model (typed API response)
  • Use NotBlankStr for locale fields in SetupNameLocalesRequest
  • Fix empty catch blocks in Vue components
  • Update CLAUDE.md and design docs for new feature

Test plan

  • uv run python -m pytest tests/ -n auto --cov=synthorg --cov-fail-under=80 -- 10302 passed, 93.71% coverage
  • npm --prefix web run test -- 768 passed
  • uv run mypy src/ tests/ -- no issues
  • npm --prefix web run type-check -- clean
  • npm --prefix web run lint -- clean
  • Pre-push hooks pass (mypy, pytest, golangci-lint, go vet, go test)
  • New tests for 3 API endpoints, helper functions, locale edge cases, web store actions

🤖 Generated with Claude Code

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 22, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails
pip/faker 40.11.0 🟢 4.9
Details
CheckScoreReason
Code-Review⚠️ 2Found 7/30 approved changesets -- score normalized to 2
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Maintained🟢 1030 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Security-Policy⚠️ 0security policy file not detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • uv.lock

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 22, 2026

Walkthrough

Adds multi-locale agent name generation via the Faker library and a curated locale registry. Introduces three setup API endpoints for discovering and persisting name-locales, a company name_locales setting, new Pydantic DTOs, and observability events. Threads locale selection through template rendering, presets, and agent expansion, updates built-in templates with concrete names, adds a setup “Names” step plus UI components and store actions, pins the faker dependency, and includes corresponding tests and documentation updates.

Suggested labels

autorelease: tagged

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main change: replacing hardcoded name pools with Faker-based multi-locale name generation, which is the primary technical objective across all file modifications.
Description check ✅ Passed The description is directly related to the changeset, providing a clear summary of the feature implementation, pre-PR fixes, and comprehensive test coverage details.
Docstring Coverage ✅ Passed Docstring coverage is 53.75% which is sufficient. The required threshold is 40.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 significantly enhances the agent naming system by transitioning from static, hardcoded name pools to dynamic, multi-locale name generation using the Faker library. It introduces a new step in the initial setup wizard for users to configure their preferred name locales, ensuring greater diversity and customization for generated agent identities. The changes span across backend API, frontend UI, and template definitions to fully integrate this new functionality.

Highlights

  • Multi-locale Name Generation: Replaced hardcoded name pools with Faker-based multi-locale name generation, supporting 57 Latin-script locales for agent names.
  • Setup Wizard Integration: Introduced a new 'Name Generation' step in the setup wizard, allowing users to select preferred locales for agent name creation.
  • New API Endpoints: Added API endpoints (GET/PUT /setup/name-locales and GET /setup/name-locales/available) to manage and retrieve available name locales.
  • UI Components: Developed a NameLocaleSelector shared component for locale selection and integrated it into both the setup wizard and the settings page via SettingsNameLocales.
  • Template Updates: Updated all 7 built-in template YAMLs to use explicit, diverse names instead of Jinja2 placeholders for auto-generated names, and threaded locale preferences through the renderer for dynamic name generation.
  • Dependency Update: Added faker==40.11.0 as a production dependency.
  • Pre-PR Review Fixes: Addressed 29 findings, including fixing Faker seeding for performance, resolving a v-if/v-else chain issue, adding robust exception handling for name locale settings, and improving validation and logging.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 22, 2026 12:14 — with GitHub Actions Inactive
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully replaces the hardcoded name generation with a more robust and internationally diverse system using the Faker library. It introduces a new setup step for selecting name locales, complete with new API endpoints and a reusable Vue component. The changes are extensive, touching the backend API, settings, templates, and frontend UI. My review has identified a couple of critical syntax issues in the new Python helper functions that use outdated Python 2 exception handling syntax, which will cause runtime errors. I've also suggested a minor improvement in the frontend to better handle potentially corrupted settings data. Overall, this is a significant and well-implemented feature enhancement.

Comment on lines +765 to +766
except MemoryError, RecursionError:
raise
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The except A, B: syntax for catching multiple exceptions is from Python 2 and is not valid in Python 3. The project requires Python 3.14+. You should use except (A, B): instead. This will cause a SyntaxError at runtime.

    except (MemoryError, RecursionError):
        raise

Comment on lines +870 to +871
except MemoryError, RecursionError:
raise
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The except A, B: syntax for catching multiple exceptions is from Python 2 and is not valid in Python 3. The project requires Python 3.14+. You should use except (A, B): instead. This will cause a SyntaxError at runtime.

    except (MemoryError, RecursionError):
        raise

Comment on lines +22 to +24
if (Array.isArray(parsed)) {
selectedLocales.value = parsed
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The code currently handles cases where entry.value is not valid JSON, but it silently ignores the case where the parsed JSON is not an array. This could happen if the setting is corrupted. It would be better to explicitly handle this case by logging a warning and informing the user, similar to how JSON.parse errors are handled.

      if (Array.isArray(parsed)) {
        selectedLocales.value = parsed
      } else {
        console.warn('[SettingsNameLocales] name_locales setting is not an array:', parsed)
        toast.add({
          severity: 'warn',
          summary: 'Saved locale preference is corrupted. Showing default.',
          life: 5000,
        })
      }

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/synthorg/api/controllers/setup.py`:
- Around line 881-888: The json.loads call when building parsed
(json.loads(entry.value)) can raise TypeError if entry.value is None; update the
handling around json.loads in the setup controller to treat None as invalid
JSON: either pre-check entry.value is truthy and log the same
SETUP_NAME_LOCALES_CORRUPTED warning with reason="invalid_json" and raw as
currently done, or broaden the except to catch both json.JSONDecodeError and
TypeError, and then call logger.warning(SETUP_NAME_LOCALES_CORRUPTED,
reason="invalid_json", raw=entry.value[:200] if entry.value else None) so parsed
and subsequent logic (parsed variable) never receives a None and no TypeError
escapes.

In `@src/synthorg/templates/builtins/full_company.yaml`:
- Around line 142-145: The template accesses backend_names[i] (and similarly
frontend_names) without guarding against num_backend_devs exceeding the list
length, which can raise an IndexError during Jinja rendering; update the
for-loop body to safely pick a name by using a bounds-safe selection (e.g.,
compute an index as i % backend_names|length or clamp i to the last index) so
Backend Developer names are chosen cyclically or capped, and apply the same fix
for frontend_names to prevent out-of-range lookups; modify the template
references to use the safe index expression instead of backend_names[i] and
frontend_names[i].

In `@src/synthorg/templates/locales.py`:
- Around line 163-164: VALID_LOCALE_CODES is built from ALL_LATIN_LOCALES but
there's no check that each locale has a display name in LOCALE_DISPLAY_NAMES,
which can lead to KeyError at runtime; add a module-level runtime assertion (or
raise a clear ValueError) after VALID_LOCALE_CODES is defined that verifies
every code in VALID_LOCALE_CODES exists as a key in LOCALE_DISPLAY_NAMES
(reference symbols: VALID_LOCALE_CODES, ALL_LATIN_LOCALES,
LOCALE_DISPLAY_NAMES), and include a helpful error message listing any missing
keys so the failure is explicit during startup.

In `@tests/unit/api/controllers/test_setup.py`:
- Line 1009: Remove the redundant local import of AsyncMock in the test module:
AsyncMock is already imported at module level, so delete the duplicate "from
unittest.mock import AsyncMock" line to avoid duplicate imports and keep only
the single module-level import; search for the symbol AsyncMock in
tests/unit/api/controllers/test_setup.py to find and remove the repeated import.
- Line 964: Remove the redundant local import of AsyncMock inside the test
function; rely on the existing module-level import that already brings in
AsyncMock (and MagicMock). Locate the inline statement "from unittest.mock
import AsyncMock" in the test (near usages of AsyncMock) and delete it so only
the top-of-module import remains, then run the unit tests to verify no import
errors.

In `@web/src/components/common/NameLocaleSelector.vue`:
- Around line 59-72: toggleRegion currently initializes current by filtering out
ALL_SENTINEL which causes loss of state when modelValue is ['__all__']; update
toggleRegion to detect if props.modelValue includes ALL_SENTINEL and, in that
case, initialize current as a Set populated from allLocales.value (otherwise
keep the existing filter behavior), then proceed with the same add/delete logic
and the existing ALL_SENTINEL size check before emitting update:modelValue;
refer to function toggleRegion, constant ALL_SENTINEL and reactive
allLocales.value for the changes.

In `@web/src/views/SettingsPage.vue`:
- Around line 238-250: SettingGroupRenderer and SettingsNameLocales are both
rendered for the 'company' namespace which causes duplicate controls when the
entries include the name_locales setting; update the render so
SettingGroupRenderer is passed entries that exclude the name_locales key when ns
=== 'company' (e.g. filter the result of settingsStore.entriesByNamespace(ns as
SettingNamespace) to remove the entry with id/name 'name_locales') or
alternatively render SettingGroupRenderer only when ns !== 'company' and keep
SettingsNameLocales for company, adjusting the call sites SettingGroupRenderer,
settingsStore.entriesByNamespace, and SettingsNameLocales accordingly.
🪄 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: 85211391-1916-478e-8efd-afb920062034

📥 Commits

Reviewing files that changed from the base of the PR and between dc6bd3f and abd453b.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (33)
  • CLAUDE.md
  • docs/design/operations.md
  • docs/design/organization.md
  • pyproject.toml
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/api/controllers/setup_agents.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/observability/events/setup.py
  • src/synthorg/settings/definitions/company.py
  • src/synthorg/templates/builtins/agency.yaml
  • src/synthorg/templates/builtins/dev_shop.yaml
  • src/synthorg/templates/builtins/full_company.yaml
  • src/synthorg/templates/builtins/product_team.yaml
  • src/synthorg/templates/builtins/research_lab.yaml
  • src/synthorg/templates/builtins/solo_founder.yaml
  • src/synthorg/templates/builtins/startup.yaml
  • src/synthorg/templates/locales.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/renderer.py
  • tests/unit/api/controllers/test_setup.py
  • tests/unit/templates/conftest.py
  • tests/unit/templates/test_inheritance.py
  • tests/unit/templates/test_presets.py
  • tests/unit/templates/test_renderer.py
  • web/src/__tests__/stores/setup.test.ts
  • web/src/api/endpoints/setup.ts
  • web/src/api/types.ts
  • web/src/components/common/NameLocaleSelector.vue
  • web/src/components/settings/SettingsNameLocales.vue
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/stores/setup.ts
  • web/src/views/SettingsPage.vue
  • web/src/views/SetupPage.vue
📜 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 Web
  • GitHub Check: Build Sandbox
  • GitHub Check: Build Backend
  • GitHub Check: Test (Python 3.14)
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.py: No from __future__ import annotations in Python code -- Python 3.14 has PEP 649 native lazy annotations
Use except A, B: syntax (no parentheses) for exception handling on Python 3.14 -- enforced by ruff
Line length must be 88 characters -- enforced by ruff

Files:

  • tests/unit/templates/test_inheritance.py
  • tests/unit/templates/conftest.py
  • src/synthorg/settings/definitions/company.py
  • tests/unit/templates/test_renderer.py
  • src/synthorg/api/controllers/setup_agents.py
  • src/synthorg/observability/events/setup.py
  • tests/unit/templates/test_presets.py
  • src/synthorg/templates/renderer.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/locales.py
  • src/synthorg/api/controllers/setup.py
  • tests/unit/api/controllers/test_setup.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.py: Use @pytest.mark.unit, @pytest.mark.integration, @pytest.mark.e2e, @pytest.mark.slow markers for tests
Use Hypothesis for property-based testing in Python with @given + @settings decorators. HYPOTHESIS_PROFILE env var controls examples (ci=50, dev=1000)
Never skip, dismiss, or ignore flaky tests -- always fix them fully. For timing-sensitive tests, mock time.monotonic() and asyncio.sleep() instead of widening margins. Use asyncio.Event().wait() for indefinite blocking instead of asyncio.sleep(large_number)
Prefer @pytest.mark.parametrize for testing similar cases instead of writing multiple test functions

Files:

  • tests/unit/templates/test_inheritance.py
  • tests/unit/templates/conftest.py
  • tests/unit/templates/test_renderer.py
  • tests/unit/templates/test_presets.py
  • tests/unit/api/controllers/test_setup.py
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: All public functions must have type hints and Google-style docstrings -- enforced by ruff D rules and mypy strict mode
Use immutability patterns: create new objects instead of mutating existing ones. For non-Pydantic collections, use copy.deepcopy() at construction and MappingProxyType for read-only enforcement
Use frozen Pydantic models for config/identity; use separate mutable-via-copy models for runtime state that evolves
Use @computed_field instead of storing redundant fields; use NotBlankStr for all identifier/name fields instead of manual whitespace validators
Prefer asyncio.TaskGroup for fan-out/fan-in parallel operations in new code instead of bare create_task
Functions must be < 50 lines, files < 800 lines
All error paths must log at WARNING or ERROR with context before raising; all state transitions must log at INFO
Every module with business logic MUST import logger via from synthorg.observability import get_logger then logger = get_logger(__name__). Never use import logging or print() in application code
Use event name constants from synthorg.observability.events.<domain> modules instead of string literals (e.g., API_REQUEST_STARTED from events.api)
Always use logger.info(EVENT, key=value) for structured logging -- never use logger.info('msg %s', val) format strings
Validate input at system boundaries (user input, external APIs, config files) rather than throughout application code
Handle errors explicitly and never silently swallow them
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples -- use generic names like example-provider, example-large-001, test-provider, test-small-001
Use copy.deepcopy() at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization) for Pydantic models with dict/list fields

Files:

  • src/synthorg/settings/definitions/company.py
  • src/synthorg/api/controllers/setup_agents.py
  • src/synthorg/observability/events/setup.py
  • src/synthorg/templates/renderer.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/locales.py
  • src/synthorg/api/controllers/setup.py
web/src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Vue 3 components must use TypeScript with type safety in the dashboard

Files:

  • web/src/views/SettingsPage.vue
  • web/src/views/SetupPage.vue
  • web/src/api/endpoints/setup.ts
  • web/src/__tests__/stores/setup.test.ts
  • web/src/api/types.ts
  • web/src/components/settings/SettingsNameLocales.vue
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/components/common/NameLocaleSelector.vue
  • web/src/stores/setup.ts
web/src/**/*.{ts,tsx,vue,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint for Vue linting in the dashboard and run lint checks via npm --prefix web run lint

Files:

  • web/src/views/SettingsPage.vue
  • web/src/views/SetupPage.vue
  • web/src/api/endpoints/setup.ts
  • web/src/__tests__/stores/setup.test.ts
  • web/src/api/types.ts
  • web/src/components/settings/SettingsNameLocales.vue
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/components/common/NameLocaleSelector.vue
  • web/src/stores/setup.ts
src/synthorg/api/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

All public API responses must follow RFC 9457 error format

Files:

  • src/synthorg/api/controllers/setup_agents.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/api/controllers/setup.py
web/src/__tests__/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Vitest for Vue component unit tests with fast-check for property-based testing

Files:

  • web/src/__tests__/stores/setup.test.ts
web/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use fast-check for property-based testing in Vue tests with fc.assert + fc.property

Files:

  • web/src/__tests__/stores/setup.test.ts
web/src/stores/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Pinia stores for state management in the Vue 3 dashboard instead of other state management approaches

Files:

  • web/src/stores/setup.ts
🧠 Learnings (29)
📚 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 : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...

Applied to files:

  • CLAUDE.md
  • docs/design/organization.md
  • src/synthorg/templates/locales.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:

  • CLAUDE.md
📚 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: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.

Applied to files:

  • CLAUDE.md
📚 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: Settings: Runtime-editable settings persistence (DB > env > YAML > code defaults), typed definitions (9 namespaces), Fernet encryption for sensitive values, config bridge, ConfigResolver (typed composed reads for controllers), validation, registry, change notifications via message bus. Per-namespace setting definitions in definitions/ submodule (api, company, providers, memory, budget, security, coordination, observability, backup).

Applied to files:

  • CLAUDE.md
  • src/synthorg/settings/definitions/company.py
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).

Applied to files:

  • CLAUDE.md
  • web/src/views/SetupPage.vue
  • web/src/components/settings/SettingsNameLocales.vue
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/components/common/NameLocaleSelector.vue
📚 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/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.

Applied to files:

  • CLAUDE.md
  • docs/design/organization.md
  • src/synthorg/templates/builtins/full_company.yaml
  • tests/unit/templates/test_presets.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/locales.py
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to docker/{Dockerfile*,compose.yml} : Docker: Backend uses 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root (UID 65532), CIS-hardened. Web uses nginxinc/nginx-unprivileged, Vue 3 SPA with PrimeVue + Tailwind CSS, SPA routing, API/WebSocket proxy to backend.

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 docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)

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/security/**/*.py : Security package (security/): SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to pyproject.toml : Dependencies: all versions use == in pyproject.toml. Groups: test (pytest + plugins, hypothesis), dev (includes test + ruff, mypy, pre-commit, commitizen, pip-audit). Required: mem0ai (Mem0 memory backend — the default and currently only backend). Install: uv sync installs everything (dev group is default).

Applied to files:

  • CLAUDE.md
📚 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 go.mod : Maintain Go 1.26+ requirement. Dependencies: Cobra (CLI framework), charmbracelet/huh and charmbracelet/lipgloss (UI), sigstore-go (code signing), go-containerregistry (container image verification), go-tuf (TUF client for Sigstore).

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 web/package.json : Web dashboard Node.js 20+; dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, ESLint, vue-tsc)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to cli/** : CLI: Go 1.26+, dependencies in cli/go.mod (Cobra, charmbracelet/huh).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to cli/go.mod : Go CLI dependencies: Go 1.26+, Cobra (commands), charmbracelet/huh (interactive CLI), charmbracelet/lipgloss (styled output).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Applies to src/synthorg/hr/**/*.py : HR package (hr/): hiring, firing, onboarding, offboarding, agent registry, performance tracking (task metrics, collaboration scoring, LLM calibration, collaboration overrides, trend detection), promotion/demotion (criteria evaluation, approval strategies, model mapping)

Applied to files:

  • src/synthorg/templates/builtins/agency.yaml
  • src/synthorg/templates/builtins/research_lab.yaml
📚 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/settings/**/*.py : Settings package (settings/): runtime-editable settings persistence (DB > env > YAML > code defaults), typed definitions (9 namespaces), Fernet encryption for sensitive values, config bridge (JSON serialization for Pydantic/collections), ConfigResolver (typed accessors), validation, registry, change notifications via message bus, SettingsSubscriber protocol, SettingsChangeDispatcher (polls `#settings` channel, routes to subscribers, restart_required filtering)

Applied to files:

  • src/synthorg/settings/definitions/company.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/settings/**/*.py : Settings use runtime-editable persistence with precedence: DB > env > YAML > code defaults. 8 namespaces with Fernet encryption for sensitive values.

Applied to files:

  • src/synthorg/settings/definitions/company.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/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers

Applied to files:

  • docs/design/operations.md
  • src/synthorg/api/controllers/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:

  • src/synthorg/observability/events/setup.py
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to src/**/*.py : Use event name constants from `synthorg.observability.events.<domain>` modules instead of string literals (e.g., `API_REQUEST_STARTED` from `events.api`)

Applied to files:

  • src/synthorg/observability/events/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/**/*.py : Always use event name constants from the domain-specific module under `synthorg.observability.events` in logging calls

Applied to files:

  • src/synthorg/observability/events/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 : Use event constants from `synthorg.observability.events.<domain>` (e.g., `API_REQUEST_STARTED` from `events.api`); import directly and log with structured kwargs: `logger.info(EVENT, key=value)`, never interpolated strings

Applied to files:

  • src/synthorg/observability/events/setup.py
📚 Learning: 2026-03-18T21:23:23.586Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-18T21:23:23.586Z
Learning: Applies to src/synthorg/**/*.py : Event names: always use constants from the domain-specific module under synthorg.observability.events (e.g., API_REQUEST_STARTED from events.api, TOOL_INVOKE_START from events.tool). Import directly from synthorg.observability.events.<domain>.

Applied to files:

  • src/synthorg/observability/events/setup.py
📚 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 : Use event name constants from synthorg.observability.events domain-specific modules (e.g., PROVIDER_CALL_START from events.provider). Import directly: from synthorg.observability.events.<domain> import EVENT_CONSTANT.

Applied to files:

  • src/synthorg/observability/events/setup.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/synthorg/**/*.py : Event names: always use constants from domain-specific modules under synthorg.observability.events (e.g., PROVIDER_CALL_START from events.provider, BUDGET_RECORD_ADDED from events.budget, etc.). Import directly: `from synthorg.observability.events.<domain> import EVENT_CONSTANT`.

Applied to files:

  • src/synthorg/observability/events/setup.py
📚 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 : Always use event name constants from domain-specific modules under `synthorg.observability.events` (e.g., `PROVIDER_CALL_START` from `events.provider`); import directly: `from synthorg.observability.events.<domain> import EVENT_CONSTANT`

Applied to files:

  • src/synthorg/observability/events/setup.py
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to web/src/**/*.{ts,tsx,vue} : Vue 3 components must use TypeScript with type safety in the dashboard

Applied to files:

  • web/src/components/setup/SetupNameLocale.vue
  • web/src/components/common/NameLocaleSelector.vue
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to web/src/stores/**/*.ts : Use Pinia stores for state management in the Vue 3 dashboard instead of other state management approaches

Applied to files:

  • web/src/stores/setup.ts
🧬 Code graph analysis (10)
tests/unit/templates/test_renderer.py (1)
src/synthorg/templates/renderer.py (1)
  • _expand_single_agent (601-666)
src/synthorg/api/controllers/setup_agents.py (2)
src/synthorg/templates/schema.py (1)
  • CompanyTemplate (229-361)
src/synthorg/templates/presets.py (1)
  • generate_auto_name (397-435)
web/src/api/endpoints/setup.ts (3)
src/synthorg/api/controllers/setup_models.py (3)
  • AvailableLocalesResponse (246-257)
  • SetupNameLocalesResponse (234-243)
  • SetupNameLocalesRequest (221-231)
web/src/api/types.ts (4)
  • AvailableLocalesResponse (917-920)
  • ApiResponse (140-142)
  • SetupNameLocalesResponse (913-915)
  • SetupNameLocalesRequest (909-911)
web/src/api/client.ts (1)
  • unwrap (98-108)
tests/unit/templates/test_presets.py (2)
src/synthorg/templates/presets.py (1)
  • generate_auto_name (397-435)
src/synthorg/templates/locales.py (1)
  • resolve_locales (167-179)
web/src/api/types.ts (1)
src/synthorg/api/controllers/setup_models.py (3)
  • SetupNameLocalesRequest (221-231)
  • SetupNameLocalesResponse (234-243)
  • AvailableLocalesResponse (246-257)
src/synthorg/templates/renderer.py (1)
src/synthorg/templates/presets.py (1)
  • generate_auto_name (397-435)
src/synthorg/api/controllers/setup_models.py (1)
web/src/api/types.ts (3)
  • SetupNameLocalesRequest (909-911)
  • SetupNameLocalesResponse (913-915)
  • AvailableLocalesResponse (917-920)
src/synthorg/api/controllers/setup.py (4)
src/synthorg/api/controllers/setup_models.py (3)
  • AvailableLocalesResponse (246-257)
  • SetupNameLocalesRequest (221-231)
  • SetupNameLocalesResponse (234-243)
web/src/api/types.ts (3)
  • AvailableLocalesResponse (917-920)
  • SetupNameLocalesRequest (909-911)
  • SetupNameLocalesResponse (913-915)
src/synthorg/api/controllers/setup_agents.py (1)
  • expand_template_agents (40-105)
src/synthorg/templates/locales.py (1)
  • resolve_locales (167-179)
tests/unit/api/controllers/test_setup.py (3)
src/synthorg/api/controllers/setup.py (2)
  • _check_has_name_locales (754-776)
  • _read_name_locales (852-897)
src/synthorg/settings/errors.py (1)
  • SettingNotFoundError (8-9)
src/synthorg/settings/service.py (1)
  • get_entry (275-298)
web/src/stores/setup.ts (2)
web/src/utils/errors.ts (1)
  • getErrorMessage (17-69)
web/src/api/endpoints/setup.ts (1)
  • saveNameLocales (69-72)
🪛 YAMLlint (1.38.0)
src/synthorg/templates/builtins/full_company.yaml

[warning] 141-141: comment not indented like content

(comments-indentation)


[error] 142-142: syntax error: found character '%' that cannot start any token

(syntax)

🔇 Additional comments (40)
src/synthorg/settings/definitions/company.py (1)

65-79: name_locales setting registration looks consistent.

The new company namespace setting is cleanly wired (type, default, grouping, and YAML mapping all align).

tests/unit/templates/test_inheritance.py (1)

359-359: Good fixture stabilization.

Adding an explicit name here keeps multi-level inheritance expectations deterministic.

tests/unit/templates/conftest.py (1)

29-182: Fixture updates are consistent with explicit-name rendering.

These explicit agent names make template tests less brittle as name generation behavior evolves.

tests/unit/templates/test_renderer.py (2)

137-150: LGTM!

The test renames and assertion updates correctly reflect the new explicit naming approach in built-in templates. test_agent_name_from_template now verifies the hardcoded name "Nia Oduya" from solo_founder.yaml, and test_agents_have_nonempty_names accurately describes what it tests.


588-617: LGTM!

Good test coverage for the __JINJA2__ placeholder detection logic. Both the substring case ("__JINJA2__ Dev") and exact match case ("__JINJA2__") are verified, ensuring auto-name generation triggers correctly and removes the placeholder.

src/synthorg/templates/builtins/full_company.yaml (1)

67-95: LGTM!

The explicit, diverse agent names across C-suite and other static roles align with the PR objective. Cultural diversity is well-represented (e.g., Oluwaseun Adeyemi, Sunita Krishnamurthy, Hans Mueller, Mei-Ling Wu).

src/synthorg/templates/builtins/solo_founder.yaml (1)

37-47: LGTM!

Explicit agent names replace the previous Jinja2 dynamic expression and omitted name. This aligns with the test expectations (test_agent_name_from_template expects "Nia Oduya") and the PR's approach to built-in templates using pre-generated diverse names.

docs/design/operations.md (1)

1071-1071: LGTM!

Documentation accurately reflects the new name-locale management API surface (GET /api/v1/setup/name-locales/available, GET /api/v1/setup/name-locales, PUT /api/v1/setup/name-locales) and the updated status reporting with has_name_locales for step resume support.

src/synthorg/api/controllers/setup_agents.py (2)

40-69: LGTM!

The locales parameter is properly threaded through to generate_auto_name, and the auto-name trigger condition (not name or name.startswith("{{") or "__JINJA2__" in name) correctly mirrors the logic in renderer.py:_expand_single_agent. Good consistency across both code paths.


265-266: LGTM!

Exception handling correctly re-raises non-recoverable errors (MemoryError, RecursionError) before falling through to the SettingNotFoundError catch. The except A, B: syntax aligns with the Python 3.14 coding guideline.

docs/design/organization.md (2)

147-175: LGTM!

Documentation clearly explains the distinction between built-in templates (explicit Faker-derived names) and user-defined templates (Jinja2 placeholders triggering locale-aware auto-generation). The example names demonstrate the diversity approach.


240-249: LGTM!

The Company Builder section accurately describes the six-step setup wizard flow, including the new Names step for locale selection and how those preferences are applied during template agent name generation.

src/synthorg/templates/renderer.py (2)

73-101: LGTM!

The locales keyword-only parameter is properly added to the public render_template API with appropriate type hint (list[str] | None) and docstring documentation. The parameter is correctly forwarded to _render_to_dict.


601-622: LGTM!

The _expand_single_agent function correctly implements the auto-name trigger condition (not name or name.startswith("{{") or "__JINJA2__" in name) and forwards the locales parameter to generate_auto_name. This ensures consistent behavior with setup_agents.py:expand_template_agents.

src/synthorg/observability/events/setup.py (1)

81-92: LGTM!

The four new event constants follow the established setup.<entity>.<action> naming convention and provide comprehensive coverage for the name-locale preference flow: saving, listing, invalid submissions, and corrupted stored data.

web/src/views/SetupPage.vue (2)

91-96: LGTM!

The new handleNameLocaleComplete handler follows the established pattern of other step completion handlers (handleAdminComplete, handleProviderComplete), correctly fetching status and advancing the step when loaded.


273-277: LGTM!

The SetupNameLocale component is correctly integrated into the wizard step flow with proper event bindings for @next and @previous navigation.

web/src/api/endpoints/setup.ts (1)

59-72: LGTM!

The new API wrapper functions follow the established patterns in this file, using correct HTTP methods (GET for fetching, PUT for saving) and proper type annotations that match the backend DTOs.

web/src/__tests__/stores/setup.test.ts (1)

448-499: LGTM!

The new test cases provide comprehensive coverage for both fetchNameLocales and saveNameLocales actions, including success paths, error handling, and verification that saveNameLocales refreshes the setup status after a successful save.

src/synthorg/templates/builtins/research_lab.yaml (1)

38-82: LGTM!

The explicit agent names are appropriately diverse across cultures and regions, aligning with the PR's goal of international name diversity. The YAML structure remains valid with the new name fields properly nested under each agent entry.

web/src/stores/setup.ts (2)

56-67: LGTM!

The sequential completion logic correctly chains the new names step between provider and company, ensuring that each step requires all prior steps to be complete before it can be marked done.


109-129: LGTM!

The new store actions follow established patterns:

  • fetchNameLocales returns an empty array on error (graceful degradation)
  • saveNameLocales refreshes status after success and re-throws errors for UI handling

Both actions properly clear and set the error state.

src/synthorg/api/controllers/setup_models.py (1)

221-257: LGTM!

The new Pydantic DTOs are well-structured:

  • SetupNameLocalesRequest properly uses NotBlankStr for locale validation and enforces sensible bounds (1-100 entries)
  • All models use frozen=True for immutability
  • Request model uses extra="forbid" to reject unknown fields
  • Docstrings follow Google style with clear attribute documentation
web/src/api/types.ts (1)

909-920: LGTM!

The new TypeScript interfaces correctly mirror the backend Pydantic DTOs from src/synthorg/api/controllers/setup_models.py, ensuring type consistency between frontend and backend.

tests/unit/templates/test_presets.py (2)

89-121: LGTM!

The updated TestGenerateAutoName tests properly cover the Faker-based name generation:

  • Verifies determinism with seeds
  • Tests locale parameter acceptance
  • Confirms non-empty output in all cases

124-185: LGTM!

TestLocalesModule provides thorough coverage of the locale registry and resolution logic:

  • Validates internal consistency between ALL_LATIN_LOCALES, LOCALE_REGIONS, and LOCALE_DISPLAY_NAMES
  • Tests resolve_locales with various inputs including edge cases (empty list, all-invalid locales)
  • Explicitly verifies deprecated locales like fr_QC are excluded
src/synthorg/templates/presets.py (2)

397-435: LGTM! Clean Faker-based name generation with deterministic seeding.

The implementation correctly:

  • Isolates random state using a local random.Random(seed) to avoid global mutation
  • Caches Faker instances via _get_faker to avoid re-initialization overhead
  • Calls seed_instance(seed) on each invocation before generating, ensuring determinism without polluting cached state across different seeds
  • Keeps the role parameter for backward compatibility with existing callers

438-447: LGTM!

Caching Faker instances by locale tuple is an effective optimization that avoids re-initializing locale providers on every call. The maxsize=128 is reasonable for the expected number of distinct locale combinations.

src/synthorg/templates/builtins/product_team.yaml (1)

44-106: LGTM! Diverse explicit agent names added.

The template now includes explicit, internationally diverse names representing multiple regions (Middle Eastern, African, Nordic, East Asian, South Asian, Latin American, Eastern European, Japanese). This aligns well with the PR's goal of diverse name representation.

web/src/components/settings/SettingsNameLocales.vue (1)

1-80: LGTM! Well-structured settings component.

The component correctly:

  • Tracks dirty state to show the save button only when changes are pending
  • Prevents concurrent saves with the saving guard
  • Handles JSON parse failures gracefully with user-facing feedback
  • Uses getErrorMessage for consistent error display
src/synthorg/templates/builtins/dev_shop.yaml (1)

38-89: LGTM! Diverse explicit agent names added.

The template includes internationally diverse names consistent with the other built-in templates.

src/synthorg/templates/locales.py (1)

167-179: LGTM!

Clean implementation that handles all edge cases: None, the "__all__" sentinel, and explicit locale lists with potential invalid codes filtered out.

web/src/components/setup/SetupNameLocale.vue (1)

1-88: LGTM! Well-implemented setup wizard step.

The component correctly:

  • Protects against concurrent saves
  • Disables "Next" when no locales are selected (edge case protection)
  • Shows an accessible error banner (role="alert") without blocking user interaction
  • Falls back gracefully to "worldwide" when loading fails
tests/unit/api/controllers/test_setup.py (2)

782-916: Good test coverage for the new locale endpoints.

The tests comprehensively cover:

  • Happy paths for all three endpoints
  • Edge cases: empty list rejection, invalid codes, sentinel handling
  • State conflicts (save after setup complete)
  • Helper function behavior including JSON parsing failures and locale filtering

923-937: No action needed. The async test methods are correctly configured for pytest-asyncio.

The codebase has asyncio_mode = "auto" configured in pyproject.toml (line 231), which means async test functions are automatically collected and executed by pytest-asyncio without requiring explicit @pytest.mark.asyncio markers. The test methods in this file follow the correct pattern.

src/synthorg/api/controllers/setup.py (4)

444-470: LGTM!

Clean endpoint that exposes the static locale registry for UI consumption. Converting MappingProxyType to dict/list for JSON serialization is correct.


501-564: LGTM! Comprehensive validation with proper error logging.

The endpoint correctly:

  • Guards against modifications after setup completion
  • Rejects mixing the "__all__" sentinel with explicit codes
  • Validates all locale codes against the known set
  • Logs invalid submissions before raising structured errors

754-776: LGTM!

The helper follows the established pattern for status checks: fail-safe return of False on errors, with proper warning logging.


837-838: LGTM!

Locale preferences are correctly threaded through to template agent expansion, enabling locale-aware auto-name generation.

web/src/components/common/NameLocaleSelector.vue (1)

98-108: Async fetch/error state handling looks solid

Good use of try/catch/finally with normalized error messaging and guaranteed loading-state reset.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/synthorg/api/controllers/setup.py`:
- Around line 773-786: The current check returns True for any non-empty DB value
which can be malformed; update the post-get validation in the block that calls
settings_svc.get_entry (the variable entry and the SettingSource.DATABASE check)
to ensure the stored entry.value is a valid names locales payload (i.e.,
parse/validate it the same way _read_name_locales() would: valid JSON and a list
of locales) before returning True; if parsing/validation fails, log the issue
and return False so has_name_locales only reports True for a usable selection.
- Around line 753-760: The locales list is not rejecting duplicate entries
(e.g., ["en_US","en_US"]) which later skews generate_auto_name() sampling; in
the SetupNameLocalesRequest boundary (handled in the setup.py block around the
sentinel/invalid checks) detect duplicates in the incoming locales list and
reject them with an ApiValidationError (or normalize by deduplicating and then
proceed) — update the validation sequence in the same function that currently
checks sentinel and invalid codes (referencing SetupNameLocalesRequest and
generate_auto_name) so duplicates are handled before any further processing or
returned/used by generate_auto_name().
- Around line 862-909: The helper _read_name_locales currently expands the
worldwide sentinel "__all__" into a concrete locale list via resolve_locales,
which causes callers like get_name_locales and SetupNameLocalesResponse/frontend
to lose the sentinel; change _read_name_locales to preserve the sentinel instead
of expanding it: when the stored/parsed value is exactly ["__all__"] (or
otherwise indicates the default/worldwide sentinel) return that sentinel list
directly, and only call resolve_locales for other lists; ensure the function
still returns None for absent/unparseable settings and keep references to
resolve_locales, _read_name_locales, get_name_locales, and
SetupNameLocalesResponse in the change so reviewers can locate the logic to
adjust generation-time resolution elsewhere.

In `@src/synthorg/templates/presets.py`:
- Around line 443-448: Replace the hardcoded string
"name_generation.faker_error" passed to logger.warning with the corresponding
event constant from the templates observability catalog (e.g., import
NAME_GENERATION_FAKER_ERROR from synthorg.observability.events.templates) and
use that constant as the first argument to logger.warning while preserving the
existing kwargs (locales=locale_list[:5], seed=seed, exc_info=True); update the
imports to include the constant and ensure the log call now references
NAME_GENERATION_FAKER_ERROR instead of the string literal.

In `@web/src/components/setup/SetupNameLocale.vue`:
- Around line 16-31: The form allows submission before the initial locale fetch
completes because selectedLocales is preseeded with '__all__'; change the flow
so selectedLocales isn't set to a default until fetchNameLocales() succeeds and
block handleNext while the fetch is pending or errored. Concretely, add a
loading/error state around the fetch (e.g., localesLoading/localesError used by
fetchNameLocales), initialize selectedLocales from the fetched result in the
fetch success path (not at module init), and update handleNext to return early
if localesLoading.value is true or localesError.value is set (prevent calling
setup.saveNameLocales). Also ensure the UI uses the loading/error state to
disable the Next action.
🪄 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: d36cec1d-948d-48fa-bdce-7f7768473acf

📥 Commits

Reviewing files that changed from the base of the PR and between abd453b and 559793b.

📒 Files selected for processing (16)
  • README.md
  • docs/architecture/tech-stack.md
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/builtins/full_company.yaml
  • src/synthorg/templates/locales.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/renderer.py
  • tests/unit/api/controllers/test_setup.py
  • tests/unit/templates/test_presets.py
  • web/src/__tests__/stores/setup.test.ts
  • web/src/components/common/NameLocaleSelector.vue
  • web/src/components/settings/SettingsNameLocales.vue
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/stores/setup.ts
  • web/src/views/SettingsPage.vue
📜 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: Test (Python 3.14)
  • GitHub Check: Build Sandbox
  • GitHub Check: Build Web
  • GitHub Check: Build Backend
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (9)
web/src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Vue 3 components must use TypeScript with type safety in the dashboard

Files:

  • web/src/views/SettingsPage.vue
  • web/src/components/common/NameLocaleSelector.vue
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/__tests__/stores/setup.test.ts
  • web/src/stores/setup.ts
  • web/src/components/settings/SettingsNameLocales.vue
web/src/**/*.{ts,tsx,vue,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint for Vue linting in the dashboard and run lint checks via npm --prefix web run lint

Files:

  • web/src/views/SettingsPage.vue
  • web/src/components/common/NameLocaleSelector.vue
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/__tests__/stores/setup.test.ts
  • web/src/stores/setup.ts
  • web/src/components/settings/SettingsNameLocales.vue
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.py: No from __future__ import annotations in Python code -- Python 3.14 has PEP 649 native lazy annotations
Use except A, B: syntax (no parentheses) for exception handling on Python 3.14 -- enforced by ruff
Line length must be 88 characters -- enforced by ruff

Files:

  • tests/unit/templates/test_presets.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/renderer.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/locales.py
  • tests/unit/api/controllers/test_setup.py
  • src/synthorg/api/controllers/setup.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.py: Use @pytest.mark.unit, @pytest.mark.integration, @pytest.mark.e2e, @pytest.mark.slow markers for tests
Use Hypothesis for property-based testing in Python with @given + @settings decorators. HYPOTHESIS_PROFILE env var controls examples (ci=50, dev=1000)
Never skip, dismiss, or ignore flaky tests -- always fix them fully. For timing-sensitive tests, mock time.monotonic() and asyncio.sleep() instead of widening margins. Use asyncio.Event().wait() for indefinite blocking instead of asyncio.sleep(large_number)
Prefer @pytest.mark.parametrize for testing similar cases instead of writing multiple test functions

Files:

  • tests/unit/templates/test_presets.py
  • tests/unit/api/controllers/test_setup.py
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: All public functions must have type hints and Google-style docstrings -- enforced by ruff D rules and mypy strict mode
Use immutability patterns: create new objects instead of mutating existing ones. For non-Pydantic collections, use copy.deepcopy() at construction and MappingProxyType for read-only enforcement
Use frozen Pydantic models for config/identity; use separate mutable-via-copy models for runtime state that evolves
Use @computed_field instead of storing redundant fields; use NotBlankStr for all identifier/name fields instead of manual whitespace validators
Prefer asyncio.TaskGroup for fan-out/fan-in parallel operations in new code instead of bare create_task
Functions must be < 50 lines, files < 800 lines
All error paths must log at WARNING or ERROR with context before raising; all state transitions must log at INFO
Every module with business logic MUST import logger via from synthorg.observability import get_logger then logger = get_logger(__name__). Never use import logging or print() in application code
Use event name constants from synthorg.observability.events.<domain> modules instead of string literals (e.g., API_REQUEST_STARTED from events.api)
Always use logger.info(EVENT, key=value) for structured logging -- never use logger.info('msg %s', val) format strings
Validate input at system boundaries (user input, external APIs, config files) rather than throughout application code
Handle errors explicitly and never silently swallow them
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples -- use generic names like example-provider, example-large-001, test-provider, test-small-001
Use copy.deepcopy() at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization) for Pydantic models with dict/list fields

Files:

  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/renderer.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/locales.py
  • src/synthorg/api/controllers/setup.py
src/synthorg/api/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

All public API responses must follow RFC 9457 error format

Files:

  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/api/controllers/setup.py
web/src/__tests__/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Vitest for Vue component unit tests with fast-check for property-based testing

Files:

  • web/src/__tests__/stores/setup.test.ts
web/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use fast-check for property-based testing in Vue tests with fc.assert + fc.property

Files:

  • web/src/__tests__/stores/setup.test.ts
web/src/stores/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Pinia stores for state management in the Vue 3 dashboard instead of other state management approaches

Files:

  • web/src/stores/setup.ts
🧠 Learnings (25)
📚 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 : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...

Applied to files:

  • README.md
  • docs/architecture/tech-stack.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 docker/Dockerfile.sandbox : Docker sandbox: `synthorg-sandbox` — Python 3.14 + Node.js + git, non-root (UID 10001), agent code execution sandbox

Applied to files:

  • README.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to cli/**/*.go : Go CLI (Go 1.26+) uses Cobra for commands, charmbracelet/huh for interactive CLI, charmbracelet/lipgloss for styled output. Cross-platform builds (linux/darwin/windows × amd64/arm64). GoReleaser for releases with cosign keyless signing of checksums.txt. SLSA L3 provenance attestations via actions/attest-build-provenance.

Applied to files:

  • docs/architecture/tech-stack.md
📚 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 go.mod : Maintain Go 1.26+ requirement. Dependencies: Cobra (CLI framework), charmbracelet/huh and charmbracelet/lipgloss (UI), sigstore-go (code signing), go-containerregistry (container image verification), go-tuf (TUF client for Sigstore).

Applied to files:

  • docs/architecture/tech-stack.md
📚 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: Security: SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies: disabled/weighted/per-category/milestone), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume).

Applied to files:

  • docs/architecture/tech-stack.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/security/**/*.py : Security package (security/): SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume)

Applied to files:

  • docs/architecture/tech-stack.md
📚 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: CLI workflow (`.github/workflows/cli.yml`) runs Go lint (golangci-lint + go vet) + test (race, coverage) + build (cross-compile matrix) + vulnerability check (govulncheck) + fuzz testing. Cross-compiles for linux/darwin/windows × amd64/arm64. GoReleaser release on v* tags with cosign keyless signing and SLSA L3 attestations.

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to docker/{Dockerfile*,compose.yml} : Docker: Backend uses 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root (UID 65532), CIS-hardened. Web uses nginxinc/nginx-unprivileged, Vue 3 SPA with PrimeVue + Tailwind CSS, SPA routing, API/WebSocket proxy to backend.

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to cli/**/*.go : Use Cobra framework for CLI commands and charmbracelet libraries (huh, lipgloss) for interactive UI

Applied to files:

  • docs/architecture/tech-stack.md
📚 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: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.

Applied to files:

  • docs/architecture/tech-stack.md
📚 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/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.

Applied to files:

  • src/synthorg/templates/builtins/full_company.yaml
  • tests/unit/templates/test_presets.py
  • src/synthorg/templates/locales.py
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).

Applied to files:

  • web/src/components/common/NameLocaleSelector.vue
  • web/src/components/settings/SettingsNameLocales.vue
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to web/src/**/*.{ts,tsx,vue} : Vue 3 components must use TypeScript with type safety in the dashboard

Applied to files:

  • web/src/components/common/NameLocaleSelector.vue
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/components/settings/SettingsNameLocales.vue
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to web/src/stores/**/*.ts : Use Pinia stores for state management in the Vue 3 dashboard instead of other state management approaches

Applied to files:

  • web/src/stores/setup.ts
📚 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/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers

Applied to files:

  • src/synthorg/api/controllers/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/api/**/*.py : REST API: Litestar framework, controllers with guards, channels for WebSocket, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint. RFC 9457 structured errors (ErrorCategory, ErrorCode, ErrorDetail, ProblemDetail, CATEGORY_TITLES, category_title, category_type_uri, content negotiation).

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to **/*.py : Use `except A, B:` syntax (no parentheses) for exception handling on Python 3.14 -- enforced by ruff

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Use `except A, B:` syntax (no parentheses) for exception handling — PEP 758 exception syntax enforced by ruff on Python 3.14

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Use PEP 758 except syntax with `except A, B:` (no parentheses) for multiple exceptions—ruff enforces this on Python 3.14.

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Use PEP 758 except syntax: `except A, B:` (no parentheses) — enforced by ruff on Python 3.14

Applied to files:

  • src/synthorg/api/controllers/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 **/*.py : Use PEP 758 except syntax: use `except A, B:` (no parentheses) — ruff enforces this on Python 3.14.

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Handle errors explicitly, never silently swallow exceptions

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Handle errors explicitly; never silently swallow exceptions

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Handle errors explicitly—never silently swallow exceptions.

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to **/*.py : No `from __future__ import annotations` in Python code -- Python 3.14 has PEP 649 native lazy annotations

Applied to files:

  • src/synthorg/api/controllers/setup.py
🧬 Code graph analysis (6)
tests/unit/templates/test_presets.py (2)
src/synthorg/templates/presets.py (1)
  • generate_auto_name (397-453)
src/synthorg/templates/locales.py (1)
  • resolve_locales (183-208)
src/synthorg/templates/renderer.py (1)
src/synthorg/templates/presets.py (1)
  • generate_auto_name (397-453)
web/src/__tests__/stores/setup.test.ts (1)
web/src/stores/setup.ts (1)
  • useSetupStore (8-217)
tests/unit/api/controllers/test_setup.py (3)
src/synthorg/api/controllers/setup.py (2)
  • _check_has_name_locales (764-786)
  • _read_name_locales (862-909)
src/synthorg/settings/service.py (1)
  • get_entry (275-298)
src/synthorg/settings/errors.py (1)
  • SettingNotFoundError (8-9)
web/src/stores/setup.ts (2)
web/src/utils/errors.ts (1)
  • getErrorMessage (17-69)
web/src/api/endpoints/setup.ts (1)
  • saveNameLocales (69-72)
src/synthorg/api/controllers/setup.py (3)
src/synthorg/api/controllers/setup_models.py (3)
  • AvailableLocalesResponse (246-257)
  • SetupNameLocalesRequest (221-231)
  • SetupNameLocalesResponse (234-243)
src/synthorg/settings/errors.py (1)
  • SettingNotFoundError (8-9)
src/synthorg/templates/locales.py (1)
  • resolve_locales (183-208)
🪛 YAMLlint (1.38.0)
src/synthorg/templates/builtins/full_company.yaml

[warning] 141-141: comment not indented like content

(comments-indentation)


[error] 142-142: syntax error: found character '%' that cannot start any token

(syntax)

🔇 Additional comments (16)
web/src/components/settings/SettingsNameLocales.vue (2)

1-65: LGTM!

The component follows Vue 3 Composition API patterns with proper TypeScript typing. Error handling is comprehensive with both parse errors and save failures handled gracefully via toasts. The saving flag correctly prevents concurrent saves, and the dirty-tracking pattern enables a clean UX with conditional save button visibility.


67-89: LGTM!

Template structure is clean with proper conditional rendering (v-if="dirty") for the save button and correct prop/event binding to the NameLocaleSelector child component.

web/src/views/SettingsPage.vue (1)

237-251: LGTM!

The inline filter correctly excludes the name_locales entry from SettingGroupRenderer when rendering the company namespace, while SettingsNameLocales provides dedicated handling. This addresses the duplicate control concern from the prior review. The <template> wrapper with v-if/v-else properly separates GUI and code mode rendering.

docs/architecture/tech-stack.md (1)

64-64: LGTM!

Documentation accurately describes the Faker integration for multi-locale name generation, including the key technical details (57 locales, 12 regions, caching, deterministic seeding).

README.md (1)

109-109: LGTM!

The Quick Start description accurately reflects the updated setup wizard flow with the new Names step positioned correctly between provider configuration and company naming.

src/synthorg/templates/builtins/full_company.yaml (3)

142-145: LGTM!

The modulo-safe indexing pattern (backend_names[i % backend_names|length]) correctly prevents IndexError when num_backend_devs exceeds the name pool size. This addresses the past review concern about out-of-bounds access.

Note: The YAMLlint errors for % characters are false positives — this is a Jinja2 template, not pure YAML.


159-162: LGTM!

Same modulo-safe pattern applied to frontend developer names.


66-95: LGTM!

Explicit diverse names added for all C-suite roles, representing a good range of cultural backgrounds (African, South Asian, German, East Asian, Latin American).

web/src/__tests__/stores/setup.test.ts (4)

9-10: LGTM!

Mock functions properly added for the new API endpoints.


452-471: LGTM!

Good test coverage for fetchNameLocales — verifies both the success path (returns locales, clears error) and failure path (sets error, re-throws for caller handling).


473-483: LGTM!

Important test ensuring fetchStatus failure correctly sets error while keeping statusLoaded as false, which maintains the fail-closed behavior for isSetupNeeded.


485-514: LGTM!

Comprehensive saveNameLocales tests verify API call with correct payload, status refresh on success, and proper error handling with re-throw on failure.

web/src/stores/setup.ts (2)

52-67: LGTM!

Sequential completion logic correctly updated to gate company behind the new names step. The dependency chain adminDone → providerDone → namesDone → companyDone → reviewDone ensures users complete steps in order.


109-129: LGTM!

Both actions follow the established error-handling pattern: clear error, call API, set error and re-throw on failure. saveNameLocales correctly refreshes status after saving to update completion state. Return types are appropriate (Promise<string[]> for fetch, Promise<void> for save).

src/synthorg/api/controllers/setup_models.py (2)

19-30: LGTM!

has_name_locales field correctly added to SetupStatusResponse with proper docstring documentation explaining its purpose in the setup wizard flow.


221-257: LGTM!

Well-structured Pydantic DTOs following project conventions:

  • All models use frozen=True for immutability
  • SetupNameLocalesRequest has extra="forbid" and sensible bounds (1–100 locales)
  • NotBlankStr prevents whitespace-only locale codes
  • AvailableLocalesResponse cleanly separates region groupings from display names for flexible UI rendering

Comment on lines +862 to +909
async def _read_name_locales(settings_svc: SettingsService) -> list[str] | None:
"""Read stored name locale preference, returning None for default.

Deserialises the JSON-encoded locale list from settings, validates
it as a list, and resolves it through ``resolve_locales`` (which
filters out invalid codes). Returns ``None`` when the setting is
absent, unparseable, or resolves to an empty list.

Args:
settings_svc: Settings service instance.

Returns:
Resolved locale codes, or None to use the default (all locales).
"""
from synthorg.templates.locales import resolve_locales # noqa: PLC0415

try:
entry = await settings_svc.get_entry("company", "name_locales")
except MemoryError, RecursionError:
raise
except SettingNotFoundError:
return None
except Exception:
logger.warning(
SETUP_STATUS_SETTINGS_UNAVAILABLE,
setting="name_locales",
exc_info=True,
)
return None
if not entry.value:
return None
try:
parsed = json.loads(entry.value)
except json.JSONDecodeError:
logger.warning(
SETUP_NAME_LOCALES_CORRUPTED,
reason="invalid_json",
raw=entry.value[:200] if entry.value else None,
)
return None
if not isinstance(parsed, list):
logger.warning(
SETUP_NAME_LOCALES_CORRUPTED,
reason="expected_list",
actual_type=type(parsed).__name__,
)
return None
return resolve_locales(parsed) or None
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Preserve the worldwide sentinel instead of expanding it here.

When the setting comes from the code default or stores ["__all__"], this helper resolves it to the full concrete locale list. get_name_locales() then returns that expanded list, but both SetupNameLocalesResponse and the frontend selector model use ["__all__"] to represent the worldwide state. The result is that a fresh/worldwide setup renders as “All” off.

💡 Keep worldwide/default as sentinel, and only resolve at generation time
-    from synthorg.templates.locales import resolve_locales  # noqa: PLC0415
+    from synthorg.templates.locales import (  # noqa: PLC0415
+        ALL_LOCALES_SENTINEL,
+        resolve_locales,
+    )

     try:
         entry = await settings_svc.get_entry("company", "name_locales")
@@
     except Exception:
         logger.warning(
             SETUP_STATUS_SETTINGS_UNAVAILABLE,
             setting="name_locales",
             exc_info=True,
         )
         return None
+    if entry.source != SettingSource.DATABASE:
+        return None
     if not entry.value:
         return None
     try:
         parsed = json.loads(entry.value)
@@
     if not isinstance(parsed, list):
         logger.warning(
             SETUP_NAME_LOCALES_CORRUPTED,
             reason="expected_list",
             actual_type=type(parsed).__name__,
         )
         return None
+    if parsed == [ALL_LOCALES_SENTINEL]:
+        return None
     return resolve_locales(parsed) or None
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/synthorg/api/controllers/setup.py` around lines 862 - 909, The helper
_read_name_locales currently expands the worldwide sentinel "__all__" into a
concrete locale list via resolve_locales, which causes callers like
get_name_locales and SetupNameLocalesResponse/frontend to lose the sentinel;
change _read_name_locales to preserve the sentinel instead of expanding it: when
the stored/parsed value is exactly ["__all__"] (or otherwise indicates the
default/worldwide sentinel) return that sentinel list directly, and only call
resolve_locales for other lists; ensure the function still returns None for
absent/unparseable settings and keep references to resolve_locales,
_read_name_locales, get_name_locales, and SetupNameLocalesResponse in the change
so reviewers can locate the logic to adjust generation-time resolution
elsewhere.

Aureliolo and others added 5 commits March 22, 2026 13:46
…ation

- Add faker dependency for internationally diverse agent name generation
- Create locales module with 57 Latin-script Faker locales across 11 world regions
- Replace _AUTO_NAMES hardcoded pools with Faker-based generate_auto_name()
- Fix __JINJA2__ placeholder detection in setup_agents.py and renderer.py
- Add explicit diverse names to all 7 template YAMLs
- Add "Name Generation" step to setup wizard (locale/region selection)
- Add NameLocaleSelector shared component (All toggle + region groups + locale chips)
- Add name_locales setting definition (company namespace)
- Add GET/PUT /setup/name-locales and GET /setup/name-locales/available API endpoints
- Add SettingsNameLocales component to Settings page Company tab
- Update SetupStatusResponse with has_name_locales field
- Update tests for new name generation and locale features

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix test_agent_name_from_jinja2 -> test_agent_name_from_template (solo_founder CEO now has explicit name)
- Add explicit names to test fixture templates to prevent Faker seed collisions in inheritance tests
- Fix test_multi_level_extends duplicate name validation error

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pre-reviewed by 15 agents, 29 findings addressed:
- Fix Faker.seed() global state mutation: use local Random + seed_instance
- Cache Faker instances via lru_cache for performance
- Fix broken v-if/v-else chain in SettingsPage.vue (GUI+code rendered together)
- Add missing except Exception handler in _check_has_name_locales
- Add WARNING logging for corrupt JSON in _read_name_locales
- Add mixed sentinel validation in save_name_locales
- Create AvailableLocalesResponse Pydantic model (typed API response)
- Use NotBlankStr for locale fields in SetupNameLocalesRequest
- Thread locales parameter through renderer for locale-aware name generation
- Add new event constants (SETUP_NAME_LOCALES_INVALID, _CORRUPTED)
- Fix empty catch blocks in Vue components (SettingsNameLocales, SetupNameLocale)
- Remove dead watcher and unused import in Vue components
- Update CLAUDE.md (faker in deps, templates/ description)
- Update design docs (operations API table, organization wizard steps)
- Add tests for 3 new API endpoints, helper functions, edge cases
- Add web store tests for fetchNameLocales/saveNameLocales

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix locale not propagated through template inheritance chain
- Fix seed_instance() mutating shared lru_cached Faker instance
- Add error handling around Faker operations with en_US fallback
- Fix toggleRegion broken when __all__ active in NameLocaleSelector
- Move en_TH from South Asia to Southeast Asia (geographic fix)
- Fix IndexError in full_company.yaml with modulo indexing for names
- Add null guard before json.loads(entry.value) in _read_name_locales
- Add Final annotations to locales.py module constants
- Add module-level assertions for locale registry consistency
- Add logging for resolve_locales dropping invalid codes
- Extract _validate_locale_selection to reduce save_name_locales length
- Fix fetchNameLocales to re-throw errors (consistent with store pattern)
- Fix duplicate name_locales control in Settings company GUI tab
- Use sanitizeForLog in Vue components instead of raw error logging
- Add toast for non-array JSON in SettingsNameLocales
- Use NotBlankStr in SetupNameLocalesResponse.locales
- Thread locales through _resolve_inheritance and _render_and_merge_parent
- Update README and tech-stack docs for Names step and Faker
- Fix resolve_locales docstring for empty-list behavior
- Add tests: mixed sentinel, generic exception, role invariance, names step
- Add fetchStatus error path test and fetchNameLocales re-throw test
- Remove redundant AsyncMock imports in test_setup.py

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use event constant TEMPLATE_NAME_GEN_FAKER_ERROR instead of string literal
- Add duplicate locale code validation in _validate_locale_selection
- Validate _check_has_name_locales parses stored value as JSON list
- Add loading state to SetupNameLocale.vue to block submit during fetch
- Disable Next button while locale fetch is in progress

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (1)
web/src/components/setup/SetupNameLocale.vue (1)

16-23: ⚠️ Potential issue | 🟠 Major

A failed initial load can still overwrite the saved locales with the worldwide fallback.

selectedLocales starts at ['__all__'], and once fetchNameLocales() fails the button becomes clickable again because only loading blocks submit. Hitting Next at that point saves the fallback over the persisted selection and advances the wizard.

💡 Safer load/save flow
 const error = ref<string | null>(null)
 const saving = ref(false)
 const loading = ref(true)
-const selectedLocales = ref<string[]>(['__all__'])
+const loadFailed = ref(false)
+const selectedLocales = ref<string[]>([])

 async function handleNext() {
-  if (saving.value || loading.value) return
+  if (saving.value || loading.value || loadFailed.value) return
   saving.value = true
   error.value = null
   try {
     await setup.saveNameLocales(selectedLocales.value)
     emit('next')
@@
 onMounted(async () => {
   try {
     const locales = await setup.fetchNameLocales()
-    if (locales.length > 0) {
-      selectedLocales.value = locales
-    }
+    selectedLocales.value = locales.length > 0 ? locales : ['__all__']
   } catch (err) {
     console.warn('[SetupNameLocale] Failed to load saved locales:', sanitizeForLog(err))
-    error.value = 'Could not load your saved locale preferences. Defaulting to worldwide.'
+    error.value = 'Could not load your saved locale preferences. Please retry.'
+    loadFailed.value = true
   } finally {
     loading.value = false
   }
 })
@@
-        :disabled="selectedLocales.length === 0 || loading"
+        :disabled="selectedLocales.length === 0 || loading || loadFailed"

Also applies to: 35-45, 82-88

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/synthorg/api/controllers/setup.py`:
- Around line 769-797: The _check_has_name_locales function currently returns
True for any non-empty JSON list; update it to mirror _read_name_locales by
validating parsed locale codes with resolve_locales and only return True if
resolve_locales yields at least one valid locale; keep existing error handling
(MemoryError/RecursionError re-raises, SettingNotFoundError returns False, other
exceptions log and return False), parse entry.value with json.loads as before,
call resolve_locales(parsed) (or the same validation routine used by
_read_name_locales) and return True only when the resolved list is non-empty,
otherwise return False.

In `@src/synthorg/templates/locales.py`:
- Around line 203-207: Replace the string literal
"locales.resolve_dropped_invalid" with a constant: add
LOCALES_RESOLVE_DROPPED_INVALID to the synthorg.observability.events.templates
module (or the appropriate events submodule for templates), import that constant
into the module containing resolve_dropped_invalid (the current template locales
module), and change the logger.warning call to use
LOCALES_RESOLVE_DROPPED_INVALID while keeping the dropped and kept_count kwargs
unchanged; also update the import block to include the new constant.

In `@src/synthorg/templates/presets.py`:
- Around line 397-472: The generate_auto_name function is too large; split its
responsibilities into small helpers: extract locale selection into a
_choose_locale(locales, seed) function that returns (locale_list,
chosen_locale_or_none), move seeded Faker construction into
_build_seeded_faker(locale, seed) and the unseeded path into
_build_unseeded_faker(locale_tuple) (which can call the existing _get_faker),
and extract the exception fallback and logging into
_fallback_name(locales_preview, seed) which logs TEMPLATE_NAME_GEN_FAKER_ERROR
and returns the fallback name; then have generate_auto_name call these helpers
to keep it under 50 lines and preserve behavior (referencing generate_auto_name,
_get_faker, TEMPLATE_NAME_GEN_FAKER_ERROR).

In `@web/src/components/common/NameLocaleSelector.vue`:
- Around line 181-186: The checkbox input currently sets an aria-label using
displayNames[locale], which is redundant because the visible label text already
provides the accessible name; remove the :aria-label binding from the input (or
alternatively replace it with aria-labelledby that points to the wrapping
label's id if you prefer explicit referencing) so update the input in the
NameLocaleSelector component (the checkbox that calls isLocaleSelected(locale)
and toggleLocale(locale, ...)) to omit :aria-label (or wire aria-labelledby to
the label element) and ensure the label text remains the authoritative
accessible name.

In `@web/src/stores/setup.ts`:
- Around line 120-129: saveNameLocales currently awaits fetchStatus(), but
fetchStatus swallows errors so a failed refresh still makes the save path
resolve and the UI advances with stale state; wrap the fetchStatus call to
ensure any refresh error propagates (e.g. change fetchStatus to rethrow on
failure or in saveNameLocales call await fetchStatus().catch(err => {
error.value = getErrorMessage(err); throw err }) ), keeping error.value set via
getErrorMessage(err) and rethrowing so the caller (SetupNameLocale.vue) sees the
failure; reference: saveNameLocales and fetchStatus.
🪄 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: d5bee346-a0b0-420f-ac7d-f350ffc637d5

📥 Commits

Reviewing files that changed from the base of the PR and between 559793b and 0c3b1cd.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (36)
  • CLAUDE.md
  • README.md
  • docs/architecture/tech-stack.md
  • docs/design/operations.md
  • docs/design/organization.md
  • pyproject.toml
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/api/controllers/setup_agents.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/observability/events/setup.py
  • src/synthorg/observability/events/template.py
  • src/synthorg/settings/definitions/company.py
  • src/synthorg/templates/builtins/agency.yaml
  • src/synthorg/templates/builtins/dev_shop.yaml
  • src/synthorg/templates/builtins/full_company.yaml
  • src/synthorg/templates/builtins/product_team.yaml
  • src/synthorg/templates/builtins/research_lab.yaml
  • src/synthorg/templates/builtins/solo_founder.yaml
  • src/synthorg/templates/builtins/startup.yaml
  • src/synthorg/templates/locales.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/renderer.py
  • tests/unit/api/controllers/test_setup.py
  • tests/unit/templates/conftest.py
  • tests/unit/templates/test_inheritance.py
  • tests/unit/templates/test_presets.py
  • tests/unit/templates/test_renderer.py
  • web/src/__tests__/stores/setup.test.ts
  • web/src/api/endpoints/setup.ts
  • web/src/api/types.ts
  • web/src/components/common/NameLocaleSelector.vue
  • web/src/components/settings/SettingsNameLocales.vue
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/stores/setup.ts
  • web/src/views/SettingsPage.vue
  • web/src/views/SetupPage.vue
📜 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: Test (Python 3.14)
  • GitHub Check: Build Backend
  • GitHub Check: Build Web
  • GitHub Check: Build Sandbox
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.py: No from __future__ import annotations in Python code -- Python 3.14 has PEP 649 native lazy annotations
Use except A, B: syntax (no parentheses) for exception handling on Python 3.14 -- enforced by ruff
Line length must be 88 characters -- enforced by ruff

Files:

  • src/synthorg/observability/events/template.py
  • src/synthorg/settings/definitions/company.py
  • src/synthorg/api/controllers/setup_agents.py
  • tests/unit/templates/test_renderer.py
  • src/synthorg/observability/events/setup.py
  • tests/unit/templates/conftest.py
  • src/synthorg/templates/renderer.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/locales.py
  • tests/unit/api/controllers/test_setup.py
  • tests/unit/templates/test_inheritance.py
  • tests/unit/templates/test_presets.py
  • src/synthorg/api/controllers/setup.py
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: All public functions must have type hints and Google-style docstrings -- enforced by ruff D rules and mypy strict mode
Use immutability patterns: create new objects instead of mutating existing ones. For non-Pydantic collections, use copy.deepcopy() at construction and MappingProxyType for read-only enforcement
Use frozen Pydantic models for config/identity; use separate mutable-via-copy models for runtime state that evolves
Use @computed_field instead of storing redundant fields; use NotBlankStr for all identifier/name fields instead of manual whitespace validators
Prefer asyncio.TaskGroup for fan-out/fan-in parallel operations in new code instead of bare create_task
Functions must be < 50 lines, files < 800 lines
All error paths must log at WARNING or ERROR with context before raising; all state transitions must log at INFO
Every module with business logic MUST import logger via from synthorg.observability import get_logger then logger = get_logger(__name__). Never use import logging or print() in application code
Use event name constants from synthorg.observability.events.<domain> modules instead of string literals (e.g., API_REQUEST_STARTED from events.api)
Always use logger.info(EVENT, key=value) for structured logging -- never use logger.info('msg %s', val) format strings
Validate input at system boundaries (user input, external APIs, config files) rather than throughout application code
Handle errors explicitly and never silently swallow them
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples -- use generic names like example-provider, example-large-001, test-provider, test-small-001
Use copy.deepcopy() at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization) for Pydantic models with dict/list fields

Files:

  • src/synthorg/observability/events/template.py
  • src/synthorg/settings/definitions/company.py
  • src/synthorg/api/controllers/setup_agents.py
  • src/synthorg/observability/events/setup.py
  • src/synthorg/templates/renderer.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/presets.py
  • src/synthorg/templates/locales.py
  • src/synthorg/api/controllers/setup.py
web/src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Vue 3 components must use TypeScript with type safety in the dashboard

Files:

  • web/src/views/SetupPage.vue
  • web/src/api/endpoints/setup.ts
  • web/src/api/types.ts
  • web/src/views/SettingsPage.vue
  • web/src/__tests__/stores/setup.test.ts
  • web/src/stores/setup.ts
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/components/settings/SettingsNameLocales.vue
  • web/src/components/common/NameLocaleSelector.vue
web/src/**/*.{ts,tsx,vue,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint for Vue linting in the dashboard and run lint checks via npm --prefix web run lint

Files:

  • web/src/views/SetupPage.vue
  • web/src/api/endpoints/setup.ts
  • web/src/api/types.ts
  • web/src/views/SettingsPage.vue
  • web/src/__tests__/stores/setup.test.ts
  • web/src/stores/setup.ts
  • web/src/components/setup/SetupNameLocale.vue
  • web/src/components/settings/SettingsNameLocales.vue
  • web/src/components/common/NameLocaleSelector.vue
src/synthorg/api/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

All public API responses must follow RFC 9457 error format

Files:

  • src/synthorg/api/controllers/setup_agents.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/api/controllers/setup.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.py: Use @pytest.mark.unit, @pytest.mark.integration, @pytest.mark.e2e, @pytest.mark.slow markers for tests
Use Hypothesis for property-based testing in Python with @given + @settings decorators. HYPOTHESIS_PROFILE env var controls examples (ci=50, dev=1000)
Never skip, dismiss, or ignore flaky tests -- always fix them fully. For timing-sensitive tests, mock time.monotonic() and asyncio.sleep() instead of widening margins. Use asyncio.Event().wait() for indefinite blocking instead of asyncio.sleep(large_number)
Prefer @pytest.mark.parametrize for testing similar cases instead of writing multiple test functions

Files:

  • tests/unit/templates/test_renderer.py
  • tests/unit/templates/conftest.py
  • tests/unit/api/controllers/test_setup.py
  • tests/unit/templates/test_inheritance.py
  • tests/unit/templates/test_presets.py
web/src/__tests__/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Vitest for Vue component unit tests with fast-check for property-based testing

Files:

  • web/src/__tests__/stores/setup.test.ts
web/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use fast-check for property-based testing in Vue tests with fc.assert + fc.property

Files:

  • web/src/__tests__/stores/setup.test.ts
web/src/stores/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use Pinia stores for state management in the Vue 3 dashboard instead of other state management approaches

Files:

  • web/src/stores/setup.ts
🧠 Learnings (53)
📚 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 : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...

Applied to files:

  • README.md
  • docs/architecture/tech-stack.md
  • CLAUDE.md
  • docs/design/organization.md
  • 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 docker/Dockerfile.sandbox : Docker sandbox: `synthorg-sandbox` — Python 3.14 + Node.js + git, non-root (UID 10001), agent code execution sandbox

Applied to files:

  • README.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to cli/**/*.go : Go CLI (Go 1.26+) uses Cobra for commands, charmbracelet/huh for interactive CLI, charmbracelet/lipgloss for styled output. Cross-platform builds (linux/darwin/windows × amd64/arm64). GoReleaser for releases with cosign keyless signing of checksums.txt. SLSA L3 provenance attestations via actions/attest-build-provenance.

Applied to files:

  • docs/architecture/tech-stack.md
📚 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 go.mod : Maintain Go 1.26+ requirement. Dependencies: Cobra (CLI framework), charmbracelet/huh and charmbracelet/lipgloss (UI), sigstore-go (code signing), go-containerregistry (container image verification), go-tuf (TUF client for Sigstore).

Applied to files:

  • docs/architecture/tech-stack.md
  • CLAUDE.md
📚 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: Security: SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies: disabled/weighted/per-category/milestone), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume).

Applied to files:

  • docs/architecture/tech-stack.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/security/**/*.py : Security package (security/): SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume)

Applied to files:

  • docs/architecture/tech-stack.md
  • CLAUDE.md
📚 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: CLI workflow (`.github/workflows/cli.yml`) runs Go lint (golangci-lint + go vet) + test (race, coverage) + build (cross-compile matrix) + vulnerability check (govulncheck) + fuzz testing. Cross-compiles for linux/darwin/windows × amd64/arm64. GoReleaser release on v* tags with cosign keyless signing and SLSA L3 attestations.

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to cli/**/*.go : Use Cobra framework for CLI commands and charmbracelet libraries (huh, lipgloss) for interactive UI

Applied to files:

  • docs/architecture/tech-stack.md
📚 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: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.

Applied to files:

  • docs/architecture/tech-stack.md
  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to docker/{Dockerfile*,compose.yml} : Docker: Backend uses 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root (UID 65532), CIS-hardened. Web uses nginxinc/nginx-unprivileged, Vue 3 SPA with PrimeVue + Tailwind CSS, SPA routing, API/WebSocket proxy to backend.

Applied to files:

  • docs/architecture/tech-stack.md
  • CLAUDE.md
📚 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:

  • CLAUDE.md
📚 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: Settings: Runtime-editable settings persistence (DB > env > YAML > code defaults), typed definitions (9 namespaces), Fernet encryption for sensitive values, config bridge, ConfigResolver (typed composed reads for controllers), validation, registry, change notifications via message bus. Per-namespace setting definitions in definitions/ submodule (api, company, providers, memory, budget, security, coordination, observability, backup).

Applied to files:

  • CLAUDE.md
  • src/synthorg/settings/definitions/company.py
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).

Applied to files:

  • CLAUDE.md
  • web/src/views/SetupPage.vue
  • web/src/views/SettingsPage.vue
  • web/src/components/common/NameLocaleSelector.vue
📚 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/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.

Applied to files:

  • CLAUDE.md
  • src/synthorg/templates/builtins/startup.yaml
  • docs/design/organization.md
  • src/synthorg/templates/builtins/solo_founder.yaml
  • src/synthorg/templates/locales.py
  • tests/unit/templates/test_presets.py
📚 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 docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to pyproject.toml : Dependencies: all versions use == in pyproject.toml. Groups: test (pytest + plugins, hypothesis), dev (includes test + ruff, mypy, pre-commit, commitizen, pip-audit). Required: mem0ai (Mem0 memory backend — the default and currently only backend). Install: uv sync installs everything (dev group is default).

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 web/package.json : Web dashboard Node.js 20+; dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, ESLint, vue-tsc)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to cli/** : CLI: Go 1.26+, dependencies in cli/go.mod (Cobra, charmbracelet/huh).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to cli/go.mod : Go CLI dependencies: Go 1.26+, Cobra (commands), charmbracelet/huh (interactive CLI), charmbracelet/lipgloss (styled output).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to src/**/*.py : Use event name constants from `synthorg.observability.events.<domain>` modules instead of string literals (e.g., `API_REQUEST_STARTED` from `events.api`)

Applied to files:

  • src/synthorg/observability/events/template.py
  • src/synthorg/observability/events/setup.py
  • src/synthorg/templates/presets.py
📚 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 : Use event name constants from synthorg.observability.events domain-specific modules (e.g., PROVIDER_CALL_START from events.provider). Import directly: from synthorg.observability.events.<domain> import EVENT_CONSTANT.

Applied to files:

  • src/synthorg/observability/events/template.py
  • src/synthorg/observability/events/setup.py
  • src/synthorg/templates/presets.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/hr/**/*.py : HR engine must provide: hiring, firing, onboarding, offboarding, agent registry, performance tracking (task metrics, collaboration scoring, trend detection), promotion/demotion

Applied to files:

  • src/synthorg/templates/builtins/startup.yaml
📚 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/settings/**/*.py : Settings package (settings/): runtime-editable settings persistence (DB > env > YAML > code defaults), typed definitions (9 namespaces), Fernet encryption for sensitive values, config bridge (JSON serialization for Pydantic/collections), ConfigResolver (typed accessors), validation, registry, change notifications via message bus, SettingsSubscriber protocol, SettingsChangeDispatcher (polls `#settings` channel, routes to subscribers, restart_required filtering)

Applied to files:

  • src/synthorg/settings/definitions/company.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/settings/**/*.py : Settings use runtime-editable persistence with precedence: DB > env > YAML > code defaults. 8 namespaces with Fernet encryption for sensitive values.

Applied to files:

  • src/synthorg/settings/definitions/company.py
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Applies to src/synthorg/hr/**/*.py : HR package (hr/): hiring, firing, onboarding, offboarding, agent registry, performance tracking (task metrics, collaboration scoring, LLM calibration, collaboration overrides, trend detection), promotion/demotion (criteria evaluation, approval strategies, model mapping)

Applied to files:

  • src/synthorg/templates/builtins/agency.yaml
  • src/synthorg/templates/builtins/research_lab.yaml
📚 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:

  • src/synthorg/observability/events/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 : Use event constants from `synthorg.observability.events.<domain>` (e.g., `API_REQUEST_STARTED` from `events.api`); import directly and log with structured kwargs: `logger.info(EVENT, key=value)`, never interpolated strings

Applied to files:

  • src/synthorg/observability/events/setup.py
  • src/synthorg/templates/presets.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/**/*.py : Always use event name constants from the domain-specific module under `synthorg.observability.events` in logging calls

Applied to files:

  • src/synthorg/observability/events/setup.py
  • src/synthorg/templates/presets.py
📚 Learning: 2026-03-18T21:23:23.586Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-18T21:23:23.586Z
Learning: Applies to src/synthorg/**/*.py : Event names: always use constants from the domain-specific module under synthorg.observability.events (e.g., API_REQUEST_STARTED from events.api, TOOL_INVOKE_START from events.tool). Import directly from synthorg.observability.events.<domain>.

Applied to files:

  • src/synthorg/observability/events/setup.py
  • src/synthorg/templates/presets.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/synthorg/**/*.py : Event names: always use constants from domain-specific modules under synthorg.observability.events (e.g., PROVIDER_CALL_START from events.provider, BUDGET_RECORD_ADDED from events.budget, etc.). Import directly: `from synthorg.observability.events.<domain> import EVENT_CONSTANT`.

Applied to files:

  • src/synthorg/observability/events/setup.py
  • src/synthorg/templates/presets.py
📚 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 : Always use event name constants from domain-specific modules under `synthorg.observability.events` (e.g., `PROVIDER_CALL_START` from `events.provider`); import directly: `from synthorg.observability.events.<domain> import EVENT_CONSTANT`

Applied to files:

  • src/synthorg/observability/events/setup.py
  • src/synthorg/templates/presets.py
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to web/src/__tests__/**/*.ts : Use Vitest for Vue component unit tests with fast-check for property-based testing

Applied to files:

  • web/src/__tests__/stores/setup.test.ts
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to web/src/stores/**/*.ts : Use Pinia stores for state management in the Vue 3 dashboard instead of other state management approaches

Applied to files:

  • web/src/stores/setup.ts
📚 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 : Use frozen Pydantic models for config/identity; separate mutable-via-copy models (using `model_copy(update=...)`) for runtime state

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
📚 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 : Use frozen Pydantic models for config/identity; use separate mutable-via-copy models (using model_copy(update=...)) for runtime state that evolves. Never mix static config fields with mutable runtime fields in one model.

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to web/src/**/*.{ts,tsx,vue} : Vue 3 components must use TypeScript with type safety in the dashboard

Applied to files:

  • web/src/components/setup/SetupNameLocale.vue
  • web/src/components/common/NameLocaleSelector.vue
📚 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:

  • src/synthorg/templates/presets.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:

  • src/synthorg/templates/presets.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:

  • src/synthorg/templates/presets.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/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers

Applied to files:

  • docs/design/operations.md
  • src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-16T20:14:00.937Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T20:14:00.937Z
Learning: Applies to **/*.py : Validate: at system boundaries (user input, external APIs, config files).

Applied to files:

  • src/synthorg/templates/locales.py
  • src/synthorg/api/controllers/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 : Handle errors explicitly, never silently swallow. Validate at system boundaries (user input, external APIs, config files).

Applied to files:

  • src/synthorg/templates/locales.py
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to **/*.py : Use `except A, B:` syntax (no parentheses) for exception handling on Python 3.14 -- enforced by ruff

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Use `except A, B:` syntax (no parentheses) for exception handling — PEP 758 exception syntax enforced by ruff on Python 3.14

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Use PEP 758 except syntax with `except A, B:` (no parentheses) for multiple exceptions—ruff enforces this on Python 3.14.

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Use PEP 758 except syntax: `except A, B:` (no parentheses) — enforced by ruff on Python 3.14

Applied to files:

  • src/synthorg/api/controllers/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 **/*.py : Use PEP 758 except syntax: use `except A, B:` (no parentheses) — ruff enforces this on Python 3.14.

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Handle errors explicitly, never silently swallow exceptions

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Handle errors explicitly; never silently swallow exceptions

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 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 **/*.py : Handle errors explicitly—never silently swallow exceptions.

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to **/*.py : No `from __future__ import annotations` in Python code -- Python 3.14 has PEP 649 native lazy annotations

Applied to files:

  • src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Applies to **/*.py : Validate at system boundaries (user input, external APIs, config files)

Applied to files:

  • src/synthorg/api/controllers/setup.py
🧬 Code graph analysis (10)
src/synthorg/settings/definitions/company.py (5)
src/synthorg/settings/registry.py (1)
  • register (30-50)
web/src/api/types.ts (3)
  • SettingDefinition (941-956)
  • SettingNamespace (924-933)
  • SettingType (935-935)
src/synthorg/settings/models.py (1)
  • SettingDefinition (34-141)
src/synthorg/settings/enums.py (2)
  • SettingNamespace (6-21)
  • SettingType (24-36)
tests/unit/settings/test_encryption.py (1)
  • key (15-16)
src/synthorg/api/controllers/setup_agents.py (2)
src/synthorg/templates/schema.py (1)
  • CompanyTemplate (229-361)
src/synthorg/templates/presets.py (1)
  • generate_auto_name (397-457)
tests/unit/templates/test_renderer.py (2)
src/synthorg/templates/loader.py (1)
  • load_template (161-217)
src/synthorg/templates/renderer.py (2)
  • render_template (73-110)
  • _expand_single_agent (608-673)
web/src/api/endpoints/setup.ts (3)
src/synthorg/api/controllers/setup_models.py (3)
  • AvailableLocalesResponse (246-257)
  • SetupNameLocalesResponse (234-243)
  • SetupNameLocalesRequest (221-231)
web/src/api/types.ts (4)
  • AvailableLocalesResponse (917-920)
  • ApiResponse (140-142)
  • SetupNameLocalesResponse (913-915)
  • SetupNameLocalesRequest (909-911)
web/src/api/client.ts (2)
  • apiClient (13-17)
  • unwrap (98-108)
web/src/api/types.ts (1)
src/synthorg/api/controllers/setup_models.py (3)
  • SetupNameLocalesRequest (221-231)
  • SetupNameLocalesResponse (234-243)
  • AvailableLocalesResponse (246-257)
web/src/stores/setup.ts (2)
web/src/utils/errors.ts (1)
  • getErrorMessage (17-69)
web/src/api/endpoints/setup.ts (1)
  • saveNameLocales (69-72)
src/synthorg/templates/renderer.py (1)
src/synthorg/templates/presets.py (1)
  • generate_auto_name (397-457)
tests/unit/api/controllers/test_setup.py (2)
src/synthorg/api/controllers/setup.py (2)
  • _check_has_name_locales (769-797)
  • _read_name_locales (873-920)
src/synthorg/settings/errors.py (1)
  • SettingNotFoundError (8-9)
tests/unit/templates/test_presets.py (2)
src/synthorg/templates/presets.py (1)
  • generate_auto_name (397-457)
src/synthorg/templates/locales.py (1)
  • resolve_locales (183-208)
src/synthorg/api/controllers/setup.py (3)
src/synthorg/api/controllers/setup_models.py (10)
  • AvailableLocalesResponse (246-257)
  • SetupAgentRequest (124-165)
  • SetupAgentResponse (168-185)
  • SetupAgentsListResponse (202-218)
  • SetupAgentSummary (70-93)
  • SetupCompanyRequest (54-67)
  • SetupCompanyResponse (96-121)
  • SetupCompleteResponse (260-269)
  • SetupNameLocalesRequest (221-231)
  • SetupNameLocalesResponse (234-243)
src/synthorg/settings/service.py (2)
  • SettingsService (152-637)
  • get_entry (275-298)
src/synthorg/templates/locales.py (1)
  • resolve_locales (183-208)
🪛 YAMLlint (1.38.0)
src/synthorg/templates/builtins/full_company.yaml

[warning] 141-141: comment not indented like content

(comments-indentation)


[error] 142-142: syntax error: found character '%' that cannot start any token

(syntax)

Comment on lines +769 to +797
async def _check_has_name_locales(settings_svc: SettingsService) -> bool:
"""Check whether name locales have been explicitly configured.

Args:
settings_svc: Settings service instance.

Returns:
True if name locales are user-configured, False otherwise.
"""
try:
entry = await settings_svc.get_entry("company", "name_locales")
except MemoryError, RecursionError:
raise
except SettingNotFoundError:
return False
except Exception:
logger.warning(
SETUP_STATUS_SETTINGS_UNAVAILABLE,
setting="name_locales",
exc_info=True,
)
return False
if entry.source != SettingSource.DATABASE or not entry.value:
return False
try:
parsed = json.loads(entry.value)
except json.JSONDecodeError, TypeError:
return False
return isinstance(parsed, list) and len(parsed) > 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how _read_name_locales handles invalid locale codes vs _check_has_name_locales
ast-grep --pattern $'async def _check_has_name_locales($_) -> bool:
  $$$
}'

echo "---"

# Check resolve_locales to understand filtering behavior
rg -n "def resolve_locales" src/synthorg/templates/locales.py -A 20

Repository: Aureliolo/synthorg

Length of output: 767


🏁 Script executed:

#!/bin/bash
# Find _read_name_locales function
rg -n "_read_name_locales" src/synthorg/api/controllers/setup.py -B 2 -A 30

Repository: Aureliolo/synthorg

Length of output: 2986


🏁 Script executed:

#!/bin/bash
# Find where _check_has_name_locales is called
rg -n "_check_has_name_locales" src/synthorg/api/controllers/setup.py -B 5 -A 5

# Also check the SetupStatus response structure
rg -n "class SetupStatus" src/synthorg/api/models/setup.py -A 20

Repository: Aureliolo/synthorg

Length of output: 1158


🏁 Script executed:

#!/bin/bash
# Find SetupStatus model
fd -t f "*.py" -path "*api*" | xargs rg -l "class SetupStatus"

# Also look at the full status endpoint to see result assignment
rg -n "has_name_locales" src/synthorg/api/controllers/setup.py -B 2 -A 2

Repository: Aureliolo/synthorg

Length of output: 1446


🏁 Script executed:

#!/bin/bash
# Find SetupStatus model definition
rg -n "class SetupStatus" src/synthorg/api/controllers/setup_models.py -A 20

# Look for wizard step logic
rg -n "Names\|name_locales" src/synthorg/api/controllers/setup.py | head -30

Repository: Aureliolo/synthorg

Length of output: 871


🏁 Script executed:

#!/bin/bash
# Search for wizard step logic or form display logic
rg -n "wizard\|step.*skip\|Names" src/synthorg/ -i --type py | grep -i "name.*locale\|locale.*name" | head -20

# Also check frontend usage of has_name_locales in response
rg -n "has_name_locales" src/ --type py | grep -v "test" | head -20

Repository: Aureliolo/synthorg

Length of output: 766


🏁 Script executed:

#!/bin/bash
# Get the full _read_name_locales implementation
rg -n "_read_name_locales" src/synthorg/api/controllers/setup.py -A 35

# Get the full resolve_locales implementation
rg -n "def resolve_locales" src/synthorg/templates/locales.py -A 40

Repository: Aureliolo/synthorg

Length of output: 4020


🏁 Script executed:

#!/bin/bash
# Get the complete _read_name_locales implementation
rg -n "_read_name_locales" src/synthorg/api/controllers/setup.py -A 50 | tail -30

Repository: Aureliolo/synthorg

Length of output: 1035


Add locale code validation to _check_has_name_locales() to match _read_name_locales() behavior.

The function returns True for any non-empty list that parses as JSON (e.g., ["invalid_code"]), but _read_name_locales() filters invalid codes through resolve_locales() and returns None if all codes are invalid. This creates a state mismatch where SetupStatusResponse.has_name_locales=True while the wizard defaults to all locales. Both functions should validate that at least one locale code is valid before returning True.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/synthorg/api/controllers/setup.py` around lines 769 - 797, The
_check_has_name_locales function currently returns True for any non-empty JSON
list; update it to mirror _read_name_locales by validating parsed locale codes
with resolve_locales and only return True if resolve_locales yields at least one
valid locale; keep existing error handling (MemoryError/RecursionError
re-raises, SettingNotFoundError returns False, other exceptions log and return
False), parse entry.value with json.loads as before, call
resolve_locales(parsed) (or the same validation routine used by
_read_name_locales) and return True only when the resolved list is non-empty,
otherwise return False.

Comment on lines +203 to +207
logger.warning(
"locales.resolve_dropped_invalid",
dropped=dropped,
kept_count=len(valid),
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Use an event constant instead of a string literal for structured logging.

The log event "locales.resolve_dropped_invalid" should be defined as a constant in synthorg.observability.events.<domain> and imported here. As per coding guidelines: "Use event name constants from synthorg.observability.events.<domain> modules instead of string literals".

♻️ Suggested approach
  1. Add a constant (e.g., LOCALES_RESOLVE_DROPPED_INVALID) in the appropriate events submodule (e.g., synthorg/observability/events/templates.py)
  2. Import and use it here:
+from synthorg.observability.events.templates import LOCALES_RESOLVE_DROPPED_INVALID
 ...
     if dropped:
         logger.warning(
-            "locales.resolve_dropped_invalid",
+            LOCALES_RESOLVE_DROPPED_INVALID,
             dropped=dropped,
             kept_count=len(valid),
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/synthorg/templates/locales.py` around lines 203 - 207, Replace the string
literal "locales.resolve_dropped_invalid" with a constant: add
LOCALES_RESOLVE_DROPPED_INVALID to the synthorg.observability.events.templates
module (or the appropriate events submodule for templates), import that constant
into the module containing resolve_dropped_invalid (the current template locales
module), and change the logger.warning call to use
LOCALES_RESOLVE_DROPPED_INVALID while keeping the dropped and kept_count kwargs
unchanged; also update the import block to include the new constant.

Comment on lines +397 to +472
def generate_auto_name(
role: str, # noqa: ARG001
*,
seed: int | None = None,
locales: list[str] | None = None,
) -> str:
"""Generate an internationally diverse agent name using Faker.

Uses a deterministic PRNG when *seed* is provided, ensuring
reproducible name generation across runs.
When *seed* is provided, a local ``random.Random`` deterministically
selects a locale, then a **fresh** single-locale Faker instance
generates the name -- the cached instance is never mutated.

The *role* parameter is accepted because callers
(``setup_agents.py``, ``renderer.py``) pass it positionally;
it does not influence name generation.

Args:
role: The agent's role name.
role: The agent's role name. Unused since the switch from
role-based name pools to Faker.
seed: Optional random seed for deterministic naming.
locales: Faker locale codes to draw from. Defaults to all
Latin-script locales when ``None`` or empty.

Returns:
A generated agent name string.
A generated full name string.
"""
import random # noqa: PLC0415

from faker import Faker # noqa: PLC0415

from synthorg.templates.locales import ALL_LATIN_LOCALES # noqa: PLC0415

locale_list = locales or list(ALL_LATIN_LOCALES)
try:
if seed is not None:
rng = random.Random(seed) # noqa: S311
chosen_locale = rng.choice(locale_list)
# Fresh instance -- never mutate the shared cached one.
fake = Faker([chosen_locale])
fake.seed_instance(seed)
else:
fake = _get_faker(tuple(locale_list))
return str(fake.name())
except MemoryError, RecursionError:
raise
except Exception:
from synthorg.observability.events.template import ( # noqa: PLC0415
TEMPLATE_NAME_GEN_FAKER_ERROR,
)

logger.warning(
TEMPLATE_NAME_GEN_FAKER_ERROR,
locales=locale_list[:5],
seed=seed,
exc_info=True,
)
# Fall back to a known-safe locale.
fallback = Faker(["en_US"])
if seed is not None:
fallback.seed_instance(seed)
return str(fallback.name())


@functools.lru_cache(maxsize=128)
def _get_faker(locale_tuple: tuple[str, ...]) -> Any:
"""Return a cached Faker instance for the given locale tuple.

Caching avoids re-initialising locale providers on every call.
The cache is keyed by locale tuple (immutable, hashable).

Only used for the **unseeded** path; seeded callers must create
a fresh instance to avoid mutating shared state.
"""
key = role.strip().lower()
pool = _AUTO_NAMES.get(key, _AUTO_NAMES["_default"])
rng = random.Random(seed) # noqa: S311
return rng.choice(pool)
from faker import Faker # noqa: PLC0415

return Faker(list(locale_tuple))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Split generate_auto_name() into smaller helpers.

This new public function now bundles locale selection, seeded/unseeded Faker construction, fallback logging, and fallback generation in one large block. Extracting those branches would bring it back under the repo’s 50-line limit and make the failure path easier to test.

As per coding guidelines "Functions must be < 50 lines, files < 800 lines".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/synthorg/templates/presets.py` around lines 397 - 472, The
generate_auto_name function is too large; split its responsibilities into small
helpers: extract locale selection into a _choose_locale(locales, seed) function
that returns (locale_list, chosen_locale_or_none), move seeded Faker
construction into _build_seeded_faker(locale, seed) and the unseeded path into
_build_unseeded_faker(locale_tuple) (which can call the existing _get_faker),
and extract the exception fallback and logging into
_fallback_name(locales_preview, seed) which logs TEMPLATE_NAME_GEN_FAKER_ERROR
and returns the fallback name; then have generate_auto_name call these helpers
to keep it under 50 lines and preserve behavior (referencing generate_auto_name,
_get_faker, TEMPLATE_NAME_GEN_FAKER_ERROR).

Comment on lines +181 to +186
<input
type="checkbox"
class="sr-only"
:checked="isLocaleSelected(locale)"
:aria-label="displayNames[locale] || locale"
@change="toggleLocale(locale, ($event.target as HTMLInputElement).checked)"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider using aria-labelledby or a more descriptive label for screen readers.

The aria-label uses the display name fallback, but since each chip is inside a <label> element wrapping the checkbox, the accessible name is already provided by the label text. The aria-label here is redundant but harmless. Optionally, you could remove it since the visible label text serves the same purpose.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/common/NameLocaleSelector.vue` around lines 181 - 186, The
checkbox input currently sets an aria-label using displayNames[locale], which is
redundant because the visible label text already provides the accessible name;
remove the :aria-label binding from the input (or alternatively replace it with
aria-labelledby that points to the wrapping label's id if you prefer explicit
referencing) so update the input in the NameLocaleSelector component (the
checkbox that calls isLocaleSelected(locale) and toggleLocale(locale, ...)) to
omit :aria-label (or wire aria-labelledby to the label element) and ensure the
label text remains the authoritative accessible name.

Comment on lines +120 to +129
async function saveNameLocales(locales: string[]) {
error.value = null
try {
await setupApi.saveNameLocales({ locales })
await fetchStatus()
} catch (err) {
error.value = getErrorMessage(err)
throw err
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Propagate the status-refresh failure after saving locales.

fetchStatus() absorbs errors, so this new success path still resolves when the follow-up refresh fails. Downstream, SetupNameLocale.vue will emit next and advance with stale completion state.

💡 One way to make the save path fail when the refresh fails
-  async function fetchStatus() {
+  async function fetchStatus(options: { rethrow?: boolean } = {}) {
     loading.value = true
     error.value = null
     try {
       status.value = await setupApi.getSetupStatus()
       statusLoaded.value = true
       syncCompletionFromStatus()
     } catch (err) {
       error.value = getErrorMessage(err)
+      if (options.rethrow) {
+        throw err
+      }
       // statusLoaded stays false -- isSetupNeeded/isAdminNeeded
       // default to true (fail-closed).
     } finally {
       loading.value = false
     }
   }
@@
   async function saveNameLocales(locales: string[]) {
     error.value = null
     try {
       await setupApi.saveNameLocales({ locales })
-      await fetchStatus()
+      await fetchStatus({ rethrow: true })
     } catch (err) {
       error.value = getErrorMessage(err)
       throw err
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/stores/setup.ts` around lines 120 - 129, saveNameLocales currently
awaits fetchStatus(), but fetchStatus swallows errors so a failed refresh still
makes the save path resolve and the UI advances with stale state; wrap the
fetchStatus call to ensure any refresh error propagates (e.g. change fetchStatus
to rethrow on failure or in saveNameLocales call await fetchStatus().catch(err
=> { error.value = getErrorMessage(err); throw err }) ), keeping error.value set
via getErrorMessage(err) and rethrowing so the caller (SetupNameLocale.vue) sees
the failure; reference: saveNameLocales and fetchStatus.

Prevent saving fallback __all__ when initial fetch fails by
adding loadFailed state that blocks handleNext and disables
the Next button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@web/src/components/setup/SetupNameLocale.vue`:
- Around line 36-47: The fetch in onMounted that calls setup.fetchNameLocales
leaves loadFailed true with no way to retry; add an explicit retry path:
implement a retry handler (e.g., fetchNameLocalesRetry) that resets
loadFailed.value = false and loading.value = true, re-invokes
setup.fetchNameLocales, and updates selectedLocales.value, error.value and
loading.value exactly as the initial try/catch does; expose this handler to the
template as a Retry button or link that is shown when loadFailed is true so
users can re-attempt the request; apply the same pattern to the other similar
fetch blocks that set loadFailed/error/loading in this component.
🪄 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: b72b9fda-a0ab-4cd2-a1b6-910b1bca5c6d

📥 Commits

Reviewing files that changed from the base of the PR and between 0c3b1cd and da48629.

📒 Files selected for processing (1)
  • web/src/components/setup/SetupNameLocale.vue
📜 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: Test (Python 3.14)
  • GitHub Check: Build Sandbox
  • GitHub Check: Build Web
  • GitHub Check: Build Backend
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (2)
web/src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Vue 3 components must use TypeScript with type safety in the dashboard

Files:

  • web/src/components/setup/SetupNameLocale.vue
web/src/**/*.{ts,tsx,vue,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint for Vue linting in the dashboard and run lint checks via npm --prefix web run lint

Files:

  • web/src/components/setup/SetupNameLocale.vue
🧠 Learnings (1)
📚 Learning: 2026-03-22T08:19:13.388Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T08:19:13.388Z
Learning: Applies to web/src/**/*.{ts,tsx,vue} : Vue 3 components must use TypeScript with type safety in the dashboard

Applied to files:

  • web/src/components/setup/SetupNameLocale.vue
🔇 Additional comments (1)
web/src/components/setup/SetupNameLocale.vue (1)

22-24: Good guard against destructive saves before initial data is trustworthy.

Blocking handleNext while loading/failed and disabling Next in the same states prevents accidental overwrite with fallback data.

Also applies to: 87-89

Extract fetch logic into reusable fetchLocales function and expose
a Retry button when loadFailed is true, so users can re-attempt
without reloading the page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@web/src/components/setup/SetupNameLocale.vue`:
- Around line 72-76: The Retry button in SetupNameLocale.vue (the <button> with
v-if="loadFailed" that calls fetchLocales) lacks an explicit type and will
default to "submit" inside forms; update that button element to include
type="button" to prevent accidental form submissions when rendered within a form
and keep the click handler fetchLocales unchanged.
🪄 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: 78125deb-562f-4ac2-9801-e2dfb858c006

📥 Commits

Reviewing files that changed from the base of the PR and between da48629 and 0c67ad0.

📒 Files selected for processing (1)
  • web/src/components/setup/SetupNameLocale.vue
📜 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: Test (Python 3.14)
  • GitHub Check: Build Backend
  • GitHub Check: Build Web
  • GitHub Check: Build Sandbox
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (2)
web/src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Vue 3 components must use TypeScript with type safety in the dashboard

Files:

  • web/src/components/setup/SetupNameLocale.vue
web/src/**/*.{ts,tsx,vue,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint for Vue linting in the dashboard and run lint checks via npm --prefix web run lint

Files:

  • web/src/components/setup/SetupNameLocale.vue
🧠 Learnings (1)
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).

Applied to files:

  • web/src/components/setup/SetupNameLocale.vue
🔇 Additional comments (2)
web/src/components/setup/SetupNameLocale.vue (2)

22-34: Good submit guard and save flow.

handleNext correctly blocks while loading/failure/saving and resets saving in finally, which avoids duplicate submissions and stuck loading states.


36-53: Retryable locale fetch path is well implemented.

Extracting fetchLocales() and wiring Retry + loadFailed gating fixes the transient failure dead-end and keeps navigation safe.

Also applies to: 67-79, 99-100

Prevents accidental form submission since native button defaults
to type=submit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@docs/design/operations.md`:
- Line 1071: Update the completion-gate description for `POST
/api/v1/setup/complete` to use plural semantics consistent with the `has_agents`
and `has_providers` status flags—e.g., change “requires company + agent +
provider” to “requires company, agents, and providers” (or “requires company +
agents + providers”) and ensure the text clarifies that the gate checks the
`has_company`, `has_agents`, and `has_providers` flags for completion
eligibility.
🪄 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: f062df87-0084-4967-b002-083363f169ed

📥 Commits

Reviewing files that changed from the base of the PR and between a4dd7a9 and c800ea7.

📒 Files selected for processing (4)
  • CLAUDE.md
  • README.md
  • docs/architecture/tech-stack.md
  • docs/design/operations.md
📜 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). (4)
  • GitHub Check: Test (Python 3.14)
  • GitHub Check: Build Sandbox
  • GitHub Check: Build Backend
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (1)
docs/**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

docs/**/*.md: Zensical builds documentation from Markdown in docs/ (config: mkdocs.yml). Do not use --strict until zensical/backlog#72 is fixed.
7 design spec pages in docs/design/, Architecture in docs/architecture/, Roadmap in docs/roadmap/, Security in docs/security.md, Licensing in docs/licensing.md, Reference in docs/reference/

Files:

  • docs/architecture/tech-stack.md
  • docs/design/operations.md
🧠 Learnings (24)
📚 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 : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...

Applied to files:

  • README.md
  • docs/architecture/tech-stack.md
  • 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 docker/Dockerfile.sandbox : Docker sandbox: `synthorg-sandbox` — Python 3.14 + Node.js + git, non-root (UID 10001), agent code execution sandbox

Applied to files:

  • README.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to cli/**/*.go : Go CLI (Go 1.26+) uses Cobra for commands, charmbracelet/huh for interactive CLI, charmbracelet/lipgloss for styled output. Cross-platform builds (linux/darwin/windows × amd64/arm64). GoReleaser for releases with cosign keyless signing of checksums.txt. SLSA L3 provenance attestations via actions/attest-build-provenance.

Applied to files:

  • docs/architecture/tech-stack.md
📚 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 go.mod : Maintain Go 1.26+ requirement. Dependencies: Cobra (CLI framework), charmbracelet/huh and charmbracelet/lipgloss (UI), sigstore-go (code signing), go-containerregistry (container image verification), go-tuf (TUF client for Sigstore).

Applied to files:

  • docs/architecture/tech-stack.md
  • 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/security/**/*.py : Security package (security/): SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume)

Applied to files:

  • docs/architecture/tech-stack.md
  • CLAUDE.md
📚 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: Security: SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, output scan response policies (redact/withhold/log-only/autonomy-tiered), risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies: disabled/weighted/per-category/milestone), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume).

Applied to files:

  • docs/architecture/tech-stack.md
📚 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: CLI workflow (`.github/workflows/cli.yml`) runs Go lint (golangci-lint + go vet) + test (race, coverage) + build (cross-compile matrix) + vulnerability check (govulncheck) + fuzz testing. Cross-compiles for linux/darwin/windows × amd64/arm64. GoReleaser release on v* tags with cosign keyless signing and SLSA L3 attestations.

Applied to files:

  • docs/architecture/tech-stack.md
📚 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: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.

Applied to files:

  • docs/architecture/tech-stack.md
  • CLAUDE.md
📚 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/security/**/*.py : Security module includes SecOps agent, rule engine (soft-allow/hard-deny), audit log, output scanner, risk classifier, autonomy levels (4 strategies), timeout policies.

Applied to files:

  • docs/architecture/tech-stack.md
📚 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:

  • CLAUDE.md
📚 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: Settings: Runtime-editable settings persistence (DB > env > YAML > code defaults), typed definitions (9 namespaces), Fernet encryption for sensitive values, config bridge, ConfigResolver (typed composed reads for controllers), validation, registry, change notifications via message bus. Per-namespace setting definitions in definitions/ submodule (api, company, providers, memory, budget, security, coordination, observability, backup).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).

Applied to files:

  • CLAUDE.md
📚 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/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to docker/{Dockerfile*,compose.yml} : Docker: Backend uses 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root (UID 65532), CIS-hardened. Web uses nginxinc/nginx-unprivileged, Vue 3 SPA with PrimeVue + Tailwind CSS, SPA routing, API/WebSocket proxy to backend.

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 docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to web/** : Web dashboard: Node.js 20+, dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, fast-check, ESLint, vue-tsc).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to pyproject.toml : Dependencies: all versions use == in pyproject.toml. Groups: test (pytest + plugins, hypothesis), dev (includes test + ruff, mypy, pre-commit, commitizen, pip-audit). Required: mem0ai (Mem0 memory backend — the default and currently only backend). Install: uv sync installs everything (dev group is default).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-22T13:16:27.243Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T13:16:27.243Z
Learning: Applies to web/package.json : Web dashboard dependencies: Node.js 20+, Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, CodeMirror 6 (vue-codemirror), js-yaml, Vitest, fast-check, ESLint, vue-tsc in web/package.json

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-22T13:16:27.243Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T13:16:27.243Z
Learning: Applies to pyproject.toml : Required Python dependencies: mem0ai (Mem0 memory backend -- the default and currently only backend), cryptography (Fernet encryption for sensitive settings at rest)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-22T13:16:27.243Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T13:16:27.243Z
Learning: Applies to pyproject.toml : Dependency groups: test (pytest + plugins, hypothesis), dev (includes test + ruff, mypy, pre-commit, commitizen, pip-audit)

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 web/package.json : Web dashboard Node.js 20+; dependencies in web/package.json (Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, ESLint, vue-tsc)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-22T13:16:27.243Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T13:16:27.243Z
Learning: Applies to cli/go.mod : CLI Go dependencies: Cobra, charmbracelet/huh, charmbracelet/lipgloss, sigstore-go, go-containerregistry, go-tuf in cli/go.mod

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to cli/** : CLI: Go 1.26+, dependencies in cli/go.mod (Cobra, charmbracelet/huh).

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/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers

Applied to files:

  • docs/design/operations.md
🔇 Additional comments (3)
docs/architecture/tech-stack.md (1)

64-64: Accurate tech-stack update for name generation.

This row cleanly reflects the new Faker-based multi-locale naming capability and its rationale.

README.md (1)

110-110: Quick-start flow is now aligned with the setup wizard.

Good update adding the name-locale step in the first-run walkthrough.

CLAUDE.md (1)

119-119: LGTM! Documentation accurately reflects the new name generation feature.

Both updates are appropriate and well-integrated:

  • The templates/ package description now includes locale-aware name generation alongside its existing responsibilities
  • The faker dependency is correctly categorized as required (it replaces hardcoded name pools) with a clear explanation of its purpose

The formatting is consistent, and the level of detail matches CLAUDE.md's role as a high-level project reference.

Also applies to: 252-252

The completion gate checks has_company, has_agents, and has_providers
(all plural). The doc said "agent" (singular).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
docs/design/operations.md (1)

1071-1071: ⚠️ Potential issue | 🟡 Minor

Complete the plural consistency fix: "provider" → "providers".

The completion gate description now correctly uses "agents" (plural) but still has "provider" (singular). The status endpoint reports has_providers (plural), so the gate description should match.

📝 Proposed fix
-| `GET /api/v1/setup/status`, `GET /api/v1/setup/templates`, `POST /api/v1/setup/company`, `POST /api/v1/setup/agent`, `GET /api/v1/setup/agents`, `PUT /api/v1/setup/agents/{index}/model` (`{index}` = zero-based position in the list returned by `GET /api/v1/setup/agents`; not a stable ID -- re-fetch to resolve; out-of-range returns 404), `GET /api/v1/setup/name-locales/available`, `GET /api/v1/setup/name-locales`, `PUT /api/v1/setup/name-locales`, `POST /api/v1/setup/complete` | First-run setup wizard: status check (public, reports `has_company`/`has_agents`/`has_providers`/`has_name_locales` for step resume), template listing, company creation (auto-creates template agents with model matching), agent listing + model reassignment, manual agent creation (blank path), name locale management (list available Faker locales, get/set selected locales for agent name generation), completion gate (requires company + agents + provider) |
+| `GET /api/v1/setup/status`, `GET /api/v1/setup/templates`, `POST /api/v1/setup/company`, `POST /api/v1/setup/agent`, `GET /api/v1/setup/agents`, `PUT /api/v1/setup/agents/{index}/model` (`{index}` = zero-based position in the list returned by `GET /api/v1/setup/agents`; not a stable ID -- re-fetch to resolve; out-of-range returns 404), `GET /api/v1/setup/name-locales/available`, `GET /api/v1/setup/name-locales`, `PUT /api/v1/setup/name-locales`, `POST /api/v1/setup/complete` | First-run setup wizard: status check (public, reports `has_company`/`has_agents`/`has_providers`/`has_name_locales` for step resume), template listing, company creation (auto-creates template agents with model matching), agent listing + model reassignment, manual agent creation (blank path), name locale management (list available Faker locales, get/set selected locales for agent name generation), completion gate (requires company + agents + providers) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/design/operations.md` at line 1071, The text in the setup endpoints
documentation uses inconsistent plurality: change the completion gate
description string that currently reads "completion gate (requires company +
agents + provider)" to use "providers" (plural) so it matches the status field
`has_providers` and the rest of the doc; locate the phrase in
docs/design/operations.md (the line describing `GET /api/v1/setup/...` endpoints
and the parenthetical summary) and update "provider" → "providers".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@docs/design/operations.md`:
- Line 1071: The text in the setup endpoints documentation uses inconsistent
plurality: change the completion gate description string that currently reads
"completion gate (requires company + agents + provider)" to use "providers"
(plural) so it matches the status field `has_providers` and the rest of the doc;
locate the phrase in docs/design/operations.md (the line describing `GET
/api/v1/setup/...` endpoints and the parenthetical summary) and update
"provider" → "providers".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ad6f5344-3b44-4f91-81d6-4a4281ddccc1

📥 Commits

Reviewing files that changed from the base of the PR and between c800ea7 and 18773d7.

📒 Files selected for processing (1)
  • docs/design/operations.md
📜 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: Test (Python 3.14)
  • GitHub Check: Build Web
  • GitHub Check: Build Sandbox
  • GitHub Check: Build Backend
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (1)
docs/**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

docs/**/*.md: Zensical builds documentation from Markdown in docs/ (config: mkdocs.yml). Do not use --strict until zensical/backlog#72 is fixed.
7 design spec pages in docs/design/, Architecture in docs/architecture/, Roadmap in docs/roadmap/, Security in docs/security.md, Licensing in docs/licensing.md, Reference in docs/reference/

Files:

  • docs/design/operations.md
🧠 Learnings (1)
📚 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/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers

Applied to files:

  • docs/design/operations.md

Matches the has_providers status field and actual gate checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Aureliolo Aureliolo merged commit 5edc6ec into main Mar 22, 2026
12 of 14 checks passed
@Aureliolo Aureliolo deleted the fix/fix-setup-wizard branch March 22, 2026 13:58
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 22, 2026 13:58 — with GitHub Actions Inactive
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 22, 2026

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
10333 1 10332 6
View the top 1 failed test(s) by shortest run time
tests.unit.memory.org.test_store.TestSQLiteOrgFactStoreOperations::test_save_sqlite_error_wraps
Stack Traces | 0.015s run time
.venv/lib/python3.14....../site-packages/aiosqlite/core.py:66: in _connection_worker_thread
    future.get_loop().call_soon_threadsafe(set_result, future, result)
../..................../_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/base_events.py:872: in call_soon_threadsafe
    self._check_closed()
../..................../_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/base_events.py:550: in _check_closed
    raise RuntimeError('Event loop is closed')
E   RuntimeError: Event loop is closed

During handling of the above exception, another exception occurred:
../..................../_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/threading.py:1082: in _bootstrap_inner
    self._context.run(self.run)
../..................../_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/threading.py:1024: in run
    self._target(*self._args, **self._kwargs)
.venv/lib/python3.14....../site-packages/aiosqlite/core.py:75: in _connection_worker_thread
    future.get_loop().call_soon_threadsafe(set_exception, future, e)
../..................../_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/base_events.py:872: in call_soon_threadsafe
    self._check_closed()
../..................../_temp/uv-python-dir/cpython-3.14.3-linux-x86_64-gnu/lib/python3.14/asyncio/base_events.py:550: in _check_closed
    raise RuntimeError('Event loop is closed')
E   RuntimeError: Event loop is closed

The above exception was the direct cause of the following exception:
.venv/lib/python3.14....../site-packages/_pytest/runner.py:353: in from_call
    result: TResult | None = func()
                             ^^^^^^
.venv/lib/python3.14....../site-packages/_pytest/runner.py:245: in <lambda>
    lambda: runtest_hook(item=item, **kwds),
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.venv/lib/python3.14.../site-packages/pluggy/_hooks.py:512: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.venv/lib/python3.14.../site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.venv/lib/python3.14.../site-packages/_pytest/logging.py:858: in pytest_runtest_teardown
    yield
.venv/lib/python3.14.../site-packages/_pytest/capture.py:905: in pytest_runtest_teardown
    return (yield)
            ^^^^^
.venv/lib/python3.14........./site-packages/_pytest/threadexception.py:152: in pytest_runtest_teardown
    collect_thread_exception(item.config)
.venv/lib/python3.14........./site-packages/_pytest/threadexception.py:70: in collect_thread_exception
    raise errors[0]
.venv/lib/python3.14........./site-packages/_pytest/threadexception.py:58: in collect_thread_exception
    warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))
E   pytest.PytestUnhandledThreadExceptionWarning: Exception in thread Thread-399 (_connection_worker_thread)
E   Enable tracemalloc to get traceback where the object was allocated.
E   See https://docs.pytest..../stable/how-to/capture-warnings.html#resource-warnings for more info.

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Aureliolo added a commit that referenced this pull request Mar 22, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.4.7](v0.4.6...v0.4.7)
(2026-03-22)


### Features

* add system user for CLI-to-backend authentication
([#710](#710))
([dc6bd3f](dc6bd3f))
* dev channel builds with incremental pre-releases between stable
releases ([#715](#715))
([0e8a714](0e8a714))
* replace hardcoded name pools with Faker multi-locale name generation
([#714](#714))
([5edc6ec](5edc6ec))


### Bug Fixes

* dev-release tag creation, dependabot coverage, go -C cli convention
([#730](#730))
([7634843](7634843))
* improve name generation step UX and fix sentinel expansion bug
([#739](#739))
([f03fd05](f03fd05))
* settings page UX polish -- toggle bug, source badges, form
improvements ([#712](#712))
([d16a0ac](d16a0ac))
* switch dev tags to semver and use same release pipeline as stable
([#729](#729))
([4df6b9b](4df6b9b)),
closes [#713](#713)
* unify CLI image discovery and standardize Go tooling
([#738](#738))
([712a785](712a785))
* use PAT in dev-release workflow to trigger downstream pipelines
([#716](#716))
([d767aa3](d767aa3))


### CI/CD

* bump astral-sh/setup-uv from 7.4.0 to 7.6.0 in
/.github/actions/setup-python-uv in the minor-and-patch group
([#731](#731))
([7887257](7887257))
* bump the minor-and-patch group with 3 updates
([#735](#735))
([7cd253a](7cd253a))
* bump wrangler from 4.75.0 to 4.76.0 in /.github in the minor-and-patch
group ([#732](#732))
([a6cafc7](a6cafc7))
* clean up all dev releases and tags on stable release
([#737](#737))
([8d90f5c](8d90f5c))


### Maintenance

* bump the minor-and-patch group across 2 directories with 2 updates
([#733](#733))
([2b60069](2b60069))
* bump the minor-and-patch group with 3 updates
([#734](#734))
([859bc25](859bc25))
* fix dependabot labels and add scope tags
([#736](#736))
([677eb15](677eb15))
* remove redundant pytest.mark.timeout(30) markers
([#740](#740))
([9ec2163](9ec2163))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant