Skip to content

refactor: split events.py into per-domain event modules#136

Merged
Aureliolo merged 3 commits intomainfrom
refactor/split-events-per-domain
Mar 6, 2026
Merged

refactor: split events.py into per-domain event modules#136
Aureliolo merged 3 commits intomainfrom
refactor/split-events-per-domain

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

  • Split monolithic observability/events.py (104 constants) into 10 per-domain submodules under observability/events/ (budget, config, execution, prompt, provider, role, routing, task, template, tool)
  • Update all 23 source files and 13 test files to import from domain-specific modules (from ai_company.observability.events.<domain> import CONSTANT)
  • Package __init__.py is a docstring-only marker with __all__ = [] — no re-exports, enforcing direct domain imports
  • Update CLAUDE.md logging convention and DESIGN_SPEC.md project tree + §15.5 conventions table
  • Add attr.isupper() guard to test helper for robustness
  • Add spot-check tests for all 10 domain modules (was 6, now 10)

Closes #110

Test plan

  • All 1816 tests pass (pytest -n auto)
  • 94.96% coverage (threshold: 80%)
  • mypy strict: 0 issues across 210 files
  • ruff lint + format: clean
  • Pre-commit hooks: all pass
  • 104 constants preserved 1:1 (zero lost, zero duplicated, zero renamed)
  • Zero stale old-style imports remain in codebase

Review coverage

Pre-reviewed by 9 agents: code-reviewer, python-reviewer, pr-test-analyzer, silent-failure-hunter, comment-analyzer, type-design-analyzer, logging-audit, resilience-audit, docs-consistency. 5 findings addressed, 2 minor items skipped (stylistic).

Aureliolo and others added 2 commits March 6, 2026 14:00
Replace monolithic observability/events.py with a per-domain package
(events/config.py, events/provider.py, events/budget.py, etc.) for
better locality and scalability as new domains are added in M3+.

Update all 37 source and test imports to use domain-specific modules.
No backwards-compat re-exports — clean break.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update DESIGN_SPEC.md §15.5 event constants row from "Adopted (flat)"
  to "Adopted (per-domain)" to reflect the new package structure
- Add attr.isupper() guard to _all_event_names() test helper to prevent
  accidental inclusion of non-constant string attributes
- Add __all__: list[str] = [] to events/__init__.py to explicitly signal
  no re-exports from the package
- Soften docstring convention from strict "domain.noun.verb" to
  "domain.noun[.verb]" to accommodate two-segment event names
- Add spot-check tests for execution, routing, prompt, and tool domains

Pre-reviewed by 9 agents, 5 findings addressed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 6, 2026 13:11
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 6, 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 6, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e3a53678-887d-43c5-a5b7-985b49413486

📥 Commits

Reviewing files that changed from the base of the PR and between 4b57b0d and 1274c70.

📒 Files selected for processing (14)
  • DESIGN_SPEC.md
  • src/ai_company/observability/events/__init__.py
  • src/ai_company/observability/events/budget.py
  • src/ai_company/observability/events/config.py
  • src/ai_company/observability/events/execution.py
  • src/ai_company/observability/events/prompt.py
  • src/ai_company/observability/events/provider.py
  • src/ai_company/observability/events/role.py
  • src/ai_company/observability/events/routing.py
  • src/ai_company/observability/events/task.py
  • src/ai_company/observability/events/template.py
  • src/ai_company/observability/events/tool.py
  • tests/unit/engine/test_prompt.py
  • tests/unit/observability/test_events.py

📝 Walkthrough

Summary by CodeRabbit

  • Refactor

    • Observability event identifiers reorganized into domain-specific event namespaces (e.g., budget, config, execution, provider, task, template, tool, etc.) instead of a single centralized module.
  • Documentation

    • Usage guidance updated to import event identifiers from the appropriate domain-specific event namespace.
  • Tests

    • Tests updated to discover and assert domain-specific event identifiers and to use the new domain constants instead of hard-coded strings.

Walkthrough

The PR reorganizes observability event constants from a single flat module (ai_company.observability.events) into a per-domain package with submodules (budget, config, execution, prompt, provider, role, routing, task, template, tool). The old flat module is removed and imports across the codebase are updated to domain-specific modules.

Changes

