Skip to content

feat: improve template metadata -- skill taxonomy, descriptions, tags, and display names#752

Merged
Aureliolo merged 4 commits intomainfrom
feat/implement-698
Mar 22, 2026
Merged

feat: improve template metadata -- skill taxonomy, descriptions, tags, and display names#752
Aureliolo merged 4 commits intomainfrom
feat/implement-698

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

  • Add SkillPattern enum (tool_wrapper, generator, reviewer, inversion, pipeline) based on Google Cloud's five-pattern taxonomy for agent collaboration
  • Classify all 7 builtin templates by which skill patterns their agents use
  • Rewrite template descriptions from vague one-liners to informative 2-3 sentence summaries
  • Expand tags with capability-specific values (ci-cd, code-review, user-research, data-pipeline, etc.)
  • Update display names for clarity: Solo Founder -> Solo Builder, Dev Shop -> Engineering Squad, Product Team -> Product Studio, Full Company -> Enterprise Org
  • Surface tags and skill_patterns through TemplateInfo, REST API (TemplateInfoResponse), and TypeScript interface
  • Add SkillPattern uniqueness validator on TemplateMetadata
  • Add TypeScript SkillPattern union type for type-safe frontend usage
  • Update design spec with Skill Pattern Taxonomy section and fix pre-existing display name discrepancies in communication.md and operations.md

Test plan

  • TestBuiltinSkillPatterns: 4 tests verifying all builtins have non-empty valid patterns, matrix covers all builtins, and expected patterns match
  • TestTemplateMetadata: skill_patterns defaults to (), round-trips with enum values, duplicate patterns rejected
  • TestLoadTemplateFile: invalid skill pattern in YAML raises TemplateValidationError
  • TestSetupTemplates: API response includes tags and skill_patterns fields
  • All 1187 source files pass mypy strict
  • All unit tests pass (336 template + setup tests, full suite green)
  • Pre-reviewed by 7 agents, 8 findings addressed

Closes #698

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 22, 2026

Dependency Review

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

Scanned Files

None

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e0419097-ddfd-4c6f-add5-11feb35d67aa

📥 Commits

Reviewing files that changed from the base of the PR and between 5bdd2bf and dadaa42.

📒 Files selected for processing (2)
  • tests/unit/api/controllers/test_setup.py
  • tests/unit/core/test_enums.py
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test (Python 3.14)
  • GitHub Check: Build Web
  • GitHub Check: Build Sandbox
  • GitHub Check: Build Backend
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.py: No from __future__ import annotations -- Python 3.14 has PEP 649 native lazy annotations.
Use PEP 758 except syntax: except A, B: (no parentheses) -- ruff enforces this on Python 3.14.
Type hints: all public functions, mypy strict mode.
Docstrings: Google style, required on public classes/functions (enforced by ruff D rules).
Immutability: create new objects, never mutate existing ones. For non-Pydantic internal collections, use copy.deepcopy() at construction + MappingProxyType wrapping for read-only enforcement. For dict/list fields in frozen Pydantic models, rely on frozen=True and copy.deepcopy() at system boundaries.
Config vs runtime state: frozen Pydantic models for config/identity; separate mutable-via-copy models for runtime state that evolves. Never mix static config fields with mutable runtime fields.
Models: Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict). Use @computed_field for derived values. Use NotBlankStr for all identifier/name fields instead of manual whitespace validators.
Async concurrency: prefer asyncio.TaskGroup for fan-out/fan-in parallel operations in new code. Prefer structured concurrency over bare create_task.
Line length: 88 characters (ruff).
Functions: < 50 lines, files < 800 lines.
Errors: handle explicitly, never silently swallow.
Validate: at system boundaries (user input, external APIs, config files).
Variable name: always logger (not _logger, not log).

Files:

  • tests/unit/core/test_enums.py
  • tests/unit/api/controllers/test_setup.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.py: Markers: @pytest.mark.unit, @pytest.mark.integration, @pytest.mark.e2e, @pytest.mark.slow
Parametrize: Prefer @pytest.mark.parametrize for testing similar cases.
Tests must use test-provider, test-small-001, etc. for vendor-agnostic test code.
Property-based testing: Python uses Hypothesis (@given + @settings). Hypothesis profiles: ci (50 examples, default) and dev (1000 examples), controlled via HYPOTHESIS_PROFILE env var.
Flaky tests: NEVER skip, dismiss, or ignore -- 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).

Files:

  • tests/unit/core/test_enums.py
  • tests/unit/api/controllers/test_setup.py
🧬 Code graph analysis (1)
tests/unit/core/test_enums.py (1)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
🔇 Additional comments (2)
tests/unit/api/controllers/test_setup.py (1)

49-52: Consider adding element-level assertions for stronger API contract validation.

The current assertions verify presence and list type, but the previous review suggested additional checks to catch serialization regressions:

             assert "tags" in template
             assert isinstance(template["tags"], list)
+            assert all(isinstance(tag, str) for tag in template["tags"])
             assert "skill_patterns" in template
             assert isinstance(template["skill_patterns"], list)
+            assert set(template["skill_patterns"]).issubset(
+                {"tool_wrapper", "generator", "reviewer", "inversion", "pipeline"}
+            )
tests/unit/core/test_enums.py (1)

104-115: LGTM!

The SkillPattern enum tests are well-structured. The cardinality check combined with the set comparison for values provides good coverage against both additions/removals and accidental renames. The expected values align with the TypeScript SkillPattern union type in web/src/api/types.ts.


Walkthrough

