Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ src/ai_company/
persistence/ # Operational data persistence — pluggable PersistenceBackend protocol, SQLite initial (§7.6)
observability/ # Structured logging, correlation tracking, log sinks
providers/ # LLM provider abstraction (LiteLLM adapter)
security/ # SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, risk classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies: disabled/weighted/per-category/milestone)
security/ # SecOps agent, rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, risk classifier, risk tier classifier, action type registry, ToolInvoker security integration, progressive trust (4 strategies: disabled/weighted/per-category/milestone), autonomy levels (presets, resolver, change strategy), timeout policies (park/resume)
templates/ # Pre-built company templates, personality presets, and builder
tools/ # Tool registry, built-in tools (file_system/, git, sandbox/, code_runner), MCP bridge (mcp/), role-based access
```
Expand Down Expand Up @@ -84,7 +84,7 @@ src/ai_company/
- **Every module** with business logic MUST have: `from ai_company.observability import get_logger` then `logger = get_logger(__name__)`
- **Never** use `import logging` / `logging.getLogger()` / `print()` in application code
- **Variable name**: always `logger` (not `_logger`, not `log`)
- **Event names**: always use constants from the domain-specific module under `ai_company.observability.events` (e.g. `PROVIDER_CALL_START` from `events.provider`, `BUDGET_RECORD_ADDED` from `events.budget`, `CFO_ANOMALY_DETECTED` from `events.cfo`, `CONFLICT_DETECTED` from `events.conflict`, `MEETING_STARTED` from `events.meeting`, `CLASSIFICATION_START` from `events.classification`, `CONSOLIDATION_START` from `events.consolidation`, `ORG_MEMORY_QUERY_START` from `events.org_memory`, `API_REQUEST_STARTED` from `events.api`, `CODE_RUNNER_EXECUTE_START` from `events.code_runner`, `DOCKER_EXECUTE_START` from `events.docker`, `MCP_INVOKE_START` from `events.mcp`, `SECURITY_EVALUATE_START` from `events.security`, `HR_HIRING_REQUEST_CREATED` from `events.hr`, `PERF_METRIC_RECORDED` from `events.performance`, `TRUST_EVALUATE_START` from `events.trust`, `PROMOTION_EVALUATE_START` from `events.promotion`, `PROMPT_BUILD_START` from `events.prompt`, `MEMORY_RETRIEVAL_START` from `events.memory`). Import directly: `from ai_company.observability.events.<domain> import EVENT_CONSTANT`
- **Event names**: always use constants from the domain-specific module under `ai_company.observability.events` (e.g. `PROVIDER_CALL_START` from `events.provider`, `BUDGET_RECORD_ADDED` from `events.budget`, `CFO_ANOMALY_DETECTED` from `events.cfo`, `CONFLICT_DETECTED` from `events.conflict`, `MEETING_STARTED` from `events.meeting`, `CLASSIFICATION_START` from `events.classification`, `CONSOLIDATION_START` from `events.consolidation`, `ORG_MEMORY_QUERY_START` from `events.org_memory`, `API_REQUEST_STARTED` from `events.api`, `CODE_RUNNER_EXECUTE_START` from `events.code_runner`, `DOCKER_EXECUTE_START` from `events.docker`, `MCP_INVOKE_START` from `events.mcp`, `SECURITY_EVALUATE_START` from `events.security`, `HR_HIRING_REQUEST_CREATED` from `events.hr`, `PERF_METRIC_RECORDED` from `events.performance`, `TRUST_EVALUATE_START` from `events.trust`, `PROMOTION_EVALUATE_START` from `events.promotion`, `PROMPT_BUILD_START` from `events.prompt`, `MEMORY_RETRIEVAL_START` from `events.memory`, `AUTONOMY_ACTION_AUTO_APPROVED` from `events.autonomy`, `TIMEOUT_POLICY_EVALUATED` from `events.timeout`). Import directly: `from ai_company.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
Expand Down
29 changes: 25 additions & 4 deletions DESIGN_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The MVP validates the core hypothesis: **a single agent can complete a real task
> **How to read this spec:** Sections describe the full vision. Each section with deferred features includes an **MVP** callout box indicating what ships in M3 and what is deferred. The full design is documented upfront to inform architecture decisions — protocol interfaces are designed even for features that won't be built until later milestones.