Cohort / File(s) Summary
Event Module Restructuring
src/ai_company/observability/events.py, src/ai_company/observability/events/__init__.py, src/ai_company/observability/events/*
Removed the monolithic events.py. Added events package with per-domain modules (budget.py, config.py, execution.py, prompt.py, provider.py, role.py, routing.py, task.py, template.py, tool.py). __init__.py contains guidance and no re-exports (__all__ = []).
Budget
src/ai_company/budget/tracker.py, tests/unit/budget/test_tracker.py
Imports changed to ai_company.observability.events.budget for budget event constants.
Config
src/ai_company/config/loader.py, src/ai_company/config/schema.py, tests/unit/config/test_loader.py
Imports changed to ai_company.observability.events.config; new config-specific constants used.
Core (role/task)
src/ai_company/core/role_catalog.py, src/ai_company/core/task.py, src/ai_company/core/task_transitions.py, tests/unit/core/*
Role and task event imports updated to ...events.role and ...events.task.
Engine / Execution / Prompt
src/ai_company/engine/*, tests/unit/engine/*
Execution- and prompt-related imports moved to ai_company.observability.events.execution and ...events.prompt; some modules import additional execution constants.
Provider
src/ai_company/providers/..., tests/unit/providers/*
Provider-related imports updated to ai_company.observability.events.provider across drivers, registry, resilience, and tests.
Routing
src/ai_company/providers/routing/*, tests/unit/providers/routing/test_router.py
Routing event imports updated to ai_company.observability.events.routing.
Template
src/ai_company/templates/*, tests/unit/templates/test_renderer.py
Template event imports updated to ai_company.observability.events.template; renderer imports expanded with render-error constants.
Tool
src/ai_company/tools/*, tests/unit/*
Tool event imports updated to ai_company.observability.events.tool; invoker and registry import expanded sets.
Tests: event discovery
tests/unit/observability/test_events.py
Test discovery refactored to iterate ai_company.observability.events submodules via pkgutil and import constants from each domain module; assertions updated for per-domain constants.
Docs & Design
CLAUDE.md, DESIGN_SPEC.md
Documentation updated to instruct importing event constants from domain-specific modules rather than a single flat module.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR does not fully meet the acceptance criteria from issue #110. The issue requires re-exports in init.py for backward compatibility, but the implementation uses all = [] with no re-exports, breaking existing imports. Either add re-exports in observability/events/init.py to maintain backward compatibility as specified in #110, or confirm this breaking change is intentional and update issue #110 acceptance criteria accordingly.
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 100.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'refactor: split events.py into per-domain event modules' accurately describes the main change: reorganizing a monolithic events module into domain-specific submodules.
Description check ✅ Passed The PR description is comprehensive and directly related to the changeset, detailing the split of events.py, file updates, testing results, and issue closure.
Out of Scope Changes check ✅ Passed All changes are in scope: splitting events.py into per-domain modules, updating imports across 36 files, updating documentation, and adding tests for the new structure.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/split-events-per-domain

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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 organization and maintainability of event constants by transitioning from a single, large module to a structured package with domain-specific submodules. This change improves code discoverability, reduces potential merge conflicts as the system grows, and ensures a clearer separation of concerns for observability events. The refactoring also involved comprehensive updates to all affected imports and relevant documentation, ensuring consistency across the codebase.

Highlights

  • Code Organization: The monolithic observability/events.py file, containing 104 event constants, was refactored into 10 distinct per-domain submodules under a new observability/events/ package. This improves modularity and maintainability.
  • Import Updates: All 23 source files and 13 test files were updated to reflect the new modular structure, importing event constants directly from their domain-specific modules (e.g., from ai_company.observability.events.<domain> import CONSTANT).
  • Documentation Updates: The CLAUDE.md logging convention and DESIGN_SPEC.md project tree and conventions table were updated to reflect the new event constant import guidelines and module structure.
  • Test Enhancements: An attr.isupper() guard was added to a test helper for increased robustness, and spot-check tests were expanded to cover all 10 new domain modules, up from 6.
Changelog
  • CLAUDE.md
    • Updated logging convention to reflect domain-specific event imports.
  • DESIGN_SPEC.md
    • Updated project tree to include the new events/ directory and its submodules.
    • Revised the 'Event constants' convention table entry to describe the new per-domain module approach.
  • src/ai_company/budget/tracker.py
    • Updated import statement for budget-related event constants to use the new events.budget submodule.
  • src/ai_company/config/loader.py
    • Updated import statement for config-related event constants to use the new events.config submodule.
  • src/ai_company/config/schema.py
    • Updated import statement for config-related event constants to use the new events.config submodule.
  • src/ai_company/core/role_catalog.py
    • Updated import statement for role-related event constants to use the new events.role submodule.
  • src/ai_company/core/task.py
    • Updated import statement for task-related event constants to use the new events.task submodule.
  • src/ai_company/core/task_transitions.py
    • Updated import statement for task-related event constants to use the new events.task submodule.
  • src/ai_company/engine/context.py
    • Updated import statement for execution-related event constants to use the new events.execution submodule.
  • src/ai_company/engine/prompt.py
    • Updated import statement for prompt-related event constants to use the new events.prompt submodule.
  • src/ai_company/engine/task_execution.py
    • Updated import statement for execution-related event constants to use the new events.execution submodule.
  • src/ai_company/observability/events.py
    • Removed the file, as its contents were distributed into new domain-specific modules.
  • src/ai_company/observability/events/init.py
    • Added an __init__.py file to mark events as a Python package, containing a docstring and an empty __all__ list to enforce direct submodule imports.
  • src/ai_company/observability/events/budget.py
    • Added a new module containing budget lifecycle event constants.
  • src/ai_company/observability/events/config.py
    • Added a new module containing config lifecycle event constants.
  • src/ai_company/observability/events/execution.py
    • Added a new module containing execution lifecycle event constants.
  • src/ai_company/observability/events/prompt.py
    • Added a new module containing prompt construction event constants.
  • src/ai_company/observability/events/provider.py
    • Added a new module containing provider lifecycle and resilience event constants.
  • src/ai_company/observability/events/role.py
    • Added a new module containing role catalog event constants.
  • src/ai_company/observability/events/routing.py
    • Added a new module containing routing lifecycle event constants.
  • src/ai_company/observability/events/task.py
    • Added a new module containing task state machine event constants.
  • src/ai_company/observability/events/template.py
    • Added a new module containing template lifecycle event constants.
  • src/ai_company/observability/events/tool.py
    • Added a new module containing tool lifecycle event constants.
  • src/ai_company/providers/base.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • src/ai_company/providers/drivers/litellm_driver.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • src/ai_company/providers/drivers/mappers.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • src/ai_company/providers/registry.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • src/ai_company/providers/resilience/rate_limiter.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • src/ai_company/providers/resilience/retry.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • src/ai_company/providers/routing/resolver.py
    • Updated import statement for routing-related event constants to use the new events.routing submodule.
  • src/ai_company/providers/routing/router.py
    • Updated import statement for routing-related event constants to use the new events.routing submodule.
  • src/ai_company/providers/routing/strategies.py
    • Updated import statement for routing-related event constants to use the new events.routing submodule.
  • src/ai_company/templates/loader.py
    • Updated import statement for template-related event constants to use the new events.template submodule.
  • src/ai_company/templates/renderer.py
    • Updated import statement for template-related event constants to use the new events.template submodule.
  • src/ai_company/tools/base.py
    • Updated import statement for tool-related event constants to use the new events.tool submodule.
  • src/ai_company/tools/invoker.py
    • Updated import statement for tool-related event constants to use the new events.tool submodule.
  • src/ai_company/tools/registry.py
    • Updated import statement for tool-related event constants to use the new events.tool submodule.
  • tests/unit/budget/test_tracker.py
    • Updated import statement for budget-related event constants to use the new events.budget submodule.
  • tests/unit/config/test_loader.py
    • Updated import statement for config-related event constants to use the new events.config submodule.
  • tests/unit/core/test_task.py
    • Updated import statement for task-related event constants to use the new events.task submodule.
  • tests/unit/core/test_task_transitions.py
    • Updated import statement for task-related event constants to use the new events.task submodule.
  • tests/unit/engine/test_context.py
    • Updated import statement for execution-related event constants to use the new events.execution submodule.
  • tests/unit/engine/test_task_execution.py
    • Updated import statement for execution-related event constants to use the new events.execution submodule.
  • tests/unit/observability/test_events.py
    • Updated the _all_event_names helper function to iterate through the new event submodules.
    • Added new test cases to verify the existence of events in the new budget, execution, routing, prompt, and tool modules.
    • Updated existing test cases to import event constants from their new domain-specific modules.
  • tests/unit/providers/resilience/test_rate_limiter.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • tests/unit/providers/resilience/test_retry.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • tests/unit/providers/routing/test_router.py
    • Updated import statements for routing-related event constants to use the new events.routing submodule.
  • tests/unit/providers/test_base_provider.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • tests/unit/providers/test_registry.py
    • Updated import statement for provider-related event constants to use the new events.provider submodule.
  • tests/unit/templates/test_renderer.py
    • Updated import statement for template-related event constants to use the new events.template submodule.
Activity
  • The pull request description indicates that the changes were pre-reviewed by 9 agents (code-reviewer, python-reviewer, pr-test-analyzer, silent-failure-hunter, comment-analyzer, type-design-analyzer, logging-audit, resilience-audit, docs-consistency).
  • 5 findings from the pre-review were addressed, and 2 minor stylistic items were intentionally skipped.
  • The author confirmed that all 1816 tests passed, coverage remained high at 94.96% (above 80% threshold), mypy strict had 0 issues, ruff lint and format were clean, and all pre-commit hooks passed.
  • Verification steps confirmed that all 104 constants were preserved 1:1, with zero lost, duplicated, or renamed, and no stale old-style imports remained in the codebase.
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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

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.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 6, 2026

Greptile Summary

This PR successfully refactors the monolithic observability/events.py (104 constants) into 10 per-domain submodules under observability/events/, updating all 23 source files and 13 test files to import from their respective domain module.

Migration completeness: All 104 constants are accounted for across the 10 new modules with no renames, losses, or duplicates. The old flat events.py is deleted with no backward-compatibility shim (intentional, since this is an internal module).

Import updates: All 23 source files correctly import from their domain-specific modules using the pattern from ai_company.observability.events.<domain> import CONSTANT.

Package structure: The __init__.py is a documentation-only marker with __all__ = [], enforcing direct imports and preventing accidental re-exports.

Test coverage: Comprehensive test suite with dynamic pkgutil-based discovery, dot-pattern validation, uniqueness enforcement, and per-domain spot-checks for all 10 domains.

Documentation: CLAUDE.md logging convention and DESIGN_SPEC.md project tree and §15.5 table are accurately updated to reflect the new module structure.

The refactoring is purely mechanical with zero functional changes and thorough test validation.

Confidence Score: 5/5

  • Safe to merge — purely mechanical refactoring with complete coverage, zero functional changes, and thorough test validation.
  • All 104 constants are migrated 1:1 with their original string values, all 23 consumer files are updated, the old flat module is fully deleted, and tests dynamically verify the complete set. No files require special attention.
  • No files require special attention

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    subgraph NEW["After: events/ package"]
        PKG["events/__init__.py\n(package marker, __all__=)"]
        B["events/budget.py - 7 constants"]
        C["events/config.py - 9 constants"]
        EX["events/execution.py - 11 constants"]
        P["events/prompt.py - 7 constants"]
        PR["events/provider.py - 27 constants"]
        RO["events/role.py - 1 constant"]
        RT["events/routing.py - 11 constants"]
        T["events/task.py - 3 constants"]
        TM["events/template.py - 13 constants"]
        TL["events/tool.py - 15 constants"]
    end

    PKG --- B & C & EX & P & PR & RO & RT & T & TM & TL

    BC["budget/tracker.py"] -->|"from events.budget import ..."| B
    CF["config/loader.py"] -->|"from events.config import ..."| C
    EP["engine/prompt.py"] -->|"from events.prompt import ..."| P
    PB["providers/base.py"] -->|"from events.provider import ..."| PR
    TR["providers/routing/router.py"] -->|"from events.routing import ..."| RT
Loading

Last reviewed commit: 1274c70

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refactors observability event constants by replacing the monolithic src/ai_company/observability/events.py with a per-domain src/ai_company/observability/events/ package, and updates internal imports/tests/docs to use domain-scoped event modules.

Changes:

  • Split event constants into per-domain modules (events/{budget,config,execution,prompt,provider,role,routing,task,template,tool}.py) and removed the old flat events.py.
  • Updated source + test imports to from ai_company.observability.events.<domain> import <CONSTANT>.
  • Updated docs (CLAUDE.md, DESIGN_SPEC.md) and expanded/adjusted event constant tests to enumerate modules under the new package.

Reviewed changes

Copilot reviewed 50 out of 50 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/unit/templates/test_renderer.py Updates template event imports to events.template.
tests/unit/providers/test_registry.py Updates provider event imports to events.provider.
tests/unit/providers/test_base_provider.py Updates provider event imports to events.provider.
tests/unit/providers/routing/test_router.py Updates routing event imports to events.routing (including in-function import).
tests/unit/providers/resilience/test_retry.py Updates resilience/provider event imports to events.provider.
tests/unit/providers/resilience/test_rate_limiter.py Updates rate-limiter/provider event imports to events.provider.
tests/unit/observability/test_events.py Updates event constant discovery to iterate per-domain modules; adds spot-check assertions for all domains.
tests/unit/engine/test_task_execution.py Updates execution event imports to events.execution.
tests/unit/engine/test_context.py Updates execution event imports to events.execution.
tests/unit/core/test_task_transitions.py Updates task transition event imports to events.task.
tests/unit/core/test_task.py Updates task event imports to events.task.
tests/unit/config/test_loader.py Updates config event imports to events.config.
tests/unit/budget/test_tracker.py Updates budget event imports to events.budget.
src/ai_company/tools/registry.py Updates tool event imports to events.tool.
src/ai_company/tools/invoker.py Updates tool event imports to events.tool.
src/ai_company/tools/base.py Updates tool event import to events.tool.
src/ai_company/templates/renderer.py Updates template event imports to events.template.
src/ai_company/templates/loader.py Updates template event imports to events.template.
src/ai_company/providers/routing/strategies.py Updates routing event imports to events.routing.
src/ai_company/providers/routing/router.py Updates routing event imports to events.routing.
src/ai_company/providers/routing/resolver.py Updates routing event imports to events.routing.
src/ai_company/providers/resilience/retry.py Updates provider/resilience event imports to events.provider.
src/ai_company/providers/resilience/rate_limiter.py Updates provider/resilience event imports to events.provider.
src/ai_company/providers/registry.py Updates provider registry event imports to events.provider.
src/ai_company/providers/drivers/mappers.py Updates provider driver event imports to events.provider.
src/ai_company/providers/drivers/litellm_driver.py Updates provider driver event imports to events.provider.
src/ai_company/providers/base.py Updates provider base event imports to events.provider.
src/ai_company/observability/events/budget.py New per-domain budget event constants module.
src/ai_company/observability/events/config.py New per-domain config event constants module.
src/ai_company/observability/events/execution.py New per-domain execution event constants module.
src/ai_company/observability/events/prompt.py New per-domain prompt event constants module.
src/ai_company/observability/events/provider.py New per-domain provider/resilience event constants module.
src/ai_company/observability/events/role.py New per-domain role event constants module.
src/ai_company/observability/events/routing.py New per-domain routing event constants module.
src/ai_company/observability/events/task.py New per-domain task event constants module.
src/ai_company/observability/events/template.py New per-domain template event constants module.
src/ai_company/observability/events/tool.py New per-domain tool event constants module.
src/ai_company/observability/events/init.py Adds package docstring + explicitly avoids re-exports (__all__ = []).
src/ai_company/observability/events.py Removes the legacy flat module containing all event constants.
src/ai_company/engine/task_execution.py Updates execution event imports to events.execution.
src/ai_company/engine/prompt.py Updates prompt event imports to events.prompt.
src/ai_company/engine/context.py Updates execution event imports to events.execution.
src/ai_company/core/task_transitions.py Updates task transition event imports to events.task.
src/ai_company/core/task.py Updates task event import to events.task.
src/ai_company/core/role_catalog.py Updates role event import to events.role.
src/ai_company/config/schema.py Updates config validation event import to events.config.
src/ai_company/config/loader.py Updates config loader event imports to events.config.
src/ai_company/budget/tracker.py Updates budget event imports to events.budget.
DESIGN_SPEC.md Updates project tree + event constants convention to “per-domain” modules.
CLAUDE.md Updates logging guidance to import event constants from events.<domain>.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

``events.provider``, ``events.budget``, ``events.tool``).
"""

__all__: list[str] = []
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Changing ai_company.observability.events from a flat module to a package with __all__ = [] removes the previously supported import style (from ai_company.observability.events import CONFIG_LOADED / events.CONFIG_LOADED). This is a breaking API change and also conflicts with issue #110’s acceptance criterion that existing imports keep working. Consider adding a backwards-compat shim (e.g., restore observability/events.py as a thin re-export layer and optionally emit a DeprecationWarning), or re-export constants from events/__init__.py for one release cycle while enforcing the new domain-specific imports via lint/docs.

Suggested change
__all__: list[str] = []
from importlib import import_module
from typing import Any
import warnings
# Public submodules for the new, domain-specific import style.
__all__: list[str] = ["config", "provider", "budget", "tool"]
# Internal list of modules to search for legacy, flat-namespace attributes.
_BACKCOMPAT_MODULES: tuple[str, ...] = tuple(__all__)
def __getattr__(name: str) -> Any:
"""Backwards-compat attribute access for legacy flat-module imports.
This allows older code such as:
from ai_company.observability.events import CONFIG_LOADED
events.CONFIG_LOADED
to keep working by resolving constants from the appropriate domain
submodule, while emitting a DeprecationWarning to encourage the
new import style::
from ai_company.observability.events.config import CONFIG_LOADED
"""
# First, allow attribute-style access to submodules themselves, e.g.
# ai_company.observability.events.config
if name in _BACKCOMPAT_MODULES:
module = import_module(f"{__name__}.{name}")
globals()[name] = module
return module
# Next, search each known domain module for the requested attribute.
for module_name in _BACKCOMPAT_MODULES:
module = import_module(f"{__name__}.{module_name}")
if hasattr(module, name):
warnings.warn(
f"`ai_company.observability.events.{name}` is deprecated; "
f"import it from `ai_company.observability.events.{module_name}` instead.",
DeprecationWarning,
stacklevel=2,
)
value = getattr(module, name)
# Cache the resolved attribute on this module for faster reuse.
globals()[name] = value
return value
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

Copilot uses AI. Check for mistakes.
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 refactors the ai_company.observability.events module by transitioning from a single, monolithic events.py file to a package structure (events/) containing multiple domain-specific submodules (e.g., events.budget, events.config, events.provider). This change aims to enhance discoverability, co-locate event constants with their relevant domain logic, and mitigate merge conflicts as the codebase expands. Documentation in CLAUDE.md and DESIGN_SPEC.md has been updated to reflect this new structure and the recommended import pattern. Consequently, all application code and unit tests that previously imported event constants from the singular events.py file have been updated to import them from their new, specific domain submodules.

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/ai_company/providers/drivers/litellm_driver.py (1)

44-58: ⚠️ Potential issue | 🟠 Major

Ensure backward compatibility for event constant imports across the codebase.

The direct submodule imports (lines 44-58) correctly follow the guidelines. However, src/ai_company/observability/events/__init__.py exports no uppercase constants (__all__ is empty), which breaks any external or internal imports using the package-root pattern from ai_company.observability.events import PROVIDER_CALL_ERROR. If this migration is intentional, confirm it doesn't conflict with other modules in the PR or external consumers. If backward compatibility is required, expose constants via __all__ at the package root.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ai_company/providers/drivers/litellm_driver.py` around lines 44 - 58, The
package root for observability events doesn't export the uppercase constants,
breaking imports like "from ai_company.observability.events import
PROVIDER_CALL_ERROR"; update the package entry (the observability.events
__init__.py) to re-export the required constants (e.g., PROVIDER_AUTH_ERROR,
PROVIDER_CALL_ERROR, PROVIDER_CONNECTION_ERROR, PROVIDER_MODEL_INFO_UNAVAILABLE,
PROVIDER_MODEL_INFO_UNEXPECTED_ERROR, PROVIDER_MODEL_NOT_FOUND,
PROVIDER_RATE_LIMITED, PROVIDER_RETRY_AFTER_PARSE_FAILED,
PROVIDER_STREAM_CHUNK_NO_DELTA, PROVIDER_STREAM_DONE,
PROVIDER_TOOL_CALL_ARGUMENTS_PARSE_FAILED,
PROVIDER_TOOL_CALL_ARGUMENTS_TRUNCATED, PROVIDER_TOOL_CALL_INCOMPLETE) by adding
them to __all__ or explicitly importing and exposing them so existing imports
using the package-root pattern continue to work.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/ai_company/providers/drivers/litellm_driver.py`:
- Around line 44-58: The package root for observability events doesn't export
the uppercase constants, breaking imports like "from
ai_company.observability.events import PROVIDER_CALL_ERROR"; update the package
entry (the observability.events __init__.py) to re-export the required constants
(e.g., PROVIDER_AUTH_ERROR, PROVIDER_CALL_ERROR, PROVIDER_CONNECTION_ERROR,
PROVIDER_MODEL_INFO_UNAVAILABLE, PROVIDER_MODEL_INFO_UNEXPECTED_ERROR,
PROVIDER_MODEL_NOT_FOUND, PROVIDER_RATE_LIMITED,
PROVIDER_RETRY_AFTER_PARSE_FAILED, PROVIDER_STREAM_CHUNK_NO_DELTA,
PROVIDER_STREAM_DONE, PROVIDER_TOOL_CALL_ARGUMENTS_PARSE_FAILED,
PROVIDER_TOOL_CALL_ARGUMENTS_TRUNCATED, PROVIDER_TOOL_CALL_INCOMPLETE) by adding
them to __all__ or explicitly importing and exposing them so existing imports
using the package-root pattern continue to work.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c9c9db61-2b8c-424d-be0d-4bfd61919be2

📥 Commits

Reviewing files that changed from the base of the PR and between 3b30b9a and 4b57b0d.

📒 Files selected for processing (50)
  • CLAUDE.md
  • DESIGN_SPEC.md
  • src/ai_company/budget/tracker.py
  • src/ai_company/config/loader.py
  • src/ai_company/config/schema.py
  • src/ai_company/core/role_catalog.py
  • src/ai_company/core/task.py
  • src/ai_company/core/task_transitions.py
  • src/ai_company/engine/context.py
  • src/ai_company/engine/prompt.py
  • src/ai_company/engine/task_execution.py
  • src/ai_company/observability/events.py
  • src/ai_company/observability/events/__init__.py
  • src/ai_company/observability/events/budget.py
  • src/ai_company/observability/events/config.py
  • src/ai_company/observability/events/execution.py
  • src/ai_company/observability/events/prompt.py
  • src/ai_company/observability/events/provider.py
  • src/ai_company/observability/events/role.py
  • src/ai_company/observability/events/routing.py
  • src/ai_company/observability/events/task.py
  • src/ai_company/observability/events/template.py
  • src/ai_company/observability/events/tool.py
  • src/ai_company/providers/base.py
  • src/ai_company/providers/drivers/litellm_driver.py
  • src/ai_company/providers/drivers/mappers.py
  • src/ai_company/providers/registry.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • src/ai_company/providers/resilience/retry.py
  • src/ai_company/providers/routing/resolver.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/providers/routing/strategies.py
  • src/ai_company/templates/loader.py
  • src/ai_company/templates/renderer.py
  • src/ai_company/tools/base.py
  • src/ai_company/tools/invoker.py
  • src/ai_company/tools/registry.py
  • tests/unit/budget/test_tracker.py
  • tests/unit/config/test_loader.py
  • tests/unit/core/test_task.py
  • tests/unit/core/test_task_transitions.py
  • tests/unit/engine/test_context.py
  • tests/unit/engine/test_task_execution.py
  • tests/unit/observability/test_events.py
  • tests/unit/providers/resilience/test_rate_limiter.py
  • tests/unit/providers/resilience/test_retry.py
  • tests/unit/providers/routing/test_router.py
  • tests/unit/providers/test_base_provider.py
  • tests/unit/providers/test_registry.py
  • tests/unit/templates/test_renderer.py
💤 Files with no reviewable changes (1)
  • src/ai_company/observability/events.py
📜 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). (2)
  • GitHub Check: Agent
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (6)
**/*.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: without parentheses — ruff enforces this on Python 3.14
Add type hints to all public functions; ensure mypy strict mode compliance
Use Google-style docstrings on all public classes and functions — required and enforced by ruff D rules
Create new objects instead of mutating existing ones; for non-Pydantic internal collections (registries, BaseTool), use copy.deepcopy() at construction and wrap with MappingProxyType for read-only enforcement
For dict/list fields in frozen Pydantic models, rely on frozen=True for field reassignment prevention and use copy.deepcopy() at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization)
Use frozen Pydantic models for config and identity; use separate mutable-via-copy models for runtime state that evolves — never mix static config fields with mutable runtime fields in one model
Use Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict); adopt @computed_field for derived values instead of storing redundant fields; use NotBlankStr for all identifier/name fields including optional and tuple variants
Prefer asyncio.TaskGroup for fan-out/fan-in parallel operations in new code (e.g. multiple tool invocations, parallel agent calls) — prefer structured concurrency over bare create_task
Keep functions under 50 lines; keep files under 800 lines
Handle errors explicitly; never silently swallow exceptions
Validate at system boundaries (user input, external APIs, config files)
Line length must be 88 characters — enforced by ruff

