feat: restructure builtin templates into inheritance tree#982
feat: restructure builtin templates into inheritance tree#982
Conversation
WalkthroughAdds a dedicated inheritance resolver ( 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
Dependency ReviewThe following issues were found:
Snapshot WarningsEnsure that dependencies are being submitted on PR branches. Re-running this action after a short time may resolve the issue. See the documentation for more information and troubleshooting advice. License Issuesuv.lock
OpenSSF ScorecardScorecard details
Scanned Files
|
There was a problem hiding this comment.
Code Review
This pull request implements a robust template inheritance system, enabling templates to extend others, merge configurations, and explicitly remove inherited departments or agents using a new _remove directive. The changes include refactoring the inheritance logic into a dedicated module, updating the merge engine to handle workflow and department overrides, and updating several builtin templates to utilize these features. Review feedback correctly identified critical issues in the dev_shop.yaml and product_team.yaml templates, where agent removals and overrides would fail because the entries lacked the merge_id values necessary to match the definitions in the parent templates.
| - role: "Full-Stack Developer" | ||
| department: "engineering" | ||
| _remove: true | ||
| - role: "Full-Stack Developer" | ||
| department: "engineering" | ||
| _remove: true |
There was a problem hiding this comment.
The removal of Full-Stack Developer agents will fail because the parent template (startup) defines these agents with specific merge_id values (fullstack-senior and fullstack-mid). Since _agent_key includes the merge_id in the comparison, these removal entries must also specify the matching merge_id to successfully target the parent agents.
- role: "Full-Stack Developer"
merge_id: "fullstack-senior"
department: "engineering"
_remove: true
- role: "Full-Stack Developer"
merge_id: "fullstack-mid"
department: "engineering"
_remove: true| # Override first Full-Stack Developer (positional): change personality | ||
| - role: "Full-Stack Developer" | ||
| name: "" | ||
| level: "senior" | ||
| model: | ||
| tier: "medium" | ||
| priority: "speed" | ||
| personality_preset: "strategic_planner" | ||
| department: "product" | ||
| - role: "UX Designer" | ||
| name: "" | ||
| level: "mid" | ||
| model: "medium" | ||
| personality_preset: "user_advocate" | ||
| department: "design" | ||
| - role: "UX Researcher" | ||
| name: "" | ||
| level: "mid" | ||
| model: "medium" | ||
| personality_preset: "methodical_analyst" | ||
| department: "design" | ||
| personality_preset: "communication_bridge" | ||
| department: "engineering" | ||
| # Remove second Full-Stack Developer (positional) | ||
| - role: "Full-Stack Developer" | ||
| department: "engineering" | ||
| _remove: true |
There was a problem hiding this comment.
The override and removal of Full-Stack Developer agents will fail to match the parent agents from startup because they are missing the required merge_id values (fullstack-senior and fullstack-mid). Without the merge_id, the merge engine treats these as different keys, resulting in duplicate agents or failed removals.
# Override first Full-Stack Developer: change personality
- role: "Full-Stack Developer"
name: ""
merge_id: "fullstack-senior"
level: "senior"
model: "medium"
personality_preset: "communication_bridge"
department: "engineering"
# Remove second Full-Stack Developer
- role: "Full-Stack Developer"
merge_id: "fullstack-mid"
department: "engineering"
_remove: trueThere was a problem hiding this comment.
Pull request overview
This PR restructures the built-in company templates to actually use the existing template inheritance system (forming a small inheritance tree), while extending the inheritance/merge pipeline to support department removal, improved workflow field handling, and post-merge agent name deduplication.
Changes:
- Reworked built-in YAML templates to use
extends(e.g.,solo_founder -> startup -> dev_shop/product_team,research_lab -> data_team) and added neededmerge_ids on base agents. - Added department-level
_removesupport (schema + render validation + merge semantics) and extracted inheritance resolution intosrc/synthorg/templates/_inheritance.py. - Added tests covering the builtin inheritance chains and department removal behavior; updated docs to reflect new merge semantics.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/templates/test_schema.py | Adds schema tests for department _remove alias/default behavior. |
| tests/unit/templates/test_inheritance.py | Adds unit + integration tests for department removal and updates variable collection import. |
| tests/unit/templates/test_builtin_inheritance.py | New tests asserting builtin templates render correctly across inheritance chains. |
| tests/unit/templates/conftest.py | Updates fixtures with merge_id and adds YAML fixtures for department removal tests. |
| src/synthorg/templates/schema.py | Adds TemplateDepartmentConfig.remove (alias _remove) to support dept removal directives. |
| src/synthorg/templates/renderer.py | Routes inheritance through new _inheritance.py and adds _as_parent mode to preserve merge_id for parent renders. |
| src/synthorg/templates/_render_helpers.py | Adds _remove handling for departments and rejects _remove when no extends. |
| src/synthorg/templates/_inheritance.py | New module extracting inheritance resolution + adds post-merge agent name deduplication and parent-variable collection. |
| src/synthorg/templates/merge.py | Adds dept _remove behavior and includes workflow in replace-if-present inheritance merge fields. |
| src/synthorg/templates/builtins/solo_founder.yaml | Adds merge_id to enable child targeting of the senior full-stack agent. |
| src/synthorg/templates/builtins/startup.yaml | Converts to extends: solo_founder and overrides the inherited full-stack agent via merge_id. |
| src/synthorg/templates/builtins/dev_shop.yaml | Converts to extends: startup and switches to removal/override deltas. |
| src/synthorg/templates/builtins/product_team.yaml | Converts to extends: startup and uses dept/agent removals + additions. |
| src/synthorg/templates/builtins/data_team.yaml | Converts to extends: research_lab and uses removals/overrides to form the data-focused subset. |
| docs/design/organization.md | Documents dept _remove, workflow merge behavior, and post-merge agent name deduplication. |
| CLAUDE.md | Updates templates directory description to mention inheritance tree. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - role: "Full-Stack Developer" | ||
| department: "engineering" | ||
| _remove: true | ||
| - role: "Full-Stack Developer" | ||
| department: "engineering" | ||
| _remove: true | ||
| - role: "Product Manager" | ||
| department: "product" | ||
| _remove: true |
There was a problem hiding this comment.
The two _remove: true entries for Full-Stack Developer won't match the inherited agents from startup because those inherited agents have merge_ids (fullstack-senior / fullstack-mid). The merge key is (role, department, merge_id), so a child entry without merge_id has key (..., "") and will raise TemplateInheritanceError (no matching parent) or fail to remove anything. Add the appropriate merge_id to each removal entry (or remove merge_id from the parent agents, but then targeted overrides become ambiguous).
| # Override first Full-Stack Developer (positional): change personality | ||
| - role: "Full-Stack Developer" | ||
| name: "" | ||
| level: "senior" | ||
| model: | ||
| tier: "medium" | ||
| priority: "speed" | ||
| personality_preset: "strategic_planner" | ||
| department: "product" | ||
| - role: "UX Designer" | ||
| name: "" | ||
| level: "mid" | ||
| model: "medium" | ||
| personality_preset: "user_advocate" | ||
| department: "design" | ||
| - role: "UX Researcher" | ||
| name: "" | ||
| level: "mid" | ||
| model: "medium" | ||
| personality_preset: "methodical_analyst" | ||
| department: "design" | ||
| personality_preset: "communication_bridge" | ||
| department: "engineering" | ||
| # Remove second Full-Stack Developer (positional) | ||
| - role: "Full-Stack Developer" | ||
| department: "engineering" | ||
| _remove: true |
There was a problem hiding this comment.
The Full-Stack Developer override/removal here is written as “positional”, but the inheritance merge matches agents by (role, department, merge_id). Since the inherited startup full-stack agents have merge_ids (fullstack-senior / fullstack-mid), the override entry (no merge_id) will be appended instead of overriding, and the _remove entry (no merge_id) will raise TemplateInheritanceError (no matching parent). Add the correct merge_id to both entries and update the comment to reflect merge-id based matching.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #982 +/- ##
==========================================
+ Coverage 91.91% 91.94% +0.02%
==========================================
Files 637 638 +1
Lines 34521 34578 +57
Branches 3367 3377 +10
==========================================
+ Hits 31730 31792 +62
+ Misses 2196 2193 -3
+ Partials 595 593 -2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/synthorg/templates/merge.py (1)
93-98:⚠️ Potential issue | 🟠 MajorParent workflow still gets overwritten when the child omits it.
This branch only inherits from
parentwhenworkflowis absent fromchild, butsrc/synthorg/templates/renderer.pyalways materializes a workflow dict from template defaults. A child template that leaves outworkflow/workflow_configstill replaces the parent workflow instead of inheriting it, so the propagation bug survives for omission-based inheritance. Please only emitworkflowwhen the YAML actually defines it, or carry an explicit sentinel through merge.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/synthorg/templates/merge.py` around lines 93 - 98, The merge logic currently treats a materialized-but-omitted workflow in child as an explicit override; change the conditional in the loop over keys ("workflow", "workflow_handoffs", "escalation_paths") so you only copy child[key] into result when the child actually declared the field (e.g., check for an explicit-sentinel like child.get("_explicit_fields") containing key or child.get("_explicit_" + key) True) and child[key] is not None; otherwise deepcopy the parent value into result. Ensure you preserve the deepcopy behavior and update the renderer to set the chosen sentinel when a field is present in the original YAML so merge.py can rely on it.
🤖 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 371-377: The docs currently contradict each other: the
`workflow_config` bullet says a child using `extends` must re-declare the full
`workflow_config` because the parent's config is not carried forward, but the
later change in this PR intends for `workflow_config` to propagate during
inheritance; update the `workflow_config` paragraph to match the implemented
behavior (i.e., describe that `workflow_config` is merged/inherited from the
parent unless overridden) and ensure its wording aligns with the existing rules
for `workflow`, `workflow_handoffs`, and `escalation_paths` (which state child
replaces entirely if present; otherwise inherits), referencing `extends`
semantics consistently.
In `@src/synthorg/templates/builtins/data_team.yaml`:
- Around line 93-97: The comment block listing inherited roles is misaligned and
triggers yamlint's comments-indentation; adjust the indentation of that entire
comment block so it lines up with the surrounding agents sequence items (i.e.,
align the "#" comment lines to the same indentation level as the "- Data
Engineer ..." list entries under agents) so yamlint no longer flags
comments-indentation in the agents section.
In `@src/synthorg/templates/renderer.py`:
- Around line 162-163: The current use of _preserve_merge_ids=_as_parent only
preserves merge_id during the immediate template expansion and loses it when
resolve_inheritance() merges parent templates; update resolve_inheritance() and
the merge path to thread a preserve_merge_ids flag through recursive inheritance
merging so merge_id is retained while traversing parents and only stripped on
the final non-parent render; modify callers that pass _preserve_merge_ids (e.g.,
the render/expand functions around _preserve_merge_ids=_as_parent and the code
paths at lines ~170-178) to forward the flag into resolve_inheritance(), ensure
merge logic respects preserve_merge_ids during intermediate merges, and perform
the final merge_id stripping only when preserve_merge_ids is false or at the
final render step.
In `@tests/unit/templates/test_builtin_inheritance.py`:
- Around line 44-282: Add regression tests in
tests/unit/templates/test_builtin_inheritance.py that exercise the two new
fragile inheritance paths: (1) a three-template chain that verifies a grandchild
inherits a parent's workflow when the intermediate parent omits it (cover the
"inheriting a parent's workflow by omission" case), and (2) a three-template
chain where an intermediate parent's agent is overridden/removed via merge_id
and ensure the grandchild reflects that removal (cover the "override/remove by
merge_id" case). Implement these as small pytest cases (similar style to
TestStartupExtendsSoloFounder and TestDevShopExtendsStartup) that render three
templates (e.g., "parent", "intermediate", "child") via _render and assert the
expected workflow presence/absence and agent list/roles (use _roles,
_dept_names, and merge_id-targeted agent lookups) so the tests fail if
inheritance rules regress.
---
Outside diff comments:
In `@src/synthorg/templates/merge.py`:
- Around line 93-98: The merge logic currently treats a materialized-but-omitted
workflow in child as an explicit override; change the conditional in the loop
over keys ("workflow", "workflow_handoffs", "escalation_paths") so you only copy
child[key] into result when the child actually declared the field (e.g., check
for an explicit-sentinel like child.get("_explicit_fields") containing key or
child.get("_explicit_" + key) True) and child[key] is not None; otherwise
deepcopy the parent value into result. Ensure you preserve the deepcopy behavior
and update the renderer to set the chosen sentinel when a field is present in
the original YAML so merge.py can rely on it.
🪄 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: 106dc189-d5de-4e8c-b31c-3090bacb9bb4
📒 Files selected for processing (16)
CLAUDE.mddocs/design/organization.mdsrc/synthorg/templates/_inheritance.pysrc/synthorg/templates/_render_helpers.pysrc/synthorg/templates/builtins/data_team.yamlsrc/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/builtins/solo_founder.yamlsrc/synthorg/templates/builtins/startup.yamlsrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pytests/unit/templates/conftest.pytests/unit/templates/test_builtin_inheritance.pytests/unit/templates/test_inheritance.pytests/unit/templates/test_schema.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). (7)
- GitHub Check: Agent
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Web
- GitHub Check: Build Sandbox
- GitHub Check: Build Backend
- GitHub Check: Analyze (python)
- GitHub Check: Dependency Review
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Python 3.14+ with PEP 649 native lazy annotations -- do NOT usefrom __future__ import annotations.
Use PEP 758 except syntax:except A, B:(no parentheses) -- ruff enforces this on Python 3.14.
Maximum line length is 88 characters (ruff enforced).
Files:
tests/unit/templates/test_schema.pytests/unit/templates/test_inheritance.pysrc/synthorg/templates/_render_helpers.pysrc/synthorg/templates/schema.pysrc/synthorg/templates/merge.pytests/unit/templates/conftest.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/_inheritance.pytests/unit/templates/test_builtin_inheritance.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use vendor-agnostic test names:test-provider,test-small-001, etc. in all Python tests.
Tests must use pytest markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow.
Minimum coverage is 80% (enforced in CI). Usepytest -m <marker> --cov=synthorg --cov-fail-under=80.
Useasyncio_mode = "auto"for async tests -- no manual@pytest.mark.asyncioneeded.
Global test timeout is 30 seconds per test (do not add per-file markers; non-default overrides liketimeout(60)are allowed).
Prefer@pytest.mark.parametrizefor testing similar cases.
Use Hypothesis for property-based testing in Python with@given+@settings. Profiles:ci(50 examples, default) anddev(1000 examples). Run dev profile:HYPOTHESIS_PROFILE=dev uv run python -m pytest tests/ -m unit -n auto -k properties.
Never skip, dismiss, or ignore flaky tests -- always fix them fully and fundamentally. For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep(). For tasks that must block indefinitely, useasyncio.Event().wait()instead ofasyncio.sleep(large_number).
Files:
tests/unit/templates/test_schema.pytests/unit/templates/test_inheritance.pytests/unit/templates/conftest.pytests/unit/templates/test_builtin_inheritance.py
src/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/**/*.py: All public functions must have type hints; mypy strict mode enforced.
Docstrings must follow Google style and are required on public classes/functions (enforced by ruff D rules).
Use immutability: create new objects, never mutate existing ones. For non-Pydantic internal collections, usecopy.deepcopy()at construction andMappingProxyTypewrapping for read-only enforcement.
Use 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 in one model.
Adopt Pydantic v2 conventions: useallow_inf_nan=Falsein allConfigDictdeclarations to rejectNaN/Infin numeric fields; use@computed_fieldfor derived values instead of storing redundant fields; useNotBlankStrfor all identifier/name fields.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code. Prefer structured concurrency over barecreate_task.
Functions must be less than 50 lines, files must be less than 800 lines.
Handle errors explicitly, never silently swallow exceptions.
Validate at system boundaries (user input, external APIs, config files).
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001. Vendor names only in: (1)docs/design/operations.md, (2).claude/files, (3) third-party imports, (4) provider presets.
Files:
src/synthorg/templates/_render_helpers.pysrc/synthorg/templates/schema.pysrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/_inheritance.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Every module with business logic MUST havefrom synthorg.observability import get_loggerthenlogger = get_logger(__name__).
Never useimport logging,logging.getLogger(), orprint()in application code. Exceptions: observability/setup.py, observability/sinks.py, observability/syslog_handler.py, observability/http_handler.py may use stdlib logging and stderr prints.
Always use variable namelogger(not_logger, notlog).
Use event name constants fromsynthorg.observability.eventsdomain-specific modules, not hardcoded strings. Import directly:from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Always use structured logging:logger.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, and entry/exit of key functions.
Files:
src/synthorg/templates/_render_helpers.pysrc/synthorg/templates/schema.pysrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/_inheritance.py
🧠 Learnings (24)
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.
Applied to files:
CLAUDE.mdtests/unit/templates/test_inheritance.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/_inheritance.pysrc/synthorg/templates/builtins/dev_shop.yamltests/unit/templates/test_builtin_inheritance.pysrc/synthorg/templates/builtins/startup.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:
CLAUDE.mdsrc/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/providers/**/*.py : Providers: LLM provider abstraction (LiteLLM adapter), auth types (api_key/oauth/custom_header/none), presets (PROVIDER_PRESETS), runtime CRUD (ProviderManagementService with asyncio.Lock serialization), hot-reload via AppState swap.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Settings: Runtime-editable settings persistence (DB > env > YAML > code defaults), typed definitions (9 namespaces), Fernet encryption for sensitive values, config bridge, ConfigResolver (typed composed reads for controllers), validation, registry, change notifications via message bus. Per-namespace setting definitions in definitions/ submodule (api, company, providers, memory, budget, security, coordination, observability, backup).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Web dashboard: see `web/CLAUDE.md` for commands, design system, and component inventory
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers
Applied to files:
CLAUDE.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: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-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/design/*.md : Update the relevant `docs/design/` page when approved deviations occur to reflect the new reality
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: 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/data_team.yaml
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to src/synthorg/**/*.py : Use event name constants from `synthorg.observability.events.<domain>` modules (e.g., `API_REQUEST_STARTED` from `events.api`, `TOOL_INVOKE_START` from `events.tool`); import directly and use in structured logging
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Use event constants from `synthorg.observability.events.<domain>` (e.g., `API_REQUEST_STARTED` from `events.api`); import directly and log with structured kwargs: `logger.info(EVENT, key=value)`, never interpolated strings
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability package (observability/): structured logging, correlation tracking, log sinks; event constants organized by domain under observability/events/ (e.g., events.api, events.tool, events.git, events.context_budget, events.backup)
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import `from synthorg.observability import get_logger` and define `logger = get_logger(__name__)`
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use event name constants from synthorg.observability.events domain-specific modules (e.g., PROVIDER_CALL_START from events.provider). Import directly: from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Applied to files:
src/synthorg/templates/renderer.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 : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Never use import logging / logging.getLogger() / print() in application code.
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability includes structured logging via `get_logger(__name__)`, correlation tracking, and log sinks.
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import logger via `from synthorg.observability import get_logger` and initialize with `logger = get_logger(__name__)`
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-04-01T18:29:59.468Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T18:29:59.468Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`.
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/**/*.py : Always use event name constants from the domain-specific module under `synthorg.observability.events` in logging calls
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/budget/**/*.py : Budget tracking includes pre-flight/in-flight checks, auto-downgrade, billing periods, cost tiers, quota/subscription. CFO includes anomaly detection, efficiency analysis, downgrade recommendations.
Applied to files:
src/synthorg/templates/builtins/dev_shop.yaml
🪛 YAMLlint (1.38.0)
src/synthorg/templates/builtins/data_team.yaml
[warning] 93-93: comment not indented like content
(comments-indentation)
🔇 Additional comments (7)
CLAUDE.md (1)
104-104: Good package-map update for templates subsystem.Line 104 now reflects the inheritance-tree and merge-engine responsibilities clearly.
src/synthorg/templates/builtins/solo_founder.yaml (1)
59-59:merge_idaddition is the right fix for deterministic inheritance targeting.Line 59 gives child templates a stable key for override/remove operations.
tests/unit/templates/test_schema.py (1)
227-238: Nice targeted schema coverage for department remove semantics.Lines 227-238 correctly lock
_removealias mapping and the defaultFalsebehavior.src/synthorg/templates/schema.py (1)
229-233: Department_removedirective is modeled cleanly in schema.Lines 229-233 align with the agent-side directive pattern and keep defaults safe.
tests/unit/templates/test_inheritance.py (1)
138-227: Strong coverage expansion for department_removebehavior.Lines 138-227 validate merge behavior, case-insensitive matching, and full-pipeline errors (
without extends/ missing parent) effectively.src/synthorg/templates/_render_helpers.py (1)
128-151: Good explicit guardrail for invalid department_removeusage.Line 139+ correctly fails fast when
_removeis used withoutextends, instead of allowing a silent no-op.tests/unit/templates/conftest.py (1)
230-288: Fixture additions are well-scoped for new inheritance/remove paths.Lines 230-288 provide clear scenario coverage for successful department removal and expected failure modes.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
src/synthorg/templates/builtins/data_team.yaml (1)
70-97: 🧹 Nitpick | 🔵 TrivialAlign comment block indentation with
agentssequence.The comment block at lines 93-97 documenting inherited agents may trigger yamllint's
comments-indentationwarning. Align these comments to the same indentation level as the agent list entries above.📝 Suggested fix
department: "engineering" - # Inherited unchanged from research_lab: - # - Data Engineer (data_analytics) - # - Data Analyst [analyst-primary] (data_analytics) - # - Data Analyst [analyst-secondary] (data_analytics) - # - ML Engineer (data_analytics) + # Inherited unchanged from research_lab: + # - Data Engineer (data_analytics) + # - Data Analyst [analyst-primary] (data_analytics) + # - Data Analyst [analyst-secondary] (data_analytics) + # - ML Engineer (data_analytics)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/synthorg/templates/builtins/data_team.yaml` around lines 70 - 97, The comment block "Inherited unchanged from research_lab:" is misaligned with the surrounding agents list and can trigger yamllint comments-indentation; move and indent that entire comment block so it lines up with the agent list entries (same leading indentation as the "- role:" lines under the agents sequence), i.e., add the same number of spaces before each "# -" comment line so the comment sits at the same column as the agent items and preserves the comment text exactly.tests/unit/templates/test_builtin_inheritance.py (1)
44-257: 🧹 Nitpick | 🔵 TrivialAdd a three-template regression for
_as_parentand workflow propagation.These tests validate final counts and roles, but they still never exercise the two fragile paths introduced here: a grandchild inheriting the workflow path when the intermediate template omits it, and a
merge_id-targeted override/remove surviving through the intermediate render. A regression in either_as_parentor the workflow propagation fix would still pass this suite.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/unit/templates/test_builtin_inheritance.py` around lines 44 - 257, Add a three-template regression that exercises _as_parent and workflow propagation: create a chain of templates (grandparent -> parent -> child) where the parent omits the workflow/path and the child relies on inheriting it from the grandparent, then call _render("child") and assert the child's workflow/path is present (verifying workflow propagation through an intermediate that omits it). Also add a case where the parent performs a merge_id-targeted override or removal on an agent defined in the grandparent and ensure that after _render("child") the merge_id change persists (verifying merge_id-targeted overrides survive the intermediate render); use existing helpers _render, _as_parent, and reference merge_id and workflow symbols in the assertions.
🤖 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/_inheritance.py`:
- Around line 78-80: Replace the runtime assert in _render_to_dict with an
explicit guard: check if loaded.template.extends is None and if so raise
TemplateInheritanceError with a clear message (include identifying information
like loaded.template.name or loaded.name) instead of relying on assert, then
assign parent_name: str = loaded.template.extends; this ensures a deterministic
error path when the caller contract is violated even under python -O.
In `@src/synthorg/templates/builtins/product_team.yaml`:
- Around line 103-113: The two Full-Stack Developer entries lack the merge key
so they won't match parent agents; add merge_id: "fullstack-senior" to the
override entry that sets personality_preset: "communication_bridge" (role:
"Full-Stack Developer", department: "engineering", level: "senior") so it
replaces the senior agent, and add merge_id: "fullstack-mid" to the removal
entry (role: "Full-Stack Developer", department: "engineering", _remove: true)
so it matches and removes the mid-level agent.
---
Duplicate comments:
In `@src/synthorg/templates/builtins/data_team.yaml`:
- Around line 70-97: The comment block "Inherited unchanged from research_lab:"
is misaligned with the surrounding agents list and can trigger yamllint
comments-indentation; move and indent that entire comment block so it lines up
with the agent list entries (same leading indentation as the "- role:" lines
under the agents sequence), i.e., add the same number of spaces before each "#
-" comment line so the comment sits at the same column as the agent items and
preserves the comment text exactly.
In `@tests/unit/templates/test_builtin_inheritance.py`:
- Around line 44-257: Add a three-template regression that exercises _as_parent
and workflow propagation: create a chain of templates (grandparent -> parent ->
child) where the parent omits the workflow/path and the child relies on
inheriting it from the grandparent, then call _render("child") and assert the
child's workflow/path is present (verifying workflow propagation through an
intermediate that omits it). Also add a case where the parent performs a
merge_id-targeted override or removal on an agent defined in the grandparent and
ensure that after _render("child") the merge_id change persists (verifying
merge_id-targeted overrides survive the intermediate render); use existing
helpers _render, _as_parent, and reference merge_id and workflow symbols in the
assertions.
🪄 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: 3e01efd1-9fda-4d66-a130-376bd896a2ab
📒 Files selected for processing (12)
docs/design/organization.mddocs/guides/agents.mddocs/guides/company-config.mdsrc/synthorg/templates/_inheritance.pysrc/synthorg/templates/_render_helpers.pysrc/synthorg/templates/builtins/data_team.yamlsrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.pytests/unit/templates/test_builtin_inheritance.pytests/unit/templates/test_inheritance.pytests/unit/templates/test_renderer.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Build Web
- GitHub Check: Build Backend
- GitHub Check: Build Sandbox
- GitHub Check: Test (Python 3.14)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Python 3.14+ with PEP 649 native lazy annotations -- do NOT usefrom __future__ import annotations.
Use PEP 758 except syntax:except A, B:(no parentheses) -- ruff enforces this on Python 3.14.
Maximum line length is 88 characters (ruff enforced).
Files:
tests/unit/templates/test_renderer.pysrc/synthorg/templates/_render_helpers.pysrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/_inheritance.pytests/unit/templates/test_inheritance.pytests/unit/templates/test_builtin_inheritance.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use vendor-agnostic test names:test-provider,test-small-001, etc. in all Python tests.
Tests must use pytest markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow.
Minimum coverage is 80% (enforced in CI). Usepytest -m <marker> --cov=synthorg --cov-fail-under=80.
Useasyncio_mode = "auto"for async tests -- no manual@pytest.mark.asyncioneeded.
Global test timeout is 30 seconds per test (do not add per-file markers; non-default overrides liketimeout(60)are allowed).
Prefer@pytest.mark.parametrizefor testing similar cases.
Use Hypothesis for property-based testing in Python with@given+@settings. Profiles:ci(50 examples, default) anddev(1000 examples). Run dev profile:HYPOTHESIS_PROFILE=dev uv run python -m pytest tests/ -m unit -n auto -k properties.
Never skip, dismiss, or ignore flaky tests -- always fix them fully and fundamentally. For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep(). For tasks that must block indefinitely, useasyncio.Event().wait()instead ofasyncio.sleep(large_number).
Files:
tests/unit/templates/test_renderer.pytests/unit/templates/test_inheritance.pytests/unit/templates/test_builtin_inheritance.py
src/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/**/*.py: All public functions must have type hints; mypy strict mode enforced.
Docstrings must follow Google style and are required on public classes/functions (enforced by ruff D rules).
Use immutability: create new objects, never mutate existing ones. For non-Pydantic internal collections, usecopy.deepcopy()at construction andMappingProxyTypewrapping for read-only enforcement.
Use 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 in one model.
Adopt Pydantic v2 conventions: useallow_inf_nan=Falsein allConfigDictdeclarations to rejectNaN/Infin numeric fields; use@computed_fieldfor derived values instead of storing redundant fields; useNotBlankStrfor all identifier/name fields.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code. Prefer structured concurrency over barecreate_task.
Functions must be less than 50 lines, files must be less than 800 lines.
Handle errors explicitly, never silently swallow exceptions.
Validate at system boundaries (user input, external APIs, config files).
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001. Vendor names only in: (1)docs/design/operations.md, (2).claude/files, (3) third-party imports, (4) provider presets.
Files:
src/synthorg/templates/_render_helpers.pysrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/_inheritance.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Every module with business logic MUST havefrom synthorg.observability import get_loggerthenlogger = get_logger(__name__).
Never useimport logging,logging.getLogger(), orprint()in application code. Exceptions: observability/setup.py, observability/sinks.py, observability/syslog_handler.py, observability/http_handler.py may use stdlib logging and stderr prints.
Always use variable namelogger(not_logger, notlog).
Use event name constants fromsynthorg.observability.eventsdomain-specific modules, not hardcoded strings. Import directly:from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Always use structured logging:logger.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, and entry/exit of key functions.
Files:
src/synthorg/templates/_render_helpers.pysrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/_inheritance.py
🧠 Learnings (20)
📚 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/guides/agents.mddocs/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/guides/agents.mddocs/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/guides/agents.mddocs/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/guides/agents.mdsrc/synthorg/templates/renderer.pysrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/_inheritance.pytests/unit/templates/test_inheritance.pytests/unit/templates/test_builtin_inheritance.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: 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-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/design/*.md : Update the relevant `docs/design/` page when approved deviations occur to reflect the new reality
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue. DESIGN_SPEC.md is a pointer file linking to the 7 design 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: 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/data_team.yaml
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to src/synthorg/**/*.py : Use event name constants from `synthorg.observability.events.<domain>` modules (e.g., `API_REQUEST_STARTED` from `events.api`, `TOOL_INVOKE_START` from `events.tool`); import directly and use in structured logging
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Use event constants from `synthorg.observability.events.<domain>` (e.g., `API_REQUEST_STARTED` from `events.api`); import directly and log with structured kwargs: `logger.info(EVENT, key=value)`, never interpolated strings
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability package (observability/): structured logging, correlation tracking, log sinks; event constants organized by domain under observability/events/ (e.g., events.api, events.tool, events.git, events.context_budget, events.backup)
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import `from synthorg.observability import get_logger` and define `logger = get_logger(__name__)`
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use event name constants from synthorg.observability.events domain-specific modules (e.g., PROVIDER_CALL_START from events.provider). Import directly: from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Applied to files:
src/synthorg/templates/renderer.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 : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Never use import logging / logging.getLogger() / print() in application code.
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability includes structured logging via `get_logger(__name__)`, correlation tracking, and log sinks.
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import logger via `from synthorg.observability import get_logger` and initialize with `logger = get_logger(__name__)`
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-04-01T18:29:59.468Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T18:29:59.468Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`.
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/**/*.py : Always use event name constants from the domain-specific module under `synthorg.observability.events` in logging calls
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : 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:
tests/unit/templates/test_inheritance.py
🪛 LanguageTool
docs/design/organization.md
[grammar] ~351-~351: Ensure spelling is correct
Context: ...d raises TemplateInheritanceError. Builtin inheritance tree: ``` solo_founder (...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (18)
src/synthorg/templates/_render_helpers.py (2)
128-150: LGTM! Clean validation helper for department removal.The function correctly validates that
_removeis only used withextends, logs appropriately at ERROR level before raising, and returns a minimal marker dict. The structured logging follows project conventions.
153-202: LGTM! Proper integration of_removehandling.The
has_extendsparameter is correctly threaded through, and the earlycontinueafter handling_removeentries prevents invalid processing of removal markers through the normal budget/head parsing path.docs/guides/company-config.md (1)
73-79: LGTM! Documentation updated to reflect inheritance-based agent counts.The agent count ranges now reflect the expanded agent rosters from template inheritance (e.g.,
dev_shopextendsstartupand adds specialized roles). These match the values documented indocs/guides/agents.md.tests/unit/templates/test_renderer.py (1)
645-661: LGTM! Test covers thepreserve_merge_idparameter for parent rendering.This test correctly validates that when
preserve_merge_id=Trueis passed (simulating parent rendering via_as_parent), themerge_idis retained even whenhas_extends=False. This enables child templates to target parent agents bymerge_id.docs/guides/agents.md (1)
283-289: LGTM! Template table updated consistently with inheritance changes.Agent counts and behavioral attributes (Autonomy, Communication) now match the actual template configurations after the inheritance restructuring. These values are consistent with
docs/guides/company-config.md.src/synthorg/templates/builtins/data_team.yaml (2)
21-21: LGTM! Clean inheritance declaration.The
extends: "research_lab"establishes the parent relationship correctly. The child template now only declares deltas (removals, overrides, additions) rather than duplicating all parent content.
46-67: LGTM! Department merge directives are well-structured.The department section correctly:
- Removes inherited
productdepartment using_remove: true- Overrides
data_analyticswith new head and reporting lines- Overrides
engineeringwithBackend Developeras headThe budget allocations (65% + 35%) sum to 100%.
docs/design/organization.md (2)
351-363: LGTM! Clear inheritance tree documentation.The builtin inheritance tree diagram accurately reflects the implemented structure:
solo_founder→startup→ {dev_shop,product_team}research_lab→data_team- Standalone:
agency,full_company,consultancyAgent counts match the template definitions.
383-399: LGTM! Merge semantics documentation is accurate and complete.The documented behaviors match the implementation:
- Department
_remove: trueremoves parent departmentsworkflow_configis consumed during rendering (not merged)workflow,workflow_handoffs,escalation_pathsfollow replace-if-present semantics- Post-merge agent name deduplication with numeric suffix
src/synthorg/templates/merge.py (4)
27-27: LGTM! Separate strip keys for departments.Using
_DEPT_STRIP_KEYS(only_remove) separately from_STRIP_KEYS(which includesmerge_id) is correct since departments don't usemerge_id.
94-98: LGTM! Replace-if-present with deep copy prevents reference sharing.The deep copy ensures that workflow fields from parent/child configs don't share references with the merged result, preventing accidental mutation of source data.
260-274: LGTM! Clean department removal and override logic.The logic correctly handles three cases:
_remove: true→ skip parent dept, mark name as seen- Override → use cleaned child version (strip
_removekey)- No match → copy parent dept
Adding to
seen_namesin the removal case prevents the department from being re-added by_collect_unmatched_child_depts.
283-311: LGTM! Error handling for invalid_removetargets.The function correctly raises
TemplateInheritanceErrorwith structured logging when a child attempts to remove a non-existent parent department. This provides clear feedback for template authors.src/synthorg/templates/renderer.py (5)
36-45: LGTM! Clean import reorganization.The inheritance resolution is now delegated to
_inheritance.py, keeping the renderer focused on Jinja2 rendering and config building. The import structure follows project conventions.
123-137: LGTM!_as_parentparameter enables merge_id preservation for parent rendering.The parameter and its docstring clearly explain that this mode preserves
merge_idon agents even when the template has noextends, allowing child templates to target parent agents bymerge_id.
384-395: LGTM! Correct computation ofpreserve_mergeflag.The logic
preserve_merge = has_extends or preserve_merge_idscorrectly ensures that:
- Templates with
extendsalways preserve merge_ids for the merge step- Parent templates (rendered via
_as_parent=True) preserve merge_ids even withoutextends
622-627: LGTM! Merge_id preservation logic is correct.The condition
if keep_merge and merge_idensures that:
merge_idis preserved when inheritance is active OR when rendering as parent- Empty
merge_idvalues are not added to the output (preventing empty string pollution)
170-178: Verified:_as_parent=Trueis correctly threaded through the callback for parent rendering.The
_render_to_dictcallback accepts the_as_parentparameter (defaultFalse), and when invoked for parent templates in_render_and_merge_parent, it is called with_as_parent=True. This parameter is passed to_build_config_dictaspreserve_merge_ids=_as_parent, ensuringmerge_idvalues survive through multi-level inheritance chains as intended.
| # Override first Full-Stack Developer (matched by role+department): change personality | ||
| - role: "Full-Stack Developer" | ||
| name: "" | ||
| level: "senior" | ||
| model: | ||
| tier: "medium" | ||
| priority: "speed" | ||
| personality_preset: "strategic_planner" | ||
| department: "product" | ||
| - role: "UX Designer" | ||
| name: "" | ||
| level: "mid" | ||
| model: "medium" | ||
| personality_preset: "user_advocate" | ||
| department: "design" | ||
| - role: "UX Researcher" | ||
| name: "" | ||
| level: "mid" | ||
| model: "medium" | ||
| personality_preset: "methodical_analyst" | ||
| department: "design" | ||
| personality_preset: "communication_bridge" | ||
| department: "engineering" | ||
| # Remove second Full-Stack Developer (matched by role+department) | ||
| - role: "Full-Stack Developer" | ||
| department: "engineering" | ||
| _remove: true |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd -i '^startup\.yaml$' | while read -r file; do
echo "== $file =="
rg -n -C2 'Full-Stack Developer|merge_id' "$file"
doneRepository: Aureliolo/synthorg
Length of output: 862
🏁 Script executed:
sed -n '100,120p' src/synthorg/templates/builtins/product_team.yaml | cat -nRepository: Aureliolo/synthorg
Length of output: 895
🏁 Script executed:
sed -n '104,147p' src/synthorg/templates/merge.py | cat -nRepository: Aureliolo/synthorg
Length of output: 2048
🏁 Script executed:
rg -n '_agent_key' src/synthorg/templates/merge.py -A 5Repository: Aureliolo/synthorg
Length of output: 760
🏁 Script executed:
sed -n '314,340p' src/synthorg/templates/merge.py | cat -nRepository: Aureliolo/synthorg
Length of output: 1017
Add merge_id to match the inherited Full-Stack Developer agents.
These entries have no merge_id, so they cannot match the parent's agents which have merge_id: "fullstack-senior" and merge_id: "fullstack-mid". The merge key is (role, department, merge_id), so missing merge_id defaults to "", creating mismatched keys.
- The override entry (line 105) will be appended instead of replacing the senior agent.
- The
_removeentry (line 112) will fail withTemplateInheritanceErrorsince no parent agent matches the key.
Add merge_id: "fullstack-senior" to the first entry and merge_id: "fullstack-mid" to the second.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/synthorg/templates/builtins/product_team.yaml` around lines 103 - 113,
The two Full-Stack Developer entries lack the merge key so they won't match
parent agents; add merge_id: "fullstack-senior" to the override entry that sets
personality_preset: "communication_bridge" (role: "Full-Stack Developer",
department: "engineering", level: "senior") so it replaces the senior agent, and
add merge_id: "fullstack-mid" to the removal entry (role: "Full-Stack
Developer", department: "engineering", _remove: true) so it matches and removes
the mid-level agent.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/synthorg/templates/_inheritance.py`:
- Around line 78-83: The branch in resolve_inheritance that raises
TemplateInheritanceError when loaded.template.extends is None lacks a logged
WARNING/ERROR; before raising, emit a structured log (e.g., logger.warning or
logger.error) that includes the template identity and context (use
loaded.source_name and indicate resolve_inheritance was called despite no
'extends') so observers can track the invalid caller; then raise
TemplateInheritanceError as before.
- Line 8: The code currently uses dict(child_vars) which only shallow-copies the
mapping and allows nested lists/dicts in child_vars to be shared and mutated by
parent layering; change the shallow copy to a deep copy (use
copy.deepcopy(child_vars)) when preparing the child context in the inheritance
logic (replace dict(child_vars) with copy.deepcopy(child_vars) in the places
where child_vars is cloned, including the occurrences around the inheritance
layering and the block referenced at lines ~226-229), and then wrap the
resulting mapping in MappingProxyType to enforce read-only access for downstream
code; also add the necessary imports (import copy and from types import
MappingProxyType) and ensure any tests that expect immutability still pass.
- Around line 48-114: The resolve_inheritance function is too large and mixes
validation, orchestration, rendering and post-merge normalization; split one
stage into a private helper to reduce its length under 50 lines. Extract either
validation (the call to _validate_inheritance_chain), parent rendering/merge
orchestration (the _render_and_merge_parent call and its args) or post-merge
normalization (the _deduplicate_merged_agent_names call) into a new private
function (e.g., _prepare_parent_merge or _finalize_merged_config) and update
resolve_inheritance to delegate to that helper while keeping calls to logger,
child_id/parent_name setup, and exception behavior unchanged so
resolve_inheritance now only coordinates logging, calls the new helper, and
returns the merged dict.
🪄 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: d7d700f9-c268-48ff-b354-b18513e7fe57
📒 Files selected for processing (2)
src/synthorg/templates/_inheritance.pytests/unit/templates/test_builtin_inheritance.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 Web
- GitHub Check: Build Sandbox
- GitHub Check: Build Backend
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Python 3.14+ with PEP 649 native lazy annotations -- do NOT usefrom __future__ import annotations.
Use PEP 758 except syntax:except A, B:(no parentheses) -- ruff enforces this on Python 3.14.
Maximum line length is 88 characters (ruff enforced).
Files:
src/synthorg/templates/_inheritance.pytests/unit/templates/test_builtin_inheritance.py
src/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/**/*.py: All public functions must have type hints; mypy strict mode enforced.
Docstrings must follow Google style and are required on public classes/functions (enforced by ruff D rules).
Use immutability: create new objects, never mutate existing ones. For non-Pydantic internal collections, usecopy.deepcopy()at construction andMappingProxyTypewrapping for read-only enforcement.
Use 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 in one model.
Adopt Pydantic v2 conventions: useallow_inf_nan=Falsein allConfigDictdeclarations to rejectNaN/Infin numeric fields; use@computed_fieldfor derived values instead of storing redundant fields; useNotBlankStrfor all identifier/name fields.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code. Prefer structured concurrency over barecreate_task.
Functions must be less than 50 lines, files must be less than 800 lines.
Handle errors explicitly, never silently swallow exceptions.
Validate at system boundaries (user input, external APIs, config files).
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:example-provider,example-large-001,example-medium-001,example-small-001. Vendor names only in: (1)docs/design/operations.md, (2).claude/files, (3) third-party imports, (4) provider presets.
Files:
src/synthorg/templates/_inheritance.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Every module with business logic MUST havefrom synthorg.observability import get_loggerthenlogger = get_logger(__name__).
Never useimport logging,logging.getLogger(), orprint()in application code. Exceptions: observability/setup.py, observability/sinks.py, observability/syslog_handler.py, observability/http_handler.py may use stdlib logging and stderr prints.
Always use variable namelogger(not_logger, notlog).
Use event name constants fromsynthorg.observability.eventsdomain-specific modules, not hardcoded strings. Import directly:from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Always use structured logging:logger.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, and entry/exit of key functions.
Files:
src/synthorg/templates/_inheritance.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use vendor-agnostic test names:test-provider,test-small-001, etc. in all Python tests.
Tests must use pytest markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow.
Minimum coverage is 80% (enforced in CI). Usepytest -m <marker> --cov=synthorg --cov-fail-under=80.
Useasyncio_mode = "auto"for async tests -- no manual@pytest.mark.asyncioneeded.
Global test timeout is 30 seconds per test (do not add per-file markers; non-default overrides liketimeout(60)are allowed).
Prefer@pytest.mark.parametrizefor testing similar cases.
Use Hypothesis for property-based testing in Python with@given+@settings. Profiles:ci(50 examples, default) anddev(1000 examples). Run dev profile:HYPOTHESIS_PROFILE=dev uv run python -m pytest tests/ -m unit -n auto -k properties.
Never skip, dismiss, or ignore flaky tests -- always fix them fully and fundamentally. For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep(). For tasks that must block indefinitely, useasyncio.Event().wait()instead ofasyncio.sleep(large_number).
Files:
tests/unit/templates/test_builtin_inheritance.py
🧠 Learnings (3)
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : 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/_inheritance.py
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Handle errors explicitly, never silently swallow. Validate at system boundaries (user input, external APIs, config files).
Applied to files:
src/synthorg/templates/_inheritance.py
🔇 Additional comments (1)
tests/unit/templates/test_builtin_inheritance.py (1)
295-343: Nice regression coverage for the three-level chain.These cases pin the workflow isolation, grandparent removal, and chained override behavior that this PR is touching, so future inheritance refactors should fail loudly.
| Extracted from ``renderer.py`` to keep file sizes under 800 lines. | ||
| """ | ||
|
|
||
| from typing import TYPE_CHECKING, Any, Protocol |
There was a problem hiding this comment.
Deep-copy child_vars before layering parent defaults.
dict(child_vars) only clones the top-level mapping. Nested lists/dicts stay shared across inheritance levels, so any mutation during parent rendering can leak back into the child pass.
Suggested fix
+import copy
from typing import TYPE_CHECKING, Any, Protocol
@@
- result: dict[str, Any] = dict(child_vars)
+ result: dict[str, Any] = copy.deepcopy(child_vars)Also applies to: 226-229
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/synthorg/templates/_inheritance.py` at line 8, The code currently uses
dict(child_vars) which only shallow-copies the mapping and allows nested
lists/dicts in child_vars to be shared and mutated by parent layering; change
the shallow copy to a deep copy (use copy.deepcopy(child_vars)) when preparing
the child context in the inheritance logic (replace dict(child_vars) with
copy.deepcopy(child_vars) in the places where child_vars is cloned, including
the occurrences around the inheritance layering and the block referenced at
lines ~226-229), and then wrap the resulting mapping in MappingProxyType to
enforce read-only access for downstream code; also add the necessary imports
(import copy and from types import MappingProxyType) and ensure any tests that
expect immutability still pass.
Restructure builtin templates to use extends, creating an inheritance tree that reduces duplication and shows the natural scaling path: - solo_founder -> startup -> dev_shop, product_team - research_lab -> data_team - agency, full_company, consultancy remain standalone Add department _remove support (mirroring agent _remove) so child templates can remove inherited departments. Fix workflow config propagation during inheritance merge. Add _as_parent rendering mode to preserve merge_ids when a template is rendered as a parent, and post-merge agent name deduplication for auto-generated names. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract inheritance functions into _inheritance.py to bring renderer.py under 800 lines. Extract dept merge/render helpers to keep functions under 50 lines. Add _DEPT_STRIP_KEYS constant for consistency with agent stripping. Simplify preserve_merge_id from bool|None to bool. Update merge docstring and design spec for workflow field propagation and post-merge name deduplication. Add missing docstrings. Pre-reviewed by 7 agents, 12 findings addressed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Source fixes: - Replace render_to_dict_fn: Any with Protocol type - Fix empty-name dedup to skip nameless agents - Fix _handle_dept_remove log level WARNING -> ERROR - Normalize _preserve_merge_ids underscore prefix - Add Returns section to _expand_single_agent docstring - Fix collect_parent_variables docstring wording - Refactor _append_unmatched_child_depts to return list - Fix "backwards compatibility" -> "as the default" in docstring YAML fixes: - Fix "positional" comments in product_team.yaml - Fix yamlint comment indentation in data_team.yaml Docs fixes: - Clarify workflow_config vs workflow merge semantics - Add builtin inheritance tree diagram - Fix Engineering Squad size 5-10 -> 6-10 - Update stale agent counts in guides Test fixes: - Add 7 tests for _deduplicate_merged_agent_names - Add 4 tests for workflow merge during inheritance - Add test for preserve_merge_id without extends - Add 3 tests for nameless department merge - Fix weak >= 1 assertion to specific count - Rename TestInheritanceIntegration -> TestInheritanceFullPipeline - Split full_company into own test class with behavioral check Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ion tests - Replace `assert loaded.template.extends is not None` with an explicit TemplateInheritanceError guard that survives python -O - Add TestThreeLevelInheritanceRegression: 3 tests verifying workflow config isolation, grandparent agent removal, and override chaining across the solo_founder -> startup -> dev_shop/product_team chain Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8ff1ab7 to
8aefe19
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
src/synthorg/templates/builtins/product_team.yaml (1)
103-113:⚠️ Potential issue | 🔴 CriticalAdd
merge_idtoFull-Stack Developerentries to match parent agents.This is the same issue flagged in the past review comment. The override entry (lines 104-109) and the
_removeentry (lines 111-113) lackmerge_id. Persrc/synthorg/templates/builtins/startup.yaml:68-103, the parent's Full-Stack Developers havemerge_id: "fullstack-senior"andmerge_id: "fullstack-mid".Without
merge_id:
- The override entry will be appended instead of replacing the senior agent
- The
_removeentry will fail withTemplateInheritanceError🐛 Proposed fix
# Override first Full-Stack Developer (matched by role+department): change personality - role: "Full-Stack Developer" name: "" + merge_id: "fullstack-senior" level: "senior" model: "medium" personality_preset: "communication_bridge" department: "engineering" # Remove second Full-Stack Developer (matched by role+department) - role: "Full-Stack Developer" + merge_id: "fullstack-mid" department: "engineering" _remove: true🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/synthorg/templates/builtins/product_team.yaml` around lines 103 - 113, The two Full-Stack Developer override entries are missing merge_id so they won't match parent agents; add merge_id: "fullstack-senior" to the override entry that sets personality_preset: "communication_bridge" (so it replaces the senior agent instead of appending) and add merge_id: "fullstack-mid" to the entry with _remove: true (so the removal matches the mid-level parent), keeping the rest of the fields unchanged.src/synthorg/templates/_inheritance.py (1)
232-232:⚠️ Potential issue | 🟠 MajorShallow copy allows nested mutation leakage.
dict(child_vars)only clones the top-level mapping. Ifchild_varscontains nested dicts or lists (e.g., complex variable defaults), those remain shared references and any mutation during parent rendering can leak back into the child pass.🛡️ Proposed fix
+import copy from typing import TYPE_CHECKING, Any, Protocol- result: dict[str, Any] = dict(child_vars) + result: dict[str, Any] = copy.deepcopy(child_vars)Based on learnings: "Use
copy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization) for dict/list fields."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/synthorg/templates/_inheritance.py` at line 232, Replace the shallow copy operation that creates result from child_vars with a deep copy to prevent nested mutation leakage: import the copy module and change the construction of result (currently using dict(child_vars)) to use copy.deepcopy(child_vars) so nested dicts/lists are fully cloned; ensure the copy import is added near other imports and keep the result variable type annotation (result: dict[str, Any]) intact.
🤖 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`:
- Line 351: The heading text "Builtin inheritance tree:" uses inconsistent
spelling; change it to "Built-in inheritance tree:" to match surrounding docs
and standard terminology, updating the exact string "Builtin inheritance tree:"
in the document to "Built-in inheritance tree:".
In `@src/synthorg/templates/builtins/dev_shop.yaml`:
- Around line 93-98: The two removal entries for role "Full-Stack Developer"
with department "engineering" in dev_shop.yaml are missing merge_id and
therefore won't match parent agents; update those two entries to include
merge_id: "fullstack-senior" and merge_id: "fullstack-mid" respectively so the
(role, department, merge_id) key matches the parent Full-Stack Developer agents
defined in startup.yaml.
---
Duplicate comments:
In `@src/synthorg/templates/_inheritance.py`:
- Line 232: Replace the shallow copy operation that creates result from
child_vars with a deep copy to prevent nested mutation leakage: import the copy
module and change the construction of result (currently using dict(child_vars))
to use copy.deepcopy(child_vars) so nested dicts/lists are fully cloned; ensure
the copy import is added near other imports and keep the result variable type
annotation (result: dict[str, Any]) intact.
In `@src/synthorg/templates/builtins/product_team.yaml`:
- Around line 103-113: The two Full-Stack Developer override entries are missing
merge_id so they won't match parent agents; add merge_id: "fullstack-senior" to
the override entry that sets personality_preset: "communication_bridge" (so it
replaces the senior agent instead of appending) and add merge_id:
"fullstack-mid" to the entry with _remove: true (so the removal matches the
mid-level parent), keeping the rest of the fields unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 88af95b2-dc4c-4720-945c-f4341e9cdc93
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (19)
CLAUDE.mddocs/design/organization.mddocs/guides/agents.mddocs/guides/company-config.mdsrc/synthorg/templates/_inheritance.pysrc/synthorg/templates/_render_helpers.pysrc/synthorg/templates/builtins/data_team.yamlsrc/synthorg/templates/builtins/dev_shop.yamlsrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/builtins/solo_founder.yamlsrc/synthorg/templates/builtins/startup.yamlsrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.pysrc/synthorg/templates/schema.pytests/unit/templates/conftest.pytests/unit/templates/test_builtin_inheritance.pytests/unit/templates/test_inheritance.pytests/unit/templates/test_renderer.pytests/unit/templates/test_schema.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: Build Web
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Python version requirement: Python 3.14+ with PEP 649 native lazy annotations
Nofrom __future__ import annotations-- Python 3.14 has PEP 649
Files:
src/synthorg/templates/schema.pytests/unit/templates/test_schema.pysrc/synthorg/templates/_render_helpers.pytests/unit/templates/conftest.pysrc/synthorg/templates/_inheritance.pytests/unit/templates/test_inheritance.pytests/unit/templates/test_renderer.pysrc/synthorg/templates/merge.pytests/unit/templates/test_builtin_inheritance.pysrc/synthorg/templates/renderer.py
src/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Use PEP 758 except syntax:
except A, B:(no parentheses) -- ruff enforces this on Python 3.14
Files:
src/synthorg/templates/schema.pysrc/synthorg/templates/_render_helpers.pysrc/synthorg/templates/_inheritance.pysrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Type hints required on all public functions, mypy strict mode
Docstrings in Google style, required on all public classes and functions -- enforced by ruff D rules
Every module with business logic MUST import logger viafrom synthorg.observability import get_loggerand assignlogger = get_logger(__name__)
Use constants from domain-specific modules undersynthorg.observability.eventsfor all event names (e.g.,API_REQUEST_STARTEDfromevents.api,TOOL_INVOKE_STARTfromevents.tool) -- import directly
Always use structured logging:logger.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
Use Pydantic v2 with BaseModel, model_validator, computed_field, ConfigDict
Useallow_inf_nan=Falsein all ConfigDict declarations to reject NaN/Inf in numeric fields at validation time
Use@computed_fieldfor derived values instead of storing and validating redundant fields (e.g., TokenUsage.total_tokens)
Use NotBlankStr from core.types for all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators
Prefer asyncio.TaskGroup for fan-out/fan-in parallel operations in new code (e.g., multiple tool invocations, parallel agent calls) over bare create_task
Line length: 88 characters, enforced by ruff
Functions must be less than 50 lines
Files must be less than 800 lines
Handle errors explicitly, never silently swallow errors
Validate at system boundaries: user input, external APIs, config files
Create new objects and never mutate existing ones -- immutability pattern. For non-Pydantic internal collections (registries, BaseTool), use copy.deepcopy() at construction + MappingProxyType wrapping for read-only enforcement.
For dict/list fields in frozen Pydantic models, rely on frozen=True for field reassignment prevention and copy.deepcopy() at system boundaries (tool execution, LLM pro...
Files:
src/synthorg/templates/schema.pysrc/synthorg/templates/_render_helpers.pysrc/synthorg/templates/_inheritance.pysrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.py
src/synthorg/!(observability)/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Never use
import logging/logging.getLogger()/print()in application code -- exceptions: observability/setup.py, observability/sinks.py, observability/syslog_handler.py, and observability/http_handler.py may use stdlib logging and print for handler construction and bootstrap
Files:
src/synthorg/templates/schema.pysrc/synthorg/templates/_render_helpers.pysrc/synthorg/templates/_inheritance.pysrc/synthorg/templates/merge.pysrc/synthorg/templates/renderer.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use test markers@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slowfor test organization
Prefer@pytest.mark.parametrizefor testing similar cases in test files
Never use real vendor names in test code -- use test-provider, test-small-001, etc.
Never skip, dismiss, or ignore flaky tests -- always fix them fully and fundamentally. For timing-sensitive tests, mock time.monotonic() and asyncio.sleep() to make them deterministic. For tasks that must block indefinitely until cancelled, use asyncio.Event().wait() instead of asyncio.sleep(large_number) for cancellation-safety.
Files:
tests/unit/templates/test_schema.pytests/unit/templates/conftest.pytests/unit/templates/test_inheritance.pytests/unit/templates/test_renderer.pytests/unit/templates/test_builtin_inheritance.py
🧠 Learnings (50)
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...
Applied to files:
CLAUDE.mdtests/unit/templates/test_inheritance.py
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.
Applied to files:
CLAUDE.mddocs/guides/agents.mdsrc/synthorg/templates/builtins/product_team.yamlsrc/synthorg/templates/_inheritance.pytests/unit/templates/test_inheritance.pysrc/synthorg/templates/renderer.py
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to {docs/design/operations.md,src/synthorg/providers/presets.py,.claude/**/*.{md,yml,yaml}} : Vendor names may appear only in: (1) Operations design page, (2) `.claude/` skill/agent files, (3) third-party import paths, (4) provider presets (`src/synthorg/providers/presets.py`), (5) tests using `test-provider`, `test-small-001`, etc.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/providers/**/*.py : Providers: LLM provider abstraction (LiteLLM adapter), auth types (api_key/oauth/custom_header/none), presets (PROVIDER_PRESETS), runtime CRUD (ProviderManagementService with asyncio.Lock serialization), hot-reload via AppState swap.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Settings: Runtime-editable settings persistence (DB > env > YAML > code defaults), typed definitions (9 namespaces), Fernet encryption for sensitive values, config bridge, ConfigResolver (typed composed reads for controllers), validation, registry, change notifications via message bus. Per-namespace setting definitions in definitions/ submodule (api, company, providers, memory, budget, security, coordination, observability, backup).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Web dashboard: see `web/CLAUDE.md` for commands, design system, and component inventory
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
CLAUDE.mddocs/guides/agents.md
📚 Learning: 2026-03-15T21:20:09.993Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:20:09.993Z
Learning: Applies to web/src/components/** : Vue components organized by feature (agents/, approvals/, budget/, common/, dashboard/, layout/, messages/, org-chart/, tasks/).
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to docs/design/*.md : Design spec pages: 7 pages in `docs/design/` — index, agents, organization, communication, engine, memory, operations
Applied to files:
docs/guides/agents.mddocs/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/guides/agents.mddocs/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/guides/agents.md
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Applies to src/synthorg/hr/**/*.py : HR package (hr/): hiring, firing, onboarding, offboarding, agent registry, performance tracking (task metrics, collaboration scoring, LLM calibration, collaboration overrides, trend detection), promotion/demotion (criteria evaluation, approval strategies, model mapping)
Applied to files:
src/synthorg/templates/builtins/data_team.yaml
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/budget/**/*.py : Budget tracking includes pre-flight/in-flight checks, auto-downgrade, billing periods, cost tiers, quota/subscription. CFO includes anomaly detection, efficiency analysis, downgrade recommendations.
Applied to files:
src/synthorg/templates/builtins/dev_shop.yaml
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/design/*.md : Update the relevant `docs/design/` page when approved deviations occur to reflect the new reality
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Handle errors explicitly, never silently swallow. Validate at system boundaries (user input, external APIs, config files).
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to src/synthorg/**/*.py : Handle errors explicitly, never silently swallow errors
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-20T21:44:04.528Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T21:44:04.528Z
Learning: Applies to src/synthorg/**/*.py : Use `copy.deepcopy()` at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization) for `dict`/`list` fields
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to **/*.py : Use `copy.deepcopy()` at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization) for dict/list fields in frozen Pydantic models
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to **/*.py : Use `copy.deepcopy()` at construction and `MappingProxyType` wrapping for read-only enforcement in non-Pydantic internal collections (registries, BaseTool)
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-20T21:44:04.528Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T21:44:04.528Z
Learning: Applies to src/synthorg/**/*.py : For non-Pydantic internal collections (registries, `BaseTool`), use `copy.deepcopy()` at construction and wrap with `MappingProxyType` for read-only enforcement
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to src/synthorg/**/*.py : For dict/list fields in frozen Pydantic models, rely on frozen=True for field reassignment prevention and copy.deepcopy() at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization)
Applied to files:
src/synthorg/templates/_inheritance.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 : For dict/list fields in frozen Pydantic models, rely on frozen=True for field reassignment prevention and copy.deepcopy() at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, serializing for persistence).
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-20T21:44:04.528Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T21:44:04.528Z
Learning: Applies to **/*.py : Immutability: create new objects, never mutate existing ones. For non-Pydantic internal collections (registries, BaseTool), use copy.deepcopy() at construction + MappingProxyType wrapping for read-only enforcement.
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to src/synthorg/**/*.py : Create new objects and never mutate existing ones -- immutability pattern. For non-Pydantic internal collections (registries, BaseTool), use copy.deepcopy() at construction + MappingProxyType wrapping for read-only enforcement.
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-16T23:05:29.577Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T23:05:29.577Z
Learning: Applies to **/*.py : For dict/list fields in frozen Pydantic models, rely on frozen=True for field reassignment prevention and copy.deepcopy() at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, serializing for persistence).
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to src/synthorg/**/*.py : Use frozen Pydantic models for config/identity; use separate mutable-via-copy models (model_copy(update=...)) for runtime state that evolves (e.g., agent execution state, task progress). Never mix static config fields with mutable runtime fields in one model.
Applied to files:
src/synthorg/templates/_inheritance.pysrc/synthorg/templates/renderer.py
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to src/synthorg/**/*.py : Functions must be less than 50 lines
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to {**/*.py,web/src/**/*.{ts,tsx}} : Keep functions under 50 lines and files under 800 lines
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to src/synthorg/**/*.py : Files must be less than 800 lines
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-16T07:22:28.134Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T07:22:28.134Z
Learning: Applies to **/*.py : Functions must be less than 50 lines; files must be less than 800 lines
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to src/synthorg/**/*.py : Line length: 88 characters, enforced by ruff
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-15T16:55:07.730Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T16:55:07.730Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising.
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-14T16:18:57.267Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T16:18:57.267Z
Learning: Applies to src/ai_company/!(observability)/**/*.py : All error paths must log at WARNING or ERROR with context before raising.
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising; all state transitions must log at INFO; DEBUG for object creation, internal flow, entry/exit of key functions
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-16T07:22:28.134Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T07:22:28.134Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, and key function entry/exit
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions.
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to src/**/*.py : All error paths must log at WARNING or ERROR with context before raising
Applied to files:
src/synthorg/templates/_inheritance.py
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to src/synthorg/**/*.py : Use event name constants from `synthorg.observability.events.<domain>` modules (e.g., `API_REQUEST_STARTED` from `events.api`, `TOOL_INVOKE_START` from `events.tool`); import directly and use in structured logging
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Use event constants from `synthorg.observability.events.<domain>` (e.g., `API_REQUEST_STARTED` from `events.api`); import directly and log with structured kwargs: `logger.info(EVENT, key=value)`, never interpolated strings
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability package (observability/): structured logging, correlation tracking, log sinks; event constants organized by domain under observability/events/ (e.g., events.api, events.tool, events.git, events.context_budget, events.backup)
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import `from synthorg.observability import get_logger` and define `logger = get_logger(__name__)`
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to src/synthorg/**/*.py : Use constants from domain-specific modules under `synthorg.observability.events` for all event names (e.g., `API_REQUEST_STARTED` from `events.api`, `TOOL_INVOKE_START` from `events.tool`) -- import directly
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-04-01T20:43:15.699Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T20:43:15.699Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST import logger via `from synthorg.observability import get_logger` and assign `logger = get_logger(__name__)`
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use event name constants from synthorg.observability.events domain-specific modules (e.g., PROVIDER_CALL_START from events.provider). Import directly: from synthorg.observability.events.<domain> import EVENT_CONSTANT.
Applied to files:
src/synthorg/templates/renderer.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 : Every module with business logic MUST have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Never use import logging / logging.getLogger() / print() in application code.
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/observability/**/*.py : Observability includes structured logging via `get_logger(__name__)`, correlation tracking, and log sinks.
Applied to files:
src/synthorg/templates/renderer.py
📚 Learning: 2026-03-19T11:33:01.580Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:33:01.580Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import logger via `from synthorg.observability import get_logger` and initialize with `logger = get_logger(__name__)`
Applied to files:
src/synthorg/templates/renderer.py
🪛 LanguageTool
docs/design/organization.md
[grammar] ~351-~351: Ensure spelling is correct
Context: ...d raises TemplateInheritanceError. Builtin inheritance tree: ``` solo_founder (...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (26)
src/synthorg/templates/_render_helpers.py (2)
128-150: LGTM!The
_handle_dept_removefunction correctly validates that_removeis only used withextends, logs at ERROR level before raising (per guidelines), and returns a minimal marker dict for the merge phase.
153-202: LGTM!The
build_departmentsfunction properly:
- Accepts the new
has_extendskeyword-only parameter- Short-circuits
_removeentries to skip budget/head parsing- Forwards
has_extendsto_handle_dept_removefor validationThe implementation aligns with the relevant code snippet from
renderer.py:383-395which shows the caller correctly passinghas_extends=has_extends.src/synthorg/templates/builtins/data_team.yaml (3)
21-21: LGTM on the inheritance structure and workflow configuration.The template correctly:
- Extends
research_labas per the PR objectives (solo_founder → startup → {dev_shop, product_team}; research_lab → data_team)- Sets workflow and communication at the template level
- Documents inherited agents in comments for clarity
Also applies to: 42-43, 93-97
46-48: No issues identified.The
productdepartment exists inresearch_lab.yaml(line 63), so the removal indata_team.yamlis valid and will not cause aTemplateInheritanceError.> Likely an incorrect or invalid review comment.
74-76: Remove this comment — the assumption is incorrect.The
research_lab.yamlfile does have aproductdepartment, and it includes aTechnical Writeras thehead_role(line 65 in research_lab.yaml). The removal entry in data_team.yaml will succeed in removing the inherited Technical Writer from the product department.> Likely an incorrect or invalid review comment.tests/unit/templates/conftest.py (2)
137-137: LGTM!Adding
merge_id: "fullstack-senior"to both override and remove fixtures ensures the child entries correctly match the parent'sFull-Stack Developeragent (which has the samemerge_idinsolo_founder.yaml). This aligns with the merge logic that uses(role, department, merge_id)as the matching key.Also applies to: 159-159
230-288: LGTM!The three new YAML fixtures provide comprehensive test coverage for department
_removebehavior:
CHILD_REMOVE_DEPARTMENT_YAML: Valid removal via inheritanceCHILD_REMOVE_NONEXISTENT_DEPT_YAML: Error case for non-existent parent departmentDEPT_REMOVE_WITHOUT_EXTENDS_YAML: Error case for_removewithoutextendsThese fixtures align with the validation logic in
_handle_dept_removeand_merge_departments.src/synthorg/templates/builtins/dev_shop.yaml (1)
21-21: LGTM on the overall structure and new agent definitions.The template correctly:
- Extends
startupper the PR objectives (solo_founder → startup → dev_shop)- Defines new departments (
quality_assurance,operations) with proper budget allocation- Defines a complete engineering squad with appropriate
merge_idvalues for the three Backend Developers- Uses structured model requirements where appropriate (tier/priority/min_context)
Also applies to: 44-68, 102-162
src/synthorg/templates/renderer.py (3)
116-178: LGTM on the inheritance resolution refactor.The
_render_to_dictfunction now correctly:
- Accepts
_as_parent: bool = Falseparameter (line 123)- Passes
preserve_merge_ids=_as_parentto_build_config_dict(line 162)- Delegates inheritance resolution to
resolve_inheritancewithrender_to_dict_fn=_render_to_dictcallback (lines 170-178)Per the context snippet from
_inheritance.py:174-181, parent templates are rendered with_as_parent=True, which correctly preservesmerge_idthrough multi-level inheritance chains.
346-395: LGTM on_build_config_dictchanges.The function correctly:
- Accepts
preserve_merge_ids: bool = Falseparameter (line 353)- Computes
preserve_merge = has_extends or preserve_merge_ids(line 384)- Forwards the flag to
_expand_agents(lines 385-391)- Passes
has_extendstobuild_departments(lines 392-395)The docstring properly documents the new parameter's purpose.
505-629: LGTM on agent expansion changes.Both
_expand_agentsand_expand_single_agentcorrectly:
- Accept and thread the
preserve_merge_ids/preserve_merge_idparameters- Compute
keep_merge = preserve_merge_ids or has_extends(lines 525, 624)- Retain
merge_idon agents whenkeep_merge and merge_id(line 626-627)This ensures parent agents retain their
merge_idvalues so child templates can target them during inheritance merge.src/synthorg/templates/merge.py (3)
27-27: LGTM on the new constants and workflow field handling.
_DEPT_STRIP_KEYScorrectly only includes"_remove"(departments don't havemerge_id)- Adding
"workflow"to the replace-if-present fields (line 94) fixes the workflow config propagation bug mentioned in the PR objectivesAlso applies to: 94-94
214-280: LGTM on department merge with_removesupport.The
_merge_departmentsfunction correctly:
- Skips parent departments when child has
_remove: true(lines 262-264)- Strips
_removefrom non-removal overrides (lines 267-270)- Tracks
seen_namesto detect unmatched child removals- Delegates unmatched handling to
_collect_unmatched_child_deptsThe docstring accurately documents the new raise condition.
283-311: LGTM on_collect_unmatched_child_deptshelper.The function correctly:
- Iterates unmatched child departments (not in
seen_names)- Raises
TemplateInheritanceErrorwith clear message for_removeon non-existent parents- Logs at ERROR level before raising (per guidelines)
- Strips
_removefrom appended departmentsThis mirrors the agent removal error handling in
_apply_child_agent.src/synthorg/templates/builtins/product_team.yaml (1)
22-22: LGTM on the overall structure and agent definitions.The template correctly:
- Extends
startupper the PR objectives (solo_founder → startup → product_team)- Sets
communication: "meeting_based"at the template level- Defines new departments (
design,quality_assurance,data_analytics)- Defines new agents with appropriate
merge_idvalues for Backend Developers- Uses UX roles moved to the new
designdepartmentAlso applies to: 44-93, 116-169
tests/unit/templates/test_inheritance.py (6)
13-24: LGTM on updated imports.The imports correctly align with the refactored code:
collect_parent_variablesand_deduplicate_merged_agent_namesmoved to_inheritancemoduleTemplateRenderErroradded for the new error case tests- New YAML fixtures imported for department removal testing
Also applies to: 36-40
141-178: LGTM on department_removeunit tests.Comprehensive coverage for
_merge_departments:
test_remove_matching_parent_department: Validates successful removaltest_remove_nonexistent_department_raises: Validates error for non-existent targettest_remove_stripped_from_output: Validates_removekey is not in outputtest_remove_case_insensitive: Validates case-insensitive matchingThese tests align with the implementation in
merge.py.
181-229: LGTM on integration tests for department removal.The
TestDepartmentRemoveIntegrationclass validates end-to-end behavior through the full render pipeline:
test_department_remove_via_extends: Successful removal via inheritancetest_department_remove_nonexistent_raises:TemplateInheritanceErrorfor missing parenttest_department_remove_without_extends_raises:TemplateRenderErrorwhen_removeused withoutextendsThese tests use the YAML fixtures from
conftest.pyand exercise the complete inheritance resolution path.
319-347: LGTM on workflow merge tests.Good coverage for the new workflow merge semantics:
test_workflow_child_replaces_parent: Child workflow replaces entirelytest_workflow_inherited_from_parent: Parent workflow inherited when child omitstest_workflow_deep_copy_isolation: Verifies deep-copy prevents mutation leakageThese tests validate the fix for workflow config propagation mentioned in the PR objectives.
350-438: LGTM on deduplication and nameless department tests.
TestDeduplicateMergedAgentNamescovers:
- Empty/missing agents → no-op
- Unique names unchanged
- Duplicate names get numeric suffixes
- Empty string names skipped
- Missing
namekey skipped
TestNamelessDepartmentMergevalidates edge cases:
- Parent nameless dept passes through
- Child nameless dept appended
- Both preserved
All tests correctly exercise the new helper functions.
804-816: LGTM on renamed class and tightened assertions.The rename from
TestInheritanceIntegrationtoTestInheritanceFullPipelinebetter describes the test scope. The exact count assertions (6 agents, 3 departments) replace the previous lower-bound checks, providing stricter validation of inheritance behavior.src/synthorg/templates/builtins/startup.yaml (1)
22-22: LGTM! Inheritance structure is correctly implemented.The
extends: "solo_founder"declaration and themerge_id: "fullstack-senior"override correctly leverage the(role, department, merge_id)matching key to target the parent's Full-Stack Developer for replacement. The resulting 5-agent composition aligns with the test assertions intest_builtin_inheritance.py.Also applies to: 69-76
tests/unit/templates/test_builtin_inheritance.py (1)
1-343: LGTM! Comprehensive test coverage for builtin inheritance chains.The test file properly uses
@pytest.mark.unitmarkers, leverages@pytest.mark.parametrizefor standalone templates, and includes the three-level inheritance regression tests that exercise workflow config and agent merge_id handling acrosssolo_founder -> startup -> dev_shop/product_team.src/synthorg/templates/_inheritance.py (3)
79-89: LGTM! Guard with logging before raising is correctly implemented.The explicit
ifcheck replaces the previous runtimeassert, and the structuredlogger.errorcall ensures observability for this contract-violation path even when assertions are disabled viapython -O.
28-40: LGTM! Protocol correctly matches the actual implementation.The
_RenderToDictFnprotocol signature with= ...defaults aligns with the actual_render_to_dictimplementation inrenderer.py(context snippet shows matching parameters including_as_parent: bool).
123-153: LGTM! Validation helpers follow structured logging conventions.Both
_validate_inheritance_chainbranches (circular detection and depth overflow) correctly log atERRORlevel with context before raisingTemplateInheritanceError.
| - role: "Full-Stack Developer" | ||
| department: "engineering" | ||
| _remove: true | ||
| - role: "Full-Stack Developer" | ||
| department: "engineering" | ||
| _remove: true |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify Full-Stack Developer merge_ids in startup.yaml
echo "=== Full-Stack Developer entries in startup.yaml ==="
rg -n -B1 -A6 'Full-Stack Developer' src/synthorg/templates/builtins/startup.yamlRepository: Aureliolo/synthorg
Length of output: 1015
🏁 Script executed:
cat -n src/synthorg/templates/builtins/dev_shop.yaml | sed -n '85,105p'Repository: Aureliolo/synthorg
Length of output: 767
Add merge_id to Full-Stack Developer removal entries to match parent agents.
The two Full-Stack Developer removal entries lack merge_id. Per src/synthorg/templates/builtins/startup.yaml, the parent's Full-Stack Developers have merge_id: "fullstack-senior" and merge_id: "fullstack-mid". The merge key is (role, department, merge_id), so missing merge_id defaults to "", which won't match the parent agents.
This will cause TemplateInheritanceError: no matching parent agent found.
🐛 Proposed fix
- role: "Full-Stack Developer"
+ merge_id: "fullstack-senior"
department: "engineering"
_remove: true
- role: "Full-Stack Developer"
+ merge_id: "fullstack-mid"
department: "engineering"
_remove: true📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - role: "Full-Stack Developer" | |
| department: "engineering" | |
| _remove: true | |
| - role: "Full-Stack Developer" | |
| department: "engineering" | |
| _remove: true | |
| - role: "Full-Stack Developer" | |
| merge_id: "fullstack-senior" | |
| department: "engineering" | |
| _remove: true | |
| - role: "Full-Stack Developer" | |
| merge_id: "fullstack-mid" | |
| department: "engineering" | |
| _remove: true |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/synthorg/templates/builtins/dev_shop.yaml` around lines 93 - 98, The two
removal entries for role "Full-Stack Developer" with department "engineering" in
dev_shop.yaml are missing merge_id and therefore won't match parent agents;
update those two entries to include merge_id: "fullstack-senior" and merge_id:
"fullstack-mid" respectively so the (role, department, merge_id) key matches the
parent Full-Stack Developer agents defined in startup.yaml.
- Add LGPL-2.0-or-later to license allow-list - Add per-package exemptions for compound AND licenses: charset-normalizer (MIT actual), wrapt (BSD-2-Clause actual) - Add null-license exemptions for aiohttp, cyclonedx-python-lib, fsspec, griffelib, grpcio (all verified permissive) - Update stale version pins: numpy 2.4.4, qdrant-client 1.17.1, mem0ai 1.0.9 - Fix "Builtin" -> "Built-in" spelling in organization.md
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/dependency-review.yml (1)
44-53:⚠️ Potential issue | 🟡 MinorAdd
LGPL-2.1-or-laterto the allow-licenses list.The allowlist includes
LGPL-2.1-only,LGPL-2.0-or-later, and other LGPL variants, butLGPL-2.1-or-lateris missing. This gap can block a future dependency bump that uses this standard SPDX identifier.Suggested patch
allow-licenses: >- MIT, MIT-0, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, MPL-2.0, PSF-2.0, Unlicense, 0BSD, CC0-1.0, CC-BY-3.0, CC-BY-4.0, Python-2.0, Python-2.0.1, LicenseRef-scancode-free-unknown, LicenseRef-scancode-protobuf, LicenseRef-scancode-google-patent-license-golang, ZPL-2.1, - LGPL-2.0-only, LGPL-2.0-or-later, LGPL-2.1-only, LGPL-3.0-only, LGPL-3.0-or-later, + LGPL-2.0-only, LGPL-2.0-or-later, LGPL-2.1-only, LGPL-2.1-or-later, + LGPL-3.0-only, LGPL-3.0-or-later, BlueOak-1.0.0, OFL-1.1🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/dependency-review.yml around lines 44 - 53, The allow-licenses list in the dependency-review workflow is missing the SPDX identifier "LGPL-2.1-or-later"; update the allow-licenses entry (the multi-line value under the allow-licenses key) to include "LGPL-2.1-or-later" alongside the existing LGPL variants (e.g., next to "LGPL-2.1-only" and "LGPL-2.0-or-later") so future dependency bumps using that identifier are not blocked.
🤖 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 353-363: The fenced code block showing the agent hierarchy
(starting with "solo_founder (base: 2 agents)" and the subsequent lines) lacks a
language identifier and triggers MD040; update the opening fence from ``` to
```text (or another appropriate language like ```yaml) so the block becomes
fenced with a language identifier, e.g., ```text, and leave the block contents
unchanged.
---
Outside diff comments:
In @.github/workflows/dependency-review.yml:
- Around line 44-53: The allow-licenses list in the dependency-review workflow
is missing the SPDX identifier "LGPL-2.1-or-later"; update the allow-licenses
entry (the multi-line value under the allow-licenses key) to include
"LGPL-2.1-or-later" alongside the existing LGPL variants (e.g., next to
"LGPL-2.1-only" and "LGPL-2.0-or-later") so future dependency bumps using that
identifier are not blocked.
🪄 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: 526b4221-2315-4c8e-8ba8-a389ed29a25a
📒 Files selected for processing (2)
.github/workflows/dependency-review.ymldocs/design/organization.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Sandbox
- GitHub Check: Build Web
- GitHub Check: Build Backend
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
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.
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/*.yml : Dependabot: daily updates for uv + github-actions + npm + pre-commit + docker + gomod, grouped minor/patch, no auto-merge. Use `/review-dep-pr` to review Dependabot PRs before merging.
Applied to files:
.github/workflows/dependency-review.yml
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Dependency allow-list in CI: permissive + weak-copyleft licenses, per-package GPL exemptions for dev-only tool deps (golangci-lint)
Applied to files:
.github/workflows/dependency-review.yml
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to pyproject.toml : Required runtime dependencies: `mem0ai` (default and currently only memory backend), `cryptography` (Fernet encryption), `faker` (multi-locale name generation)
Applied to files:
.github/workflows/dependency-review.yml
📚 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-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-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.
Applied to files:
docs/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-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/design/*.md : Update the relevant `docs/design/` page when approved deviations occur to reflect the new reality
Applied to files:
docs/design/organization.md
🪛 markdownlint-cli2 (0.22.0)
docs/design/organization.md
[warning] 353-353: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (1)
docs/design/organization.md (1)
383-399: Docs align with implemented inheritance semantics.
departments._remove, workflow replace/inherit behavior, and post-merge agent-name deduplication now match the current implementation and reduce ambiguity.
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 386-395: Clarify the inheritance semantics by updating the prose
to state that during Jinja2 rendering each template's workflow_config (not the
parent's raw workflow_config) is used and transformed by the renderer
(mentioning _build_workflow_dict) into a workflow dict per-template, and that at
config-merge time the workflow dict produced by the child always overrides the
parent's (so the "otherwise inherited" case for workflow does not occur in
practice); also explicitly call out that only workflow_handoffs and
escalation_paths use the "replace-if-present-else-inherit" merge rule because
they may be absent from rendered output.
🪄 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: b3875311-50df-4b62-a405-1da10085ee0c
📒 Files selected for processing (2)
.github/workflows/dependency-review.ymldocs/design/organization.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Deploy Preview
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Backend
- GitHub Check: Build Sandbox
- GitHub Check: Build Web
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
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.
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/*.yml : Dependabot: daily updates for uv + github-actions + npm + pre-commit + docker + gomod, grouped minor/patch, no auto-merge. Use `/review-dep-pr` to review Dependabot PRs before merging.
Applied to files:
.github/workflows/dependency-review.yml
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Dependency allow-list in CI: permissive + weak-copyleft licenses, per-package GPL exemptions for dev-only tool deps (golangci-lint)
Applied to files:
.github/workflows/dependency-review.yml
📚 Learning: 2026-03-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to pyproject.toml : Required runtime dependencies: `mem0ai` (default and currently only memory backend), `cryptography` (Fernet encryption), `faker` (multi-locale name generation)
Applied to files:
.github/workflows/dependency-review.yml
📚 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-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-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/design/*.md : Update the relevant `docs/design/` page when approved deviations occur to reflect the new reality
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-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.
Applied to files:
docs/design/organization.md
🔇 Additional comments (8)
.github/workflows/dependency-review.yml (4)
52-52: Allowlist expansion for LGPL variants looks correct.Adding the
-or-laterLGPL SPDX variants is consistent with the existing weak-copyleft policy and avoids unnecessary false failures.Based on learnings: Dependency allow-list in CI: permissive + weak-copyleft licenses, per-package GPL exemptions for dev-only tool deps (golangci-lint).
57-60: Manual verification notes are clear and appropriately scoped.The updated comments make the newly exempted Python packages auditable and easier to maintain.
66-75: Good documentation for compound-license edge cases.The
charset-normalizerandwraptnotes clearly explain why package-level exemptions are used.
94-104: Version-pinned package exemptions are well implemented.Keeping exemptions tied to exact package versions preserves review friction on future upgrades instead of silently allowing drift.
Based on learnings: Applies to .github/workflows/*.yml : Dependabot: daily updates for uv + github-actions + npm + pre-commit + docker + gomod, grouped minor/patch, no auto-merge. Use
/review-dep-prto review Dependabot PRs before merging.docs/design/organization.md (4)
351-363: LGTM: Inheritance tree documentation is clear and complete.The built-in inheritance tree structure is well-documented and matches the PR objectives. The previous spelling and markdown linting issues have been resolved (correct "Built-in" spelling and
textlanguage identifier on the code block).
383-383: LGTM: Department _remove documentation is clear.The addition clearly documents the department removal feature and maintains consistency with the agent
_removepattern shown earlier in the document.
397-399: LGTM: Agent name deduplication is clearly documented.The post-merge deduplication behavior is clearly explained with a concrete example format. This accurately reflects the PR objective to add name deduplication for auto-generated names.
16-16: No changes needed—the Engineering Squad size range is accurate.The size range of
6-10correctly matches the actualdev_shop.yamlbuiltin template, which definesmin_agents: 6andmax_agents: 10. The 8 agents in the template definition represent the standard configuration, while the range allows flexibility for customization.
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 403-405: The documentation example shows deduplication as "Kenji
Matsuda 2" but the actual implementation in
src/synthorg/templates/_inheritance.py appends an underscore before the numeric
suffix (e.g., "Kenji Matsuda_2"); update docs/design/organization.md to reflect
the real format by changing the example to use the underscore-suffixed form and
ensure any explanatory text mentions the underscore convention used by the
deduplication logic in _inheritance.py.
🪄 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: c0eef18c-b9e5-4c57-98f1-3bb6accf4bec
📒 Files selected for processing (1)
docs/design/organization.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Sandbox
- GitHub Check: Build Web
- GitHub Check: Build Backend
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (3)
📚 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-31T14:17:24.182Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T14:17:24.182Z
Learning: Applies to docs/design/*.md : Update the relevant `docs/design/` page when approved deviations occur to reflect the new reality
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
🔇 Additional comments (4)
docs/design/organization.md (4)
16-16: Looks good: updated Engineering Squad sizing is consistent with the inheritance restructure context.
351-364: Built-in inheritance tree section is clear and correctly scoped.
This matches the documented parent→child template relationships and standalone templates.
383-383: Department_removesemantics are documented correctly.
This line is aligned with merge behavior for department removal.
386-401: Workflow inheritance/merge semantics are now well clarified and implementation-aligned.
The distinction between render-timeworkflow_confighandling and merge-time replacement behavior is accurate.
| After merging, agent names are deduplicated: if parent and child auto-generation | ||
| produces the same name, later occurrences receive a numeric suffix (e.g., | ||
| ``"Kenji Matsuda 2"``). |
There was a problem hiding this comment.
Fix deduplication example format to match actual suffixing behavior.
The example says Kenji Matsuda 2, but implementation suffixes with an underscore (Kenji Matsuda_2) in src/synthorg/templates/_inheritance.py.
Suggested doc fix
-``"Kenji Matsuda 2"``).
+``"Kenji Matsuda_2"``).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/design/organization.md` around lines 403 - 405, The documentation
example shows deduplication as "Kenji Matsuda 2" but the actual implementation
in src/synthorg/templates/_inheritance.py appends an underscore before the
numeric suffix (e.g., "Kenji Matsuda_2"); update docs/design/organization.md to
reflect the real format by changing the example to use the underscore-suffixed
form and ensure any explanatory text mentions the underscore convention used by
the deduplication logic in _inheritance.py.
🤖 I have created a release *beep* *boop* --- ## [0.5.6](v0.5.5...v0.5.6) (2026-04-02) ### Features * calendar + hybrid ceremony scheduling strategies ([#985](#985)) ([59a9b84](59a9b84)), closes [#969](#969) [#970](#970) * landing page interactive components ([#984](#984)) ([49868cb](49868cb)) * log aggregation and shipping (syslog, HTTP, compression) ([#964](#964)) ([84be9f8](84be9f8)) * restructure builtin templates into inheritance tree ([#982](#982)) ([3794c12](3794c12)) * sprint ceremony runtime scheduler with pluggable strategies ([#983](#983)) ([43564a9](43564a9)) ### Maintenance * add no-bash-file-writes rule to CLAUDE.md ([#968](#968)) ([a854dcc](a854dcc)) * bump web dependencies (lodash, eslint-react v4, storybook, playwright, esbuild, codemirror) ([#987](#987)) ([c344dfb](c344dfb)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
solo_founder -> startup -> dev_shop, product_teamandresearch_lab -> data_team; agency, full_company, consultancy remain standalone_removesupport (mirroring agent_remove) so child templates can remove inherited departments_as_parentrendering mode to preservemerge_idwhen a template is rendered as a parent_inheritance.pyto keeprenderer.pyunder 800 linesTest plan
uv run python -m pytest tests/unit/templates/ -n auto -v-- 459 tests covering all inheritance chains, dept _remove, standalone templatesuv run ruff check src/ tests/-- passesuv run mypy src/ tests/-- passesPre-reviewed by 7 agents, 12 findings addressed
Closes #725
🤖 Generated with Claude Code