Added a SkillPattern taxonomy and exported enum with five members (tool_wrapper, generator, reviewer, inversion, pipeline). Template metadata was extended with skill_patterns and tags, multiple built-in templates were renamed (e.g., Solo Founder→Solo Builder, Dev Shop→Engineering Squad, Full Company→Enterprise Org, Product Team→Product Studio) and given expanded descriptions. Loader, schema, and template models were updated to include and validate skill_patterns. The setup API and TypeScript response types now return tags and skill_patterns. Unit tests were updated accordingly.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.71% which is insufficient. The required threshold is 40.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: introducing a skill taxonomy, improving template descriptions, expanding tags, and updating display names—all of which are central to the PR.
Description check ✅ Passed The description clearly relates to the changeset, detailing the skill pattern enum, template reclassification, rewrites, tag expansion, display name updates, and API surface changes.
Linked Issues check ✅ Passed All major coding requirements from issue #698 are met: SkillPattern enum with five values is defined [enums.py], all 7 builtin templates are classified [all YAML files], descriptions are rewritten to 2-3 sentences, tags are expanded with capability-specific values, display names updated (Solo Founder→Solo Builder, Dev Shop→Engineering Squad, Product Team→Product Studio, Full Company→Enterprise Org), and SkillPattern validation is implemented [schema.py].
Out of Scope Changes check ✅ Passed The changes include some extensions beyond the core scope: adding optional nullable ID fields (subordinate_id, supervisor_id, head_id) to TypeScript and Python models, and updating docstrings in company.py regarding identity key and role name descriptions. These are minor enhancements aligned with the metadata improvement goals but not explicitly listed in issue #698.

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


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

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the metadata associated with company templates, providing richer and more structured information. By introducing a skill pattern taxonomy, updating descriptions, expanding tags, and clarifying display names, the changes aim to improve the discoverability, understanding, and classification of templates for users and internal systems. The modifications are propagated through the API and frontend, ensuring consistency across the platform and laying groundwork for more sophisticated template management.

Highlights

  • Skill Pattern Taxonomy: Introduced a SkillPattern enum to categorize agent interaction patterns based on Google Cloud's five-pattern taxonomy, including Tool Wrapper, Generator, Reviewer, Inversion, and Pipeline.
  • Enhanced Template Metadata: Updated all seven built-in templates with new, more descriptive summaries, expanded capability-specific tags, and assigned relevant skill_patterns.
  • Template Display Name Clarity: Renamed several built-in templates for improved clarity and consistency (e.g., "Solo Founder" to "Solo Builder", "Dev Shop" to "Engineering Squad", "Product Team" to "Product Studio", and "Full Company" to "Enterprise Org").
  • API and Frontend Integration: Integrated tags and skill_patterns into the TemplateInfo data structure, REST API responses, and the TypeScript frontend interface, ensuring metadata is surfaced across the platform.
  • Metadata Validation: Implemented validation logic to ensure the uniqueness of skill_patterns within template metadata, preventing redundant entries.
  • Documentation Updates: Updated design documentation to reflect the new template display names and introduced a dedicated "Skill Pattern Taxonomy" section for comprehensive understanding.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

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

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

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

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

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@src/synthorg/templates/builtins/dev_shop.yaml`:
- Around line 3-7: The YAML "description" field is too verbose; rewrite the
description in src/synthorg/templates/builtins/dev_shop.yaml to 2–3 sentences
only, preserving key facts (lean engineering team led by a Software Architect,
core roles: three backend developers, frontend specialist, QA pipeline, DevOps
engineer, and focus on throughput with quality gates). Replace the existing
multi-sentence paragraph under the description key with a concise 2–3 sentence
summary that bundles roles and purpose into one or two combined sentences and
ends with the optimization/quality intent.
- Line 2: The template's display name was changed to "Engineering Squad" but the
default metadata field company_name still reads "Dev Shop"; update the
company_name default in the YAML (and any other occurrences of "Dev Shop" in the
same template) to "Engineering Squad" so default metadata matches the name field
(check the name: "Engineering Squad" and company_name keys in the template and
make them consistent).
🪄 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: f1a93d82-b60b-43a4-8ac2-bd8c635f70b4

📥 Commits

Reviewing files that changed from the base of the PR and between b7dd7de and 9e7c753.

📒 Files selected for processing (20)
  • docs/design/communication.md
  • docs/design/operations.md
  • docs/design/organization.md
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/core/__init__.py
  • src/synthorg/core/enums.py
  • src/synthorg/templates/builtins/agency.yaml
  • src/synthorg/templates/builtins/dev_shop.yaml
  • src/synthorg/templates/builtins/full_company.yaml
  • src/synthorg/templates/builtins/product_team.yaml
  • src/synthorg/templates/builtins/research_lab.yaml
  • src/synthorg/templates/builtins/solo_founder.yaml
  • src/synthorg/templates/builtins/startup.yaml
  • src/synthorg/templates/loader.py
  • src/synthorg/templates/schema.py
  • tests/unit/api/controllers/test_setup.py
  • tests/unit/templates/test_loader.py
  • tests/unit/templates/test_schema.py
  • web/src/api/types.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test (Python 3.14)
  • GitHub Check: Build Web
  • GitHub Check: Build Sandbox
  • GitHub Check: Build Backend
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.py: No from __future__ import annotations -- Python 3.14 has PEP 649 native lazy annotations.
Use PEP 758 except syntax: except A, B: (no parentheses) -- ruff enforces this on Python 3.14.
Type hints: all public functions, mypy strict mode.
Docstrings: Google style, required on public classes/functions (enforced by ruff D rules).
Immutability: create new objects, never mutate existing ones. For non-Pydantic internal collections, use copy.deepcopy() at construction + MappingProxyType wrapping for read-only enforcement. For dict/list fields in frozen Pydantic models, rely on frozen=True and copy.deepcopy() at system boundaries.
Config vs runtime state: frozen Pydantic models for config/identity; separate mutable-via-copy models for runtime state that evolves. Never mix static config fields with mutable runtime fields.
Models: Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict). Use @computed_field for derived values. Use NotBlankStr for all identifier/name fields instead of manual whitespace validators.
Async concurrency: prefer asyncio.TaskGroup for fan-out/fan-in parallel operations in new code. Prefer structured concurrency over bare create_task.
Line length: 88 characters (ruff).
Functions: < 50 lines, files < 800 lines.
Errors: handle explicitly, never silently swallow.
Validate: at system boundaries (user input, external APIs, config files).
Variable name: always logger (not _logger, not log).

Files:

  • tests/unit/api/controllers/test_setup.py
  • src/synthorg/core/__init__.py
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/core/enums.py
  • tests/unit/templates/test_schema.py
  • src/synthorg/templates/loader.py
  • src/synthorg/templates/schema.py
  • src/synthorg/api/controllers/setup_models.py
  • tests/unit/templates/test_loader.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.py: Markers: @pytest.mark.unit, @pytest.mark.integration, @pytest.mark.e2e, @pytest.mark.slow
Parametrize: Prefer @pytest.mark.parametrize for testing similar cases.
Tests must use test-provider, test-small-001, etc. for vendor-agnostic test code.
Property-based testing: Python uses Hypothesis (@given + @settings). Hypothesis profiles: ci (50 examples, default) and dev (1000 examples), controlled via HYPOTHESIS_PROFILE env var.
Flaky tests: NEVER skip, dismiss, or ignore -- 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).

Files:

  • tests/unit/api/controllers/test_setup.py
  • tests/unit/templates/test_schema.py
  • tests/unit/templates/test_loader.py
src/synthorg/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/synthorg/**/*.py: Every module with business logic MUST have: from synthorg.observability import get_logger then logger = get_logger(__name__)
Event names: always use constants from domain-specific modules under synthorg.observability.events (e.g., API_REQUEST_STARTED from events.api). Import directly: from synthorg.observability.events.<domain> import EVENT_CONSTANT
Structured kwargs: always logger.info(EVENT, key=value) -- never logger.info("msg %s", val)
All error paths must log at WARNING or ERROR with context before raising.
All state transitions must log at INFO.
DEBUG for object creation, internal flow, entry/exit of key functions.
Vendor-agnostic everywhere: NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names: example-provider, example-large-001, example-medium-001, example-small-001, large/medium/small as aliases.
Pure data models, enums, and re-exports do NOT need logging.
Use NotBlankStr from core.types for all identifier/name fields -- including optional (NotBlankStr | None) and tuple variants -- instead of manual whitespace validators.

Files:

  • src/synthorg/core/__init__.py
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/core/enums.py
  • src/synthorg/templates/loader.py
  • src/synthorg/templates/schema.py
  • src/synthorg/api/controllers/setup_models.py
src/synthorg/!(observability)/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Never use import logging / logging.getLogger() / print() in application code (exception: observability/setup.py and observability/sinks.py may use stdlib logging and print for bootstrap).

Files:

  • src/synthorg/core/__init__.py
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/core/enums.py
  • src/synthorg/templates/loader.py
  • src/synthorg/templates/schema.py
  • src/synthorg/api/controllers/setup_models.py
🧠 Learnings (20)
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.

Applied to files:

  • docs/design/communication.md
  • docs/design/operations.md
  • src/synthorg/api/controllers/setup.py
  • docs/design/organization.md
  • src/synthorg/templates/loader.py
  • src/synthorg/templates/builtins/full_company.yaml
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...

Applied to files:

  • src/synthorg/core/__init__.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/core/**/*.py : Core module must contain shared domain models, base classes, resilience config (RetryConfig, RateLimiterConfig)

Applied to files:

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

Applied to files:

  • src/synthorg/core/__init__.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/core/__init__.py
📚 Learning: 2026-03-22T19:37:56.694Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T19:37:56.694Z
Learning: Applies to src/synthorg/**/*.py : Event names: always use constants from domain-specific modules under `synthorg.observability.events` (e.g., `API_REQUEST_STARTED` from `events.api`). Import directly: `from synthorg.observability.events.<domain> import EVENT_CONSTANT`

Applied to files:

  • src/synthorg/core/__init__.py
📚 Learning: 2026-03-22T19:37:56.694Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T19:37:56.694Z
Learning: Applies to src/synthorg/**/*.py : Use `NotBlankStr` from `core.types` for all identifier/name fields -- including optional (`NotBlankStr | None`) and tuple variants -- instead of manual whitespace validators.

Applied to files:

  • src/synthorg/core/__init__.py
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Always use event name constants from domain-specific modules under `synthorg.observability.events` (e.g., `PROVIDER_CALL_START` from `events.provider`); import directly: `from synthorg.observability.events.<domain> import EVENT_CONSTANT`

Applied to files:

  • src/synthorg/core/__init__.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 BaseModel, model_validator, computed_field, ConfigDict.

Applied to files:

  • tests/unit/templates/test_schema.py
  • src/synthorg/templates/schema.py
  • src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T18:42:17.990Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:42:17.990Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`