Files:

  • src/ai_company/config/loader.py
  • tests/unit/providers/routing/test_router.py
  • tests/unit/providers/test_registry.py
  • src/ai_company/providers/base.py
  • tests/unit/core/test_task.py
  • src/ai_company/observability/events/execution.py
  • src/ai_company/providers/drivers/litellm_driver.py
  • tests/unit/engine/test_context.py
  • src/ai_company/observability/events/role.py
  • src/ai_company/observability/events/prompt.py
  • tests/unit/templates/test_renderer.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • src/ai_company/providers/routing/strategies.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/observability/events/config.py
  • tests/unit/engine/test_task_execution.py
  • src/ai_company/observability/events/template.py
  • src/ai_company/observability/events/provider.py
  • src/ai_company/observability/events/budget.py
  • src/ai_company/engine/task_execution.py
  • src/ai_company/tools/base.py
  • src/ai_company/engine/context.py
  • src/ai_company/budget/tracker.py
  • tests/unit/providers/resilience/test_retry.py
  • src/ai_company/templates/loader.py
  • src/ai_company/observability/events/routing.py
  • src/ai_company/engine/prompt.py
  • src/ai_company/templates/renderer.py
  • tests/unit/observability/test_events.py
  • src/ai_company/core/task_transitions.py
  • src/ai_company/tools/invoker.py
  • src/ai_company/core/role_catalog.py
  • tests/unit/config/test_loader.py
  • tests/unit/budget/test_tracker.py
  • tests/unit/providers/resilience/test_rate_limiter.py
  • tests/unit/core/test_task_transitions.py
  • src/ai_company/config/schema.py
  • src/ai_company/providers/resilience/retry.py
  • src/ai_company/providers/routing/resolver.py
  • src/ai_company/providers/drivers/mappers.py
  • src/ai_company/providers/registry.py
  • src/ai_company/core/task.py
  • src/ai_company/observability/events/__init__.py
  • src/ai_company/observability/events/tool.py
  • src/ai_company/tools/registry.py
  • tests/unit/providers/test_base_provider.py
  • src/ai_company/observability/events/task.py
