Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ web/src/api/types/generated.d.ts
# (hand-off artefact for issue #1417; regenerate locally as needed).
web/src/i18n/_extracted_catalog.json

# Generated comparison page (built by scripts/generate_comparison.py)
docs/reference/comparison.md

# Astro / Node.js (landing page)
site/node_modules/
site/dist/
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ When tests fail due to timeout, slowness, or xdist resource contention:
- **Timeout**: 30 seconds per test (global in `pyproject.toml`; do not add per-file `pytest.mark.timeout(30)` markers; non-default overrides like `timeout(60)` are allowed)
- **Parallelism**: `pytest-xdist` via `-n 8`. **ALWAYS** include `-n 8` when running pytest locally, never run tests sequentially. CI uses `-n auto` (fewer cores on runners).
- **Parametrize**: Prefer `@pytest.mark.parametrize` for testing similar cases
- **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. Vendor names may only appear in: (1) Operations design page provider list (`docs/design/operations.md`), (2) `.claude/` skill/agent files, (3) third-party import paths/module names (e.g. `litellm.types.llms.openai`), (4) provider presets (`src/synthorg/providers/presets.py`) which are user-facing runtime data, (5) provider logo assets (`web/public/provider-logos/*.svg` plus the matching README) -- the SVG filenames mirror the preset names by necessity, and `<ProviderLogo>` falls back to a generic icon if a file is absent. Tests must use `test-provider`, `test-small-001`, etc.
- **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. Vendor names may only appear in: (1) `.claude/` skill/agent files, (2) third-party import paths/module names (e.g. `litellm.types.llms.openai`), (3) provider presets (`src/synthorg/providers/presets.py`) which are user-facing runtime data, (4) provider logo assets (`web/public/provider-logos/*.svg` plus the matching README) -- the SVG filenames mirror the preset names by necessity, and `<ProviderLogo>` falls back to a generic icon if a file is absent. Tests must use `test-provider`, `test-small-001`, etc.
- **Property-based testing**: Python uses [Hypothesis](https://hypothesis.readthedocs.io/), React uses [fast-check](https://fast-check.dev/), Go uses `testing.F` fuzz functions. CI runs 10 deterministic examples per property test (`derandomize=True`, no flakes). When Hypothesis finds a failure, it is a **real bug**: read the shrunk example, fix the underlying bug, and add an explicit `@example(...)` decorator so the case is permanently covered. See [docs/reference/claude-reference.md](docs/reference/claude-reference.md) §"Property-based Testing (Hypothesis): Deep Dive" for profile catalog, local fuzzing commands, and failure-handling workflow.
- **Flaky tests**: NEVER skip, dismiss, or ignore flaky tests; always fix them fully and fundamentally. For timing-sensitive tests, the **FakeClock-first** rule applies: if the class under test accepts a `clock=` parameter, inject `FakeClock` from `tests._shared.fake_clock` and drive virtual time via `clock.advance(...)` / `await clock.advance_async(...)`. Patch `time.monotonic()` / `asyncio.sleep()` at the module level only for legacy code paths that don't yet have a `Clock` seam. For tasks that must block indefinitely until cancelled (e.g. simulating a slow provider or stubborn coroutine), use `asyncio.Event().wait()` instead of `asyncio.sleep(large_number)`; it is cancellation-safe and carries no timing assumptions.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ SynthOrg is a Python framework for building **synthetic organizations**, autonom

Define your company in YAML. Agents collaborate through a message bus, follow workflows (Kanban, Agile sprints, or custom), track costs against budgets, and produce real artifacts. The framework is provider-agnostic (100+ LLMs via [LiteLLM](https://github.com/BerriAI/litellm)), configuration-driven ([Pydantic v2](https://docs.pydantic.dev/) models), and designed for the full autonomy spectrum, from human approval on every action to fully autonomous operation.

> **Early access.** Core subsystems are built and tested (25,000+ unit tests, 80%+ coverage). APIs may change between releases. See the [roadmap](https://synthorg.io/docs/roadmap/) for what's next.
> **Early access.** Core subsystems are built and tested (27,000+ tests, 80%+ coverage). APIs may change between releases. See the [roadmap](https://synthorg.io/docs/roadmap/) for what's next.

## Why SynthOrg?

Expand Down
1 change: 1 addition & 0 deletions docs/DESIGN_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ The design specification has been split into focused documentation pages for bet
| [Client Simulation](design/client-simulation.md) | Client Types, Intake, Review Pipeline, Simulation | Synthetic client framework for workload generation and evaluation |
| [Strategy & Trendslop Mitigation](design/strategy.md) | Lenses, Principles, Confidence, Impact | Anti-trendslop mitigation for strategic agents |
| [Self-Improvement](design/self-improvement.md) | Meta-Loop, Signals, Rules, Proposals, Rollout | Self-improving company: signal aggregation, rule engine, improvement proposals, staged rollout |
| [Internationalization](design/internationalization.md) | Locale Resolution, UI Text, Translation Scope | British English UI default, locale-aware Intl-based display formatting, no planned translation framework |

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

UI-locale default text conflicts with current implementation.

Line 46 says “British English UI default”, but web/src/utils/locale.ts:20-30 sets APP_LOCALE_FALLBACK = 'en' (neutral English). Please align the row with current behavior (or update runtime code to en-GB if that is the intended spec).

Proposed docs-only fix
-| [Internationalization](design/internationalization.md) | Locale Resolution, UI Text, Translation Scope | British English UI default, locale-aware Intl-based display formatting, no planned translation framework |
+| [Internationalization](design/internationalization.md) | Locale Resolution, UI Text, Translation Scope | Neutral English (`en`) fallback, locale-aware Intl-based display formatting, no planned translation framework |

Based on learnings: If implementation deviates from the spec, alert the user and explain why; the user decides whether to proceed or update the spec; do NOT silently diverge.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| [Internationalization](design/internationalization.md) | Locale Resolution, UI Text, Translation Scope | British English UI default, locale-aware Intl-based display formatting, no planned translation framework |
| [Internationalization](design/internationalization.md) | Locale Resolution, UI Text, Translation Scope | Neutral English (`en`) fallback, locale-aware Intl-based display formatting, no planned translation framework |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/DESIGN_SPEC.md` at line 46, The DESIGN_SPEC row claiming "British
English UI default" conflicts with the runtime constant APP_LOCALE_FALLBACK in
web/src/utils/locale.ts (currently set to 'en'); decide whether the
source-of-truth should be the spec or the code and make a single consistent
change: either update the docs row text to "Neutral English (en) UI default" to
match APP_LOCALE_FALLBACK, or change APP_LOCALE_FALLBACK to 'en-GB' and adjust
any Intl/formatting tests to use en-GB; ensure you update the unique identifiers
in the same commit (the spec table entry and the APP_LOCALE_FALLBACK constant)
so they stay aligned.


## Supporting Pages

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ All significant design and architecture decisions in force today, organized by d

| ID | Decision | Rationale | Alternatives considered |
|----|----------|-----------|------------------------|
| D16 | Docker MVP via `aiodocker`; `SandboxBackend` protocol for future backends | Docker cold start (1-2s) invisible against LLM latency (2-30s). Pre-built image + user config. Fail if Docker unavailable; no unsafe subprocess fallback. gVisor as config-level hardening upgrade | Docker + WASM (CPython can't run pip packages in WASM), Docker + Firecracker (Linux-only, requires KVM), docker-py (sync, no 3.14 support). Precedents: E2B, major cloud providers, Daytona (none offer unsandboxed fallback) |
| D16 | Layered `SandboxBackend` protocol via `aiodocker`. Subprocess default for low-risk categories (file_system, git); Docker required for high-risk (code_execution, terminal, database, web) | Subprocess is genuinely safe for read-only / workspace-scoped categories: env filtering (allowlist + denylist), restricted PATH, workspace-scoped cwd, timeout + process-group kill, library-injection-var blocking. Docker is required where arbitrary code or network egress can land. Layered design preserves the local-first quickstart (file/git tools work without Docker) without weakening isolation where it matters. Docker cold start (1-2s) is invisible against LLM latency (2-30s). gVisor remains a config-level hardening upgrade for the Docker tier | Docker + WASM (CPython can't run pip packages in WASM), Docker + Firecracker (Linux-only, requires KVM), docker-py (sync, no 3.14 support), Docker-only for every category (rejected: forces a running container for trivial file reads, breaks local-first quickstart, no isolation gain over subprocess for read-only file_system tools). Precedents: E2B, major cloud providers, Daytona |
| D17 | Official `mcp` Python SDK, exact-pinned (`==`), updated via Renovate; `MCPBridgeTool` adapter | Used by every major framework (LangChain, CrewAI, major agent SDKs, Pydantic AI). Python 3.14 compatible. Pydantic v2 compatible. Thin adapter isolates codebase from SDK changes | Custom MCP client (must implement protocol handshake, track spec changes manually) |
| D18 | MCP result mapping via adapter in `MCPBridgeTool` | Keep `ToolResult` as-is. Text concatenation for LLM path. Rich content in metadata. Zero disruption to existing codebase | Extend ToolResult for multi-modal (cascading changes across codebase; LLM providers consume as text anyway) |

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/tech-stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ The SynthOrg engine is structured as a set of loosely coupled subsystems. Each b
| **Product Telemetry** | Optional: Logfire (via `logfire` SDK), NoopReporter (default) | Opt-in anonymous product telemetry (disabled by default). Pluggable `TelemetryReporter` protocol with `PrivacyScrubber` (allowlist validation). Optional dependency: `telemetry = ["logfire"]`. |
| **Agent Communication** | A2A Protocol compatible | Future-proof inter-agent communication. See [Industry Standards](../reference/standards.md). |
| **Authentication** | PyJWT + argon2-cffi | JWT (HMAC HS256/384/512) for session tokens, Argon2id for password hashing, HMAC-SHA256 for API key storage (keyed with server secret). |
| **Name Generation** | Faker | Multi-locale agent name generation for templates and setup wizard. 57 Latin-script locales across 12 world regions, cached Faker instances, deterministic seeding for reproducible names. |
| **Name Generation** | Faker | Multi-locale agent name generation for templates and setup wizard. 57 Latin-script locales across 11 world regions, cached Faker instances, deterministic seeding for reproducible names. |
| **Config Format** | YAML + Pydantic validation | Human-readable config with strict validation. |
| **CLI** | Go (Cobra + charm.land/huh/v2, charm.land/lipgloss/v2) | Cross-platform binary for Docker lifecycle management: `init`, `start`, `stop`, `status`, `logs`, `update`, `doctor`, `uninstall`, `version`, `cleanup`, `backup`, `wipe`, `config`, `completion-install`. Update channel (stable/dev) selectable via `synthorg config set channel dev`. Distributed via GoReleaser + install scripts (`curl \| bash`, `irm \| iex`). Syft generates CycloneDX JSON SBOMs per archive (via GoReleaser `sboms:` stanza). Cosign keyless signing of checksums file (`.sig` + `.pem`). SLSA Level 3 provenance attestations on all release archives. Sigstore provenance bundle (`.sigstore.json`) attached to releases. |

Expand Down
2 changes: 1 addition & 1 deletion docs/design/communication.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ a bidirectional reference for the gateway translation layer.
| `COMPLETED` | `completed` | Bidirectional | Successful completion |
| `FAILED` | `failed` | Bidirectional | Unrecoverable failure |
| `CANCELLED` | `canceled` | Bidirectional | Client-initiated cancellation |
| `REJECTED` *(proposed)* | `rejected` | Bidirectional | Task refused by agent or guard (requires new TaskStatus value) |
| `REJECTED` | `rejected` | Bidirectional | Task refused by agent or guard |

**Gate verdict mapping** (not a task state):

Expand Down
1 change: 0 additions & 1 deletion docs/design/self-improvement.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ src/synthorg/meta/
ab_test.py -- A/B test group assignment and observation loop
ab_comparator.py -- Control vs treatment comparison (Welch-backed)
ab_models.py -- GroupAssignment, ABTestVerdict, GroupMetrics (sample-backed)
clock.py -- Clock protocol + RealClock (wall-time abstraction for tests)
roster.py -- OrgRoster protocol + CallableOrgRoster / NoOpOrgRoster
group_aggregator.py -- GroupSignalAggregator protocol + TrackerGroupAggregator
inverse_dispatch.py -- RollbackHandler protocol + 4 mutator protocols + default handlers
Expand Down
3 changes: 2 additions & 1 deletion docs/design/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ the local-first experience lightweight while providing strong isolation where it

Docker MVP uses `aiodocker` (async-native) with a pre-built image
(Python 3.14 + Node.js LTS + basic utils, <500MB). If Docker is unavailable, the framework
fails with a clear error; no unsafe subprocess fallback for code execution
fails with a clear error for any tool category whose configured backend is Docker;
low-risk categories (file_system, git) continue to run via subprocess
([Decision Log](../architecture/decisions.md) D16).

### Container Log Shipping
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/claude-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ curl http://localhost:3000/api/v1/readyz # backend (via web proxy)

```text
src/synthorg/
api/ # Litestar REST + WebSocket API, RFC 9457 errors, setup wizard, personality presets, auth/ (role-based access control, HttpOnly cookie sessions, CSRF double-submit, lockout_store, refresh_store, concurrent session enforcement, session store, user presence, OrgRole enum for org config permissions), guards (HumanRole-based + OrgRole-based with department scoping via require_org_mutation), user management (CRUD + org-role grant/revoke), dto_org (request DTOs for company/department/agent mutations), dto_workflow (request/response DTOs for workflow definition and execution operations), services/org_mutations (read-modify-write config mutation service), auto-wiring, lifecycle (auto-promote first owner), bootstrap (agent registry init from config), template packs (list + live-apply), memory admin (fine-tuning pipeline with orchestrator, checkpoint management, preflight checks, run history, embedder queries), optimistic concurrency (ETag/If-Match), TLS config, tiered rate limiting (unauth by IP, auth by user ID), rate_limits/policies (RATE_LIMIT_POLICIES canonical registry of (max_requests, window_seconds) defaults per operation id + per_op_rate_limit_from_policy helper; operator overrides flow through PerOpRateLimitConfig.overrides separately), workflows (visual workflow definition CRUD, validation, YAML export, blueprint listing, blueprint instantiation, version history, diff, rollback), workflow executions (activate, list, get, cancel), ceremony policy (project + per-department query/override, resolved policy with field origins), quality overrides (per-agent quality score override CRUD), reports (on-demand report generation, period listing), notification_dispatcher (fan-out notification sink), training (training plan CRUD, execution, preview, overrides)
api/ # Litestar REST + WebSocket API, RFC 9457 errors, setup wizard, personality presets, auth/ (role-based access control, HttpOnly cookie sessions, CSRF double-submit, lockout / refresh-token / session repositories under persistence/{sqlite,postgres}/, concurrent session enforcement, user presence, OrgRole enum for org config permissions), guards (HumanRole-based + OrgRole-based with department scoping via require_org_mutation), user management (CRUD + org-role grant/revoke), dto_org (request DTOs for company/department/agent mutations), dto_workflow (request/response DTOs for workflow definition and execution operations), services/org_mutations (read-modify-write config mutation service), auto-wiring, lifecycle (auto-promote first owner), bootstrap (agent registry init from config), template packs (list + live-apply), memory admin (fine-tuning pipeline with orchestrator, checkpoint management, preflight checks, run history, embedder queries), optimistic concurrency (ETag/If-Match), TLS config, tiered rate limiting (unauth by IP, auth by user ID), rate_limits/policies (RATE_LIMIT_POLICIES canonical registry of (max_requests, window_seconds) defaults per operation id + per_op_rate_limit_from_policy helper; operator overrides flow through PerOpRateLimitConfig.overrides separately), workflows (visual workflow definition CRUD, validation, YAML export, blueprint listing, blueprint instantiation, version history, diff, rollback), workflow executions (activate, list, get, cancel), ceremony policy (project + per-department query/override, resolved policy with field origins), quality overrides (per-agent quality score override CRUD), reports (on-demand report generation, period listing), notification_dispatcher (fan-out notification sink), training (training plan CRUD, execution, preview, overrides)
backup/ # Backup/restore orchestrator, scheduler, retention, handlers/
budget/ # Cost tracking, budget enforcement, quota degradation (including synchronous peek for routing-time selector hints), CFO optimization, trend analysis, budget forecasting, configurable currency formatting, risk budget (cumulative risk-unit tracking, risk scoring integration, risk check, risk records), automated reporting (periodic comprehensive reports, spending/performance/task-completion/risk-trends templates, report scheduling config), coordination metrics (9 empirical metrics: efficiency, overhead, error amplification, message density, redundancy, Amdahl ceiling, straggler gap, token/speedup ratio, message overhead), project cost aggregates (durable per-project lifetime cost totals surviving retention pruning)
cli/ # Python CLI module (superseded by top-level cli/ Go binary)
Expand Down
Loading
Loading