Applied to files:

  • tests/unit/templates/test_schema.py
  • src/synthorg/templates/schema.py
  • src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. For derived values use `computed_field` instead of storing + validating redundant fields. Use `NotBlankStr` (from `core.types`) for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.

Applied to files:

  • src/synthorg/templates/schema.py
  • src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-17T11:41:02.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T11:41:02.964Z
Learning: Applies to src/**/*.py : Models: Pydantic v2 (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values instead of storing + validating redundant fields. Use `NotBlankStr` for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.

Applied to files:

  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-22T19:37:56.694Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T19:37:56.694Z
Learning: Applies to **/*.py : Models: Pydantic v2 (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values. Use `NotBlankStr` for all identifier/name fields instead of manual whitespace validators.

Applied to files:

  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 with adopted conventions: use computed_field for derived values instead of storing + validating redundant fields; use NotBlankStr from core.types for all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.

Applied to files:

  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to **/*.py : Models: Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict). Use computed_field for derived values instead of storing + validating redundant fields. Use NotBlankStr (from core.types) for all identifier/name fields — including optional (NotBlankStr | None) and tuple (tuple[NotBlankStr, ...]) variants — instead of manual whitespace validators.

Applied to files:

  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Use frozen Pydantic models for config/identity; separate mutable-via-copy models (using `model_copy(update=...)`) for runtime state

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use frozen Pydantic models for config/identity; use separate mutable-via-copy models (using model_copy(update=...)) for runtime state that evolves. Never mix static config fields with mutable runtime fields in one model.

Applied to files:

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

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-22T19:37:56.694Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T19:37:56.694Z
Learning: Applies to src/synthorg/**/*.py : Vendor-agnostic everywhere: NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names: `example-provider`, `example-large-001`, `example-medium-001`, `example-small-001`, `large`/`medium`/`small` as aliases.

Applied to files:

  • src/synthorg/templates/builtins/full_company.yaml
🧬 Code graph analysis (6)
src/synthorg/core/__init__.py (2)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
src/synthorg/core/enums.py (1)
  • SkillPattern (175-198)
src/synthorg/core/enums.py (1)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
tests/unit/templates/test_schema.py (2)
src/synthorg/core/enums.py (2)
  • CompanyType (148-158)
  • SkillPattern (175-198)
src/synthorg/templates/schema.py (1)
  • TemplateMetadata (199-254)
web/src/api/types.ts (2)
src/synthorg/core/enums.py (1)
  • SkillPattern (175-198)
src/synthorg/api/controllers/setup_models.py (1)
  • TemplateInfoResponse (36-61)
src/synthorg/templates/schema.py (2)
src/synthorg/core/enums.py (1)
  • SkillPattern (175-198)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