src/ai_company/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/ai_company/**/*.py: Every module with business logic must import and use logger: from ai_company.observability import get_logger then logger = get_logger(__name__) — use variable name logger (not _logger, not log)
Never use import logging, logging.getLogger(), or print() in application code — use the standardized logger from ai_company.observability
Always use event name constants from ai_company.observability.events (e.g. PROVIDER_CALL_START, BUDGET_RECORD_ADDED, TOOL_INVOKE_START) — import directly and log structured kwargs as 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; use DEBUG for object creation, internal flow, and entry/exit of key functions

Files:

  • src/ai_company/config/loader.py
  • src/ai_company/providers/base.py
  • src/ai_company/observability/events/execution.py
  • src/ai_company/providers/drivers/litellm_driver.py
  • src/ai_company/observability/events/role.py
  • src/ai_company/observability/events/prompt.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • src/ai_company/providers/routing/strategies.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/observability/events/config.py
  • src/ai_company/observability/events/template.py
  • src/ai_company/observability/events/provider.py
  • src/ai_company/observability/events/budget.py
  • src/ai_company/engine/task_execution.py
  • src/ai_company/tools/base.py
  • src/ai_company/engine/context.py
  • src/ai_company/budget/tracker.py
  • src/ai_company/templates/loader.py
  • src/ai_company/observability/events/routing.py
  • src/ai_company/engine/prompt.py
  • src/ai_company/templates/renderer.py
  • src/ai_company/core/task_transitions.py
  • src/ai_company/tools/invoker.py
  • src/ai_company/core/role_catalog.py
  • src/ai_company/config/schema.py
  • src/ai_company/providers/resilience/retry.py
  • src/ai_company/providers/routing/resolver.py
  • src/ai_company/providers/drivers/mappers.py
  • src/ai_company/providers/registry.py
  • src/ai_company/core/task.py
  • src/ai_company/observability/events/__init__.py
  • src/ai_company/observability/events/tool.py
  • src/ai_company/tools/registry.py
  • src/ai_company/observability/events/task.py
src/ai_company/config/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Set RetryConfig and RateLimiterConfig per-provider in ProviderConfig

Files:

  • src/ai_company/config/loader.py
  • src/ai_company/config/schema.py
tests/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.py: Mark tests with @pytest.mark.unit, @pytest.mark.integration, @pytest.mark.e2e, or @pytest.mark.slow
Use asyncio_mode = 'auto' for async tests — no manual @pytest.mark.asyncio needed
Use fake model IDs and vendor-agnostic fixture names in tests (e.g. test-haiku-001, test-provider) — never use real vendor model IDs; tests must not be coupled to external providers

Files:

  • tests/unit/providers/routing/test_router.py
  • tests/unit/providers/test_registry.py
  • tests/unit/core/test_task.py
  • tests/unit/engine/test_context.py
  • tests/unit/templates/test_renderer.py
  • tests/unit/engine/test_task_execution.py
  • tests/unit/providers/resilience/test_retry.py
  • tests/unit/observability/test_events.py
  • tests/unit/config/test_loader.py
  • tests/unit/budget/test_tracker.py
  • tests/unit/providers/resilience/test_rate_limiter.py
  • tests/unit/core/test_task_transitions.py
  • tests/unit/providers/test_base_provider.py
src/ai_company/providers/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/ai_company/providers/**/*.py: All provider calls go through BaseCompletionProvider which applies retry and rate limiting automatically — never implement retry logic in driver subclasses or calling code
Mark retryable errors with is_retryable=True: RateLimitError, ProviderTimeoutError, ProviderConnectionError, ProviderInternalError — all other errors raise immediately without retry
Rate limiter respects RateLimitError.retry_after from providers — automatically pauses future requests

Files:

  • src/ai_company/providers/base.py
  • src/ai_company/providers/drivers/litellm_driver.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • src/ai_company/providers/routing/strategies.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/providers/resilience/retry.py
  • src/ai_company/providers/routing/resolver.py
  • src/ai_company/providers/drivers/mappers.py
  • src/ai_company/providers/registry.py
src/ai_company/engine/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

RetryExhaustedError signals all retries failed — the engine layer catches this to trigger fallback chains

Files:

  • src/ai_company/engine/task_execution.py
  • src/ai_company/engine/context.py
  • src/ai_company/engine/prompt.py
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/**/*.py : Always use event name constants from ai_company.observability.events (e.g. PROVIDER_CALL_START, BUDGET_RECORD_ADDED, TOOL_INVOKE_START) — import directly and log structured kwargs as logger.info(EVENT, key=value), never logger.info('msg %s', val)
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/**/*.py : Always use event name constants from ai_company.observability.events (e.g. PROVIDER_CALL_START, BUDGET_RECORD_ADDED, TOOL_INVOKE_START) — import directly and log structured kwargs as logger.info(EVENT, key=value), never logger.info('msg %s', val)

Applied to files:

  • src/ai_company/config/loader.py
  • CLAUDE.md
  • tests/unit/providers/routing/test_router.py
  • tests/unit/providers/test_registry.py
  • src/ai_company/providers/base.py
  • tests/unit/core/test_task.py
  • src/ai_company/observability/events/execution.py
  • src/ai_company/providers/drivers/litellm_driver.py
  • tests/unit/engine/test_context.py
  • src/ai_company/observability/events/prompt.py
  • tests/unit/templates/test_renderer.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • src/ai_company/providers/routing/strategies.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/observability/events/config.py
  • tests/unit/engine/test_task_execution.py
  • src/ai_company/observability/events/template.py
  • src/ai_company/observability/events/provider.py
  • src/ai_company/observability/events/budget.py
  • src/ai_company/engine/task_execution.py
  • src/ai_company/tools/base.py
  • src/ai_company/engine/context.py
  • src/ai_company/budget/tracker.py
  • tests/unit/providers/resilience/test_retry.py
  • DESIGN_SPEC.md
  • src/ai_company/templates/loader.py
  • src/ai_company/observability/events/routing.py
  • src/ai_company/engine/prompt.py
  • src/ai_company/templates/renderer.py
  • tests/unit/observability/test_events.py
  • src/ai_company/core/task_transitions.py
  • src/ai_company/tools/invoker.py
  • src/ai_company/core/role_catalog.py
  • tests/unit/config/test_loader.py
  • tests/unit/budget/test_tracker.py
  • tests/unit/providers/resilience/test_rate_limiter.py
  • src/ai_company/config/schema.py
  • src/ai_company/providers/resilience/retry.py
  • src/ai_company/providers/routing/resolver.py
  • src/ai_company/providers/drivers/mappers.py
  • src/ai_company/providers/registry.py
  • src/ai_company/core/task.py
  • src/ai_company/observability/events/__init__.py
  • src/ai_company/observability/events/tool.py
  • src/ai_company/tools/registry.py
  • tests/unit/providers/test_base_provider.py
  • src/ai_company/observability/events/task.py
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/**/*.py : Never use `import logging`, `logging.getLogger()`, or `print()` in application code — use the standardized logger from ai_company.observability

Applied to files:

  • src/ai_company/config/loader.py
  • CLAUDE.md
  • src/ai_company/providers/base.py
  • src/ai_company/providers/drivers/litellm_driver.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • src/ai_company/providers/routing/strategies.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/engine/task_execution.py
  • src/ai_company/engine/context.py
  • src/ai_company/budget/tracker.py
  • src/ai_company/templates/loader.py
  • src/ai_company/engine/prompt.py
  • src/ai_company/templates/renderer.py
  • src/ai_company/core/task_transitions.py
  • src/ai_company/tools/invoker.py
  • src/ai_company/core/role_catalog.py
  • tests/unit/config/test_loader.py
  • src/ai_company/config/schema.py
  • src/ai_company/providers/resilience/retry.py
  • src/ai_company/providers/routing/resolver.py
  • src/ai_company/providers/drivers/mappers.py
  • src/ai_company/providers/registry.py
  • src/ai_company/observability/events/__init__.py
  • src/ai_company/tools/registry.py
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/**/*.py : Every module with business logic must import and use logger: `from ai_company.observability import get_logger` then `logger = get_logger(__name__)` — use variable name `logger` (not `_logger`, not `log`)

