Organisation & Templates¶
Company Types¶
SynthOrg provides pre-built company templates for common organisational patterns:
| Template | Size | Posture | Autonomy | Communication | Workflow | Use Case |
|---|---|---|---|---|---|---|
| Solo Builder | 2-3 | autonomous | full | event_driven | kanban | Quick prototypes, solo projects |
| Tech Startup | 3-5 | autonomous | semi | hybrid | agile_kanban | Small projects, MVPs |
| Engineering Squad | 6-10 | cost_disciplined | semi | hybrid | agile_kanban | Software throughput on a budget |
| Product Studio | 8-12 | knowledge_heavy | semi | meeting_based | agile_kanban | Discovery-led product development |
| Agency | 10-15 | supervised_client_facing | supervised | hierarchical | kanban | Creative and marketing client work |
| Enterprise Org | 20-50 | supervised_client_facing | supervised | hierarchical | agile_kanban | Enterprise simulation |
| Research Lab | 5-10 | research_autonomous | full | event_driven | kanban | Autonomous research and analysis |
| Consultancy | 4-6 | supervised_client_facing | supervised | hierarchical | kanban | Senior client-facing advisory |
| Data Team | 5-8 | knowledge_heavy | full | event_driven | kanban | Analytics and ML pipelines |
| Support Desk | 5-7 | supervised_client_facing | supervised | hierarchical | kanban | Customer support, incident response |
| Security Team | 4-6 | security_hardened | supervised | hierarchical | kanban | Threat modelling, security review |
| Growth Marketing Studio | 5-8 | cost_disciplined | semi | hybrid | agile_kanban | Content, campaigns, growth |
| Custom | Any | -- | semi | hybrid | agile_kanban | Anything |
A template's posture expands to a coherent bundle of runtime feature flags (knowledge substrate, conversational chat modes, mid-flight steering, red-team gate, cost-dial auto-downgrade), so a template configures behaviour, not just an org chart. See Operating Postures.
Company size vs. per-task coordination group size
The Size column above describes the full company roster, not the number of
agents working on any single task. Per-task coordination-group size is
bounded separately by coordination.max_concurrency_per_wave (settings
registry default 5; 3-4 recommended per research, adoption tracked
on R1 #1250); an Enterprise Org with 50 agents does not run 50-agent
coordination waves. See
Task Decomposability & Coordination Topology
for the full bounds and S1 Multi-Agent Architecture Decision §2.
See the Template System section for details on how templates are defined, inherited, and customised.
Operating Postures¶
A template declares a named posture that resolves to a frozen bundle of
runtime feature flags. The bundle threads into the company configuration: the
config-resident knobs (security.red_team, budget.auto_downgrade) are set on
the rendered RootConfig, and the settings-resident flags (conversational chat
modes, mid-flight steering) are seeded into the settings service at setup so the
best-effort boot wiring enables them. Boot wiring degrades cleanly when a
dependency (provider, persistence, memory backend) is absent.
| Posture | Enables |
|---|---|
autonomous |
Knowledge substrate, mid-flight steering |
supervised_client_facing |
Group chat, agent invite, clarify-or-park + routing proposals, steering |
knowledge_heavy |
Knowledge substrate, clarify proposals, steering |
cost_disciplined |
Budget auto-downgrade |
security_hardened |
Red-team completion gate (knowledge-substrate grounding), knowledge substrate, steering |
research_autonomous |
Knowledge substrate, clarify + routing proposals, steering |
Postures resolve through a pluggable PostureExpansionStrategy (default: a
curated named-bundle registry). Inheritance is child-wins: a child template's
posture replaces its parent's. A template pack may declare a posture that unions
additively into the host template's bundle (each flag takes the more-capable
value). The toolsmith is intentionally not posture driven: enabling it needs an
explicit capability allowlist, so it stays an operator opt-in.
Skill Pattern Taxonomy¶
Each template is classified using a five-pattern taxonomy that describes how its agents interact to accomplish work. Based on Google Cloud's agent skill design patterns:
| Pattern | Description |
|---|---|
| Tool Wrapper | On-demand domain expertise; agents self-direct using specialised context |
| Generator | Consistent structured output from reusable templates |
| Reviewer | Modular rubric-based evaluation; separates what to check from how to check it |
| Inversion | Agent interviews user before acting; structured requirements gathering |
| Pipeline | Strict sequential workflow with hard checkpoints between stages |
Templates declare which patterns they exhibit via the skill_patterns metadata field:
| Template | Skill Patterns |
|---|---|
| Solo Builder | Tool Wrapper |
| Tech Startup | Tool Wrapper, Generator, Pipeline |
| Engineering Squad | Pipeline, Reviewer, Tool Wrapper |
| Product Studio | Inversion, Pipeline, Reviewer |
| Agency | Pipeline, Generator, Reviewer |
| Enterprise Org | Tool Wrapper, Generator, Reviewer, Inversion, Pipeline |
| Research Lab | Inversion, Generator, Reviewer |
| Consultancy | Generator, Inversion, Reviewer |
| Data Team | Generator, Reviewer, Tool Wrapper |
| Support Desk | Inversion, Reviewer, Tool Wrapper |
| Security Team | Inversion, Reviewer, Tool Wrapper |
| Growth Marketing Studio | Generator, Reviewer, Tool Wrapper |
Patterns compose naturally: a Pipeline can embed a Reviewer step at each gate, a Generator can begin with an Inversion phase to gather variables, and individual Pipeline stages can activate different Tool Wrapper skills depending on the domain.
Organisational Hierarchy¶
The framework supports a full organisational hierarchy with reporting lines and delegation authority:
graph TD
CEO["CEO"]
CEO --> CTO["CTO"]
CEO --> CPO["CPO"]
CEO --> CFO["CFO"]
CTO --> EngLead["Eng Lead"]
CTO --> QALead["QA Lead"]
CTO --> DevOpsLead["DevOps Lead"]
CPO --> PM["Product Managers"]
CPO --> Design["UX/UI Designers"]
CPO --> TechWriter["Tech Writers"]
CFO --> BudgetMgmt["Budget Mgmt"]
EngLead --> SrDevs["Sr Devs"]
EngLead --> JrDevs["Jr Devs"]
QALead --> QAEng["QA Engineers"]
QALead --> AutoEng["Automation Engineers"]
DevOpsLead --> SRE["SRE"]
Each node in the hierarchy corresponds to an agent with a defined seniority level that determines their authority, delegation rights, and typical model tier.
Department Configuration¶
Full department configuration YAML
departments:
- name: "engineering"
head: "cto"
budget_percent: 60
policies:
review_requirements:
min_reviewers: 2
approval_chains:
- action_type: "code_review"
approvers: ["Software Architect", "CTO"]
teams:
- name: "backend"
lead: "backend_lead"
members: ["sr_backend_1", "mid_backend_1", "jr_backend_1"]
- name: "frontend"
lead: "frontend_lead"
members: ["sr_frontend_1", "mid_frontend_1"]
reporting_lines:
- subordinate: "Backend Developer"
subordinate_id: "backend-senior"
supervisor: "Software Architect"
- subordinate: "Backend Developer"
subordinate_id: "backend-mid"
supervisor: "Backend Developer"
supervisor_id: "backend-senior"
- subordinate: "Frontend Developer"
supervisor: "Software Architect"
- name: "product"
head: "cpo"
budget_percent: 20
teams:
- name: "core"
lead: "pm_lead"
members: ["pm_1", "ux_designer_1", "ui_designer_1"]
- name: "operations"
head: "coo"
budget_percent: 10
teams:
- name: "devops"
lead: "devops_lead"
members: ["sre_1"]
- name: "quality"
head: "qa_lead"
budget_percent: 10
teams:
- name: "qa"
lead: "qa_lead"
members: ["qa_engineer_1", "automation_engineer_1"]
Each department defines:
- head (optional): the agent who leads the department (typically a C-suite or Lead role). Defaults to
Nonewhen no head is designated; hierarchy resolution skips the team-lead-to-head link for headless departments. When multiple agents share the same role name, use the companionhead_idfield to disambiguate. In template YAML this is written ashead_merge_id(matching the agent'smerge_id); the renderer maps it tohead_idat runtime, paralleling howsubordinate_id/supervisor_idwork inreporting_lines - budget_percent: the share of the company's task-execution budget allocated to this department (covers agent compute and API costs, not provider subscriptions or seat licensing)
- teams: named sub-groups within the department, each with a lead and members
- reporting_lines: explicit subordinate/supervisor relationships within the department. Each entry has
subordinateandsupervisor(role names), plus optionalsubordinate_id/supervisor_idfor disambiguating agents that share the same role name (typically matching the agent'smerge_id) - policies (optional): department-level operational policies. Contains
review_requirements(minimum reviewers, required reviewer roles, self-review toggle) andapproval_chains(ordered approver lists keyed by action type such ascode_review,security_review, orchange_management). Defaults to a single required reviewer and no approval chains when omitted
Dynamic Scaling¶
The company can dynamically grow or shrink through several mechanisms:
- Auto-scale: the HR agent detects workload increases and proposes new hires
- Manual scale: a human adds or removes agents via config or UI
- Budget-driven: the CFO agent caps headcount based on budget constraints
- Skill-gap: HR analyses team capabilities, identifies missing skills, and proposes targeted hires
Template System¶
Templates are YAML/JSON files defining a complete company setup. The framework uses templates as the primary mechanism for bootstrapping organisations.
Template Structure¶
# templates/startup.yaml (simplified -- real templates also declare
# min_agents/max_agents, tags, and department policies)
template:
name: "Tech Startup"
description: "Small team for building MVPs and prototypes"
version: "1.0"
variables:
- name: "sprint_length"
description: "Sprint duration in days"
var_type: "int"
default: 7
- name: "wip_limit"
description: "Work-in-progress limit per column"
var_type: "int"
default: 3
posture: "autonomous" # expands to a runtime feature-flag bundle
company:
type: "startup"
budget_monthly: "{{ budget | default(50.00) }}"
autonomy:
level: "semi"
# Built-in templates omit the agent `name` field entirely; Faker
# auto-generates names at render time using the locales selected in the
# Names setup step. User-defined templates may instead set an explicit
# name or a Jinja2 placeholder (e.g. {{ name | auto }}).
# The `model` field is a capability reference: either a structured dict
# (priority / min_context / requires_tools / requires_vision /
# requires_reasoning, plus an optional family or model_pattern), or an
# explicit model id/alias string to pin a configured model. The matcher
# resolves it against the configured providers; personality-preset affinity
# fills any capability defaults the agent omits. Built-in templates use
# capability dicts so they resolve on any provider, Ollama Cloud included.
agents:
- role: "CEO" # name omitted -> Faker at render time
model: # capability requirement
priority: "quality"
min_context: 100000
requires_reasoning: true
personality_preset: "visionary_leader"
- role: "CTO"
model:
priority: "quality"
min_context: 100000
requires_reasoning: true
personality_preset: "rapid_prototyper"
- role: "Full-Stack Developer"
merge_id: "fullstack-senior"
level: "senior"
model:
priority: "balanced"
requires_tools: true
personality_preset: "pragmatic_builder"
- role: "Full-Stack Developer"
merge_id: "fullstack-mid"
level: "mid"
model:
priority: "cost"
requires_tools: true
personality_preset: "team_diplomat"
- role: "Product Manager"
model:
priority: "speed"
personality_preset: "strategic_planner"
departments:
- name: "executive"
budget_percent: 20
head_role: "CEO"
reporting_lines:
- subordinate: "CTO"
supervisor: "CEO"
- name: "engineering"
budget_percent: 60
head_role: "CTO"
reporting_lines:
- subordinate: "Full-Stack Developer"
subordinate_id: "fullstack-senior"
supervisor: "CTO"
- subordinate: "Full-Stack Developer"
subordinate_id: "fullstack-mid"
supervisor: "CTO"
- name: "product"
budget_percent: 20
head_role: "Product Manager"
workflow: "agile_kanban" # operational configs vary per template;
communication: "hybrid" # see Company Types table for each template's defaults
workflow_config: # optional Kanban/Sprint sub-configurations
kanban:
wip_limits:
- column: "in_progress"
limit: {{ wip_limit | default(3) }}
- column: "review"
limit: 2
enforce_wip: true
sprint:
duration_days: {{ sprint_length | default(7) }}
ceremonies:
- name: "sprint_planning"
protocol: "structured_phases"
frequency: "weekly"
- name: "sprint_review"
protocol: "round_robin"
frequency: "weekly"
workflow_handoffs:
- from_department: "engineering"
to_department: "product"
trigger: "Feature implementation completed for product review"
artifacts:
- "pull_request"
- "release_notes"
escalation_paths:
- from_department: "engineering"
to_department: "executive"
condition: "Technical blocker requiring executive decision"
priority_boost: 1
Templates support Jinja2-style variables ({{ variable | default(value) }}) for
user-customizable values, and personality presets for reusable agent personality
configurations.
Personality Presets¶
Personality presets come in two flavors:
- Built-in presets ship with the codebase (
templates/presets.py) and are read-only. - Custom presets are user-defined via the REST API (
POST /api/v1/personalities/presets), persisted to the database, and managed through full CRUD operations.
Custom preset names must match ^[a-z][a-z0-9_]*$ and cannot shadow built-in names. All custom presets are validated against PersonalityConfig before persistence. The API distinguishes origin via a source: "builtin" | "custom" field in responses.
During template rendering and setup agent expansion, custom presets are fetched from the database and passed into the rendering pipeline alongside builtins. If an agent references a preset name that exists in neither custom nor built-in collections, the system logs a warning rather than raising an error: during template rendering, the personality is omitted (the agent proceeds with no personality assigned); during setup agent expansion, the agent falls back to the pragmatic_builder default. The validate_preset_references() function provides advisory pre-flight validation for template import/export scenarios, returning warning strings for unknown presets without raising.
Discovery endpoints (GET /api/v1/personalities/presets, GET /api/v1/personalities/presets/{name}, GET /api/v1/personalities/schema) are available to all authenticated users. CRUD endpoints require write access.
Template Inheritance¶
Templates can extend other templates using extends:
template:
name: "Extended Startup"
extends: "startup" # inherits all agents, departments, config
agents:
- role: "QA Engineer" # appended to parent agents
level: "mid"
- role: "Full-Stack Developer"
merge_id: "fullstack-mid"
department: "engineering"
_remove: true # removes matching parent agent by key
Inheritance resolves parent-to-child chains up to 10 levels deep. Circular inheritance
is detected via chain tracking and raises TemplateInheritanceError.
Built-in inheritance tree:
solo_founder (base)
-> startup (extends solo_founder)
-> dev_shop (extends startup)
-> product_team (extends startup)
research_lab (base)
-> data_team (extends research_lab)
Standalone (no inheritance): agency, consultancy, full_company,
support_desk, security_team, growth_marketing
Each template's roster size is declared by its own min_agents / max_agents
(see the Company Types table); extending templates inherit the parent roster
and append (or _remove) their own agents.
Merge Semantics¶
The merge behaviour during template inheritance follows these rules:
- Scalars (
company_name,company_type) - Child wins if present.
configdict- Deep-merged (child keys override parent).
agentslist- Merged by
(role, department, merge_id)composite key. Whenmerge_idis omitted, it defaults to an empty string, making the key(role, department, ""). The child template can override, append, or remove (_remove: true) parent agents. departmentslist- Merged by department
name(case-insensitive). A child department with the samenamereplaces the parent entry entirely; departments with new names are appended. A child department with_remove: trueremoves the matching parent department. workflow_configdict- Not merged during inheritance. Each template's
workflow_configis transformed into aworkflowdict by_build_workflow_dictduring rendering (before the merge step). A child template that usesextendsmust declare its ownworkflow_configif it needs one; the parent'sworkflow_configis not carried forward as raw config. workflowdict- The renderer always produces a
workflowdict fromworkflow_config(or schema defaults), soworkflowis always present in the child's rendered output. At merge time the child'sworkflowreplaces the parent's entirely; the "inherit from parent" path cannot trigger. workflow_handoffsandescalation_paths- Child replaces entirely if present; otherwise inherited from parent.
Unlike
workflow, these fields may be absent from the rendered output, so the inherit-from-parent fallback applies.
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").
Template Packs¶
Packs are small, focused template fragments (same schema as full templates)
that can be applied additively to a running org or composed into templates
via the uses_packs field.
Built-in packs (in src/synthorg/templates/packs/):
| Pack | Agents | Description |
|---|---|---|
security-team |
Security Engineer, Security Operations | Threat modelling and compliance |
data-team |
Data Analyst, Data Engineer, ML Engineer | Data analytics pipeline |
qa-pipeline |
QA Lead, QA Engineer, Automation Engineer | Quality assurance |
creative-marketing |
Content Writer, Brand Strategist | Content and brand |
design-team |
UX Designer, UX Researcher | Design and user research |
verifier-harness |
Planner, Generator, Evaluator | Three-agent verification with calibrated rubric grading (see Verification & Quality: Verification Stage) |
User packs live in ~/.synthorg/template-packs/ (YAML files). User packs
override built-in packs of the same name.
Composition via uses_packs:
Resolution order: extends parent is merged first, then each pack in
uses_packs order, then the template's own fields override last. Circular
pack dependencies are detected and raise TemplateRenderError.
Live application:
The POST /api/v1/template-packs/apply endpoint applies a pack to a running
org, adding its agents and departments to the existing config. Department
names are deduplicated (case-insensitive); agent names are deduplicated by
name.
Company Builder¶
The web dashboard includes a setup wizard with a mode selection gate after account creation
(conditional; only shown when no admin exists). The user chooses Guided Setup
(recommended, full wizard) or Quick Setup (minimal: company name + provider, configure
the rest later in Settings). Guided mode steps: Mode, Template (searchable grid with
category/size filters, recommended/others grouping, and structural metadata cards showing
agent count, departments, autonomy level, and workflow), Company (name, description,
currency, and model tier profile), Providers (configure LLM providers with auto-detection
for local instances (with probe-detected base URLs) and full provider form supporting
API key, subscription, custom configurations, and manually entered base URLs),
Agents (customise names, roles, personality presets, and model assignments),
Theme (set UI preferences for palette, density, animation, sidebar, and typography), and
Complete (review summary and launch). Quick mode steps: Mode, Company, Providers, and
Complete, skipping template, agents, and theme. Providers are configured before agents so
model assignment is available during agent customisation. When a template is selected, all
template agents are auto-created with models matched to configured providers via a tier
classification engine that respects each agent's priority axis (quality, speed, cost, or
balanced). All configuration is persisted to the database via REST API calls. To re-run the
setup wizard from scratch, use synthorg wipe (walks you through an interactive backup,
wipes all data, and optionally restarts the stack to re-open the wizard).
MCP Service Facades¶
The organisation domain exposes service facades on AppState for MCP handler shims
(CompanyReadService, DepartmentService, TeamService, RoleVersionService). The
facade inventory and the MCP args contract live in the
MCP Handler Contract reference.