tests/unit/templates/test_loader.py (4)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
src/synthorg/core/enums.py (1)
  • SkillPattern (175-198)
src/synthorg/templates/loader.py (2)
  • load_template (169-225)
  • load_template_file (228-249)
tests/unit/templates/conftest.py (2)
  • tmp_template_file (217-225)
  • TemplateFileFactory (12-15)
🔇 Additional comments (36)
src/synthorg/core/enums.py (1)

175-198: LGTM!

The SkillPattern enum is well-documented with a clear taxonomy description and per-member docstrings. The string values align with the TypeScript union type in web/src/api/types.ts (lines 846-851), ensuring API consistency.

src/synthorg/core/__init__.py (1)

51-51: LGTM!

The SkillPattern import is correctly added and re-exported via __all__, maintaining alphabetical ordering.

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

226-254: LGTM!

The tags and skill_patterns fields are correctly implemented:

  • Immutable tuple types appropriate for a frozen model
  • NotBlankStr used for tags per coding guidelines
  • Duplicate skill_patterns validator logs before raising and produces deterministic sorted output
docs/design/operations.md (1)

846-847: LGTM!

Documentation correctly updated to reflect the renamed template display names (Solo Founder → Solo Builder, Full Company → Enterprise Org), aligning with the PR objectives.

tests/unit/api/controllers/test_setup.py (1)

49-50: LGTM!

Test correctly extended to verify that the /api/v1/setup/templates response includes the new tags and skill_patterns fields, aligning with the TemplateInfoResponse model updates.

docs/design/communication.md (1)

89-90: LGTM!

Documentation correctly updated to reflect the renamed template display names, maintaining consistency with docs/design/operations.md and the PR objectives.

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

205-206: LGTM!

The controller correctly passes the tags and skill_patterns fields from the TemplateInfo object to the TemplateInfoResponse, completing the API surface exposure of the new metadata.

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

3-21: LGTM!

The template metadata is well-updated:

  • Description rewritten as a concise 2-3 sentence summary per PR objectives
  • Tags expanded with capability-specific values (agile, iterative, lean)
  • skill_patterns values (tool_wrapper, generator, pipeline) are valid SkillPattern enum members
tests/unit/templates/test_schema.py (4)

8-8: LGTM!

Import correctly includes SkillPattern from synthorg.core.enums to support the new skill pattern tests.


201-201: LGTM!

Properly asserts the default empty tuple for skill_patterns in the minimal case.


212-222: LGTM!

Good coverage of the full case with multiple skill patterns. The assertion correctly verifies that the stored tuple matches the input.


241-250: LGTM!

Properly tests the uniqueness validator by passing duplicate PIPELINE entries and asserting the expected validation error message.

web/src/api/types.ts (2)

847-852: LGTM!

The SkillPattern union type correctly mirrors the backend SkillPattern enum values, providing frontend type safety.


859-860: LGTM!

The tags and skill_patterns fields correctly use readonly arrays for immutability, and skill_patterns uses the SkillPattern type for compile-time validation.

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

3-7: LGTM!

Clear, informative description that explains the template's distinctive approach: structured inquiry before data work, with peer-reviewed output.


14-20: LGTM!

Tags and skill patterns are well-chosen. The patterns (inversion, generator, reviewer) correctly reflect the research workflow: defining questions first (inversion), producing structured artifacts (generator), and peer review before publication (reviewer).

src/synthorg/templates/loader.py (5)

71-80: LGTM!

TemplateInfo dataclass correctly extended with tags and skill_patterns fields, both defaulting to empty tuples. Docstring properly documents the new attributes.


122-123: LGTM!

Correctly populates tags and skill_patterns from template metadata. The skill_patterns are properly converted from enum values to strings via sp.value.


149-150: LGTM!

Consistent with the builtin template handling — user templates also populate tags and skill_patterns from metadata.


441-441: LGTM!

Correctly extracts skill_patterns from YAML data during normalization, defaulting to an empty tuple when absent.


486-486: LGTM!

Correctly uses PEP 758 except syntax (except TypeError, ValueError: without parentheses) as per coding guidelines.

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

44-48: LGTM!

Docstring properly documents the new attributes, and adding extra="forbid" to ConfigDict tightens response validation to reject unexpected fields.


54-61: LGTM!

Fields correctly typed as tuple[str, ...] for JSON serialization. Using string tuples rather than the enum type is appropriate for the API response layer since the loader already converts SkillPattern values to strings.

docs/design/organization.md (2)

14-21: LGTM!

Template table correctly updated with renamed display names. The use cases and operational configurations remain consistent with the template archetypes.


26-54: LGTM!

Excellent documentation of the skill pattern taxonomy. The section clearly explains each pattern's purpose and documents which patterns each template exhibits. The composability explanation helps users understand how patterns can be combined.

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

2-7: LGTM!

Template renamed to "Solo Builder" with a clear description explaining the lean, two-agent, event-driven setup with full autonomy.


14-18: LGTM!

Tags appropriately updated, and the single tool_wrapper skill pattern is correct for this minimal template where agents self-direct using specialized context.

tests/unit/templates/test_loader.py (5)

9-9: LGTM!

Import of SkillPattern enum correctly added for the new skill pattern validation tests.


152-157: LGTM!

Assertions correctly updated to expect "Solo Builder" instead of "Solo Founder" to match the renamed template.


182-183: LGTM!

Comment correctly updated to clarify that the user template has "Test Template" name, not "Solo Builder".


237-255: LGTM!

Good test coverage for invalid skill pattern rejection. The test correctly uses an invalid pattern value and asserts TemplateValidationError is raised during loading.


417-483: LGTM!

Comprehensive test suite for builtin skill patterns. The tests are well-structured:

  • Coverage check ensures all builtins are tested
  • Validation that all builtins declare at least one pattern
  • Validation that all pattern values are valid enum members
  • Order-insensitive pattern matching using set comparison (line 482-483)
src/synthorg/templates/builtins/dev_shop.yaml (1)

13-20: Tag and skill-pattern classification looks consistent.

The added tags and skill_patterns are coherent with the taxonomy and improve discoverability.

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

3-21: Metadata update is clear and taxonomy-aligned.

Description, expanded tags, and skill_patterns are consistent and improve template filtering/intent clarity.

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

2-23: Enterprise metadata changes are internally consistent.

The new name, expanded tags, and full five-pattern classification are coherent and match the taxonomy intent.

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

2-21: Product template metadata update looks solid.