Applied to files:

  • src/ai_company/config/loader.py
  • CLAUDE.md
  • src/ai_company/providers/base.py
  • src/ai_company/providers/drivers/litellm_driver.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • src/ai_company/providers/routing/strategies.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/engine/task_execution.py
  • src/ai_company/engine/context.py
  • src/ai_company/budget/tracker.py
  • src/ai_company/templates/loader.py
  • src/ai_company/core/task_transitions.py
  • src/ai_company/core/role_catalog.py
  • src/ai_company/config/schema.py
  • src/ai_company/providers/resilience/retry.py
  • src/ai_company/providers/routing/resolver.py
  • src/ai_company/providers/drivers/mappers.py
  • src/ai_company/observability/events/__init__.py
  • src/ai_company/tools/registry.py
📚 Learning: 2026-02-26T17:43:50.902Z
Learnt from: CR
Repo: Aureliolo/story-factory PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-26T17:43:50.902Z
Learning: When making changes that affect architecture, services, key files, settings, or workflows, update the relevant sections of existing documentation (CLAUDE.md, README.md, etc.) to reflect those changes.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/**/*.py : All error paths must log at WARNING or ERROR with context before raising; all state transitions must log at INFO; use DEBUG for object creation, internal flow, and entry/exit of key functions

Applied to files:

  • CLAUDE.md
  • src/ai_company/providers/routing/strategies.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/engine/task_execution.py
  • src/ai_company/engine/context.py
  • src/ai_company/templates/loader.py
  • src/ai_company/core/task_transitions.py
  • src/ai_company/config/schema.py
📚 Learning: 2026-01-26T08:59:32.818Z
Learnt from: CR
Repo: Aureliolo/story-factory PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-26T08:59:32.818Z
Learning: Applies to **/*.py : All functions and methods should have appropriate logging for debugging and traceability. Use `logger.debug()` for routine operations, `logger.info()` for significant events, `logger.warning()` for unexpected but recoverable situations, and `logger.error()` for failures.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-02-26T17:43:50.902Z
Learnt from: CR
Repo: Aureliolo/story-factory PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-26T17:43:50.902Z
Learning: Applies to src/**/*.py : All functions and methods should have appropriate logging using `logger.debug()` for routine operations, `logger.info()` for significant events, `logger.warning()` for unexpected but recoverable situations, and `logger.error()` for failures.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-26T08:59:32.818Z
Learnt from: CR
Repo: Aureliolo/story-factory PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-26T08:59:32.818Z
Learning: Applies to **/*.py : Use logging levels: debug (routine), info (significant), warning (unexpected but recoverable), error (failures)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-26T08:59:32.818Z
Learnt from: CR
Repo: Aureliolo/story-factory PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-26T08:59:32.818Z
Learning: Applies to **/*.py : Logs must be written to `output/logs/story_factory.log` using `logger = logging.getLogger(__name__)`

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-24T09:54:45.426Z
Learnt from: CR
Repo: Aureliolo/story-factory PR: 0
File: .github/instructions/agents.instructions.md:0-0
Timestamp: 2026-01-24T09:54:45.426Z
Learning: Applies to agents/*.py : Log all significant operations using Python logging with appropriate levels: debug for detailed info, info for successes, warning for retries, error for failures

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-01-26T08:59:32.818Z
Learnt from: CR
Repo: Aureliolo/story-factory PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-26T08:59:32.818Z
Learning: Applies to src/services/**/*.py : Services in `src/services/` must be business logic layer with no UI imports, receiving settings via dependency injection

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/config/**/*.py : Set RetryConfig and RateLimiterConfig per-provider in ProviderConfig

Applied to files:

  • tests/unit/providers/routing/test_router.py
  • tests/unit/providers/test_registry.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • src/ai_company/providers/routing/router.py
  • src/ai_company/observability/events/provider.py
  • tests/unit/providers/resilience/test_retry.py
  • tests/unit/providers/resilience/test_rate_limiter.py
  • src/ai_company/providers/resilience/retry.py
  • src/ai_company/providers/routing/resolver.py
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/providers/**/*.py : All provider calls go through BaseCompletionProvider which applies retry and rate limiting automatically — never implement retry logic in driver subclasses or calling code

Applied to files:

  • src/ai_company/providers/base.py
  • src/ai_company/providers/resilience/rate_limiter.py
  • tests/unit/providers/resilience/test_retry.py
  • src/ai_company/providers/resilience/retry.py
  • tests/unit/providers/test_base_provider.py
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/providers/**/*.py : Rate limiter respects RateLimitError.retry_after from providers — automatically pauses future requests

Applied to files:

  • src/ai_company/providers/resilience/rate_limiter.py
  • tests/unit/providers/resilience/test_retry.py
  • tests/unit/providers/resilience/test_rate_limiter.py
  • src/ai_company/providers/resilience/retry.py
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/providers/**/*.py : Mark retryable errors with is_retryable=True: RateLimitError, ProviderTimeoutError, ProviderConnectionError, ProviderInternalError — all other errors raise immediately without retry

Applied to files:

  • tests/unit/providers/resilience/test_retry.py
  • src/ai_company/providers/resilience/retry.py
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to **/*.py : Use Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict); adopt computed_field for derived values instead of storing redundant fields; use NotBlankStr for all identifier/name fields including optional and tuple variants

Applied to files:

  • DESIGN_SPEC.md
📚 Learning: 2026-03-06T11:57:38.189Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-06T11:57:38.189Z
Learning: Applies to src/ai_company/engine/**/*.py : RetryExhaustedError signals all retries failed — the engine layer catches this to trigger fallback chains

Applied to files:

  • src/ai_company/providers/resilience/retry.py
🔇 Additional comments (44)
src/ai_company/observability/events/__init__.py (1)

10-14: No changes needed; the package-level import surface is correctly designed.

All event constants are imported directly from domain modules (e.g., from ai_company.observability.events.config import CONFIG_LOADED), and the __init__.py docstring correctly documents this pattern. The codebase contains zero imports of the form from ai_company.observability.events import CONFIG_LOADED, so there is no backward compatibility requirement to maintain. The empty __all__ and module-level docstring are appropriate and align with the intended usage pattern shown throughout the codebase.

src/ai_company/observability/events/config.py (1)

1-13: LGTM!

Clean, well-organized config event constants. The naming convention (CONFIG_* prefix) and value namespacing (config.<category>.<action>) are consistent and follow the established pattern for observability events.

src/ai_company/config/schema.py (1)

16-16: LGTM!

Import path correctly updated to the domain-specific module. The usage at line 228 follows the structured logging convention with kwargs.

src/ai_company/config/loader.py (1)

21-31: LGTM!

Import path correctly updated to the domain-specific config events module. All 9 imported constants match those defined in events/config.py, and their usage throughout the file follows the structured logging convention.

DESIGN_SPEC.md (2)

2119-2130: LGTM!

The project structure tree accurately reflects the new per-domain events package layout with all 10 domain modules (budget, config, execution, prompt, provider, role, routing, task, template, tool) plus the package marker __init__.py.


2247-2247: LGTM!

The engineering conventions table clearly documents the adopted per-domain event constants approach, including the import pattern and rationale for the split (discoverability, co-location, reduced merge conflicts).

CLAUDE.md (1)

83-83: LGTM!

The logging guidance is correctly updated to reflect the per-domain module structure. The examples (PROVIDER_CALL_START from events.provider, BUDGET_RECORD_ADDED from events.budget) and the import pattern are clear and actionable.

src/ai_company/observability/events/routing.py (1)

1-15: LGTM!

Well-organized routing event constants with consistent naming (ROUTING_* prefix) and proper value namespacing (routing.<category>.<action>). All constants are confirmed to be used correctly in the routing subsystem (router.py, resolver.py, strategies.py).

src/ai_company/observability/events/execution.py (1)

1-15: LGTM!

Complete set of execution lifecycle event constants. All 11 constants are properly typed as Final[str] with consistent naming (EXECUTION_*) and value namespacing (execution.<category>.<action>). The constants are correctly split between task execution concerns (5 constants used by task_execution.py) and agent context concerns (6 constants used by context.py).

src/ai_company/engine/task_execution.py (1)

17-23: LGTM!

Import path correctly updated to the domain-specific execution events module. All 5 imported constants are used appropriately throughout the file with structured kwargs and proper log levels (DEBUG for creation/cost, INFO for transitions, WARNING/ERROR for failures).

src/ai_company/observability/events/template.py (1)

1-17: LGTM!

The template event constants module is well-structured with all 13 constants properly typed as Final[str]. All constants required by loader.py and renderer.py are present and correctly named.

src/ai_company/templates/renderer.py (1)

23-31: LGTM!

The import path correctly points to the new domain-specific module ai_company.observability.events.template. All 7 imported constants are properly defined in the template module and are used with structured logging throughout the file.

src/ai_company/templates/loader.py (1)

24-31: LGTM!

The import path correctly points to the new domain-specific module ai_company.observability.events.template. All 6 imported constants are properly defined in the template module.

src/ai_company/observability/events/tool.py (1)

1-19: LGTM!

The tool event constants module is well-structured with all 15 constants properly typed as Final[str]. All constants required by invoker.py, registry.py, and base.py are present and correctly named.

src/ai_company/tools/base.py (1)

15-15: LGTM!

The import path correctly points to the new domain-specific module ai_company.observability.events.tool. The TOOL_BASE_INVALID_NAME constant is properly used with structured logging.

src/ai_company/tools/invoker.py (1)

19-30: LGTM!

The import path correctly points to the new domain-specific module ai_company.observability.events.tool. All 10 imported constants are properly defined in the tool module and are used with structured logging throughout the file.

src/ai_company/tools/registry.py (1)

11-16: LGTM!

The import path correctly points to the new domain-specific module ai_company.observability.events.tool. All 4 imported constants are properly defined in the tool module and are used with structured logging throughout the file.

src/ai_company/observability/events/provider.py (1)

1-42: LGTM!

The provider event constants module is well-structured with all 27 constants properly typed as Final[str]. The module is well-organized with clear section comments separating lifecycle events from resilience events. All constants required by the consumers (base.py, retry.py, rate_limiter.py, litellm_driver.py) are present and correctly named.