> **Implementation snapshot (2026-03-10):**
> - **Done:** M0–M6 (tooling, config/core, providers, single-agent engine, multi-agent orchestration, API/CLI surface) + Docker sandbox (#50), MCP bridge (#53), code runner + HR engine (hiring/firing/onboarding/offboarding/registry) + performance tracking (task metrics, quality scoring, collaboration scoring, trend detection, rolling windows). Memory layer backend selected ([ADR-001](docs/decisions/ADR-001-memory-layer.md)). Persistence backend (§7.6) completed. Memory retrieval pipeline (#41: ranking, token-budget formatting, context injection, non-inferable filtering) complete. Budget enforcement complete (BudgetEnforcer + configurable cost tiers + quota/subscription tracking). CFO cost optimization complete (CostOptimizer: anomaly detection, efficiency analysis, downgrade recommendations, routing optimization, approval decisions; ReportGenerator: multi-dimensional spending reports). Shared org memory (#125: HybridPromptRetrievalBackend, OrgFactStore, access control, factory) complete. Memory consolidation/archival (#48: ConsolidationService, SimpleConsolidationStrategy, RetentionEnforcer, ArchivalStore protocol) complete. SecOps agent (rule engine, audit log, output scanner, risk classifier, ToolInvoker integration), progressive trust (4 strategies: disabled/weighted/per-category/milestone behind TrustStrategy protocol), promotion/demotion (criteria evaluation, approval strategies, model mapping).
> - **Done:** M0–M6 (tooling, config/core, providers, single-agent engine, multi-agent orchestration, API/CLI surface) + Docker sandbox (#50), MCP bridge (#53), code runner + HR engine (hiring/firing/onboarding/offboarding/registry) + performance tracking (task metrics, quality scoring, collaboration scoring, trend detection, rolling windows). Memory layer backend selected ([ADR-001](docs/decisions/ADR-001-memory-layer.md)). Persistence backend (§7.6) completed. Memory retrieval pipeline (#41: ranking, token-budget formatting, context injection, non-inferable filtering) complete. Budget enforcement complete (BudgetEnforcer + configurable cost tiers + quota/subscription tracking). CFO cost optimization complete (CostOptimizer: anomaly detection, efficiency analysis, downgrade recommendations, routing optimization, approval decisions; ReportGenerator: multi-dimensional spending reports). Shared org memory (#125: HybridPromptRetrievalBackend, OrgFactStore, access control, factory) complete. Memory consolidation/archival (#48: ConsolidationService, SimpleConsolidationStrategy, RetentionEnforcer, ArchivalStore protocol) complete. SecOps agent (rule engine, audit log, output scanner, risk classifier, ToolInvoker integration), progressive trust (4 strategies: disabled/weighted/per-category/milestone behind TrustStrategy protocol), promotion/demotion (criteria evaluation, approval strategies, model mapping). Autonomy levels (#42: AutonomyLevel enum, presets, 3-level resolver, rule-based auto-downgrade/human-only promotion change strategy) + approval timeout policies (#126: 4 timeout policies, park/resume service, risk tier classifier, timeout checker) complete.
> - **Remaining:** JWT/OAuth auth, approval workflow gates.

### 1.5 Configuration Philosophy
Expand Down Expand Up @@ -232,6 +232,7 @@ agent:
reports_to: "engineering_lead"
can_delegate_to: ["junior_developers"]
budget_limit: 5.00 # max USD per task
autonomy_level: null # optional: full, semi, supervised, locked (overrides department/company default, §12.2)
hiring_date: "2026-02-27"
status: "active" # active, on_leave, terminated (on config model today)

Expand Down Expand Up @@ -1558,7 +1559,7 @@ persistence:
| `CostRecord` | `budget/cost_record.py` | `CostRecordRepository` | by agent, by task, aggregations |
| `Message` | `communication/message.py` | `MessageRepository` | by channel |
| Audit entries (planned — M7) | `security/` | `AuditRepository` (planned) | by agent, by action type, time range |
| `ParkedContext` (planned — M7) | `engine/` | `ParkedContextRepository` (planned) | by execution_id, by agent_id, by task_id |
| `ParkedContext` | `security/timeout/parked_context.py` | `ParkedContextRepository` | by execution_id, by agent_id, by task_id |
| Agent runtime state (planned — M7) | `engine/` | `AgentStateRepository` (planned) | by agent_id, active agents |

#### Migration Strategy
Expand Down Expand Up @@ -2963,7 +2964,7 @@ ai-company/
│ ├── persistence/ # Operational data persistence (§7.6)
│ │ ├── __init__.py # Package exports
│ │ ├── protocol.py # PersistenceBackend protocol (M5)
│ │ ├── repositories.py # Repository protocols: TaskRepository, CostRecordRepository, MessageRepository (M5); AuditRepository planned (M7)
│ │ ├── repositories.py # Repository protocols: TaskRepository, CostRecordRepository, MessageRepository, ParkedContextRepository (M5); AuditRepository planned (M7)
│ │ ├── config.py # PersistenceConfig model (M5)
│ │ ├── errors.py # Persistence error hierarchy (M5)
│ │ ├── factory.py # create_backend() factory (M5)
Expand All @@ -2972,6 +2973,7 @@ ai-company/
│ │ ├── backend.py # SQLitePersistenceBackend
│ │ ├── repositories.py # SQLite repository implementations
│ │ ├── hr_repositories.py # SQLite HR repositories (LifecycleEvent, TaskMetricRecord, CollaborationMetricRecord)
│ │ ├── parked_context_repo.py # SQLiteParkedContextRepository (park/resume serialized agent state)
│ │ └── migrations.py # Schema migrations (user_version pragma)
│ ├── observability/ # Structured logging & correlation
│ │ ├── __init__.py # get_logger() entry point
Expand All @@ -2982,6 +2984,7 @@ ai-company/
│ │ ├── events/ # Per-domain event constants
│ │ │ ├── __init__.py # Package marker with usage docs; no re-exports
│ │ │ ├── api.py # API_* event constants
│ │ │ ├── autonomy.py # AUTONOMY_* constants
│ │ │ ├── budget.py # BUDGET_* constants
│ │ │ ├── cfo.py # CFO_* constants
│ │ │ ├── classification.py # CLASSIFICATION_* constants
Expand Down Expand Up @@ -3014,6 +3017,7 @@ ai-company/
│ │ │ ├── task_assignment.py # TASK_ASSIGNMENT_* constants
│ │ │ ├── task_routing.py # TASK_ROUTING_* constants
│ │ │ ├── template.py # TEMPLATE_* constants
│ │ │ ├── timeout.py # TIMEOUT_* constants
│ │ │ ├── tool.py # TOOL_* constants
│ │ │ ├── workspace.py # WORKSPACE_* constants
│ │ │ ├── code_runner.py # CODE_RUNNER_* constants
Expand Down Expand Up @@ -3100,6 +3104,23 @@ ai-company/
│ │ ├── output_scanner.py # Post-tool output scanning (regex-based redaction)
│ │ ├── protocol.py # SecurityInterceptionStrategy protocol
│ │ ├── service.py # SecOpsService — meta-agent coordinating security
│ │ ├── autonomy/ # Autonomy levels, presets, resolver, change strategy (§12.2)
│ │ │ ├── __init__.py # Package exports
│ │ │ ├── models.py # AutonomyLevel enum, AutonomyPreset, AutonomyConfig, AutonomyChangeEvent
│ │ │ ├── protocol.py # AutonomyChangeStrategy protocol
│ │ │ ├── change_strategy.py # Rule-based auto-downgrade + human-only promotion strategy
│ │ │ └── resolver.py # AutonomyResolver (agent → department → company chain)
│ │ ├── timeout/ # Approval timeout policies, park/resume, risk tier classifier (§12.4)
│ │ │ ├── __init__.py # Package exports
│ │ │ ├── config.py # TimeoutPolicyConfig
│ │ │ ├── factory.py # build_timeout_policy() factory
│ │ │ ├── models.py # TimeoutDecision, RiskTier
│ │ │ ├── park_service.py # ParkResumeService (park/resume blocked tasks)
│ │ │ ├── parked_context.py # ParkedContext model (serialized agent state)
│ │ │ ├── policies.py # WaitForeverPolicy, AutoDenyPolicy, TieredPolicy, EscalationChainPolicy
│ │ │ ├── protocol.py # TimeoutPolicy protocol
│ │ │ ├── risk_tier_classifier.py # RiskTierClassifier (ActionType → RiskTier)
│ │ │ └── timeout_checker.py # TimeoutChecker (polls pending approvals)
│ │ └── rules/ # Rule engine and detectors
│ │ ├── engine.py # RuleEngine (soft-allow + hard-deny, fail-closed)
│ │ ├── protocol.py # SecurityRule protocol
Expand Down Expand Up @@ -3147,7 +3168,7 @@ ai-company/
│ │ ├── bus_bridge.py # Message-bus → WebSocket bridge
│ │ ├── channels.py # WebSocket channel definitions
│ │ ├── config.py # API configuration models (ServerConfig, CorsConfig)
│ │ ├── controllers/ # 13 class-based controllers + 1 WebSocket handler (14 route modules)
│ │ ├── controllers/ # 14 class-based controllers + 1 WebSocket handler (15 route modules)
│ │ ├── dto.py # Request/response DTOs and envelopes
│ │ ├── errors.py # API error hierarchy (ApiError, NotFoundError, etc.)
│ │ ├── exception_handlers.py # Litestar exception handler registration
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ AI Company lets you spin up a virtual organization staffed entirely by AI agents

- **Memory Backend Adapter (M5)** - Memory protocols, retrieval pipeline, org memory, and consolidation are complete; initial Mem0 adapter backend ([ADR-001](docs/decisions/ADR-001-memory-layer.md)) pending; research backends (GraphRAG, Temporal KG) planned
- **CLI Surface** - `cli/` package is placeholder-only
- **Security/Approval System (M7)** - SecOps agent with rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, risk classifier, and ToolInvoker integration are implemented; real authentication (JWT/OAuth) and approval workflow gates are planned
- **Security/Approval System (M7)** - SecOps agent with rule engine (soft-allow/hard-deny, fail-closed), audit log, output scanner, risk classifier, and ToolInvoker integration are implemented; progressive trust (4 strategies), promotion/demotion, autonomy levels (5 tiers with presets, resolver, change strategies) and approval timeout policies (wait-forever, auto-deny, tiered, escalation-chain with task park/resume) are implemented; real authentication (JWT/OAuth) and approval workflow gates are planned
- **Advanced Product Surface** - web dashboard, external integrations

## Status
Expand Down
3 changes: 3 additions & 0 deletions src/ai_company/api/controllers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from ai_company.api.controllers.analytics import AnalyticsController
from ai_company.api.controllers.approvals import ApprovalsController
from ai_company.api.controllers.artifacts import ArtifactController
from ai_company.api.controllers.autonomy import AutonomyController
from ai_company.api.controllers.budget import BudgetController
from ai_company.api.controllers.company import CompanyController
from ai_company.api.controllers.departments import DepartmentController
Expand All @@ -31,6 +32,7 @@
AnalyticsController,
ProviderController,
ApprovalsController,
AutonomyController,
)

__all__ = [
Expand All @@ -39,6 +41,7 @@
"AnalyticsController",
"ApprovalsController",
"ArtifactController",
"AutonomyController",
"BudgetController",
"CompanyController",
"Controller",
Expand Down
Loading