The rename, rewritten description, capability tags, and pattern mapping are consistent and well-scoped.

Comment on lines +3 to +7
description: >-
A lean engineering team built for shipping. No C-suite overhead
-- a Software Architect leads directly. Three backend developers,
a frontend specialist, QA pipeline, and a DevOps engineer.
Optimized for throughput with quality gates.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Condense this to 2–3 sentences to match the metadata standard.

This description currently reads as 4 sentences, which misses the PR objective for concise 2–3 sentence summaries.

🤖 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 3 - 7, The YAML
"description" field is too verbose; rewrite the description in
src/synthorg/templates/builtins/dev_shop.yaml to 2–3 sentences only, preserving
key facts (lean engineering team led by a Software Architect, core roles: three
backend developers, frontend specialist, QA pipeline, DevOps engineer, and focus
on throughput with quality gates). Replace the existing multi-sentence paragraph
under the description key with a concise 2–3 sentence summary that bundles roles
and purpose into one or two combined sentences and ends with the
optimization/quality intent.

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a SkillPattern taxonomy to provide richer metadata for company templates. The changes are comprehensive, updating documentation, backend models and logic, API responses, and frontend types. The implementation is of high quality, with thorough test coverage for the new functionality. My review includes a couple of minor suggestions to improve the clarity of the documentation and the maintainability of the test data.

| **Engineering Squad** | Pipeline, Reviewer, Tool Wrapper |
| **Product Studio** | Inversion, Pipeline, Reviewer |
| **Agency** | Pipeline, Generator, Reviewer |
| **Enterprise Org** | All five |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

For consistency with the other rows in this table, it would be clearer to explicitly list all five skill patterns instead of using the text "All five". This makes the table easier to scan and understand without cross-referencing the taxonomy definition table above.

Suggested change
| **Enterprise Org** | All five |
| **Enterprise Org** | Tool Wrapper, Generator, Reviewer, Inversion, Pipeline |

Comment on lines +426 to +452
_EXPECTED_PATTERNS: ClassVar[list[tuple[str, tuple[str, ...]]]] = [
("solo_founder", ("tool_wrapper",)),
("startup", ("tool_wrapper", "generator", "pipeline")),
(
"dev_shop",
("pipeline", "reviewer", "tool_wrapper"),
),
(
"product_team",
("inversion", "pipeline", "reviewer"),
),
("agency", ("pipeline", "generator", "reviewer")),
(
"full_company",
(
"tool_wrapper",
"generator",
"reviewer",
"inversion",
"pipeline",
),
),
(
"research_lab",
("inversion", "generator", "reviewer"),
),
]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

For better readability and consistency in the test data, consider sorting the skill patterns alphabetically within each tuple in _EXPECTED_PATTERNS. While the test correctly uses sets for comparison, making the order irrelevant for correctness, sorted test data is easier to maintain and visually inspect for differences.

    _EXPECTED_PATTERNS: ClassVar[list[tuple[str, tuple[str, ...]]]] = [
        ("solo_founder", ("tool_wrapper",)),
        ("startup", ("generator", "pipeline", "tool_wrapper")),
        (
            "dev_shop",
            ("pipeline", "reviewer", "tool_wrapper"),
        ),
        (
            "product_team",
            ("inversion", "pipeline", "reviewer"),
        ),
        ("agency", ("generator", "pipeline", "reviewer")),
        (
            "full_company",
            (
                "generator",
                "inversion",
                "pipeline",
                "reviewer",
                "tool_wrapper",
            ),
        ),
        (
            "research_lab",
            ("generator", "inversion", "reviewer"),
        ),
    ]

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.31%. Comparing base (118235b) to head (dadaa42).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #752      +/-   ##
==========================================
+ Coverage   92.29%   92.31%   +0.01%     
==========================================
  Files         573      573              
  Lines       29704    29727      +23     
  Branches     2879     2881       +2     
==========================================
+ Hits        27414    27441      +27     
+ Misses       1810     1806       -4     
  Partials      480      480              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Aureliolo and others added 3 commits March 22, 2026 22:44
…, and display names

Add SkillPattern enum (tool_wrapper, generator, reviewer, inversion,
pipeline) based on Google Cloud's five-pattern taxonomy for agent
collaboration. Each builtin template is classified by which patterns
its agents use.

Rewrite template descriptions from vague one-liners to informative
2-3 sentence summaries explaining what makes each template distinct.
Expand tags with capability-specific values (ci-cd, code-review,
user-research, etc.) beyond generic categorization.

Update display names for clarity: Solo Founder -> Solo Builder,
Dev Shop -> Engineering Squad, Product Team -> Product Studio,
Full Company -> Enterprise Org.

Surface tags and skill_patterns through TemplateInfo, the REST API
(TemplateInfoResponse), and the TypeScript interface for the web
dashboard.

Closes #698

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Fix stale display names in communication.md and operations.md.
Add SkillPattern uniqueness validator to TemplateMetadata. Add
TypeScript SkillPattern union type for type-safe frontend usage.
Use set comparison in test_expected_patterns to avoid order
sensitivity. Add test for invalid skill_patterns rejection.
Add extra="forbid" to TemplateInfoResponse. Fix stale test comment.

Pre-reviewed by 7 agents, 8 findings addressed.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…mini

- Strengthen TemplateInfoResponse types: tags uses NotBlankStr, skill_patterns
  uses SkillPattern enum (preserving type safety through the full DTO chain)
- Add subordinate_id/supervisor_id to DepartmentReportingLine TypeScript type
- Add head_id to DepartmentEntry TypeScript type
- Fix ReportingLine and Department docstrings: "agent name" -> "role name"
- Soften subordinate_id/supervisor_id docstring: remove template-specific
  merge_id reference, use generic "stable unique string" phrasing
- Add _identity_key docstring examples for tuple namespace clarity
- Add head_merge_id_requires_head_role validator on TemplateDepartmentConfig
- Fix head_merge_id docstring: "Required" -> "Should be provided"
- Align _validate_unique_skill_patterns with Counter-only class convention
- Add SkillPattern to TestEnumMemberCounts (5 members)
- Add head_merge_id tests: default None, valid with head_role, blank/whitespace
  rejected, without head_role rejected
- Remove dead test_all_pattern_values_are_valid (enum membership guaranteed)
- Sort _EXPECTED_PATTERNS alphabetically for readability
- Update dev_shop.yaml company_name default from "Dev Shop" to "Engineering Squad"
- List all five pattern names in organization.md table instead of "All five"
- Improve tags/skill_patterns descriptions in DTOs

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/synthorg/templates/builtins/dev_shop.yaml (1)