tests/unit/providers/resilience/test_retry.py (1)

8-13: Provider event import update looks correct.

This keeps the test aligned with the new per-domain event layout without changing the asserted event names or behavior.

src/ai_company/providers/resilience/rate_limiter.py (1)

8-11: Domain-specific provider event imports are wired correctly.

The logger calls still consume the same constants, so this stays a pure organizational change in this module.

src/ai_company/providers/drivers/mappers.py (1)

13-18: Mapper logging imports are consistent with the split.

These constants remain provider-specific, so moving them into the provider events module is the right fit.

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

16-16: Task event import is updated cleanly.

The test continues to validate the same emitted event while matching the new task-domain module layout.

src/ai_company/providers/routing/resolver.py (1)

13-17: Routing event imports are correctly localized.

This preserves the existing resolver logging behavior while matching the new routing-specific event module.

tests/unit/providers/resilience/test_rate_limiter.py (1)

10-13: Rate-limiter test imports were updated cleanly.

The assertions still target the same provider events, so this remains a straightforward namespace migration.

tests/unit/providers/test_registry.py (1)

9-12: Provider registry event imports look good.

The test continues to assert the same event emissions while following the new provider-domain module structure.

tests/unit/providers/routing/test_router.py (1)

8-11: Routing test imports are consistently updated.

Both the module-level and scoped event imports now point at the routing domain module, with no change to the tested logging behavior.

Also applies to: 156-156

tests/unit/budget/test_tracker.py (1)

12-16: Budget test import matches the new domain split.

The assertions still target the same BUDGET_* event names, so the test intent stays unchanged.

src/ai_company/providers/routing/strategies.py (1)

16-22: Routing strategy events are sourced from the right module.

This keeps routing-specific constants colocated without changing strategy behavior.

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

8-8: Task transition logging test stays aligned.

Only the source module changed; the test still validates the same task event.

src/ai_company/budget/tracker.py (1)

25-33: Budget tracker import split looks clean.

The module continues to use direct BUDGET_* constants and structured logging after the move.

tests/unit/config/test_loader.py (1)

29-33: Config loader logging tests remain targeted.

Switching to events.config keeps the asserted CONFIG_* events explicit.

tests/unit/engine/test_task_execution.py (1)

13-19: Execution event assertions remain clear.

The tests still exercise the same EXECUTION_* event names after the module split.

src/ai_company/providers/routing/router.py (1)

9-14: Router event import update is consistent.

The router keeps using direct routing constants while following the new package layout.

src/ai_company/providers/registry.py (1)

12-17: LGTM!

The import path correctly references the domain-specific provider events module. All four constants (PROVIDER_DRIVER_FACTORY_MISSING, PROVIDER_DRIVER_INSTANTIATED, PROVIDER_DRIVER_NOT_REGISTERED, PROVIDER_REGISTRY_BUILT) are properly defined in ai_company.observability.events.provider and used consistently throughout the file.

tests/unit/engine/test_context.py (1)

18-25: LGTM!

The import path correctly references the domain-specific execution events module, aligning with the source module src/ai_company/engine/context.py. All six execution event constants are properly used in the test assertions to verify logging behavior.

src/ai_company/providers/base.py (1)

15-20: LGTM!

The import path correctly references the domain-specific provider events module. The four provider call lifecycle constants are properly imported and used throughout the file for structured logging.

src/ai_company/engine/context.py (1)

20-27: LGTM!

The import path correctly references the domain-specific execution events module. All six execution context event constants are properly imported and used with appropriate log levels: DEBUG for creation/snapshots, INFO for turn completion, and ERROR/WARNING for error paths. This aligns with the coding guidelines.

src/ai_company/providers/resilience/retry.py (1)

8-13: LGTM!

The import path correctly references the domain-specific provider events module. The four provider resilience constants (PROVIDER_CALL_ERROR, PROVIDER_RETRY_ATTEMPT, PROVIDER_RETRY_EXHAUSTED, PROVIDER_RETRY_SKIPPED) are properly defined in ai_company.observability.events.provider (lines 37-40 per the context snippet) and used appropriately throughout the retry handler.

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

10-13: LGTM!

The import path correctly references the domain-specific template events module. Both constants (TEMPLATE_RENDER_START, TEMPLATE_RENDER_SUCCESS) are properly defined in ai_company.observability.events.template per context snippet 4 and used correctly in the logging test.

tests/unit/providers/test_base_provider.py (1)

8-13: LGTM!

The import path correctly references the domain-specific provider events module, aligning with the source module src/ai_company/providers/base.py. All four provider call event constants are properly used in the test assertions to verify logging behavior.

tests/unit/observability/test_events.py (3)

36-47: LGTM!

The refactored _all_event_names() helper correctly discovers event constants from all submodules using pkgutil.iter_modules(). The attr.isupper() guard on line 45 adds robustness by ensuring only uppercase string attributes (constants) are collected, filtering out any helper functions or other module-level attributes.


10-29: LGTM!

The imports correctly reference all 10 domain-specific event modules (budget, config, execution, prompt, provider, role, routing, task, template, tool), providing comprehensive spot-check coverage for the per-domain event structure.


90-103: LGTM!

Good addition of spot-check tests for the four newly covered domain modules (budget, execution, routing, prompt, tool). This ensures all 10 domain modules have explicit validation tests, completing the coverage expansion mentioned in the PR objectives.

src/ai_company/observability/events/budget.py (1)

1-11: LGTM.

Clean domain-local constant module. The names are explicit, stable, and support the direct-import logging convention expected by the codebase. Based on learnings: "Always use event name constants from ai_company.observability.events (e.g. PROVIDER_CALL_START, BUDGET_RECORD_ADDED, TOOL_INVOKE_START) — import directly and log structured kwargs as logger.info(EVENT, key=value), never logger.info('msg %s', val)".

- Fix inaccurate naming convention in events/__init__.py docstring
  (domain.noun[.verb] → domain.subject[.qualifier])
- Replace hardcoded event strings in test_prompt.py with constant imports
- Update DESIGN_SPEC.md tree comment for events/__init__.py
- Add test_all_domain_modules_discovered to verify all 10 modules
- Standardize docstring format across all 10 event domain modules

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Aureliolo Aureliolo merged commit e9cba89 into main Mar 6, 2026
7 checks passed
@Aureliolo Aureliolo deleted the refactor/split-events-per-domain branch March 6, 2026 13:27
Aureliolo added a commit that referenced this pull request Mar 10, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.1](ai-company-v0.1.0...ai-company-v0.1.1)
(2026-03-10)


### Features

