Organisation¶
Company structure facades: company, departments, teams, and role versions.
Enums¶
enums
¶
Models¶
models
¶
Organization-layer domain models.
Holds the input models for company, department, and agent mutations so
the organization service layer can validate the same input shapes
without importing from the API layer. The synthorg.api.dto_org
module re-exports these for HTTP controllers.
UpdateCompanyRequest
pydantic-model
¶
Bases: BaseModel
Partial update for company-level settings.
Lives in the organization domain layer so the service can
validate input without importing from synthorg.api.dto_org.
Config:
frozen:Trueallow_inf_nan:Falseextra:forbid
Fields:
-
company_name(NotBlankStr | None) -
autonomy_level(AutonomyLevel | None) -
budget_monthly(float | None) -
communication_pattern(NotBlankStr | None)
autonomy_level
pydantic-field
¶
Org-wide autonomy level (full, semi, supervised, locked).
budget_monthly
pydantic-field
¶
Monthly budget cap for the company in the operator's configured currency; set to 0 to disable enforcement.
communication_pattern
pydantic-field
¶
Communication strategy or pattern identifier.
CreateDepartmentRequest
pydantic-model
¶
Bases: BaseModel
Request body for creating a new department.
Config:
frozen:Trueallow_inf_nan:Falseextra:forbid
Fields:
-
name(NotBlankStr) -
head(NotBlankStr | None) -
budget_percent(float) -
autonomy_level(AutonomyLevel | None)
UpdateDepartmentRequest
pydantic-model
¶
Bases: BaseModel
Partial update for an existing department.
Config:
frozen:Trueallow_inf_nan:Falseextra:forbid
Fields:
-
head(NotBlankStr | None) -
budget_percent(float | None) -
autonomy_level(AutonomyLevel | None) -
teams(tuple[Team, ...] | None) -
ceremony_policy(dict[str, object] | None)
Validators:
-
_validate_ceremony_policy→ceremony_policy -
_deep_copy_ceremony_policy
ReorderDepartmentsRequest
pydantic-model
¶
Bases: BaseModel
Reorder departments -- must be an exact permutation.
Config:
frozen:Trueallow_inf_nan:Falseextra:forbid
Fields:
-
department_names(tuple[NotBlankStr, ...])
CreateAgentOrgRequest
pydantic-model
¶
Bases: BaseModel
Request body for creating a new agent in the org config.
Config:
frozen:Trueallow_inf_nan:Falseextra:forbid
Fields:
-
name(NotBlankStr) -
role(NotBlankStr) -
department(NotBlankStr) -
model_provider(NotBlankStr | None) -
model_id(NotBlankStr | None)
Validators:
-
_validate_model_pair
UpdateAgentOrgRequest
pydantic-model
¶
Bases: BaseModel
Partial update for an existing agent in the org config.
Config:
frozen:Trueallow_inf_nan:Falseextra:forbid
Fields:
-
name(NotBlankStr | None) -
role(NotBlankStr | None) -
department(NotBlankStr | None) -
autonomy_level(AutonomyLevel | None) -
model_provider(NotBlankStr | None) -
model_id(NotBlankStr | None)
Validators:
-
_validate_model_pair
ReorderAgentsRequest
pydantic-model
¶
Bases: BaseModel
Reorder agents within a department -- must be an exact permutation.
Config:
frozen:Trueallow_inf_nan:Falseextra:forbid
Fields:
-
agent_names(tuple[NotBlankStr, ...])
Services¶
services
¶
Organization facades for the MCP handler layer.
Hosts CompanyReadService (company snapshot + version history),
DepartmentService (durable department CRUD + health), and
RoleVersionService (role-version history). Company writes route
through org_mutation_service; reads and version history project the
same durable sources the REST controllers use (the config resolver and
the per-entity version repositories). Team CRUD lives in the sibling
_team_service module, which mutates the settings-backed
company.departments[*].teams blob.
The file-level EM101 suppression is intentional: every capability
gap in this module raises :class:CapabilityNotSupportedError from a
short identifier and operator-readable reason, both string literals by
design so capability telemetry has a stable, grep-able message.
CompanyReadService
¶
Read + light-mutation facade over the company/org surface.
Reads project the same durable sources the REST company controllers
use: the config resolver for the company snapshot + departments, and
the VersionRepository[Company] for history. Writes route through
OrgMutationService (the single owner of the company-settings write
+ snapshot flow). company_versions is optional: a persistence-less
deployment has no durable history, so the version reads surface a
capability gap rather than a 503.
Source code in src/synthorg/organization/services.py
get_company
async
¶
Return the curated company snapshot (name, agents, departments).
Returns:
| Type | Description |
|---|---|
Mapping[str, object]
|
A JSON-safe mapping mirroring the REST |
Source code in src/synthorg/organization/services.py
update_company
async
¶
Apply a partial company-settings update.
The payload is validated against :class:UpdateCompanyRequest
here so unknown keys are rejected before reaching the mutation
service. actor_id is bound to the actor-context seam for the
call so the mutation service's snapshot leaf attributes the
version to this caller (the MCP layer is bypassed by the
HTTP-only AuthContextMiddleware, so the binding is explicit
here).
Returns:
| Type | Description |
|---|---|
Mapping[str, object]
|
The updated company fields returned by the mutation service. |
Source code in src/synthorg/organization/services.py
list_departments
async
¶
Return the company's departments.
Returns:
| Type | Description |
|---|---|
Sequence[object]
|
The department models resolved from company settings. |
reorder_departments
async
¶
Apply a new department ordering (by name), auditing the change.
department_ids is an exact permutation of the current
department names (the reorder key is the display name, matching
the REST POST /company/reorder-departments contract).
Source code in src/synthorg/organization/services.py
list_versions
async
¶
Return every company-snapshot version, newest-repo-order.
Returns:
| Type | Description |
|---|---|
Sequence[object]
|
All company version snapshots from the durable repository. |
Raises:
| Type | Description |
|---|---|
CapabilityNotSupportedError
|
When no durable version repository is wired (a persistence-less deployment). |
Source code in src/synthorg/organization/services.py
get_version
async
¶
Fetch a single company-snapshot version by its version number.
version_id is the one-based monotonic version number (the only
stable key company snapshots carry); a non-numeric or out-of-range
value resolves to None so the handler maps it onto
not_found.
Returns:
| Type | Description |
|---|---|
object | None
|
The matching company-snapshot version, or |
Raises:
| Type | Description |
|---|---|
CapabilityNotSupportedError
|
When no durable version repository is wired (a persistence-less deployment). |
Source code in src/synthorg/organization/services.py
DepartmentService
¶
Department CRUD + health.
Mutations are serialised through a single :class:asyncio.Lock so
concurrent MCP handler calls cannot race on the in-memory dict
(check-then-act in :meth:update_department and
:meth:delete_department).
Source code in src/synthorg/organization/services.py
rehydrate
async
¶
Load durable departments into the in-memory cache at boot.
A no-op when no durable repository is wired (the in-memory service stands alone). After this the cache mirrors the durable store, so reads stay in memory and writes go through to the repository.
Source code in src/synthorg/organization/services.py
list_departments
async
¶
Return paginated departments newest-first plus unfiltered total.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
offset
|
int
|
Non-negative page offset. |
0
|
limit
|
int | None
|
Optional positive page size; |
None
|
Raises:
| Type | Description |
|---|---|
ValidationError
|
If |
Source code in src/synthorg/organization/services.py
get_department
async
¶
Fetch a single department by UUID or None if not found.
Returns:
| Type | Description |
|---|---|
_DepartmentRecord | None
|
A deep copy of the stored department, or |
_DepartmentRecord | None
|
is malformed or no such department exists. |
Source code in src/synthorg/organization/services.py
create_department
async
¶
Create a department, auditing the event on success.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
NotBlankStr
|
Department display name (UNIQUE in the durable store). |
required |
description
|
str
|
Human-readable description (optional free text,
matching the persisted :class: |
''
|
actor_id
|
NotBlankStr
|
Auditing actor identifier. |
required |
department_id
|
UUID | None
|
Optional explicit primary key. Supplied by
rollback paths so a re-created department keeps its
original id and existing references stay valid; defaults
to a fresh |
None
|
Returns:
| Type | Description |
|---|---|
_DepartmentRecord
|
A deep copy of the newly created department record. |
Source code in src/synthorg/organization/services.py
update_department
async
¶
Patch a department's name / description in place.
Returns:
| Type | Description |
|---|---|
_DepartmentRecord | None
|
A deep copy of the updated department, or |
_DepartmentRecord | None
|
is malformed or no such department exists. |
Source code in src/synthorg/organization/services.py
delete_department
async
¶
Remove a department; emit the audit event only on real removal.
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
is malformed or no such department exists. |
Source code in src/synthorg/organization/services.py
get_health
async
¶
Return a summary health payload for the department.
Source code in src/synthorg/organization/services.py
RoleVersionService
¶
Read facade for the per-role version-snapshot history.
Role snapshots are keyed by (role_name, version) in the durable
VersionRepository[Role] (there is no global snapshot id), so both
reads require the role name. role_versions is optional: a
persistence-less deployment has no durable history and the reads
surface a capability gap rather than a 503.
Source code in src/synthorg/organization/services.py
list_versions
async
¶
Return a paginated slice of a role's snapshots plus the total.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
role_name
|
NotBlankStr
|
The role whose version history to list (required; snapshots are per-role in the durable store). |
required |
offset
|
int
|
Non-negative page offset. |
0
|
limit
|
int | None
|
Optional positive page size; |
None
|
Returns:
| Type | Description |
|---|---|
tuple[object, ...]
|
A |
int
|
of |
Raises:
| Type | Description |
|---|---|
CapabilityNotSupportedError
|
When no durable version repository is wired (a persistence-less deployment). |
Source code in src/synthorg/organization/services.py
get_version
async
¶
Fetch a single role snapshot by role name + version number.
version_id is the one-based monotonic version number; a
non-numeric or out-of-range value resolves to None so the
handler maps it onto not_found.
Returns:
| Type | Description |
|---|---|
object | None
|
The matching role-snapshot version, or |
Raises:
| Type | Description |
|---|---|
CapabilityNotSupportedError
|
When no durable version repository is wired (a persistence-less deployment). |