3-7: ⚠️ Potential issue | 🟡 Minor

Condense this description to 2–3 sentences.

This remains 4 sentences, so it still misses the PR objective for concise template summaries.

Proposed edit
   description: >-
-    A lean engineering team built for shipping. No C-suite overhead
-    -- a Software Architect leads directly. Three backend developers,
-    a frontend specialist, QA pipeline, and a DevOps engineer.
-    Optimized for throughput with quality gates.
+    A lean engineering squad optimized for fast shipping, led directly
+    by a Software Architect without C-suite overhead. It combines three
+    backend developers, a frontend specialist, QA pipeline, and DevOps
+    support to keep delivery moving. Built for throughput with explicit
+    quality gates.
🤖 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 3 - 7, The
description field in dev_shop.yaml is still four sentences; update the
description value so it is condensed into 2–3 sentences while preserving the key
points: a lean engineering team led by a Software Architect, the core roles
(backend, frontend, QA, DevOps), and the focus on throughput with quality gates;
modify the 'description' string in src/synthorg/templates/builtins/dev_shop.yaml
(the description: >- block) to combine or trim phrases into two or three concise
sentences that convey leadership, team composition, and optimization for
throughput with quality controls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/unit/api/controllers/test_setup.py`:
- Around line 49-50: The test currently only asserts presence of "tags" and
"skill_patterns" in the template; strengthen these to assert concrete shapes and
simple value constraints: verify template["tags"] is a list of non-empty strings
(e.g., isinstance(list) and all(isinstance(t, str) and t.strip() for t in
template["tags"])), and verify template["skill_patterns"] is a list of dict-like
objects where each entry contains expected keys (e.g., "name" and "pattern")
with non-empty string values (e.g., isinstance and non-empty checks). Update the
assertions that reference the template variable in
tests/unit/api/controllers/test_setup.py to use these type/shape/value checks so
serialization regressions are caught.

In `@tests/unit/core/test_enums.py`:
- Around line 104-105: The test test_skill_pattern_has_5_members only asserts
cardinality; change it to assert explicit enum values to catch accidental
renames — update the test (keeping or renaming test_skill_pattern_has_5_members)
to assert that the set/list of SkillPattern members equals the expected values
(e.g., compare [m.value for m in SkillPattern] or [m.name for m in SkillPattern]
to the explicit expected list/order), so the test fails if any SkillPattern
member name or value changes.

---

Duplicate comments:
In `@src/synthorg/templates/builtins/dev_shop.yaml`:
- Around line 3-7: The description field in dev_shop.yaml is still four
sentences; update the description value so it is condensed into 2–3 sentences
while preserving the key points: a lean engineering team led by a Software
Architect, the core roles (backend, frontend, QA, DevOps), and the focus on
throughput with quality gates; modify the 'description' string in
src/synthorg/templates/builtins/dev_shop.yaml (the description: >- block) to
combine or trim phrases into two or three concise sentences that convey
leadership, team composition, and optimization for throughput with quality
controls.
🪄 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: de43877d-dd4e-496a-89d8-55805f7659ff

📥 Commits

Reviewing files that changed from the base of the PR and between 9e7c753 and 5bdd2bf.

📒 Files selected for processing (22)
  • docs/design/communication.md
  • docs/design/operations.md
  • docs/design/organization.md
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/core/__init__.py
  • src/synthorg/core/company.py
  • src/synthorg/core/enums.py
  • src/synthorg/templates/builtins/agency.yaml
  • src/synthorg/templates/builtins/dev_shop.yaml
  • src/synthorg/templates/builtins/full_company.yaml
  • src/synthorg/templates/builtins/product_team.yaml
  • src/synthorg/templates/builtins/research_lab.yaml
  • src/synthorg/templates/builtins/solo_founder.yaml
  • src/synthorg/templates/builtins/startup.yaml
  • src/synthorg/templates/loader.py
  • src/synthorg/templates/schema.py
  • tests/unit/api/controllers/test_setup.py
  • tests/unit/core/test_enums.py
  • tests/unit/templates/test_loader.py
  • tests/unit/templates/test_schema.py
  • web/src/api/types.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.py: No from __future__ import annotations -- Python 3.14 has PEP 649 native lazy annotations.
Use PEP 758 except syntax: except A, B: (no parentheses) -- ruff enforces this on Python 3.14.
Type hints: all public functions, mypy strict mode.
Docstrings: Google style, required on public classes/functions (enforced by ruff D rules).
Immutability: create new objects, never mutate existing ones. For non-Pydantic internal collections, use copy.deepcopy() at construction + MappingProxyType wrapping for read-only enforcement. For dict/list fields in frozen Pydantic models, rely on frozen=True and copy.deepcopy() at system boundaries.
Config vs runtime state: frozen Pydantic models for config/identity; separate mutable-via-copy models for runtime state that evolves. Never mix static config fields with mutable runtime fields.
Models: Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict). Use @computed_field for derived values. Use NotBlankStr for all identifier/name fields instead of manual whitespace validators.
Async concurrency: prefer asyncio.TaskGroup for fan-out/fan-in parallel operations in new code. Prefer structured concurrency over bare create_task.
Line length: 88 characters (ruff).
Functions: < 50 lines, files < 800 lines.
Errors: handle explicitly, never silently swallow.
Validate: at system boundaries (user input, external APIs, config files).
Variable name: always logger (not _logger, not log).

Files:

  • tests/unit/api/controllers/test_setup.py
  • tests/unit/core/test_enums.py
  • src/synthorg/templates/loader.py
  • src/synthorg/api/controllers/setup_models.py
  • tests/unit/templates/test_loader.py
  • src/synthorg/core/company.py
  • tests/unit/templates/test_schema.py
  • src/synthorg/templates/schema.py
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/core/__init__.py
  • src/synthorg/core/enums.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.py: Markers: @pytest.mark.unit, @pytest.mark.integration, @pytest.mark.e2e, @pytest.mark.slow
Parametrize: Prefer @pytest.mark.parametrize for testing similar cases.
Tests must use test-provider, test-small-001, etc. for vendor-agnostic test code.
Property-based testing: Python uses Hypothesis (@given + @settings). Hypothesis profiles: ci (50 examples, default) and dev (1000 examples), controlled via HYPOTHESIS_PROFILE env var.
Flaky tests: NEVER skip, dismiss, or ignore -- 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).

Files:

  • tests/unit/api/controllers/test_setup.py
  • tests/unit/core/test_enums.py
  • tests/unit/templates/test_loader.py
  • tests/unit/templates/test_schema.py
src/synthorg/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/synthorg/**/*.py: Every module with business logic MUST have: from synthorg.observability import get_logger then logger = get_logger(__name__)
Event names: always use constants from domain-specific modules under synthorg.observability.events (e.g., API_REQUEST_STARTED from events.api). Import directly: from synthorg.observability.events.<domain> import EVENT_CONSTANT
Structured kwargs: always logger.info(EVENT, key=value) -- never logger.info("msg %s", val)
All error paths must log at WARNING or ERROR with context before raising.
All state transitions must log at INFO.
DEBUG for object creation, internal flow, entry/exit of key functions.
Vendor-agnostic everywhere: NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names: example-provider, example-large-001, example-medium-001, example-small-001, large/medium/small as aliases.
Pure data models, enums, and re-exports do NOT need logging.
Use NotBlankStr from core.types for all identifier/name fields -- including optional (NotBlankStr | None) and tuple variants -- instead of manual whitespace validators.

Files:

  • src/synthorg/templates/loader.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/core/company.py
  • src/synthorg/templates/schema.py
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/core/__init__.py
  • src/synthorg/core/enums.py
src/synthorg/!(observability)/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Never use import logging / logging.getLogger() / print() in application code (exception: observability/setup.py and observability/sinks.py may use stdlib logging and print for bootstrap).

Files:

  • src/synthorg/templates/loader.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/core/company.py
  • src/synthorg/templates/schema.py
  • src/synthorg/api/controllers/setup.py
  • src/synthorg/core/__init__.py
  • src/synthorg/core/enums.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/design/communication.md
  • 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/communication.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/communication.md
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.

Applied to files:

  • docs/design/communication.md
  • docs/design/operations.md
  • src/synthorg/templates/loader.py
  • docs/design/organization.md
  • src/synthorg/templates/builtins/solo_founder.yaml
  • src/synthorg/templates/builtins/full_company.yaml
  • src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 BaseModel, model_validator, computed_field, ConfigDict.

Applied to files:

  • src/synthorg/templates/loader.py
  • src/synthorg/api/controllers/setup_models.py
  • tests/unit/templates/test_schema.py
  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Handle errors explicitly, never silently swallow. Validate at system boundaries (user input, external APIs, config files).

Applied to files:

  • src/synthorg/templates/loader.py
📚 Learning: 2026-03-17T06:43:14.114Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:43:14.114Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions. Pure data models, enums, and re-exports do NOT need logging.

Applied to files:

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

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use frozen Pydantic models for config/identity; use separate mutable-via-copy models (using model_copy(update=...)) for runtime state that evolves. Never mix static config fields with mutable runtime fields in one model.

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. For derived values use `computed_field` instead of storing + validating redundant fields. Use `NotBlankStr` (from `core.types`) for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-15T18:42:17.990Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:42:17.990Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
  • tests/unit/templates/test_schema.py
  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : 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/api/controllers/setup_models.py
📚 Learning: 2026-03-17T11:41:02.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T11:41:02.964Z
Learning: Applies to src/**/*.py : Models: Pydantic v2 (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values instead of storing + validating redundant fields. Use `NotBlankStr` for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-22T19:37:56.694Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T19:37:56.694Z
Learning: Applies to **/*.py : Models: Pydantic v2 (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values. Use `NotBlankStr` for all identifier/name fields instead of manual whitespace validators.

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to **/*.py : Models: Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict). Use computed_field for derived values instead of storing + validating redundant fields. Use NotBlankStr (from core.types) for all identifier/name fields — including optional (NotBlankStr | None) and tuple (tuple[NotBlankStr, ...]) variants — instead of manual whitespace validators.

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 with adopted conventions: use computed_field for derived values instead of storing + validating redundant fields; use NotBlankStr from core.types for all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.

Applied to files:

  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/templates/schema.py
📚 Learning: 2026-03-22T19:37:56.694Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T19:37:56.694Z
Learning: Applies to src/synthorg/**/*.py : Vendor-agnostic everywhere: NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names: `example-provider`, `example-large-001`, `example-medium-001`, `example-small-001`, `large`/`medium`/`small` as aliases.

Applied to files:

  • src/synthorg/templates/builtins/full_company.yaml
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...

Applied to files:

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

Applied to files:

  • src/synthorg/core/__init__.py
🧬 Code graph analysis (8)
tests/unit/core/test_enums.py (1)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
src/synthorg/templates/loader.py (2)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
src/synthorg/core/enums.py (1)
  • SkillPattern (175-198)
tests/unit/templates/test_loader.py (1)
src/synthorg/templates/loader.py (2)
  • load_template (171-227)
  • load_template_file (230-251)
tests/unit/templates/test_schema.py (2)
src/synthorg/core/enums.py (2)
  • CompanyType (148-158)
  • SkillPattern (175-198)
src/synthorg/templates/schema.py (2)
  • TemplateDepartmentConfig (155-208)
  • TemplateMetadata (211-265)
src/synthorg/templates/schema.py (2)
src/synthorg/core/enums.py (1)
  • SkillPattern (175-198)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
web/src/api/types.ts (2)
src/synthorg/core/enums.py (1)
  • SkillPattern (175-198)
src/synthorg/api/controllers/setup_models.py (1)
  • TemplateInfoResponse (36-62)
src/synthorg/core/__init__.py (2)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
src/synthorg/core/enums.py (1)
  • SkillPattern (175-198)
src/synthorg/core/enums.py (1)
web/src/api/types.ts (1)
  • SkillPattern (847-852)
🔇 Additional comments (25)
src/synthorg/core/company.py (1)

35-40: Documentation updates are clear and consistent with current validation behavior.

These clarifications improve identity/disambiguation semantics without changing runtime behavior.

Also applies to: 50-61, 66-67, 357-365, 379-379

docs/design/operations.md (1)

846-847: Template rename updates look consistent with the new display-name set.

tests/unit/core/test_enums.py (1)

27-27: SkillPattern import wiring is correct.

src/synthorg/core/__init__.py (1)

51-52: Public re-export of SkillPattern is correctly wired.

Also applies to: 128-128

docs/design/communication.md (1)

89-90: Archetype mapping rename update is clear and consistent.

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

205-206: /setup/templates correctly propagates tags and skill_patterns into the API DTO.

docs/design/organization.md (1)

14-20: The taxonomy and template-name documentation updates are well-structured and aligned with the feature goals.

Also applies to: 26-54

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

3-20: Metadata update is consistent and well-structured.

The expanded description, capability-focused tags, and valid skill_patterns values all align with the new taxonomy and discovery goals.

src/synthorg/core/enums.py (1)

175-198: SkillPattern enum is clean and correctly defined.

The five-member StrEnum is well-documented and uses stable snake_case values suitable for schema/API typing.

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

3-21: Startup template metadata looks solid.

The revised summary, expanded tags, and skill_patterns classification are coherent and aligned with the taxonomy rollout.

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

72-83: TemplateInfo propagation is implemented consistently.

Both builtin and user template paths now expose tags and skill_patterns uniformly through TemplateInfo.

Also applies to: 124-126, 151-153


443-443: Pass-1 normalization correctly includes skill_patterns.

Adding skill_patterns to metadata normalization keeps loader output aligned with schema/API expectations.

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

188-225: New schema test coverage is strong and targeted.

The added cases validate head_merge_id constraints and skill_patterns default/duplicate handling with clear expectations.

Also applies to: 239-260, 279-289

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

49-62: TemplateInfoResponse extension is well-modeled.

extra="forbid" plus typed tags and skill_patterns provides a stricter and safer API contract for the new metadata.

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

151-156: Display-name expectation updates are correct.

The assertions now reflect the renamed builtin metadata ("Solo Builder") while preserving override behavior.

Also applies to: 181-182


236-255: Skill-pattern loader tests are comprehensive.

The new negative test plus builtin pattern matrix provides good guardrails for validation and taxonomy completeness.

Also applies to: 421-466

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

2-18: Solo template metadata changes are coherent and safe.

The display-name rename, richer summary, updated tags, and tool_wrapper pattern declaration all fit the intended taxonomy and UX improvements.

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

3-21: Good metadata update and taxonomy mapping.

Description, tags, and skill_patterns are consistent with the template’s workflow and the new discovery taxonomy.

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

198-208: head_merge_id guard is a solid correctness check.

The new validator prevents invalid department configs from slipping through and keeps error reporting consistent.


242-265: skill_patterns modeling and uniqueness validation look correct.

Typed enum storage plus duplicate rejection is the right schema-level enforcement for this metadata.

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

2-23: Enterprise template metadata is well-aligned with the new taxonomy.

The rename, expanded description, tags, and full five-pattern classification are coherent and internally consistent.

web/src/api/types.ts (2)

847-860: Type-level API parity for template metadata looks good.

SkillPattern plus TemplateInfoResponse.skill_patterns/tags keeps frontend typing aligned with backend payloads.


1007-1008: Department ID field additions are modeled correctly.

Using optional nullable fields here is appropriate for partial/legacy payload compatibility.

Also applies to: 1014-1014

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

2-21: Strong update for Product Studio metadata.

The description, tag specialization, and selected skill patterns are clear and consistent with the template’s flow.

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

25-25: Nice catch updating the default company name.

company_name now matches the renamed template and removes stale user-facing text.

Comment on lines +49 to +50
assert "tags" in template
assert "skill_patterns" in template
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Strengthen API contract assertions for tags and skill_patterns.

Lines 49-50 only check presence. Add shape/value assertions so serialization regressions are caught early.

Proposed assertion upgrades
         for template in body["data"]:
             assert "name" in template
             assert "display_name" in template
             assert "description" in template
             assert "source" in template
             assert "tags" in template
             assert "skill_patterns" in template
+            assert isinstance(template["tags"], list)
+            assert all(isinstance(tag, str) for tag in template["tags"])
+            assert isinstance(template["skill_patterns"], list)
+            assert set(template["skill_patterns"]).issubset(
+                {"tool_wrapper", "generator", "reviewer", "inversion", "pipeline"}
+            )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/api/controllers/test_setup.py` around lines 49 - 50, The test
currently only asserts presence of "tags" and "skill_patterns" in the template;
strengthen these to assert concrete shapes and simple value constraints: verify
template["tags"] is a list of non-empty strings (e.g., isinstance(list) and
all(isinstance(t, str) and t.strip() for t in template["tags"])), and verify
template["skill_patterns"] is a list of dict-like objects where each entry
contains expected keys (e.g., "name" and "pattern") with non-empty string values
(e.g., isinstance and non-empty checks). Update the assertions that reference
the template variable in tests/unit/api/controllers/test_setup.py to use these
type/shape/value checks so serialization regressions are caught.