* add autonomy levels and approval timeout policies
([#42](#42),
[#126](#126))
([#197](#197))
([eecc25a](eecc25a))
* add CFO cost optimization service with anomaly detection, reports, and
approval decisions
([#186](#186))
([a7fa00b](a7fa00b))
* add code quality toolchain (ruff, mypy, pre-commit, dependabot)
([#63](#63))
([36681a8](36681a8))
* add configurable cost tiers and subscription/quota-aware tracking
([#67](#67))
([#185](#185))
([9baedfa](9baedfa))
* add container packaging, Docker Compose, and CI pipeline
([#269](#269))
([435bdfe](435bdfe)),
closes [#267](#267)
* add coordination error taxonomy classification pipeline
([#146](#146))
([#181](#181))
([70c7480](70c7480))
* add cost-optimized, hierarchical, and auction assignment strategies
([#175](#175))
([ce924fa](ce924fa)),
closes [#173](#173)
* add design specification, license, and project setup
([8669a09](8669a09))
* add env var substitution and config file auto-discovery
([#77](#77))
([7f53832](7f53832))
* add FastestStrategy routing + vendor-agnostic cleanup
([#140](#140))
([09619cb](09619cb)),
closes [#139](#139)
* add HR engine and performance tracking
([#45](#45),
[#47](#47))
([#193](#193))
([2d091ea](2d091ea))
* add issue auto-search and resolution verification to PR review skill
([#119](#119))
([deecc39](deecc39))
* add memory retrieval, ranking, and context injection pipeline
([#41](#41))
([873b0aa](873b0aa))
* add pluggable MemoryBackend protocol with models, config, and events
([#180](#180))
([46cfdd4](46cfdd4))
* add pluggable MemoryBackend protocol with models, config, and events
([#32](#32))
([46cfdd4](46cfdd4))
* add pluggable PersistenceBackend protocol with SQLite implementation
([#36](#36))
([f753779](f753779))
* add progressive trust and promotion/demotion subsystems
([#43](#43),
[#49](#49))
([3a87c08](3a87c08))
* add retry handler, rate limiter, and provider resilience
([#100](#100))
([b890545](b890545))
* add SecOps security agent with rule engine, audit log, and ToolInvoker
integration ([#40](#40))
([83b7b6c](83b7b6c))
* add shared org memory and memory consolidation/archival
([#125](#125),
[#48](#48))
([4a0832b](4a0832b))
* design unified provider interface
([#86](#86))
([3e23d64](3e23d64))
* expand template presets, rosters, and add inheritance
([#80](#80),
[#81](#81),
[#84](#84))
([15a9134](15a9134))
* implement agent runtime state vs immutable config split
([#115](#115))
([4cb1ca5](4cb1ca5))
* implement AgentEngine core orchestrator
([#11](#11))
([#143](#143))
([f2eb73a](f2eb73a))
* implement basic tool system (registry, invocation, results)
([#15](#15))
([c51068b](c51068b))
* implement built-in file system tools
([#18](#18))
([325ef98](325ef98))
* implement communication foundation — message bus, dispatcher, and
messenger ([#157](#157))
([8e71bfd](8e71bfd))
* implement company template system with 7 built-in presets
([#85](#85))
([cbf1496](cbf1496))
* implement conflict resolution protocol
([#122](#122))
([#166](#166))
([e03f9f2](e03f9f2))
* implement core entity and role system models
([#69](#69))
([acf9801](acf9801))
* implement crash recovery with fail-and-reassign strategy
([#149](#149))
([e6e91ed](e6e91ed))
* implement engine extensions — Plan-and-Execute loop and call
categorization
([#134](#134),
[#135](#135))
([#159](#159))
([9b2699f](9b2699f))
* implement enterprise logging system with structlog
([#73](#73))
([2f787e5](2f787e5))
* implement graceful shutdown with cooperative timeout strategy
([#130](#130))
([6592515](6592515))
* implement hierarchical delegation and loop prevention
([#12](#12),
[#17](#17))
([6be60b6](6be60b6))
* implement LiteLLM driver and provider registry
([#88](#88))
([ae3f18b](ae3f18b)),
closes [#4](#4)
* implement LLM decomposition strategy and workspace isolation
([#174](#174))
([aa0eefe](aa0eefe))
* implement meeting protocol system
([#123](#123))
([ee7caca](ee7caca))
* implement message and communication domain models
([#74](#74))
([560a5d2](560a5d2))
* implement model routing engine
([#99](#99))
([d3c250b](d3c250b))
* implement parallel agent execution
([#22](#22))
([#161](#161))
([65940b3](65940b3))
* implement per-call cost tracking service
([#7](#7))
([#102](#102))
([c4f1f1c](c4f1f1c))
* implement personality injection and system prompt construction
([#105](#105))
([934dd85](934dd85))
* implement single-task execution lifecycle
([#21](#21))
([#144](#144))
([c7e64e4](c7e64e4))
* implement subprocess sandbox for tool execution isolation
([#131](#131))
([#153](#153))
([3c8394e](3c8394e))
* implement task assignment subsystem with pluggable strategies
([#172](#172))
([c7f1b26](c7f1b26)),
closes [#26](#26)
[#30](#30)
* implement task decomposition and routing engine
([#14](#14))
([9c7fb52](9c7fb52))
* implement Task, Project, Artifact, Budget, and Cost domain models
([#71](#71))
([81eabf1](81eabf1))
* implement tool permission checking
([#16](#16))
([833c190](833c190))
* implement YAML config loader with Pydantic validation
([#59](#59))
([ff3a2ba](ff3a2ba))
* implement YAML config loader with Pydantic validation
([#75](#75))
([ff3a2ba](ff3a2ba))
* initialize project with uv, hatchling, and src layout
([39005f9](39005f9))
* initialize project with uv, hatchling, and src layout
([#62](#62))
([39005f9](39005f9))
* Litestar REST API, WebSocket feed, and approval queue (M6)
([#189](#189))
([29fcd08](29fcd08))
* make TokenUsage.total_tokens a computed field
([#118](#118))
([c0bab18](c0bab18)),
closes [#109](#109)
* parallel tool execution in ToolInvoker.invoke_all
([#137](#137))
([58517ee](58517ee))
* testing framework, CI pipeline, and M0 gap fixes
([#64](#64))
([f581749](f581749))
* wire all modules into observability system
([#97](#97))
([f7a0617](f7a0617))


### Bug Fixes

* address Greptile post-merge review findings from PRs
[#170](https://github.com/Aureliolo/ai-company/issues/170)-[#175](https://github.com/Aureliolo/ai-company/issues/175)
([#176](#176))
([c5ca929](c5ca929))
* address post-merge review feedback from PRs
[#164](https://github.com/Aureliolo/ai-company/issues/164)-[#167](https://github.com/Aureliolo/ai-company/issues/167)
([#170](#170))
([3bf897a](3bf897a)),
closes [#169](#169)
* enforce strict mypy on test files
([#89](#89))
([aeeff8c](aeeff8c))
* harden Docker sandbox, MCP bridge, and code runner
([#50](#50),
[#53](#53))
([d5e1b6e](d5e1b6e))
* harden git tools security + code quality improvements
([#150](#150))
([000a325](000a325))
* harden subprocess cleanup, env filtering, and shutdown resilience
([#155](#155))
([d1fe1fb](d1fe1fb))
* incorporate post-merge feedback + pre-PR review fixes
([#164](#164))
([c02832a](c02832a))
* pre-PR review fixes for post-merge findings
([#183](#183))
([26b3108](26b3108))
* strengthen immutability for BaseTool schema and ToolInvoker boundaries
([#117](#117))
([7e5e861](7e5e861))


### Performance

* harden non-inferable principle implementation
([#195](#195))
([02b5f4e](02b5f4e)),
closes [#188](#188)


### Refactoring

* adopt NotBlankStr across all models
([#108](#108))
([#120](#120))
([ef89b90](ef89b90))
* extract _SpendingTotals base class from spending summary models
([#111](#111))
([2f39c1b](2f39c1b))
* harden BudgetEnforcer with error handling, validation extraction, and
review fixes
([#182](#182))
([c107bf9](c107bf9))
* harden personality profiles, department validation, and template
rendering ([#158](#158))
([10b2299](10b2299))
* pre-PR review improvements for ExecutionLoop + ReAct loop
([#124](#124))
([8dfb3c0](8dfb3c0))
* split events.py into per-domain event modules
([#136](#136))
([e9cba89](e9cba89))


### Documentation

* add ADR-001 memory layer evaluation and selection
([#178](#178))
([db3026f](db3026f)),
closes [#39](#39)
* add agent scaling research findings to DESIGN_SPEC
([#145](#145))
([57e487b](57e487b))
* add CLAUDE.md, contributing guide, and dev documentation
([#65](#65))
([55c1025](55c1025)),
closes [#54](#54)
* add crash recovery, sandboxing, analytics, and testing decisions
([#127](#127))
([5c11595](5c11595))
* address external review feedback with MVP scope and new protocols
([#128](#128))
([3b30b9a](3b30b9a))
* expand design spec with pluggable strategy protocols
([#121](#121))
([6832db6](6832db6))
* finalize 23 design decisions (ADR-002)
([#190](#190))
([8c39742](8c39742))
* update project docs for M2.5 conventions and add docs-consistency
review agent
([#114](#114))
([99766ee](99766ee))


### Tests

* add e2e single agent integration tests
([#24](#24))
([#156](#156))
([f566fb4](f566fb4))
* add provider adapter integration tests
([#90](#90))
([40a61f4](40a61f4))


### CI/CD

* add Release Please for automated versioning and GitHub Releases
([#278](#278))
([a488758](a488758))
* bump actions/checkout from 4 to 6
([#95](#95))
([1897247](1897247))
* bump actions/upload-artifact from 4 to 7
([#94](#94))
([27b1517](27b1517))
* harden CI/CD pipeline
([#92](#92))
([ce4693c](ce4693c))
* split vulnerability scans into critical-fail and high-warn tiers
([#277](#277))
([aba48af](aba48af))


### Maintenance

* add /worktree skill for parallel worktree management
([#171](#171))
([951e337](951e337))
* add design spec context loading to research-link skill
([8ef9685](8ef9685))
* add post-merge-cleanup skill
([#70](#70))
([f913705](f913705))
* add pre-pr-review skill and update CLAUDE.md
([#103](#103))
([92e9023](92e9023))
* add research-link skill and rename skill files to SKILL.md
([#101](#101))
([651c577](651c577))
* bump aiosqlite from 0.21.0 to 0.22.1
([#191](#191))
([3274a86](3274a86))
* bump pyyaml from 6.0.2 to 6.0.3 in the minor-and-patch group
([#96](#96))
([0338d0c](0338d0c))
* bump ruff from 0.15.4 to 0.15.5
([a49ee46](a49ee46))
* fix M0 audit items
([#66](#66))
([c7724b5](c7724b5))
* pin setup-uv action to full SHA
([#281](#281))
([4448002](4448002))
* post-audit cleanup — PEP 758, loggers, bug fixes, refactoring, tests,
hookify rules
([#148](#148))
([c57a6a9](c57a6a9))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Aureliolo added a commit that referenced this pull request Mar 11, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.0](v0.0.0...v0.1.0)
(2026-03-11)


### Features

* add autonomy levels and approval timeout policies
([#42](#42),
[#126](#126))
([#197](#197))
([eecc25a](eecc25a))
* add CFO cost optimization service with anomaly detection, reports, and
approval decisions
([#186](#186))
([a7fa00b](a7fa00b))
* add code quality toolchain (ruff, mypy, pre-commit, dependabot)
([#63](#63))
([36681a8](36681a8))
* add configurable cost tiers and subscription/quota-aware tracking
([#67](#67))
([#185](#185))
([9baedfa](9baedfa))
* add container packaging, Docker Compose, and CI pipeline
([#269](#269))
([435bdfe](435bdfe)),
closes [#267](#267)
* add coordination error taxonomy classification pipeline
([#146](#146))
([#181](#181))
([70c7480](70c7480))
* add cost-optimized, hierarchical, and auction assignment strategies
([#175](#175))
([ce924fa](ce924fa)),
closes [#173](#173)
* add design specification, license, and project setup
([8669a09](8669a09))
* add env var substitution and config file auto-discovery
([#77](#77))
([7f53832](7f53832))
* add FastestStrategy routing + vendor-agnostic cleanup
([#140](#140))
([09619cb](09619cb)),
closes [#139](#139)
* add HR engine and performance tracking
([#45](#45),
[#47](#47))
([#193](#193))
([2d091ea](2d091ea))
* add issue auto-search and resolution verification to PR review skill
([#119](#119))
([deecc39](deecc39))
* add mandatory JWT + API key authentication
([#256](#256))
([c279cfe](c279cfe))
* add memory retrieval, ranking, and context injection pipeline
([#41](#41))
([873b0aa](873b0aa))
* add pluggable MemoryBackend protocol with models, config, and events
([#180](#180))
([46cfdd4](46cfdd4))
* add pluggable MemoryBackend protocol with models, config, and events
([#32](#32))
([46cfdd4](46cfdd4))
* add pluggable output scan response policies
([#263](#263))
([b9907e8](b9907e8))
* add pluggable PersistenceBackend protocol with SQLite implementation
([#36](#36))
([f753779](f753779))
* add progressive trust and promotion/demotion subsystems
([#43](#43),
[#49](#49))
([3a87c08](3a87c08))
* add retry handler, rate limiter, and provider resilience
([#100](#100))
([b890545](b890545))
* add SecOps security agent with rule engine, audit log, and ToolInvoker
integration ([#40](#40))
([83b7b6c](83b7b6c))
* add shared org memory and memory consolidation/archival
([#125](#125),
[#48](#48))
([4a0832b](4a0832b))
* design unified provider interface
([#86](#86))
([3e23d64](3e23d64))
* expand template presets, rosters, and add inheritance
([#80](#80),
[#81](#81),
[#84](#84))
([15a9134](15a9134))
* implement agent runtime state vs immutable config split
([#115](#115))
([4cb1ca5](4cb1ca5))
* implement AgentEngine core orchestrator
([#11](#11))
([#143](#143))
([f2eb73a](f2eb73a))
* implement AuditRepository for security audit log persistence
([#279](#279))
([94bc29f](94bc29f))
* implement basic tool system (registry, invocation, results)
([#15](#15))
([c51068b](c51068b))
* implement built-in file system tools
([#18](#18))
([325ef98](325ef98))
* implement communication foundation — message bus, dispatcher, and
messenger ([#157](#157))
([8e71bfd](8e71bfd))
* implement company template system with 7 built-in presets
([#85](#85))
([cbf1496](cbf1496))
* implement conflict resolution protocol
([#122](#122))
([#166](#166))
([e03f9f2](e03f9f2))
* implement core entity and role system models
([#69](#69))
([acf9801](acf9801))
* implement crash recovery with fail-and-reassign strategy
([#149](#149))
([e6e91ed](e6e91ed))
* implement engine extensions — Plan-and-Execute loop and call
categorization
([#134](#134),
[#135](#135))
([#159](#159))
([9b2699f](9b2699f))
* implement enterprise logging system with structlog
([#73](#73))
([2f787e5](2f787e5))
* implement graceful shutdown with cooperative timeout strategy
([#130](#130))
([6592515](6592515))
* implement hierarchical delegation and loop prevention
([#12](#12),
[#17](#17))
([6be60b6](6be60b6))
* implement LiteLLM driver and provider registry
([#88](#88))
([ae3f18b](ae3f18b)),
closes [#4](#4)
* implement LLM decomposition strategy and workspace isolation
([#174](#174))
([aa0eefe](aa0eefe))
* implement meeting protocol system
([#123](#123))
([ee7caca](ee7caca))
* implement message and communication domain models
([#74](#74))
([560a5d2](560a5d2))
* implement model routing engine
([#99](#99))
([d3c250b](d3c250b))
* implement parallel agent execution
([#22](#22))
([#161](#161))
([65940b3](65940b3))
* implement per-call cost tracking service
([#7](#7))
([#102](#102))
([c4f1f1c](c4f1f1c))
* implement personality injection and system prompt construction
([#105](#105))
([934dd85](934dd85))
* implement single-task execution lifecycle
([#21](#21))
([#144](#144))
([c7e64e4](c7e64e4))
* implement subprocess sandbox for tool execution isolation
([#131](#131))
([#153](#153))
([3c8394e](3c8394e))
* implement task assignment subsystem with pluggable strategies
([#172](#172))
([c7f1b26](c7f1b26)),
closes [#26](#26)
[#30](#30)
* implement task decomposition and routing engine
([#14](#14))
([9c7fb52](9c7fb52))
* implement Task, Project, Artifact, Budget, and Cost domain models
([#71](#71))
([81eabf1](81eabf1))
* implement tool permission checking
([#16](#16))
([833c190](833c190))
* implement YAML config loader with Pydantic validation
([#59](#59))
([ff3a2ba](ff3a2ba))
* implement YAML config loader with Pydantic validation
([#75](#75))
([ff3a2ba](ff3a2ba))
* initialize project with uv, hatchling, and src layout
([39005f9](39005f9))
* initialize project with uv, hatchling, and src layout
([#62](#62))
([39005f9](39005f9))
* Litestar REST API, WebSocket feed, and approval queue (M6)
([#189](#189))
([29fcd08](29fcd08))
* make TokenUsage.total_tokens a computed field
([#118](#118))
([c0bab18](c0bab18)),
closes [#109](#109)
* parallel tool execution in ToolInvoker.invoke_all
([#137](#137))
([58517ee](58517ee))
* testing framework, CI pipeline, and M0 gap fixes
([#64](#64))
([f581749](f581749))
* wire all modules into observability system
([#97](#97))
([f7a0617](f7a0617))


### Bug Fixes

* address Greptile post-merge review findings from PRs
[#170](https://github.com/Aureliolo/ai-company/issues/170)-[#175](https://github.com/Aureliolo/ai-company/issues/175)
([#176](#176))
([c5ca929](c5ca929))
* address post-merge review feedback from PRs
[#164](https://github.com/Aureliolo/ai-company/issues/164)-[#167](https://github.com/Aureliolo/ai-company/issues/167)
([#170](#170))
([3bf897a](3bf897a)),
closes [#169](#169)
* enforce strict mypy on test files
([#89](#89))
([aeeff8c](aeeff8c))
* harden Docker sandbox, MCP bridge, and code runner
([#50](#50),
[#53](#53))
([d5e1b6e](d5e1b6e))
* harden git tools security + code quality improvements
([#150](#150))
([000a325](000a325))
* harden subprocess cleanup, env filtering, and shutdown resilience
([#155](#155))
([d1fe1fb](d1fe1fb))
* incorporate post-merge feedback + pre-PR review fixes
([#164](#164))
([c02832a](c02832a))
* pre-PR review fixes for post-merge findings
([#183](#183))
([26b3108](26b3108))
* resolve circular imports, bump litellm, fix release tag format
([#286](#286))
([a6659b5](a6659b5))
* strengthen immutability for BaseTool schema and ToolInvoker boundaries
([#117](#117))
([7e5e861](7e5e861))


### Performance

* harden non-inferable principle implementation
([#195](#195))
([02b5f4e](02b5f4e)),
closes [#188](#188)


### Refactoring

* adopt NotBlankStr across all models
([#108](#108))
([#120](#120))
([ef89b90](ef89b90))
* extract _SpendingTotals base class from spending summary models
([#111](#111))
([2f39c1b](2f39c1b))
* harden BudgetEnforcer with error handling, validation extraction, and
review fixes
([#182](#182))
([c107bf9](c107bf9))
* harden personality profiles, department validation, and template
rendering ([#158](#158))
([10b2299](10b2299))
* pre-PR review improvements for ExecutionLoop + ReAct loop
([#124](#124))
([8dfb3c0](8dfb3c0))
* split events.py into per-domain event modules
([#136](#136))
([e9cba89](e9cba89))


### Documentation

* add ADR-001 memory layer evaluation and selection
([#178](#178))
([db3026f](db3026f)),
closes [#39](#39)
* add agent scaling research findings to DESIGN_SPEC
([#145](#145))
([57e487b](57e487b))
* add CLAUDE.md, contributing guide, and dev documentation
([#65](#65))
([55c1025](55c1025)),
closes [#54](#54)
* add crash recovery, sandboxing, analytics, and testing decisions
([#127](#127))
([5c11595](5c11595))
* address external review feedback with MVP scope and new protocols
([#128](#128))
([3b30b9a](3b30b9a))
* expand design spec with pluggable strategy protocols
([#121](#121))
([6832db6](6832db6))
* finalize 23 design decisions (ADR-002)
([#190](#190))
([8c39742](8c39742))
* update project docs for M2.5 conventions and add docs-consistency
review agent
([#114](#114))
([99766ee](99766ee))


### Tests

* add e2e single agent integration tests
([#24](#24))
([#156](#156))
([f566fb4](f566fb4))
* add provider adapter integration tests
([#90](#90))
([40a61f4](40a61f4))


### CI/CD

* add Release Please for automated versioning and GitHub Releases
([#278](#278))
([a488758](a488758))
* bump actions/checkout from 4 to 6
([#95](#95))
([1897247](1897247))
* bump actions/upload-artifact from 4 to 7
([#94](#94))
([27b1517](27b1517))
* bump anchore/scan-action from 6.5.1 to 7.3.2
([#271](#271))
([80a1c15](80a1c15))
* bump docker/build-push-action from 6.19.2 to 7.0.0
([#273](#273))
([dd0219e](dd0219e))
* bump docker/login-action from 3.7.0 to 4.0.0
([#272](#272))
([33d6238](33d6238))
* bump docker/metadata-action from 5.10.0 to 6.0.0
([#270](#270))
([baee04e](baee04e))
* bump docker/setup-buildx-action from 3.12.0 to 4.0.0
([#274](#274))
([5fc06f7](5fc06f7))
* bump sigstore/cosign-installer from 3.9.1 to 4.1.0
([#275](#275))
([29dd16c](29dd16c))
* harden CI/CD pipeline
([#92](#92))
([ce4693c](ce4693c))
* split vulnerability scans into critical-fail and high-warn tiers
([#277](#277))
([aba48af](aba48af))


### Maintenance

* add /worktree skill for parallel worktree management
([#171](#171))
([951e337](951e337))
* add design spec context loading to research-link skill
([8ef9685](8ef9685))
* add post-merge-cleanup skill
([#70](#70))
([f913705](f913705))
* add pre-pr-review skill and update CLAUDE.md
([#103](#103))
([92e9023](92e9023))
* add research-link skill and rename skill files to SKILL.md
([#101](#101))
([651c577](651c577))
* bump aiosqlite from 0.21.0 to 0.22.1
([#191](#191))
([3274a86](3274a86))
* bump pyyaml from 6.0.2 to 6.0.3 in the minor-and-patch group
([#96](#96))
([0338d0c](0338d0c))
* bump ruff from 0.15.4 to 0.15.5
([a49ee46](a49ee46))
* fix M0 audit items
([#66](#66))
([c7724b5](c7724b5))
* **main:** release ai-company 0.1.1
([#282](#282))
([2f4703d](2f4703d))
* pin setup-uv action to full SHA
([#281](#281))
([4448002](4448002))
* post-audit cleanup — PEP 758, loggers, bug fixes, refactoring, tests,
hookify rules
([#148](#148))
([c57a6a9](c57a6a9))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Signed-off-by: Aurelio <19254254+Aureliolo@users.noreply.github.com>
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.

Split events.py into per-domain event modules

2 participants