Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (14)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
🧰 Additional context used📓 Path-based instructions (4)**/*.py📄 CodeRabbit inference engine (CLAUDE.md)
Files:
tests/**/*.py📄 CodeRabbit inference engine (CLAUDE.md)
Files:
src/synthorg/**/*.py📄 CodeRabbit inference engine (CLAUDE.md)
Files:
src/synthorg/!(observability)/**/*.py📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (22)📓 Common learnings📚 Learning: 2026-03-22T19:37:56.694ZApplied to files:
📚 Learning: 2026-03-17T22:08:13.456ZApplied to files:
📚 Learning: 2026-03-15T19:14:27.144ZApplied to files:
📚 Learning: 2026-03-17T11:41:02.964ZApplied to files:
📚 Learning: 2026-03-15T19:14:27.144ZApplied to files:
📚 Learning: 2026-03-22T19:37:56.694ZApplied to files:
📚 Learning: 2026-03-19T07:13:44.964ZApplied to files:
📚 Learning: 2026-03-16T06:24:56.341ZApplied to files:
📚 Learning: 2026-03-19T07:12:14.508ZApplied to files:
📚 Learning: 2026-03-17T22:08:13.456ZApplied to files:
📚 Learning: 2026-03-15T18:28:13.207ZApplied to files:
📚 Learning: 2026-03-22T19:37:56.694ZApplied to files:
📚 Learning: 2026-03-16T06:24:56.341ZApplied to files:
📚 Learning: 2026-03-19T07:12:14.508ZApplied to files:
📚 Learning: 2026-03-19T07:13:44.964ZApplied to files:
📚 Learning: 2026-03-14T15:43:05.601ZApplied to files:
📚 Learning: 2026-03-20T08:28:32.845ZApplied to files:
📚 Learning: 2026-03-15T19:14:27.144ZApplied to files:
📚 Learning: 2026-03-15T18:42:17.990ZApplied to files:
📚 Learning: 2026-03-15T18:28:13.207ZApplied to files:
📚 Learning: 2026-03-17T22:08:13.456ZApplied to files:
🧬 Code graph analysis (3)tests/unit/core/test_company_workflows.py (1)
tests/unit/core/test_company_reporting.py (1)
tests/unit/core/test_company.py (1)
🪛 YAMLlint (1.38.0)src/synthorg/templates/builtins/full_company.yaml[error] 54-54: syntax error: found character '%' that cannot start any token (syntax) 🔇 Additional comments (27)
WalkthroughAdded helper 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the organizational modeling capabilities by introducing explicit reporting lines, workflow handoffs, and escalation paths within the system's templates. The core Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request effectively introduces subordinate_id and supervisor_id to the ReportingLine model, enabling disambiguation of agents with the same role name. The changes are well-implemented, with corresponding updates to validators and comprehensive new unit tests that cover various edge cases. The documentation and built-in templates have also been updated accordingly. I have one suggestion for a minor refactoring in _validate_not_self_report to improve readability.
src/synthorg/core/company.py
Outdated
| if self.subordinate_id is not None and self.supervisor_id is not None: | ||
| sub_key = self.subordinate_id.strip().casefold() | ||
| sup_key = self.supervisor_id.strip().casefold() | ||
| elif self.subordinate_id is None and self.supervisor_id is None: | ||
| sub_key = self.subordinate.strip().casefold() | ||
| sup_key = self.supervisor.strip().casefold() | ||
| else: | ||
| # Asymmetric ID presence: one side identified by ID, the | ||
| # other by name -- they cannot be the same agent. | ||
| return self | ||
| if sub_key == sup_key: |
There was a problem hiding this comment.
The logic to determine which fields to use for the self-report check can be simplified to improve readability and reduce branching. By first checking for asymmetric ID presence and returning early, the subsequent comparison logic can be streamlined.
sub_id_present = self.subordinate_id is not None
sup_id_present = self.supervisor_id is not None
if sub_id_present != sup_id_present:
# Asymmetric ID presence: one side identified by ID, the
# other by name -- they cannot be the same agent.
return self
sub_key_val = self.subordinate_id if sub_id_present else self.subordinate
sup_key_val = self.supervisor_id if sup_id_present else self.supervisor
if sub_key_val.strip().casefold() == sup_key_val.strip().casefold():There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/design/organization.md (1)
114-119:⚠️ Potential issue | 🟡 MinorClarify that
budget_percentonly covers execution spend.Lines 114-119 still describe
budget_percentas a generic department budget split. Issue#719asked the docs to state that this is task-execution budget, not provider subscription or seat cost, so that distinction is still missing here.📝 Suggested wording
-- **budget_percent** -- The share of the company's total budget allocated to this department +- **budget_percent** -- The share of the company's task-execution budget allocated to this department; it does not represent provider subscription or seat costsAs per coding guidelines,
docs/design/*.md: When approved deviations occur, update the relevantdocs/design/page to reflect the new reality.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/design/organization.md` around lines 114 - 119, Update the description of budget_percent in the organization.md section so it explicitly states that budget_percent refers only to task-execution spend (e.g., API/compute/agent-run costs) and does not include provider subscriptions, seat/licensing costs, or other overhead; edit the bullet for **budget_percent** (near the entries for **head**, **teams**, and **reporting_lines**) to add a short clarifying clause like "covers only task execution spend, not provider subscriptions or seat costs" and ensure surrounding text still reads naturally with role names such as head, teams, and reporting_lines untouched.src/synthorg/core/company.py (1)
352-369:⚠️ Potential issue | 🟠 MajorKeep name-based and ID-based duplicate checks in separate buckets.
The self-report validator now treats asymmetric ID/name references as different agents, but Lines 354-361 collapse every reporting line into one normalized string. That still flags a false duplicate when a raw subordinate name happens to equal another line’s
subordinate_id(for example,subordinate="backend-1"vs.subordinate_id="backend-1"), which contradicts the new asymmetry rule.♻️ Suggested fix
def _validate_unique_subordinates(self) -> Self: """Ensure no duplicate subordinates in reporting lines.""" - subs = [ - ( - r.subordinate_id.strip().casefold() - if r.subordinate_id is not None - else r.subordinate.strip().casefold() - ) - for r in self.reporting_lines - ] - if len(subs) != len(set(subs)): - dupes = sorted(s for s, c in Counter(subs).items() if c > 1) + subordinate_ids = [ + r.subordinate_id.strip().casefold() + for r in self.reporting_lines + if r.subordinate_id is not None + ] + subordinate_names = [ + r.subordinate.strip().casefold() + for r in self.reporting_lines + if r.subordinate_id is None + ] + dupes = sorted( + [s for s, c in Counter(subordinate_ids).items() if c > 1] + + [s for s, c in Counter(subordinate_names).items() if c > 1] + ) + if dupes: msg = ( f"Duplicate subordinates in reporting lines " f"for department {self.name!r}: {dupes}" )A regression test for a subordinate name colliding with another line’s
subordinate_idwould help lock this behavior in.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/synthorg/core/company.py` around lines 352 - 369, In _validate_unique_subordinates, stop collapsing subordinate_id and subordinate into one normalized string; instead build two separate normalized buckets (one for subordinate_id values and one for subordinate name values) from self.reporting_lines, check duplicates within each bucket independently (using Counter or set-length comparison), and only warn/raise ValueError when duplicates are found inside the same bucket; reference the method _validate_unique_subordinates and the fields reporting_lines, subordinate_id, and subordinate when making the change so name-vs-id asymmetry is preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@docs/design/organization.md`:
- Around line 114-119: Update the description of budget_percent in the
organization.md section so it explicitly states that budget_percent refers only
to task-execution spend (e.g., API/compute/agent-run costs) and does not include
provider subscriptions, seat/licensing costs, or other overhead; edit the bullet
for **budget_percent** (near the entries for **head**, **teams**, and
**reporting_lines**) to add a short clarifying clause like "covers only task
execution spend, not provider subscriptions or seat costs" and ensure
surrounding text still reads naturally with role names such as head, teams, and
reporting_lines untouched.
In `@src/synthorg/core/company.py`:
- Around line 352-369: In _validate_unique_subordinates, stop collapsing
subordinate_id and subordinate into one normalized string; instead build two
separate normalized buckets (one for subordinate_id values and one for
subordinate name values) from self.reporting_lines, check duplicates within each
bucket independently (using Counter or set-length comparison), and only
warn/raise ValueError when duplicates are found inside the same bucket;
reference the method _validate_unique_subordinates and the fields
reporting_lines, subordinate_id, and subordinate when making the change so
name-vs-id asymmetry is preserved.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: ec2677a4-dc6c-4fcd-b37a-cc7194f1b452
📒 Files selected for processing (9)
docs/design/organization.mdsrc/synthorg/core/company.pysrc/synthorg/templates/builtins/agency.yamlsrc/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/builtins/research_lab.yamlsrc/synthorg/templates/builtins/startup.yamltests/unit/core/test_company.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build 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 (5)
docs/design/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
When approved deviations occur, update the relevant
docs/design/page to reflect the new reality.
Files:
docs/design/organization.md
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Nofrom __future__ import annotations—Python 3.14 has PEP 649 native lazy annotations.
Useexcept A, B:(no parentheses) per PEP 758 except syntax for Python 3.14.
Type hints are required on all public functions; use mypy strict mode.
Use Google-style docstrings required on public classes and functions, enforced by ruff D rules.
Fordict/listfields in frozen Pydantic models, rely onfrozen=Truefor field reassignment prevention and usecopy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization).
Never mix static config fields with mutable runtime fields in one model. Use frozen Pydantic models for config/identity and separate mutable-via-copy models for runtime state that evolves.
Use Pydantic v2 (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values instead of storing redundant fields. UseNotBlankStrfor all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Files:
src/synthorg/core/company.pytests/unit/core/test_company.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Create new objects instead of mutating existing ones. For non-Pydantic internal collections (registries,BaseTool), usecopy.deepcopy()at construction andMappingProxyTypewrapping for read-only enforcement.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code (e.g., multiple tool invocations, parallel agent calls). Prefer structured concurrency over barecreate_task.
Functions should be less than 50 lines; files should be less than 800 lines.
Every module with business logic MUST import logger:from synthorg.observability import get_loggerthenlogger = get_logger(__name__).
Never useimport logging,logging.getLogger(), orprint()in application code.
Variable name for logger is alwayslogger(not_logger, notlog).
Always use constants from domain-specific modules undersynthorg.observability.eventsfor event names (e.g.,API_REQUEST_STARTEDfromevents.api,TOOL_INVOKE_STARTfromevents.tool). Import directly:from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Use structured logging: alwayslogger.info(EVENT, key=value)—neverlogger.info("msg %s", val).
All error paths must log at WARNING or ERROR with context before raising.
All state transitions must log at INFO.
DEBUG logging is for object creation, internal flow, and entry/exit of key functions.
Pure data models, enums, and re-exports do NOT need logging.
NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001,large/medium/smallas aliases.
Files:
src/synthorg/core/company.py
{**/*.py,cli/**/*.go}
📄 CodeRabbit inference engine (CLAUDE.md)
Line length is 88 characters (enforced by ruff).
Files:
src/synthorg/core/company.pytests/unit/core/test_company.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use test markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow.
Test timeout is 30 seconds per test globally inpyproject.toml—do not add per-filepytest.mark.timeout(30)markers; only non-default overrides liketimeout(60)are allowed.
Prefer@pytest.mark.parametrizefor testing similar cases.
In tests, usetest-provider,test-small-001, etc. instead of vendor-specific names.
Use Hypothesis for property-based testing in Python with@givenand@settingsdecorators. Use profiles:ci(50 examples, default) anddev(1000 examples).
For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()to make them deterministic instead of widening timing margins.
For tasks that must block indefinitely until cancelled (e.g., simulating slow providers), useasyncio.Event().wait()instead ofasyncio.sleep(large_number)—it is cancellation-safe and carries no timing assumptions.
Files:
tests/unit/core/test_company.py
🧠 Learnings (3)
📚 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.yamlsrc/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/research_lab.yamlsrc/synthorg/templates/builtins/product_team.yaml
📚 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/agency.yamlsrc/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/full_company.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/**/*.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:
src/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/startup.yaml
🧬 Code graph analysis (1)
tests/unit/core/test_company.py (1)
src/synthorg/core/company.py (2)
ReportingLine(25-73)Department(287-370)
🪛 YAMLlint (1.38.0)
src/synthorg/templates/builtins/full_company.yaml
[error] 52-52: syntax error: found character '%' that cannot start any token
(syntax)
🔇 Additional comments (4)
src/synthorg/templates/builtins/startup.yaml (4)
31-33: LGTM!The CTO → CEO reporting line is correctly defined within the executive department, and both roles are unique so no ID disambiguation is needed.
37-43: LGTM!The
subordinate_idvalues correctly match themerge_idfields defined on the corresponding agents (lines 63 and 70), properly disambiguating the two Full-Stack Developer roles.
85-91: LGTM!The workflow handoff from engineering to product is well-defined with appropriate artifacts. For a minimal startup template, a single handoff direction is reasonable.
93-101: LGTM!The escalation paths appropriately route blockers from engineering and product to the executive department. Both paths use consistent
priority_boost: 1values.
f682885 to
5489085
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/synthorg/templates/builtins/product_team.yaml`:
- Around line 31-44: The head_role field is ambiguous because both
backend-senior and backend-mid share the "Backend Developer" role; update the
template to disambiguate the team lead by adding a head_id field (e.g., head_id:
"backend-senior") alongside head_role, or alternatively replace head_role with a
specific head reference, and ensure the schema supports head_id; refer to the
head_role, head_id, backend-senior, backend-mid, and reporting_lines entries
when making the change.
🪄 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: 8b18d830-e571-4d80-9ad0-c08c63717a1e
📒 Files selected for processing (11)
docs/design/organization.mdsrc/synthorg/core/company.pysrc/synthorg/templates/builtins/agency.yamlsrc/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/builtins/research_lab.yamlsrc/synthorg/templates/builtins/startup.yamltests/unit/core/test_company.pytests/unit/core/test_company_reporting.pytests/unit/core/test_company_workflows.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Sandbox
- GitHub Check: Build Backend
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (python)
- GitHub Check: Analyze (go)
🧰 Additional context used
📓 Path-based instructions (5)
docs/design/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
When approved deviations occur, update the relevant
docs/design/page to reflect the new reality.
Files:
docs/design/organization.md
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Nofrom __future__ import annotations—Python 3.14 has PEP 649 native lazy annotations.
Useexcept A, B:(no parentheses) per PEP 758 except syntax for Python 3.14.
Type hints are required on all public functions; use mypy strict mode.
Use Google-style docstrings required on public classes and functions, enforced by ruff D rules.
Fordict/listfields in frozen Pydantic models, rely onfrozen=Truefor field reassignment prevention and usecopy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization).
Never mix static config fields with mutable runtime fields in one model. Use frozen Pydantic models for config/identity and separate mutable-via-copy models for runtime state that evolves.
Use Pydantic v2 (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values instead of storing redundant fields. UseNotBlankStrfor all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Files:
tests/unit/core/test_company_workflows.pytests/unit/core/test_company_reporting.pytests/unit/core/test_company.pysrc/synthorg/core/company.py
{**/*.py,cli/**/*.go}
📄 CodeRabbit inference engine (CLAUDE.md)
Line length is 88 characters (enforced by ruff).
Files:
tests/unit/core/test_company_workflows.pytests/unit/core/test_company_reporting.pytests/unit/core/test_company.pysrc/synthorg/core/company.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use test markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow.
Test timeout is 30 seconds per test globally inpyproject.toml—do not add per-filepytest.mark.timeout(30)markers; only non-default overrides liketimeout(60)are allowed.
Prefer@pytest.mark.parametrizefor testing similar cases.
In tests, usetest-provider,test-small-001, etc. instead of vendor-specific names.
Use Hypothesis for property-based testing in Python with@givenand@settingsdecorators. Use profiles:ci(50 examples, default) anddev(1000 examples).
For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()to make them deterministic instead of widening timing margins.
For tasks that must block indefinitely until cancelled (e.g., simulating slow providers), useasyncio.Event().wait()instead ofasyncio.sleep(large_number)—it is cancellation-safe and carries no timing assumptions.
Files:
tests/unit/core/test_company_workflows.pytests/unit/core/test_company_reporting.pytests/unit/core/test_company.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Create new objects instead of mutating existing ones. For non-Pydantic internal collections (registries,BaseTool), usecopy.deepcopy()at construction andMappingProxyTypewrapping for read-only enforcement.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code (e.g., multiple tool invocations, parallel agent calls). Prefer structured concurrency over barecreate_task.
Functions should be less than 50 lines; files should be less than 800 lines.
Every module with business logic MUST import logger:from synthorg.observability import get_loggerthenlogger = get_logger(__name__).
Never useimport logging,logging.getLogger(), orprint()in application code.
Variable name for logger is alwayslogger(not_logger, notlog).
Always use constants from domain-specific modules undersynthorg.observability.eventsfor event names (e.g.,API_REQUEST_STARTEDfromevents.api,TOOL_INVOKE_STARTfromevents.tool). Import directly:from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Use structured logging: alwayslogger.info(EVENT, key=value)—neverlogger.info("msg %s", val).
All error paths must log at WARNING or ERROR with context before raising.
All state transitions must log at INFO.
DEBUG logging is for object creation, internal flow, and entry/exit of key functions.
Pure data models, enums, and re-exports do NOT need logging.
NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001,large/medium/smallas aliases.
Files:
src/synthorg/core/company.py
🧠 Learnings (9)
📚 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.yamldocs/design/organization.mdsrc/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/research_lab.yamlsrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/builtins/dev_shop.yaml
📚 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:
docs/design/organization.md
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/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/full_company.yamlsrc/synthorg/templates/builtins/dev_shop.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/**/*.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:
src/synthorg/templates/builtins/full_company.yaml
📚 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 Pydantic v2 BaseModel, model_validator, computed_field, ConfigDict.
Applied to files:
tests/unit/core/test_company.py
📚 Learning: 2026-03-15T18:42:17.990Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:42:17.990Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`
Applied to files:
tests/unit/core/test_company.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 : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. For derived values use `computed_field` instead of storing + validating redundant fields. Use `NotBlankStr` (from `core.types`) for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.
Applied to files:
tests/unit/core/test_company.py
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to tests/**/*.py : Test markers: pytest.mark.unit, pytest.mark.integration, pytest.mark.e2e, pytest.mark.slow. Coverage: 80% minimum (enforced in CI).
Applied to files:
tests/unit/core/test_company.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 tests/**/*.py : Test markers: `pytest.mark.unit`, `pytest.mark.integration`, `pytest.mark.e2e`, `pytest.mark.slow`. Coverage: 80% minimum. Async: `asyncio_mode = 'auto'` — no manual `pytest.mark.asyncio` needed. Timeout: 30 seconds per test. Parallelism: `pytest-xdist` via `-n auto` — ALWAYS include `-n auto` when running pytest, never run tests sequentially.
Applied to files:
tests/unit/core/test_company.py
🧬 Code graph analysis (3)
tests/unit/core/test_company_workflows.py (1)
src/synthorg/core/company.py (5)
ApprovalChain(131-170)DepartmentPolicies(173-201)EscalationPath(249-279)ReviewRequirements(105-128)WorkflowHandoff(218-246)
tests/unit/core/test_company_reporting.py (1)
src/synthorg/core/company.py (2)
Department(316-401)ReportingLine(40-102)
tests/unit/core/test_company.py (1)
src/synthorg/core/company.py (4)
Department(316-401)DepartmentPolicies(173-201)ReviewRequirements(105-128)Company(483-566)
🪛 YAMLlint (1.38.0)
src/synthorg/templates/builtins/full_company.yaml
[error] 52-52: syntax error: found character '%' that cannot start any token
(syntax)
🔇 Additional comments (23)
tests/unit/core/test_company.py (2)
218-232: LGTM!The new policy tests properly verify:
- Custom
DepartmentPoliciesconfiguration withReviewRequirements(min_reviewers=2)- Backward-compatible default behavior when
policiesis omittedThese tests align with the
Departmentmodel'spoliciesfield havingdefault_factory=DepartmentPolicies.
495-549: Formatting-only changes.The multi-line
Company(...)constructor formatting improves readability without changing behavior.src/synthorg/templates/builtins/agency.yaml (2)
31-64: LGTM!The reporting lines correctly establish hierarchies within each department. The engineering department properly uses
subordinate_id/supervisor_idto disambiguate the twoFull-Stack Developeragents (fullstack-senior and fullstack-mid), with IDs matching the correspondingmerge_idvalues in the agents section (lines 111 and 136).
145-195: LGTM!The workflow handoffs create a logical delivery pipeline (operations → design → engineering → QA → operations) with appropriate triggers and artifacts. The escalation paths correctly route technical/QA/design issues to operations for client communication with sensible
priority_boostvalues.tests/unit/core/test_company_workflows.py (1)
1-239: LGTM!This new test module provides comprehensive coverage for workflow models:
ReviewRequirements: defaults and custom valuesApprovalChain: empty approvers, min_approvals bounds, duplicate detection (case-insensitive), immutabilityDepartmentPolicies: unique action_types across approval chainsWorkflowHandoff/EscalationPath: same-department rejection (case-insensitive), priority_boost bounds (0-3)The tests properly verify the validation logic implemented in
src/synthorg/core/company.py.src/synthorg/core/company.py (3)
25-37: LGTM!The
_identity_keyhelper correctly implements namespace-tagged identity comparison:
- Returns
("id", normalized_id)when an ID is provided- Falls back to
("name", normalized_name)otherwise- Namespacing prevents false collisions when an ID value coincidentally matches a name
The function is pure, well-documented, and concise.
60-102: LGTM!The
ReportingLinemodel updates correctly implement ID-based disambiguation:
subordinate_id/supervisor_idareNotBlankStr | Nonewith sensible defaults- Self-report validation compares within the same namespace only (avoiding false positives across ID/name boundaries)
- Error messages include ID values when present for easier debugging
The explicit branching logic (lines 80-85) is a sound design choice for handling asymmetric ID presence.
380-401: LGTM!The updated
_validate_unique_subordinatescorrectly uses_identity_keyfor deduplication, ensuring:
- Same subordinate role name with different
subordinate_idvalues are treated as distinct- Duplicate detection is namespace-aware (
id:vsname:prefixes in error messages)- Case-insensitive and whitespace-trimmed comparison is preserved
docs/design/organization.md (3)
82-92: LGTM!The example clearly demonstrates the new
reporting_linesstructure:
- Basic subordinate/supervisor role name usage
- Optional
subordinate_id/supervisor_idfor disambiguating agents with the same role name- Hierarchical relationships within the same department
118-120: LGTM!The clarifications address Issue
#719's request to documentbudget_percentintent:
- Explicitly states it covers "task-execution budget" (agent compute and API costs)
- Excludes provider subscriptions and seat licensing
- Documents the optional ID fields for
reporting_lines
187-223: LGTM!The updated startup template example demonstrates the complete organizational structure:
- Departments with
budget_percent,head_role, andreporting_linessubordinate_idusage matching agentmerge_idvaluesworkflow_handoffswith triggers and artifactsescalation_pathswith conditions andpriority_boostsrc/synthorg/templates/builtins/dev_shop.yaml (2)
31-48: LGTM!The reporting lines correctly establish engineering and QA hierarchies:
- Backend developers use
subordinate_idvalues matching theirmerge_id(backend-senior-1, backend-mid, backend-senior-2 on lines 62, 69, 100)- Frontend developer reports directly by role name (no ID needed as it's unique)
- QA Engineer reports to QA Lead
109-131: LGTM!The workflow handoffs create a bidirectional code review cycle (engineering ↔ QA) with appropriate triggers and artifacts. Escalation paths correctly route critical defects to engineering and infrastructure issues to operations.
tests/unit/core/test_company_reporting.py (2)
1-141: LGTM!Excellent coverage of
ReportingLinevalidation:
- Self-report rejection by name and ID (case-insensitive)
- Same role name with different IDs accepted (correct disambiguation)
- Asymmetric ID presence handling (subordinate-only, supervisor-only)
- Cross-namespace non-collision (name matching other's ID is allowed)
@pytest.mark.parametrizeappropriately used for blank ID rejection tests (lines 119-140)
143-321: LGTM!Comprehensive coverage of
Departmentreporting-line uniqueness validation:
- Duplicate subordinate detection (case/whitespace insensitive)
- Same role name with different
subordinate_idvalues are accepted- Duplicate
subordinate_idvalues are rejected- Mixed ID and no-ID entries coexist correctly
- Namespace separation prevents name/ID collisions
src/synthorg/templates/builtins/full_company.yaml (2)
39-61: LGTM!The reporting lines correctly establish hierarchies across all departments. The Jinja2 loops (lines 52-61) properly generate
subordinate_idvalues (backend-{{ i }},frontend-{{ i }}) that match the corresponding agentmerge_idvalues generated in the agents section (lines 187-217).Note: The YAMLlint error on line 52 is a false positive—YAMLlint doesn't understand Jinja2 template syntax (
{% for ... %}), which is valid and will render correctly.
293-365: LGTM!The workflow handoffs create a comprehensive cross-department delivery pipeline:
- Product → Design → Engineering → QA → Operations (main flow)
- Engineering ↔ Security (bidirectional for security reviews)
- Data Analytics / Creative Marketing → Product (insights loops)
The escalation paths have appropriately differentiated
priority_boostvalues (security vulnerabilities at 3, critical technical/QA issues at 2, operational/strategic at 1).src/synthorg/templates/builtins/research_lab.yaml (2)
31-47: LGTM! Reporting lines correctly disambiguate duplicate roles.The
supervisor_idandsubordinate_idfields properly reference the agentmerge_idvalues (analyst-primaryon line 73,analyst-secondaryon line 86), enabling clear hierarchical relationships between the two Data Analyst agents.
101-129: LGTM! Workflow handoffs and escalation paths are well-structured.The bidirectional handoffs between
data_analyticsandengineeringreflect realistic research lab workflows, and thedata_analytics → producthandoff for documentation aligns with the Technical Writer role in that department.src/synthorg/templates/builtins/startup.yaml (2)
31-43: LGTM! Reporting lines correctly use IDs to disambiguate Full-Stack Developers.The
subordinate_idvalues (fullstack-senior,fullstack-mid) properly match the corresponding agentmerge_idfields (lines 63, 70). The cross-department supervision (CTO inexecutivesupervisingengineeringagents) reflects a typical startup structure.
85-101: LGTM! Workflow and escalation paths align with startup structure.The single handoff from engineering to product for feature review and the escalation paths to executive for blockers and scope conflicts are appropriate for a small team.
src/synthorg/templates/builtins/product_team.yaml (2)
48-56: LGTM! Design and QA reporting lines are straightforward.Single-level hierarchies with unique role names don't require ID disambiguation.
128-172: LGTM! Comprehensive workflow cycle and prioritized escalations.The workflow handoffs form a complete
product → design → engineering → QA → productdevelopment loop. The higherpriority_boost: 2for critical QA defects appropriately reflects urgency compared to standard escalations.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/design/organization.md`:
- Around line 187-206: The example's reporting_lines reference a missing agent
("CTO") causing inconsistency: update the example by either adding an agent
entry with id/name matching "CTO" to the agents list or change the
reporting_lines under departments->executive and departments->engineering to
reference an existing agent id/name from the agents list; specifically reconcile
the "CTO" head_role and subordinate in departments/executive.reporting_lines and
departments/engineering.head_role with the agents defined earlier so the role
referenced exists.
🪄 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: 1937fdf3-813c-4034-9790-8ba1511f958f
📒 Files selected for processing (7)
docs/design/organization.mdsrc/synthorg/core/company.pysrc/synthorg/templates/builtins/agency.yamlsrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pytests/unit/core/test_company_reporting.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Build Backend
- GitHub Check: Build Sandbox
- GitHub Check: Test (Python 3.14)
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Nofrom __future__ import annotations—Python 3.14 has PEP 649 native lazy annotations.
Useexcept A, B:(no parentheses) per PEP 758 except syntax for Python 3.14.
Type hints are required on all public functions; use mypy strict mode.
Use Google-style docstrings required on public classes and functions, enforced by ruff D rules.
Fordict/listfields in frozen Pydantic models, rely onfrozen=Truefor field reassignment prevention and usecopy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization).
Never mix static config fields with mutable runtime fields in one model. Use frozen Pydantic models for config/identity and separate mutable-via-copy models for runtime state that evolves.
Use Pydantic v2 (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values instead of storing redundant fields. UseNotBlankStrfor all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Files:
src/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pysrc/synthorg/core/company.pytests/unit/core/test_company_reporting.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Create new objects instead of mutating existing ones. For non-Pydantic internal collections (registries,BaseTool), usecopy.deepcopy()at construction andMappingProxyTypewrapping for read-only enforcement.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code (e.g., multiple tool invocations, parallel agent calls). Prefer structured concurrency over barecreate_task.
Functions should be less than 50 lines; files should be less than 800 lines.
Every module with business logic MUST import logger:from synthorg.observability import get_loggerthenlogger = get_logger(__name__).
Never useimport logging,logging.getLogger(), orprint()in application code.
Variable name for logger is alwayslogger(not_logger, notlog).
Always use constants from domain-specific modules undersynthorg.observability.eventsfor event names (e.g.,API_REQUEST_STARTEDfromevents.api,TOOL_INVOKE_STARTfromevents.tool). Import directly:from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Use structured logging: alwayslogger.info(EVENT, key=value)—neverlogger.info("msg %s", val).
All error paths must log at WARNING or ERROR with context before raising.
All state transitions must log at INFO.
DEBUG logging is for object creation, internal flow, and entry/exit of key functions.
Pure data models, enums, and re-exports do NOT need logging.
NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001,large/medium/smallas aliases.
Files:
src/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pysrc/synthorg/core/company.py
{**/*.py,cli/**/*.go}
📄 CodeRabbit inference engine (CLAUDE.md)
Line length is 88 characters (enforced by ruff).
Files:
src/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pysrc/synthorg/core/company.pytests/unit/core/test_company_reporting.py
docs/design/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
When approved deviations occur, update the relevant
docs/design/page to reflect the new reality.
Files:
docs/design/organization.md
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use test markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow.
Test timeout is 30 seconds per test globally inpyproject.toml—do not add per-filepytest.mark.timeout(30)markers; only non-default overrides liketimeout(60)are allowed.
Prefer@pytest.mark.parametrizefor testing similar cases.
In tests, usetest-provider,test-small-001, etc. instead of vendor-specific names.
Use Hypothesis for property-based testing in Python with@givenand@settingsdecorators. Use profiles:ci(50 examples, default) anddev(1000 examples).
For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()to make them deterministic instead of widening timing margins.
For tasks that must block indefinitely until cancelled (e.g., simulating slow providers), useasyncio.Event().wait()instead ofasyncio.sleep(large_number)—it is cancellation-safe and carries no timing assumptions.
Files:
tests/unit/core/test_company_reporting.py
🧠 Learnings (5)
📓 Common learnings
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)
📚 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.yamldocs/design/organization.mdsrc/synthorg/templates/builtins/product_team.yaml
📚 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:
docs/design/organization.md
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to tests/**/*.py : Test markers: pytest.mark.unit, pytest.mark.integration, pytest.mark.e2e, pytest.mark.slow. Coverage: 80% minimum (enforced in CI).
Applied to files:
tests/unit/core/test_company_reporting.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/product_team.yaml
🧬 Code graph analysis (1)
tests/unit/core/test_company_reporting.py (1)
src/synthorg/core/company.py (2)
Department(316-409)ReportingLine(40-102)
🔇 Additional comments (14)
src/synthorg/templates/renderer.py (1)
786-793: LGTM!The conditional injection of
head_idonly whenhead_merge_idis truthy correctly prevents passing empty strings that would failNotBlankStrvalidation onDepartment.head_id. The logic integrates cleanly with the schema and model changes.src/synthorg/templates/schema.py (1)
185-188: LGTM!The
head_merge_idfield correctly follows the same pattern asmerge_idonTemplateAgentConfig(line 132-135), usingstrwith empty string default to indicate "no disambiguation needed". The renderer's truthiness check filters this appropriately.src/synthorg/templates/builtins/agency.yaml (2)
31-65: LGTM!The reporting lines are well-structured with proper ID disambiguation for the Full-Stack Developer roles. The
head_merge_id: "fullstack-senior"correctly identifies which of the two Full-Stack Developers leads the engineering department, and the reporting lines appropriately usesubordinate_id/supervisor_idto establish thefullstack-mid → fullstack-seniorrelationship.
146-196: LGTM!The workflow handoffs form a coherent agency delivery loop (operations → design → engineering → QA → operations) with a parallel marketing track. Escalation paths appropriately route blockers from technical departments to operations where the Project Manager can coordinate client communication.
src/synthorg/core/company.py (3)
25-38: LGTM!The
_identity_keyhelper cleanly separates the namespacing concern. Using distinct namespaces ("id" vs "name") prevents false collisions when an ID value happens to match a name string, which is an important edge case for robust validation.
60-102: LGTM!The self-report validation logic correctly handles all cases:
- Same namespace + same key → rejected as self-report
- Different namespaces (asymmetric ID presence) → accepted as distinct agents
- Error messages include ID context when IDs are involved
The case-insensitive comparison via
casefold()and whitespace trimming viastrip()ensure robust matching.
347-350: LGTM!The
head_idfield follows the same pattern as the other optional ID fields. The updated_validate_unique_subordinatescorrectly uses namespace-tagged identity keys, and the error message format (namespace:key) provides clear debugging information.Also applies to: 388-409
docs/design/organization.md (3)
82-92: LGTM!The example clearly demonstrates the ID disambiguation pattern with multiple Backend Developers, showing both
subordinate_idandsupervisor_idusage for establishing reporting relationships.
117-120: LGTM!Good documentation updates clarifying the
head_iddisambiguation mechanism, the scope ofbudget_percent(task-execution costs vs. subscriptions), and the optional ID fields on reporting lines.
211-223: LGTM!The workflow_handoffs and escalation_paths examples demonstrate the cross-department governance model effectively with appropriate triggers, artifacts, conditions, and priority boosts.
tests/unit/core/test_company_reporting.py (2)
1-141: LGTM!Comprehensive test coverage for
ReportingLinevalidation including self-report detection (by name and by ID), case-insensitivity, asymmetric ID handling, and blank ID rejection. The parametrized test for blank IDs efficiently covers multiple edge cases.
146-340: LGTM!Thorough coverage of
Departmentreporting-line validation including duplicate detection by name, by ID, case/whitespace insensitivity, namespace separation (name vs ID), andhead_idbehavior. The tests correctly verify the namespace-tagged identity key approach.src/synthorg/templates/builtins/product_team.yaml (2)
34-45: LGTM!The addition of
head_merge_id: "backend-senior"properly disambiguates which Backend Developer serves as the engineering department head, addressing the concern from the previous review. The reporting lines correctly establish the hierarchy with the senior developer supervising the mid-level developer, frontend developer, and full-stack developer.
129-173: LGTM!The workflow handoffs create a coherent product development cycle (product → design → engineering → QA → product) with a data analytics feedback loop. The escalation paths appropriately route technical constraints to product and critical defects through the engineering chain.
5393e09 to
30ed259
Compare
There was a problem hiding this comment.
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 `@docs/design/organization.md`:
- Around line 117-120: Update the "head" paragraph to explicitly state that
while runtime objects use the field head_id for disambiguation, template YAML
must use head_merge_id (which maps to the agent's merge_id) to avoid schema
errors; mention this parallels the reporting_lines subordinate_id/supervisor_id
pattern and clarify that head_merge_id in templates becomes head_id at runtime.
In `@src/synthorg/core/company.py`:
- Around line 347-350: The Department model currently allows head_id to be set
without a corresponding head object; add a validation rule on the Department
class (e.g., a `@root_validator` or `@validator`) that if head_id is not None then
head must be provided and its identifier must match head_id (or at minimum head
is non-null); update the validator to raise a ValidationError with a clear
message referencing head_id/head when the check fails so Department(name=...,
head_id=...) cannot validate without providing head.
In `@src/synthorg/templates/builtins/full_company.yaml`:
- Around line 47-61: Add a reporting line that connects the engineering lead to
the department head: inside the reporting_lines block in
src/synthorg/templates/builtins/full_company.yaml, create an entry with
subordinate: "Software Architect" and supervisor: "CTO" (optionally include a
subordinate_id if you use ids elsewhere) so the Software Architect is linked up
to the CTO and the engineering subtree is attached to the department head.
In `@src/synthorg/templates/builtins/research_lab.yaml`:
- Around line 34-37: The template entry with name "data_analytics" uses
head_role: "Data Analyst" which is ambiguous because there are two agents
("analyst-primary" and "analyst-secondary"); update the "data_analytics" block
to add a head_merge_id pointing to the intended agent's merge id (e.g.,
"analyst-primary" or "analyst-secondary") so the head identity is explicit and
matches the ID-aware reporting_lines structure; ensure head_role remains "Data
Analyst" if you want the title preserved but the head_merge_id disambiguates
which agent instance is the head.
In `@src/synthorg/templates/renderer.py`:
- Around line 786-793: The code currently adds dept_dict["head_id"] when
head_merge_id is present even if head_role was missing and fell back to
dept_name; change the guard so head_id is only set when head_merge_id is present
AND a real head role was provided (i.e., head_role is non-empty and not the
fallback dept_name). Update the conditional around head_merge_id to check both
head_merge_id and head_role != dept_name (and head_role truthy) before assigning
dept_dict["head_id"] so you don't manufacture bogus department heads.
In `@src/synthorg/templates/schema.py`:
- Around line 185-188: Replace the plain string Field for head_merge_id with a
validated NotBlankStr type so whitespace-only values are rejected at schema
parse time; specifically change the Field declaration for head_merge_id in the
Template schema to use core.types.NotBlankStr (importing it where needed) and
keep the same default/description semantics so identifier validation occurs at
the schema boundary instead of later in render/root-config validation.
In `@tests/unit/core/test_company_workflows.py`:
- Around line 203-221: Tests test_priority_boost_above_3_rejected and
test_priority_boost_negative_rejected duplicate the same pattern; replace them
with a single parametrized test using pytest.mark.parametrize to iterate invalid
priority_boost values (e.g., 4 and -1) and assert EscalationPath(...) raises
ValidationError, referencing the test function name (e.g.,
test_priority_boost_invalid_rejected) and the EscalationPath and ValidationError
symbols so the test remains clear and DRY.
🪄 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: f9572175-9140-4d3c-b5a4-d45125155363
📒 Files selected for processing (13)
docs/design/organization.mdsrc/synthorg/core/company.pysrc/synthorg/templates/builtins/agency.yamlsrc/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/builtins/research_lab.yamlsrc/synthorg/templates/builtins/startup.yamlsrc/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pytests/unit/core/test_company.pytests/unit/core/test_company_reporting.pytests/unit/core/test_company_workflows.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Web
- GitHub Check: Build Backend
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Nofrom __future__ import annotations-- Python 3.14 has PEP 649 native lazy annotations.
Use PEP 758 except syntax:except A, B:(no parentheses) -- ruff enforces this on Python 3.14.
Type hints: all public functions, mypy strict mode.
Docstrings: Google style, required on public classes/functions (enforced by ruff D rules).
Immutability: create new objects, never mutate existing ones. For non-Pydantic internal collections, usecopy.deepcopy()at construction +MappingProxyTypewrapping for read-only enforcement. Fordict/listfields in frozen Pydantic models, rely onfrozen=Trueandcopy.deepcopy()at system boundaries.
Config vs runtime state: frozen Pydantic models for config/identity; separate mutable-via-copy models for runtime state that evolves. Never mix static config fields with mutable runtime fields.
Models: Pydantic v2 (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values. UseNotBlankStrfor all identifier/name fields instead of manual whitespace validators.
Async concurrency: preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code. Prefer structured concurrency over barecreate_task.
Line length: 88 characters (ruff).
Functions: < 50 lines, files < 800 lines.
Errors: handle explicitly, never silently swallow.
Validate: at system boundaries (user input, external APIs, config files).
Variable name: alwayslogger(not_logger, notlog).
Files:
src/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pysrc/synthorg/core/company.pytests/unit/core/test_company_workflows.pytests/unit/core/test_company_reporting.pytests/unit/core/test_company.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Every module with business logic MUST have:from synthorg.observability import get_loggerthenlogger = get_logger(__name__)
Event names: always use constants from domain-specific modules undersynthorg.observability.events(e.g.,API_REQUEST_STARTEDfromevents.api). Import directly:from synthorg.observability.events.<domain> import EVENT_CONSTANT
Structured kwargs: alwayslogger.info(EVENT, key=value)-- neverlogger.info("msg %s", val)
All error paths must log at WARNING or ERROR with context before raising.
All state transitions must log at INFO.
DEBUG for object creation, internal flow, entry/exit of key functions.
Vendor-agnostic everywhere: NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001,large/medium/smallas aliases.
Pure data models, enums, and re-exports do NOT need logging.
UseNotBlankStrfromcore.typesfor all identifier/name fields -- including optional (NotBlankStr | None) and tuple variants -- instead of manual whitespace validators.
Files:
src/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pysrc/synthorg/core/company.py
src/synthorg/!(observability)/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
import logging/logging.getLogger()/print()in application code (exception:observability/setup.pyandobservability/sinks.pymay use stdlib logging and print for bootstrap).
Files:
src/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pysrc/synthorg/core/company.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow
Parametrize: Prefer@pytest.mark.parametrizefor testing similar cases.
Tests must usetest-provider,test-small-001, etc. for vendor-agnostic test code.
Property-based testing: Python uses Hypothesis (@given+@settings). Hypothesis profiles:ci(50 examples, default) anddev(1000 examples), controlled viaHYPOTHESIS_PROFILEenv var.
Flaky tests: NEVER skip, dismiss, or ignore -- always fix them fully and fundamentally. For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()to make them deterministic. For tasks that must block indefinitely until cancelled, useasyncio.Event().wait()instead ofasyncio.sleep(large_number).
Files:
tests/unit/core/test_company_workflows.pytests/unit/core/test_company_reporting.pytests/unit/core/test_company.py
🧠 Learnings (13)
📓 Common learnings
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)
📚 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.yamlsrc/synthorg/templates/builtins/startup.yamlsrc/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/product_team.yamldocs/design/organization.mdsrc/synthorg/templates/builtins/research_lab.yaml
📚 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.yamlsrc/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/product_team.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/**/*.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:
src/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/product_team.yaml
📚 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 Pydantic v2 BaseModel, model_validator, computed_field, ConfigDict.
Applied to files:
tests/unit/core/test_company.py
📚 Learning: 2026-03-15T18:42:17.990Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:42:17.990Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`
Applied to files:
tests/unit/core/test_company.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 : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. For derived values use `computed_field` instead of storing + validating redundant fields. Use `NotBlankStr` (from `core.types`) for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.
Applied to files:
tests/unit/core/test_company.py
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to tests/**/*.py : Test markers: pytest.mark.unit, pytest.mark.integration, pytest.mark.e2e, pytest.mark.slow. Coverage: 80% minimum (enforced in CI).
Applied to files:
tests/unit/core/test_company.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 tests/**/*.py : Test markers: `pytest.mark.unit`, `pytest.mark.integration`, `pytest.mark.e2e`, `pytest.mark.slow`. Coverage: 80% minimum. Async: `asyncio_mode = 'auto'` — no manual `pytest.mark.asyncio` needed. Timeout: 30 seconds per test. Parallelism: `pytest-xdist` via `-n auto` — ALWAYS include `-n auto` when running pytest, never run tests sequentially.
Applied to files:
tests/unit/core/test_company.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 docs/design/**/*.md : Design specification pages in `docs/design/` must be consulted before implementing features (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
docs/design/organization.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 docs/design/*.md : Design spec pages: 7 pages in `docs/design/` — index, agents, organization, communication, engine, memory, operations
Applied to files:
docs/design/organization.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: Always read the relevant `docs/design/` page before implementing any feature or planning any issue — DESIGN_SPEC.md is a pointer file linking to 7 design pages (Agents, Organization, Communication, Engine, Memory, Operations)
Applied to files:
docs/design/organization.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:
docs/design/organization.md
🧬 Code graph analysis (4)
src/synthorg/templates/renderer.py (1)
src/synthorg/memory/org/store.py (2)
get(82-95)get(349-379)
tests/unit/core/test_company_workflows.py (1)
src/synthorg/core/company.py (5)
ApprovalChain(131-170)DepartmentPolicies(173-201)EscalationPath(249-279)ReviewRequirements(105-128)WorkflowHandoff(218-246)
tests/unit/core/test_company_reporting.py (1)
src/synthorg/core/company.py (2)
Department(316-409)ReportingLine(40-102)
tests/unit/core/test_company.py (1)
src/synthorg/core/company.py (4)
Department(316-409)DepartmentPolicies(173-201)ReviewRequirements(105-128)Company(491-574)
🪛 YAMLlint (1.38.0)
src/synthorg/templates/builtins/full_company.yaml
[error] 52-52: syntax error: found character '%' that cannot start any token
(syntax)
🔇 Additional comments (5)
tests/unit/core/test_company_workflows.py (1)
17-200: Good workflow-model validation coverage.This suite exercises defaults, bounds, duplicate detection, same-department rejection, and frozen-model behavior with clear assertions.
Also applies to: 223-239
src/synthorg/templates/builtins/startup.yaml (1)
31-43: Startup template hierarchy and cross-department flow look solid.Reporting lines and new handoff/escalation paths are consistent with the defined departments/agents and correctly disambiguate duplicate Full-Stack Developer roles via IDs.
Also applies to: 85-101
tests/unit/core/test_company_reporting.py (1)
14-340: Excellent ID-aware reporting-line test coverage.The cases for symmetric/asymmetric ID presence, case-insensitive collisions, namespace separation, and duplicate subordinate detection are comprehensive and directly validate the intended model behavior.
src/synthorg/templates/builtins/research_lab.yaml (1)
101-129: Workflow handoffs and escalations are well-structured.The added cross-department handoffs and escalation paths are coherent and reference valid departments with bounded
priority_boostvalues.src/synthorg/templates/builtins/product_team.yaml (1)
34-57: Nice update—this template now has clear hierarchy and realistic workflow routing.
head_merge_idresolves the duplicated Backend Developer head ambiguity, and the added reporting lines/handoffs/escalations are internally consistent.Also applies to: 129-173
There was a problem hiding this comment.
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/templates/renderer.py`:
- Around line 786-793: The code currently drops dept["head_merge_id"] when
dept.get("head_role") is falsy without notifying the user; update the logic
around head_merge_id (using the variables head_merge_id and
dept.get("head_role") and the dept_dict population) to log a warning when
head_merge_id is present but head_role is missing/falsey — mirror the existing
missing head_role warning behavior at the earlier check (same logging
style/location) so that custom template authors are alerted whenever
head_merge_id is discarded instead of silently ignored.
In `@tests/unit/core/test_company_reporting.py`:
- Around line 337-345: Add a new unit test to validate that whitespace-only
head_id values are rejected: create a test function similar to
test_blank_head_id_rejected (e.g., test_whitespace_head_id_rejected) that
constructs Department(name="eng", head="cto", head_id=" ") and asserts it
raises a ValidationError matching a "whitespace-only" or equivalent message;
reference the Department model and existing tests test_blank_head_id_rejected
and test_head_id_without_head_rejected to place and name the new test
consistently.
In `@tests/unit/core/test_company_workflows.py`:
- Around line 150-167: The two tests test_same_department_rejected and
test_same_department_case_insensitive duplicate the same assertion pattern
against the WorkflowHandoff model; replace them with a single parametrized test
using `@pytest.mark.parametrize` to iterate cases like ("eng","eng") and
("Eng","eng") and assert a ValidationError with "different departments" when
constructing WorkflowHandoff(from_department=..., to_department=...,
trigger="test"); keep the same match string and test name (e.g.,
test_same_department_rejected_parametrized) so intent remains clear.
- Around line 79-93: Combine the two duplicate-approver tests into a single
parametrized test using pytest.mark.parametrize to cover both ("lead","lead")
and ("Lead","lead") cases; replace the separate
test_duplicate_approvers_rejected and test_duplicate_approvers_case_insensitive
with one function (e.g., test_duplicate_approvers_rejected_param) that takes an
approvers tuple parameter, constructs ApprovalChain(action_type="deploy",
approvers=approvers), and asserts a ValidationError with match "Duplicate
approvers".
- Around line 214-230: Combine the two duplicate tests into a single
parametrized test using pytest.mark.parametrize: replace
test_same_department_rejected and test_same_department_case_insensitive with one
test (e.g., test_same_department_rejected_param) that parametrizes input pairs
for from_department/to_department (like ("eng","eng") and ("Eng","eng")) and
asserts EscalationPath(...) raises ValidationError with "different departments";
locate the assertions around EscalationPath construction and reuse the same
match string to keep behavior identical.
🪄 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: b78f1bc7-dead-4356-a2de-a6309003fd94
📒 Files selected for processing (9)
docs/design/organization.mdsrc/synthorg/core/company.pysrc/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/research_lab.yamlsrc/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pytests/unit/core/conftest.pytests/unit/core/test_company_reporting.pytests/unit/core/test_company_workflows.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build 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 (4)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Nofrom __future__ import annotations-- Python 3.14 has PEP 649 native lazy annotations.
Use PEP 758 except syntax:except A, B:(no parentheses) -- ruff enforces this on Python 3.14.
Type hints: all public functions, mypy strict mode.
Docstrings: Google style, required on public classes/functions (enforced by ruff D rules).
Immutability: create new objects, never mutate existing ones. For non-Pydantic internal collections, usecopy.deepcopy()at construction +MappingProxyTypewrapping for read-only enforcement. Fordict/listfields in frozen Pydantic models, rely onfrozen=Trueandcopy.deepcopy()at system boundaries.
Config vs runtime state: frozen Pydantic models for config/identity; separate mutable-via-copy models for runtime state that evolves. Never mix static config fields with mutable runtime fields.
Models: Pydantic v2 (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values. UseNotBlankStrfor all identifier/name fields instead of manual whitespace validators.
Async concurrency: preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code. Prefer structured concurrency over barecreate_task.
Line length: 88 characters (ruff).
Functions: < 50 lines, files < 800 lines.
Errors: handle explicitly, never silently swallow.
Validate: at system boundaries (user input, external APIs, config files).
Variable name: alwayslogger(not_logger, notlog).
Files:
tests/unit/core/conftest.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pytests/unit/core/test_company_workflows.pysrc/synthorg/core/company.pytests/unit/core/test_company_reporting.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow
Parametrize: Prefer@pytest.mark.parametrizefor testing similar cases.
Tests must usetest-provider,test-small-001, etc. for vendor-agnostic test code.
Property-based testing: Python uses Hypothesis (@given+@settings). Hypothesis profiles:ci(50 examples, default) anddev(1000 examples), controlled viaHYPOTHESIS_PROFILEenv var.
Flaky tests: NEVER skip, dismiss, or ignore -- always fix them fully and fundamentally. For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()to make them deterministic. For tasks that must block indefinitely until cancelled, useasyncio.Event().wait()instead ofasyncio.sleep(large_number).
Files:
tests/unit/core/conftest.pytests/unit/core/test_company_workflows.pytests/unit/core/test_company_reporting.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Every module with business logic MUST have:from synthorg.observability import get_loggerthenlogger = get_logger(__name__)
Event names: always use constants from domain-specific modules undersynthorg.observability.events(e.g.,API_REQUEST_STARTEDfromevents.api). Import directly:from synthorg.observability.events.<domain> import EVENT_CONSTANT
Structured kwargs: alwayslogger.info(EVENT, key=value)-- neverlogger.info("msg %s", val)
All error paths must log at WARNING or ERROR with context before raising.
All state transitions must log at INFO.
DEBUG for object creation, internal flow, entry/exit of key functions.
Vendor-agnostic everywhere: NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001,large/medium/smallas aliases.
Pure data models, enums, and re-exports do NOT need logging.
UseNotBlankStrfromcore.typesfor all identifier/name fields -- including optional (NotBlankStr | None) and tuple variants -- instead of manual whitespace validators.
Files:
src/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pysrc/synthorg/core/company.py
src/synthorg/!(observability)/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
import logging/logging.getLogger()/print()in application code (exception:observability/setup.pyandobservability/sinks.pymay use stdlib logging and print for bootstrap).
Files:
src/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pysrc/synthorg/core/company.py
🧠 Learnings (17)
📚 Learning: 2026-03-22T19:37:56.694Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T19:37:56.694Z
Learning: Applies to src/synthorg/**/*.py : Use `NotBlankStr` from `core.types` for all identifier/name fields -- including optional (`NotBlankStr | None`) and tuple variants -- instead of manual whitespace validators.
Applied to files:
src/synthorg/templates/schema.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 : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. For derived values use `computed_field` instead of storing + validating redundant fields. Use `NotBlankStr` (from `core.types`) for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.
Applied to files:
src/synthorg/templates/schema.pysrc/synthorg/core/company.py
📚 Learning: 2026-03-17T11:41:02.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T11:41:02.964Z
Learning: Applies to src/**/*.py : Models: Pydantic v2 (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values instead of storing + validating redundant fields. Use `NotBlankStr` for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.
Applied to files:
src/synthorg/templates/schema.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 Pydantic v2 with adopted conventions: use computed_field for derived values instead of storing + validating redundant fields; use NotBlankStr from core.types for all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Applied to files:
src/synthorg/templates/schema.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 **/*.py : Models: Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict). Use computed_field for derived values instead of storing + validating redundant fields. Use NotBlankStr (from core.types) for all identifier/name fields — including optional (NotBlankStr | None) and tuple (tuple[NotBlankStr, ...]) variants — instead of manual whitespace validators.
Applied to files:
src/synthorg/templates/schema.py
📚 Learning: 2026-03-22T19:37:56.694Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T19:37:56.694Z
Learning: Applies to **/*.py : Models: Pydantic v2 (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values. Use `NotBlankStr` for all identifier/name fields instead of manual whitespace validators.
Applied to files:
src/synthorg/templates/schema.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 tests/**/*.py : Prefer `pytest.mark.parametrize` for testing similar cases.
Applied to files:
tests/unit/core/test_company_workflows.py
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to tests/**/*.py : Parametrize: Prefer pytest.mark.parametrize for testing similar cases.
Applied to files:
tests/unit/core/test_company_workflows.py
📚 Learning: 2026-03-22T19:37:56.694Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T19:37:56.694Z
Learning: Applies to tests/**/*.py : Parametrize: Prefer `pytest.mark.parametrize` for testing similar cases.
Applied to files:
tests/unit/core/test_company_workflows.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:
docs/design/organization.mdsrc/synthorg/templates/builtins/full_company.yamltests/unit/core/test_company_reporting.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 docs/design/*.md : Design spec pages: 7 pages in `docs/design/` — index, agents, organization, communication, engine, memory, operations
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to docs/design/**/*.md : Design specification pages in `docs/design/` must be consulted before implementing features (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
docs/design/organization.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: Always read the relevant `docs/design/` page before implementing any feature or planning any issue — DESIGN_SPEC.md is a pointer file linking to 7 design pages (Agents, Organization, Communication, Engine, Memory, Operations)
Applied to files:
docs/design/organization.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:
docs/design/organization.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:
docs/design/organization.md
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/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/full_company.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/**/*.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:
src/synthorg/templates/builtins/full_company.yamlsrc/synthorg/templates/builtins/research_lab.yaml
🧬 Code graph analysis (1)
tests/unit/core/test_company_reporting.py (1)
src/synthorg/core/company.py (2)
Department(316-421)ReportingLine(40-102)
🪛 YAMLlint (1.38.0)
src/synthorg/templates/builtins/full_company.yaml
[error] 54-54: syntax error: found character '%' that cannot start any token
(syntax)
🔇 Additional comments (20)
src/synthorg/core/company.py (5)
374-384: LGTM! Addresses the requirement thathead_idrequireshead.This validator correctly rejects configurations where
head_idis set without a correspondinghead, preventing impossible states for downstream hierarchy consumers.
25-37: LGTM! Well-designed identity key helper.The namespace-tagging approach (
("id", ...)vs("name", ...)) correctly prevents false collisions when an ID value happens to match a name from a different entry. The docstring clearly explains the rationale.
60-67: LGTM! Proper use ofNotBlankStr | Nonefor optional ID fields.The optional ID fields correctly use
NotBlankStr | Noneper coding guidelines, ensuring whitespace-only values are rejected at the model boundary.
69-102: LGTM! Robust self-report validation with namespace awareness.The validator correctly:
- Computes identity keys for both sides
- Short-circuits when namespaces differ (legitimate asymmetric ID configurations)
- Provides context-aware error messages including IDs when present
400-421: LGTM! Duplicate subordinate detection using identity keys.The updated validator correctly uses
_identity_keyfor namespace-tagged duplicate detection, and the error message format (ns:key) provides clear diagnostic output.src/synthorg/templates/schema.py (1)
165-188: LGTM! Proper validation forhead_merge_idat schema boundary.The field correctly uses
NotBlankStr | Nonewithdefault=None, ensuring whitespace-only values are rejected during the first parsing pass rather than deferring validation to render time.docs/design/organization.md (2)
117-121: LGTM! Clear documentation ofhead_merge_id→head_idmapping.The documentation now explicitly explains that template YAML uses
head_merge_idwhile runtime objects usehead_id, paralleling thesubordinate_id/supervisor_idpattern inreporting_lines.
82-91: LGTM! Documentation example now complete.The example correctly demonstrates:
- Reporting lines with optional ID disambiguation (
subordinate_id/supervisor_id)- A CTO agent definition that matches the department references
Also applies to: 168-172
src/synthorg/templates/builtins/research_lab.yaml (2)
34-48: LGTM! Proper disambiguation withhead_merge_idand ID-aware reporting lines.The
data_analyticsdepartment now correctly:
- Uses
head_merge_id: "analyst-primary"to disambiguate the department head- Uses
supervisor_id: "analyst-primary"in reporting lines to reference the correct Data Analyst instance
102-130: LGTM! Well-structured cross-department workflows.The
workflow_handoffsandescalation_pathsdefine realistic bidirectional flows betweendata_analytics,engineering, andproductwith appropriate triggers, artifacts, and priority boosts.src/synthorg/templates/builtins/full_company.yaml (2)
47-63: LGTM! Engineering hierarchy now complete with Jinja2-generated reporting lines.The reporting lines correctly:
- Connect
Software Architect → CTO(addressing prior feedback)- Use Jinja2 loops to generate dynamic
subordinate_idvalues matching agentmerge_idpatterns (backend-{{ i }},frontend-{{ i }})The YAMLlint error about
%on line 54 is a false positive — the{% for %}syntax is valid Jinja2 that will be processed before YAML parsing.
295-368: LGTM! Comprehensive enterprise workflow definitions.The
workflow_handoffsmodel a realistic product pipeline (product → design → engineering → QA → operations) plus security review loops, whileescalation_pathsprovide appropriate priority boosts (1-3) for different severity levels.tests/unit/core/conftest.py (1)
128-134: LGTM! Factory updated to match model changes.Adding
head_id = Nonekeeps theDepartmentFactoryaligned with the new optionalDepartment.head_idfield.tests/unit/core/test_company_reporting.py (2)
14-141: LGTM! ComprehensiveReportingLinetest coverage.The tests thoroughly cover:
- Valid cases and self-report rejection (case-insensitive)
- ID handling: defaults, same role with different IDs, same ID rejection
- Asymmetric ID configurations (one side has ID, other doesn't)
- Namespace collision prevention (name matching other side's ID)
- Blank/whitespace ID rejection via parametrized tests
146-322: LGTM! ThoroughDepartmentreporting-line validation tests.The tests comprehensively cover:
- Basic reporting lines and backward compatibility (empty tuple default)
- Duplicate subordinate detection (by name, case-insensitive, whitespace-insensitive)
- ID-based duplicate detection and case insensitivity
- Mixed ID/no-ID entries
- Namespace isolation (name matching another entry's ID)
head_idacceptance, defaults, and validationtests/unit/core/test_company_workflows.py (5)
1-37: LGTM! Clean test structure and comprehensive coverage.The module is well-organized with proper imports, type hints, docstrings, and test markers. The
TestReviewRequirementsclass appropriately tests both default values and custom configurations.
39-78: LGTM! Thorough validation testing.The tests for
ApprovalChainproperly verify valid construction and enforce validation rules (empty approvers, min_approvals constraints, and special handling of zero).
95-129: LGTM! Proper immutability and policy validation testing.The frozen test correctly verifies immutability, and
TestDepartmentPoliciesappropriately tests defaults and duplicate action_type validation.
139-148: LGTM! Proper valid handoff test.The test appropriately verifies that a valid
WorkflowHandoffcan be constructed and checks the expected field values.
176-212: LGTM! Excellent priority_boost test coverage.The
EscalationPathtests properly verify valid construction, boundary values (0 and 3), and parametrized rejection of invalid values. The parametrization at line 203 correctly addresses the past review comment.
… templates Add subordinate_id/supervisor_id optional fields to ReportingLine for disambiguating agents that share the same role name (e.g. multiple "Backend Developer" agents with different merge_ids). Update self-report and unique-subordinate validators to use ids when present. Populate reporting_lines, workflow_handoffs, and escalation_paths across 6 builtin templates (startup, dev_shop, research_lab, product_team, agency, full_company). Solo founder skipped (only 2 agents). Key additions per template: - startup: 3 reporting lines, 1 handoff, 2 escalations - dev_shop: 5 reporting lines, 2 handoffs, 2 escalations - research_lab: 4 reporting lines, 3 handoffs, 2 escalations - product_team: 5 reporting lines, 5 handoffs, 3 escalations - agency: 7 reporting lines, 6 handoffs, 3 escalations - full_company: 15 reporting lines (with Jinja2 loops for dynamic backend/frontend devs), 8 handoffs, 5 escalations Closes #719 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Use explicit branching instead of `or` fallback when comparing subordinate/supervisor identity keys. The `or` pattern mixed ID and name namespaces, which could produce false self-report rejections when only one side carries an ID. Now: both IDs present -> compare IDs; neither present -> compare names; asymmetric -> always different agents. Also: replace redundant test with asymmetric-ID and blank-ID edge cases, add case-insensitive duplicate subordinate_id test, document reporting_lines in docs/design/organization.md, fix docstring spacing. Pre-reviewed by 7 agents, 10 findings addressed. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
… Gemini - Fix cross-namespace collision in _validate_unique_subordinates by using namespace-tagged (ns, key) tuples instead of flat strings - Extract _identity_key() helper to eliminate duplicated identity resolution logic between validators - Conditionally format self-report error message (omit id=None noise) - Reword asymmetric ID comment to describe design decision, not impossibility assertion - Split test_company.py (1045 lines) into three files under 800 lines: test_company.py (578), test_company_reporting.py (321), test_company_workflows.py (239) - Add cross-namespace collision test, reverse asymmetric ID test - Parametrize blank-ID rejection tests with match= assertions - Document budget_percent as task-execution budget in organization.md - Fix Template Structure example: add departments section, correct department names, add artifacts and priority_boost fields - Add supervisor_id to Department Configuration YAML example - Update merge_id docstring reference to be layer-neutral Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Add head_id to Department model and head_merge_id to template schema to resolve ambiguity when multiple agents share the head_role name. The renderer passes head_merge_id through as head_id on Department. Applied to product_team (backend-senior) and agency (fullstack-senior) templates where head_role matches multiple agents. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The example referenced "CTO" in departments (head_role, reporting lines) but did not include a CTO agent in the agents list. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Add validator: head_id requires head to be non-null on Department - Add Software Architect -> CTO reporting line in full_company.yaml (connects engineering subtree to department head) - Add head_merge_id to research_lab.yaml data_analytics department (disambiguates which Data Analyst is head) - Guard renderer: only set head_id when head_role was explicitly provided (not the dept_name fallback) - Change head_merge_id schema type from str to NotBlankStr | None (rejects whitespace-only values at parse time) - Document head_merge_id -> head_id mapping in organization.md - Parametrize priority_boost invalid-value tests Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Log warning when head_merge_id is present but head_role is missing (renderer silently discarded it before) - Add whitespace-only head_id rejection test - Parametrize duplicate-approver tests (exact + case-insensitive) - Parametrize same-department tests for WorkflowHandoff and EscalationPath (exact + case-insensitive) Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
6c42a8f to
6f07dea
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #745 +/- ##
=======================================
Coverage 92.28% 92.28%
=======================================
Files 573 573
Lines 29664 29690 +26
Branches 2871 2877 +6
=======================================
+ Hits 27374 27398 +24
- Misses 1810 1811 +1
- Partials 480 481 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🤖 I have created a release *beep* *boop* --- ## [0.4.8](v0.4.7...v0.4.8) (2026-03-22) ### Features * add auto_cleanup config and improve update UX ([#741](#741)) ([289638f](289638f)) * add reporting lines, escalation paths, and workflow handoffs to templates ([#745](#745)) ([c374cc9](c374cc9)) * differentiate template operational configs ([#742](#742)) ([9b48345](9b48345)) * diversify personality preset assignments across templates ([#743](#743)) ([15487a5](15487a5)) * improve template metadata -- skill taxonomy, descriptions, tags, and display names ([#752](#752)) ([f333f24](f333f24)) ### Bug Fixes * resolve log analysis findings (Ollama prefix, logging, init) ([#748](#748)) ([8f871a4](8f871a4)) * use git tag for dev release container image tags ([#749](#749)) ([f30d071](f30d071)) * use subordinate_id/supervisor_id in HierarchyResolver ([#751](#751)) ([118235b](118235b)) ### Performance * add long-lived cache headers for content-hashed static assets ([#747](#747)) ([4d350b5](4d350b5)) * use worksteal distribution for pytest-xdist ([#750](#750)) ([b7dd7de](b7dd7de)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Summary
subordinate_id/supervisor_idfields toReportingLinemodel for disambiguating agents that share the same role name (e.g. multiple "Backend Developer" agents with different merge_ids)reporting_lines,workflow_handoffs, andescalation_pathsacross 6 builtin templates:reporting_lineswithsubordinate_id/supervisor_idindocs/design/organization.mdNotes
solo_founder.yamlskipped (only 2 agents, no meaningful hierarchy)full_company.yamlproduct department hashead_role: "Product Manager"but contains CPO (c_suite) -- pre-existing issue, not addressed hereHierarchyResolverincommunication/delegation/hierarchy.pydoes not yet consume the new ID fields -- tracked separately as it affects runtime hierarchy resolution in a different moduleTest plan
test_all_builtins_load_successfullyandtest_render_all_builtins_produce_valid_root_config)Closes #719