- Add type assertions for tags/skill_patterns in test_template_fields
- Add SkillPattern value assertions alongside member count test

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 22, 2026 22:02 — with GitHub Actions Inactive
@Aureliolo Aureliolo merged commit f333f24 into main Mar 22, 2026
33 checks passed
@Aureliolo Aureliolo deleted the feat/implement-698 branch March 22, 2026 22:08
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 22, 2026 22:08 — with GitHub Actions Inactive
Aureliolo added a commit that referenced this pull request Mar 22, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.4.8](v0.4.7...v0.4.8)
(2026-03-22)


### Features

* add auto_cleanup config and improve update UX
([#741](#741))
([289638f](289638f))
* add reporting lines, escalation paths, and workflow handoffs to
templates ([#745](#745))
([c374cc9](c374cc9))
* differentiate template operational configs
([#742](#742))
([9b48345](9b48345))
* diversify personality preset assignments across templates
([#743](#743))
([15487a5](15487a5))
* improve template metadata -- skill taxonomy, descriptions, tags, and
display names ([#752](#752))
([f333f24](f333f24))


### Bug Fixes

* resolve log analysis findings (Ollama prefix, logging, init)
([#748](#748))
([8f871a4](8f871a4))
* use git tag for dev release container image tags
([#749](#749))
([f30d071](f30d071))
* use subordinate_id/supervisor_id in HierarchyResolver
([#751](#751))
([118235b](118235b))


### Performance

* add long-lived cache headers for content-hashed static assets
([#747](#747))
([4d350b5](4d350b5))
* use worksteal distribution for pytest-xdist
([#750](#750))
([b7dd7de](b7dd7de))

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: improve template metadata -- skill taxonomy, descriptions, tags, and display names

1 participant