feat: implement message and communication domain models#74
Conversation
Add pure domain models for inter-agent communication covering message format, channels, and loop prevention config per DESIGN_SPEC 5.3-5.5. Source models: enums, Attachment, MessageMetadata, Message (with from/sender alias), Channel, and 8 config models including LoopPreventionConfig with ancestry_tracking enforcement. 140 unit tests at 100% module coverage.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (4)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds a communication domain: StrEnum enums, immutable Pydantic domain models (Channel, Message, Attachment, MessageMetadata), a frozen hierarchical CommunicationConfig, package-level exports, core NotBlankStr utility, comprehensive test factories/fixtures, many unit tests, and two doc-only Shell Usage additions to CLAUDE.md. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
Summary of ChangesHello, 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 establishes the foundational domain and configuration models for the AI company's communication subsystem. It introduces structured data types for messages, channels, and various operational settings, ensuring data consistency and adherence to design specifications. The changes are thoroughly tested, providing a robust and well-defined communication framework for future development. Highlights
Changelog
Activity
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive set of domain models for communication, including messages, channels, and configuration, along with extensive unit tests. The implementation is of high quality, using modern Pydantic features for validation and immutability. My review includes a couple of suggestions to reduce code duplication in validation logic by creating reusable validators, which will improve long-term maintainability. Overall, this is an excellent contribution.
| @model_validator(mode="after") | ||
| def _validate_channels(self) -> Self: | ||
| """Ensure channel names are non-blank and unique.""" | ||
| for ch in self.channels: | ||
| if not ch.strip(): | ||
| msg = "Empty or whitespace-only entry in channels" | ||
| raise ValueError(msg) | ||
| if len(self.channels) != len(set(self.channels)): | ||
| dupes = sorted(c for c, n in Counter(self.channels).items() if n > 1) | ||
| msg = f"Duplicate entries in channels: {dupes}" | ||
| raise ValueError(msg) | ||
| return self |
There was a problem hiding this comment.
The validation logic here to ensure channel names are non-blank and unique is very similar to the logic in _validate_subscribers in src/ai_company/communication/channel.py. To improve maintainability and adhere to the DRY principle, consider extracting this logic into a reusable utility function that can be called from both model_validators.
| @model_validator(mode="after") | ||
| def _validate_strings_not_blank(self) -> Self: | ||
| """Ensure required string fields are not whitespace-only.""" | ||
| for field_name in ("sender", "to", "channel", "content"): | ||
| if not getattr(self, field_name).strip(): | ||
| msg = f"{field_name} must not be whitespace-only" | ||
| raise ValueError(msg) | ||
| return self |
There was a problem hiding this comment.
The logic to validate that required string fields are not blank or whitespace-only is repeated in this validator and also in Attachment._validate_ref_not_blank and MessageMetadata._validate_optional_strings. To avoid this repetition and improve maintainability, you could define a reusable validator.
With Pydantic v2, typing.Annotated is a great way to create reusable validation logic for fields. For example:
from typing import Annotated
from pydantic import AfterValidator
def _check_not_whitespace(v: str) -> str:
if not v.strip():
raise ValueError("string must not be whitespace-only")
return v
NotBlankStr = Annotated[str, AfterValidator(_check_not_whitespace)]
# Then in your model, you can use this type and remove this validator:
class Message(BaseModel):
# ...
sender: NotBlankStr = Field(min_length=1, alias="from", description="Sender agent ID")
to: NotBlankStr = Field(min_length=1, description="Recipient agent or channel")
channel: NotBlankStr = Field(min_length=1, description="Channel the message is sent through")
content: NotBlankStr = Field(min_length=1, description="Message body text")
# ...This approach makes the validation declarative on the field itself and removes the need for a separate model_validator for this check.
There was a problem hiding this comment.
Pull request overview
Implements the new communication domain layer (per DESIGN_SPEC §5) by adding immutable Pydantic models for messages, channels, and communication configuration, plus comprehensive unit tests.
Changes:
- Added
StrEnumtypes for message/channel semantics (MessageType,MessagePriority,ChannelType, etc.). - Added frozen Pydantic models for
Message,Attachment,MessageMetadata,Channel, and communication config models (bus/meetings/hierarchy/loop-prevention). - Added a full unit test suite for the new communication models, including factories/fixtures.
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/ai_company/communication/enums.py |
Adds communication-related StrEnum definitions used throughout the new domain models. |
src/ai_company/communication/message.py |
Introduces Attachment, MessageMetadata, and Message models (including "from" aliasing). |
src/ai_company/communication/channel.py |
Adds Channel model with subscriber validation. |
src/ai_company/communication/config.py |
Adds communication configuration models for message bus, meetings, hierarchy, and loop prevention. |
src/ai_company/communication/__init__.py |
Re-exports communication models/enums as the public package surface. |
tests/unit/communication/conftest.py |
Adds Polyfactory factories and sample fixtures for communication models. |
tests/unit/communication/test_enums.py |
Adds unit tests for the new communication enums. |
tests/unit/communication/test_message.py |
Adds unit tests for Attachment, MessageMetadata, and Message behavior/validation/serialization. |
tests/unit/communication/test_channel.py |
Adds unit tests for Channel behavior/validation/serialization. |
tests/unit/communication/test_config.py |
Adds unit tests for communication config models and validation rules. |
tests/unit/communication/__init__.py |
Adds the unit test package initializer. |
CLAUDE.md |
Adds a “Shell Usage” guidance section (no cd usage). |
Comments suppressed due to low confidence (2)
src/ai_company/communication/config.py:90
MeetingTypeConfigdoesn’t currently guard against whitespace-only strings forname/frequency/trigger, and it doesn’t validateparticipantsentries (e.g., whitespace-only values or duplicates). Other domain models in this repo consistently reject whitespace-only identifiers and validate tuple entries (e.g.,core.company.Team,communication.Channel). Consider adding anaftervalidator that.strip()-checks these fields and enforces non-blank/uniqueparticipants.
name: str = Field(min_length=1, description="Meeting type name")
frequency: str | None = Field(
default=None,
min_length=1,
description="Recurrence schedule",
)
trigger: str | None = Field(
default=None,
min_length=1,
description="Event trigger",
)
participants: tuple[str, ...] = Field(
default=(),
description="Participant role or agent identifiers",
)
CLAUDE.md:46
- This documentation example includes a user-specific, Windows-only path (
C:/Users/Aurelio/...). To keep guidance portable and avoid embedding personal paths in the repo, consider replacing it with a generic placeholder path (or just state “don’t usecd” without an example path).
## Shell Usage
- **NEVER use `cd` in Bash commands** — the working directory is already set to the project root. Use absolute paths or run commands directly. Do NOT prefix commands with `cd C:/Users/Aurelio/ai-company &&`.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/unit/communication/test_config.py`:
- Around line 29-35: The test_defaults in
tests/unit/communication/test_config.py is brittle because it asserts
len(cfg.channels) == 7; update the test to avoid depending on a hard-coded count
by either removing that length assertion or replacing it with an assertion that
cfg.channels contains the expected key channels (e.g., "#all-hands",
"#engineering", "#watercooler"), or import and compare against the canonical
default channels from MessageBusConfig (referencing MessageBusConfig and
cfg.channels) so the test only fails for actual contract changes.
ℹ️ Review info
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (12)
CLAUDE.mdsrc/ai_company/communication/__init__.pysrc/ai_company/communication/channel.pysrc/ai_company/communication/config.pysrc/ai_company/communication/enums.pysrc/ai_company/communication/message.pytests/unit/communication/__init__.pytests/unit/communication/conftest.pytests/unit/communication/test_channel.pytests/unit/communication/test_config.pytests/unit/communication/test_enums.pytests/unit/communication/test_message.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). (1)
- GitHub Check: Agent
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Do not usefrom __future__ import annotations— Python 3.14 has PEP 649 native lazy annotations
Include type hints on all public functions and classes, enforced by mypy in strict mode
Write Google-style docstrings on all public classes and functions, enforced by ruff D rules
Create new objects instead of mutating existing ones (immutability principle)
Maintain line length of 88 characters, enforced by ruff
Keep functions under 50 lines and files under 800 lines
Handle errors explicitly and never silently swallow exceptions
Validate input at system boundaries: user input, external API responses, and config files
Files:
src/ai_company/communication/message.pysrc/ai_company/communication/__init__.pytests/unit/communication/test_channel.pytests/unit/communication/test_config.pytests/unit/communication/test_message.pytests/unit/communication/test_enums.pysrc/ai_company/communication/channel.pysrc/ai_company/communication/config.pytests/unit/communication/conftest.pysrc/ai_company/communication/enums.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use pytest markers@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slowto categorize tests
Useasyncio_mode = "auto"in pytest configuration; no manual@pytest.mark.asynciodecorator needed
Set 30-second timeout per test to prevent hanging tests
Files:
tests/unit/communication/test_channel.pytests/unit/communication/test_config.pytests/unit/communication/test_message.pytests/unit/communication/test_enums.pytests/unit/communication/conftest.py
🧠 Learnings (5)
📚 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-02-28T12:05:29.985Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-28T12:05:29.985Z
Learning: Applies to src/ai_company/{config,core}/**/*.py : Use Pydantic v2 models with `BaseModel`, `model_validator`, and `ConfigDict`
Applied to files:
src/ai_company/communication/config.py
📚 Learning: 2026-01-24T09:54:56.100Z
Learnt from: CR
Repo: Aureliolo/story-factory PR: 0
File: .github/instructions/test-files.instructions.md:0-0
Timestamp: 2026-01-24T09:54:56.100Z
Learning: Applies to **/tests/conftest.py : Place shared pytest fixtures in `tests/conftest.py`
Applied to files:
tests/unit/communication/conftest.py
📚 Learning: 2026-01-24T09:54:56.100Z
Learnt from: CR
Repo: Aureliolo/story-factory PR: 0
File: .github/instructions/test-files.instructions.md:0-0
Timestamp: 2026-01-24T09:54:56.100Z
Learning: Applies to **/test_*.py : Use appropriate fixture scopes (`function`, `class`, `module`, `session`) and document complex fixtures with docstrings
Applied to files:
tests/unit/communication/conftest.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 tests/**/*.py : Use pytest fixtures for test setup. Shared fixtures should be in `tests/conftest.py`
Applied to files:
tests/unit/communication/conftest.py
🧬 Code graph analysis (9)
src/ai_company/communication/message.py (1)
src/ai_company/communication/enums.py (3)
AttachmentType(43-48)MessagePriority(22-32)MessageType(6-19)
src/ai_company/communication/__init__.py (4)
src/ai_company/communication/channel.py (1)
Channel(11-51)src/ai_company/communication/config.py (8)
CircuitBreakerConfig(184-205)CommunicationConfig(256-290)HierarchyConfig(138-157)LoopPreventionConfig(208-253)MeetingsConfig(109-135)MeetingTypeConfig(60-106)MessageBusConfig(25-57)RateLimitConfig(160-181)src/ai_company/communication/enums.py (6)
AttachmentType(43-48)ChannelType(35-40)CommunicationPattern(51-60)MessageBusBackend(63-72)MessagePriority(22-32)MessageType(6-19)src/ai_company/communication/message.py (3)
Attachment(17-36)Message(103-161)MessageMetadata(39-100)
tests/unit/communication/test_channel.py (3)
src/ai_company/communication/channel.py (1)
Channel(11-51)src/ai_company/communication/enums.py (1)
ChannelType(35-40)tests/unit/communication/conftest.py (2)
ChannelFactory(49-52)sample_channel(127-132)
tests/unit/communication/test_config.py (1)
src/ai_company/communication/enums.py (2)
CommunicationPattern(51-60)MessageBusBackend(63-72)
tests/unit/communication/test_message.py (2)
src/ai_company/communication/message.py (3)
Attachment(17-36)Message(103-161)MessageMetadata(39-100)tests/unit/communication/conftest.py (3)
AttachmentFactory(29-30)MessageMetadataFactory(33-39)MessageFactory(42-46)
tests/unit/communication/test_enums.py (1)
src/ai_company/communication/enums.py (6)
AttachmentType(43-48)ChannelType(35-40)CommunicationPattern(51-60)MessageBusBackend(63-72)MessagePriority(22-32)MessageType(6-19)
src/ai_company/communication/channel.py (1)
src/ai_company/communication/enums.py (1)
ChannelType(35-40)
src/ai_company/communication/config.py (1)
src/ai_company/communication/enums.py (2)
CommunicationPattern(51-60)MessageBusBackend(63-72)
tests/unit/communication/conftest.py (4)
src/ai_company/communication/channel.py (1)
Channel(11-51)src/ai_company/communication/config.py (8)
CircuitBreakerConfig(184-205)CommunicationConfig(256-290)HierarchyConfig(138-157)LoopPreventionConfig(208-253)MeetingsConfig(109-135)MeetingTypeConfig(60-106)MessageBusConfig(25-57)RateLimitConfig(160-181)src/ai_company/communication/enums.py (3)
ChannelType(35-40)MessagePriority(22-32)MessageType(6-19)src/ai_company/communication/message.py (3)
Attachment(17-36)Message(103-161)MessageMetadata(39-100)
🔇 Additional comments (21)
CLAUDE.md (1)
44-46: LGTM!The "Shell Usage" section is a useful addition, providing clear guidance to avoid common pitfalls with working directory assumptions.
src/ai_company/communication/message.py (3)
17-36: LGTM!The
Attachmentmodel is well-implemented with appropriate validation for whitespace-only strings and immutability.
39-100: LGTM!The
MessageMetadatamodel correctly uses an immutable tuple structure for theextrafield and has thorough validation for both optional string fields and key uniqueness.
103-161: LGTM!The
Messagemodel correctly implements the DESIGN_SPEC 5.3 schema with proper aliasing ofsenderto"from"for JSON compatibility, while usingpopulate_by_name=Trueto allow both field names during deserialization.src/ai_company/communication/enums.py (1)
1-72: LGTM!All six
StrEnumclasses are well-defined with clear docstrings referencing the relevant DESIGN_SPEC sections. The explicit note inMessagePriorityabout using"normal"instead of"medium"(unlikecore.enums.Priority) is helpful for avoiding confusion.src/ai_company/communication/channel.py (1)
11-51: LGTM!The
Channelmodel is cleanly implemented with proper immutability viatuple[str, ...]for subscribers, and thorough validation for both name and subscriber entries (non-blank, unique).src/ai_company/communication/__init__.py (1)
1-43: LGTM!The module properly aggregates and re-exports all public entities from submodules with an explicit
__all__list. The alphabetical ordering enhances maintainability.src/ai_company/communication/config.py (8)
13-57: LGTM!
MessageBusConfigcorrectly defaults to the DESIGN_SPEC 5.4 channels and validates for non-blank, unique entries.
60-106: LGTM!
MeetingTypeConfigcorrectly enforces the mutual exclusivity constraint betweenfrequencyandtriggerfields per DESIGN_SPEC requirements.
109-135: LGTM!
MeetingsConfigproperly validates uniqueness of meeting type names.
138-157: LGTM!
HierarchyConfigis straightforward with sensible defaults for chain-of-command enforcement.
160-181: LGTM!
RateLimitConfighas appropriate constraints withgt=0for the rate limit andge=0for burst allowance.
184-205: LGTM!
CircuitBreakerConfigcorrectly constrains both fields to positive values.
208-253: LGTM!
LoopPreventionConfigcorrectly enforces thatancestry_trackingmust always beTrueper DESIGN_SPEC 5.5, preventing misconfiguration while still documenting the field's existence.
256-290: LGTM!
CommunicationConfigcleanly aggregates all sub-configurations with appropriatedefault_factoryusage for nested models.tests/unit/communication/conftest.py (2)
29-91: LGTM!The factories are well-structured with appropriate defaults to satisfy model validation constraints (e.g.,
frequency="daily"forMeetingTypeConfigFactory,ancestry_tracking=TrueforLoopPreventionConfigFactory). Factory composition is correctly used for nested models.
96-147: LGTM!The fixtures provide well-constructed sample instances with realistic data. The
sample_messagefixture correctly uses fixture dependency injection forsample_metadata.tests/unit/communication/test_enums.py (1)
1-97: LGTM!Comprehensive enum tests with appropriate markers (
@pytest.mark.unit) and timeout (pytest.mark.timeout(30)). Thetest_normal_not_mediumtest inTestMessagePriorityis a good guard against accidental confusion withcore.enums.Priority.tests/unit/communication/test_channel.py (1)
1-120: LGTM!The test file is well-structured with comprehensive coverage of the Channel domain model:
- Proper use of
pytest.mark.timeout(30)at module level per coding guidelines- Each test class appropriately marked with
@pytest.mark.unit- Good coverage of construction, validation (empty name, whitespace, duplicates), immutability, serialization round-trips, and factory/fixture integration
- Tests align with the validation logic in
Channelmodel (whitespace checks, duplicate subscriber detection)tests/unit/communication/test_message.py (1)
1-366: LGTM!Comprehensive test coverage for Attachment, MessageMetadata, and Message models:
- Proper module-level timeout and unit markers per coding guidelines
- Excellent coverage of DESIGN_SPEC 5.3 alias handling (
from/sender) inTestMessageAlias- Thorough validation testing for whitespace rejection across all string fields
- Good use of
_make_messagehelper to reduce boilerplate while maintaining test clarity- Factory and fixture integration tests ensure test infrastructure works correctly
tests/unit/communication/test_config.py (1)
36-511: LGTM!Excellent test coverage across all configuration models:
- Thorough validation testing including mutual exclusivity for
MeetingTypeConfig(frequency XOR trigger)- Critical test for
ancestry_tracking=Falserejection (lines 391-396) per DESIGN_SPEC 5.5- Proper immutability and
model_copybehavior verification- JSON round-trip tests ensure serialization integrity
- Factory and fixture integration ensures test infrastructure consistency
- Add MeetingTypeConfig validators: whitespace-only name/frequency/trigger, blank/duplicate participants (Critical: 3 items) - Replace ancestry_tracking bool+validator with Literal[True] (Major) - Use AwareDatetime for Message.timestamp to enforce timezone (Major) - Extract NotBlankStr annotated type to core/types.py, eliminating 5 repeated model validators across message.py, channel.py, config.py (Major: DRY) - Fix MessageMetadata/Message docstrings for spec accuracy (Major) - Expand ChannelType and AttachmentType docstrings (Medium) - Fix noqa comment consistency on imports (Medium) - Add 13 new tests: __all__ exports, JSON alias roundtrip, empty string boundaries, unique message IDs, MeetingTypeConfig validation (Medium) - Replace brittle len(channels)==7 with _DEFAULT_CHANNELS comparison (Minor)
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/ai_company/communication/config.py`:
- Around line 28-60: Extract the repeated non-blank/unique string validation
into a shared helper (e.g., validate_non_blank_unique_strings) and call it from
each validator to remove duplication: replace the logic inside
MessageBusConfig._validate_channels, MeetingTypeConfig._validate_participants,
and Channel._validate_subscribers with a single call to
validate_non_blank_unique_strings(self.channels, "channels") /
validate_non_blank_unique_strings(self.participants, "participants") /
validate_non_blank_unique_strings(self.subscribers, "subscribers"); implement
the helper in a central module (e.g., core/types.py or a new validators module),
have it raise ValueError with the same messages (including duplicate list) so
existing validators simply call it and return self.
ℹ️ Review info
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (10)
src/ai_company/communication/channel.pysrc/ai_company/communication/config.pysrc/ai_company/communication/enums.pysrc/ai_company/communication/message.pysrc/ai_company/core/__init__.pysrc/ai_company/core/types.pytests/unit/communication/test_channel.pytests/unit/communication/test_config.pytests/unit/communication/test_enums.pytests/unit/communication/test_message.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Do not usefrom __future__ import annotations— Python 3.14 has PEP 649 native lazy annotations
Include type hints on all public functions and classes, enforced by mypy in strict mode
Write Google-style docstrings on all public classes and functions, enforced by ruff D rules
Create new objects instead of mutating existing ones (immutability principle)
Maintain line length of 88 characters, enforced by ruff
Keep functions under 50 lines and files under 800 lines
Handle errors explicitly and never silently swallow exceptions
Validate input at system boundaries: user input, external API responses, and config files
Files:
src/ai_company/communication/message.pysrc/ai_company/core/__init__.pysrc/ai_company/communication/channel.pytests/unit/communication/test_channel.pytests/unit/communication/test_config.pysrc/ai_company/core/types.pysrc/ai_company/communication/config.pytests/unit/communication/test_message.pytests/unit/communication/test_enums.pysrc/ai_company/communication/enums.py
src/ai_company/{config,core}/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Use Pydantic v2 models with
BaseModel,model_validator, andConfigDict
Files:
src/ai_company/core/__init__.pysrc/ai_company/core/types.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use pytest markers@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slowto categorize tests
Useasyncio_mode = "auto"in pytest configuration; no manual@pytest.mark.asynciodecorator needed
Set 30-second timeout per test to prevent hanging tests
Files:
tests/unit/communication/test_channel.pytests/unit/communication/test_config.pytests/unit/communication/test_message.pytests/unit/communication/test_enums.py
🧠 Learnings (1)
📚 Learning: 2026-02-28T12:05:29.985Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-28T12:05:29.985Z
Learning: Applies to src/ai_company/{config,core}/**/*.py : Use Pydantic v2 models with `BaseModel`, `model_validator`, and `ConfigDict`
Applied to files:
src/ai_company/communication/config.py
🧬 Code graph analysis (6)
src/ai_company/communication/message.py (1)
src/ai_company/communication/enums.py (3)
AttachmentType(49-60)MessagePriority(22-32)MessageType(6-19)
src/ai_company/communication/channel.py (1)
src/ai_company/communication/enums.py (1)
ChannelType(35-46)
tests/unit/communication/test_channel.py (3)
src/ai_company/communication/channel.py (1)
Channel(14-46)src/ai_company/communication/enums.py (1)
ChannelType(35-46)tests/unit/communication/conftest.py (2)
ChannelFactory(49-52)sample_channel(127-132)
src/ai_company/communication/config.py (1)
src/ai_company/communication/enums.py (2)
CommunicationPattern(63-72)MessageBusBackend(75-84)
tests/unit/communication/test_message.py (2)
src/ai_company/communication/enums.py (3)
AttachmentType(49-60)MessagePriority(22-32)MessageType(6-19)src/ai_company/communication/message.py (3)
Attachment(19-30)Message(88-138)MessageMetadata(33-85)
tests/unit/communication/test_enums.py (1)
src/ai_company/communication/enums.py (6)
AttachmentType(49-60)ChannelType(35-46)CommunicationPattern(63-72)MessageBusBackend(75-84)MessagePriority(22-32)MessageType(6-19)
🔇 Additional comments (22)
src/ai_company/communication/enums.py (1)
1-84: LGTM!Clean and well-documented enum definitions. All enums have proper Google-style docstrings with DESIGN_SPEC references, and the
StrEnumusage ensures proper string serialization for JSON compatibility.src/ai_company/core/__init__.py (1)
53-53: LGTM!Clean addition of
NotBlankStrto the public API surface, maintaining alphabetical ordering in__all__.Also applies to: 79-79
tests/unit/communication/test_enums.py (1)
1-106: LGTM!Comprehensive test coverage for all communication enums. Good use of
@pytest.mark.unitmarkers and 30-second timeout per coding guidelines. Thetest_normal_not_mediumtest effectively documents the intentional difference betweenMessagePriority.NORMALandcore.Priority.MEDIUM.src/ai_company/core/types.py (1)
1-21: LGTM!Clean implementation of a reusable
NotBlankStrtype that enforces both non-empty and non-whitespace-only constraints. Good use of Pydantic v2'sStringConstraintsandAfterValidatorfor composable validation.tests/unit/communication/test_message.py (1)
1-385: LGTM!Excellent test coverage for the message domain models. Tests comprehensively cover:
- Construction and default values
- Validation (empty/whitespace strings, negative values, duplicate keys)
- Immutability via frozen models
- JSON roundtrip with alias handling (
from/sender)- Factory and fixture integration
The helper
_make_message()effectively reduces test boilerplate while maintaining readability.src/ai_company/communication/channel.py (1)
1-46: LGTM!Clean implementation of the
Channelmodel with proper immutability viafrozen=True. The_validate_subscribersvalidator correctly enforces non-blank and unique entries. Thenoqa: TC001comment appropriately explains whyNotBlankStrimport is needed at runtime.src/ai_company/communication/message.py (1)
1-138: LGTM!Well-designed message domain models following DESIGN_SPEC 5.3. Notable implementations:
AwareDatetimecorrectly enforces timezone-aware timestampssenderalias to"from"withpopulate_by_name=Trueenables JSON compatibility while avoiding Python keyword collision- Immutable
extrafield usingtuple[tuple[str, str], ...]with proper key uniqueness validation- All numeric fields have appropriate
ge=0constraintstests/unit/communication/test_config.py (2)
7-7: Note on private import usage.Importing
_DEFAULT_CHANNELSfrom the config module is a reasonable approach for testing default behavior without hardcoding values. This addresses the previous review feedback about brittle count assertions. Be aware that changes to_DEFAULT_CHANNELSwill affect this test, which is the intended behavior.
1-553: LGTM!Thorough test coverage for all communication configuration models. Tests comprehensively validate:
- Default values and custom configurations
- Validation rules (mutual exclusivity, bounds checking, uniqueness)
- Immutability via frozen models
- JSON serialization roundtrips
- Factory integration
The test structure is well-organized with clear separation by model and concern (construction, validation, immutability, serialization).
tests/unit/communication/test_channel.py (6)
1-9: LGTM! Test file structure follows guidelines.The file correctly applies:
pytest.mark.timeout(30)at module level (Line 9)@pytest.mark.unitmarkers on all test classes
15-31: LGTM! Construction tests validate defaults and explicit field assignment.Tests correctly verify that:
- Minimal construction requires only
namewith sensible defaults fortypeandsubscribers- All fields can be explicitly set and retrieved
71-82: LGTM! Immutability tests correctly verify frozen model behavior.Tests validate that:
- Direct attribute mutation raises
ValidationErroron frozen modelmodel_copycreates a new instance without mutating the original
88-102: LGTM! Serialization tests cover JSON roundtrip and enum serialization.Tests correctly verify:
- JSON roundtrip preserves model equality
- Enum values serialize to their string representations
108-126: LGTM! Factory and fixture tests validate test infrastructure.Tests verify the
ChannelFactoryproduces validChannelinstances and thesample_channelfixture provides expected test data.
37-65: Error message pattern for whitespace-only name validation is correct.The
NotBlankStrvalidator raisesValueErrorwith the message"must not be whitespace-only", which matches the regex pattern"whitespace-only"used in the test at line 44. The test is correct as written.src/ai_company/communication/config.py (7)
1-26: LGTM! Module setup and default channels are well-defined.The docstring, imports, and default channel configuration align with DESIGN_SPEC Section 5.4. The
noqa: TC001comment correctly documents whyNotBlankStrmust be imported at runtime for Pydantic validation.
63-120: LGTM! MeetingTypeConfig enforces mutual exclusivity and participant integrity.The two validators correctly ensure:
- Exactly one of
frequencyortriggeris set (lines 98-107)- Participants are non-blank and unique (lines 109-120)
The use of
NotBlankStr | Nonefor optional fields with non-blank enforcement when present is appropriate.
123-149: LGTM! MeetingsConfig validates unique meeting type names.The validator correctly identifies and reports duplicate meeting type names.
152-171: LGTM! HierarchyConfig is straightforward with sensible defaults.The boolean flags for chain-of-command enforcement and skip-level messaging are well-documented.
174-219: LGTM! Rate limit and circuit breaker configs use appropriate constraints.
RateLimitConfig:gt=0for rate,ge=0for burst allowance (zero burst is valid)CircuitBreakerConfig:gt=0for both threshold and cooldown
222-259: LGTM! LoopPreventionConfig correctly enforces ancestry_tracking as always-on.Using
Literal[True]forancestry_tracking(line 256) is an elegant solution that:
- Makes the constraint self-documenting via the type system
- Rejects
Falseat validation time without a custom validator- Aligns with DESIGN_SPEC 5.5 requirement that ancestry tracking cannot be disabled
262-296: LGTM! CommunicationConfig aggregates all subsystem configs with sensible defaults.Using
default_factoryfor nested config models ensures each instance gets independent defaults. The top-level structure cleanly maps to DESIGN_SPEC Sections 5.4 and 5.5.
DRY up repeated non-blank/unique tuple-of-strings validation across MessageBusConfig, MeetingTypeConfig, and Channel into a single reusable helper in core.types. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
src/ai_company/communication/config.py:15
NotBlankStris imported only for use in Pydantic field annotations, which Ruff'sflake8-type-checkingtypically flags asTC001unless explicitly exempted. Other modules in this repo suppress this pattern with# noqa: TC001on the import (e.g.,src/ai_company/core/task.py:9). Consider adding the same suppression here (or otherwise ensuring this import won’t be auto-suggested into aTYPE_CHECKINGblock, which would break Pydantic runtime schema generation under PEP 649).
from ai_company.core.types import (
NotBlankStr,
validate_non_blank_unique_strings,
)
src/ai_company/communication/channel.py:11
NotBlankStrappears to be used only in type annotations for this Pydantic model. With Ruff’sflake8-type-checkingenabled in this repo, similar annotation-only imports are suppressed using# noqa: TC001to avoid being moved underTYPE_CHECKING(which can break Pydantic runtime evaluation under PEP 649). Consider adding that suppression on this import for consistency with existing core models.
from ai_company.core.types import (
NotBlankStr,
validate_non_blank_unique_strings,
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
🤖 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).
🤖 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>
Summary
StrEnumtypes (MessageType,MessagePriority,ChannelType,AttachmentType,CommunicationPattern,MessageBusBackend) incommunication/enums.pyAttachment,MessageMetadata, andMessagemodels incommunication/message.py—Message.senderaliased to"from"for DESIGN_SPEC 5.3 JSON compatChannelmodel incommunication/channel.pywith subscriber validationcommunication/config.py:MessageBusConfig,MeetingTypeConfig,MeetingsConfig,HierarchyConfig,RateLimitConfig,CircuitBreakerConfig,LoopPreventionConfig,CommunicationConfigLoopPreventionConfig.ancestry_trackingrejectsFalse(spec: "always on, not configurable")MeetingTypeConfigenforces exactly one offrequencyortrigger__init__.pyre-exportsmodel_copy, JSON roundtrip, and polyfactory factoriescdin commands)Closes #58
Test plan
uv run ruff check src/ai_company/communication/ tests/unit/communication/— all passeduv run ruff format --check— all formatteduv run mypy src/ai_company/communication/— no issuesuv run pytest tests/unit/communication/ -v— 140/140 passeduv run pytest tests/ -n auto --cov=ai_company --cov-fail-under=80— 785 passed, 98.19% coverage🤖 Generated with Claude Code