fix: address Greptile post-merge review findings from PRs #170-#175#176
fix: address Greptile post-merge review findings from PRs #170-#175#176
Conversation
…resolve mypy attr-defined Tests in test_cost_optimized_assignment.py were written against old "default-missing-to-0.0" semantics but the implementation uses all-or-nothing fallback. Also fix mypy error on CI where protocol type doesn't expose _scorer attribute.
PR #174 — git_worktree.py: - _validate_git_ref now accepts error_cls/event params so merge context raises WorkspaceMergeError and teardown raises WorkspaceCleanupError - _run_git catches asyncio.CancelledError to kill subprocess before re-raising, preventing orphaned git processes PR #172 — task assignment: - TaskAssignmentConfig.strategy validated against known strategy names - max_concurrent_tasks_per_agent now enforced in _score_and_filter_candidates via new AssignmentRequest.max_concurrent_tasks field - TaskAssignmentStrategy protocol docstring documents error signaling contract PR #171 — worktree skill: - rebase uses --left-right --count with triple-dot to detect behind-main - setup reuse path uses correct git worktree add (without -b) - setup handles dirty working tree with stash/abort prompt - status table shows both ahead and behind counts - tree command provides circular dependency recovery guidance PR #170 — meeting parsing: - Fix assigned? regex to assigned (prevents false-positive assignee extraction from "assign to X" in action item descriptions)
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (13)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds capacity-aware task assignment and strategy-name validation; tightens meeting-assignee parsing and event logging; generalizes git worktree validation and git subprocess handling to use context-specific error types and log events; updates tests and worktree documentation to reflect dual-number ahead/behind semantics and new flows. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
✨ Simplify code
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 focuses on enhancing the stability and reliability of the system by resolving critical CI failures and addressing a comprehensive list of post-merge review findings. The changes span across various modules, improving git worktree management, refining task assignment logic with better validation and capacity enforcement, and bolstering workspace isolation. The overall impact is a more robust and predictable system behavior, particularly in areas involving git operations and agent task assignments. 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.
Actionable comments posted: 3
🤖 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/meeting/test_parsing.py`:
- Around line 85-92: In test_assign_to_not_matched_as_assignee, add an assertion
that verifies result[0].description remains the original action text (e.g.,
"Please assign to bob the new module") so the test validates that
_parse_assignee did not strip or mutate the description; specifically assert the
value of result[0].description equals the expected description derived from the
input text.
In `@tests/unit/config/test_schema.py`:
- Around line 552-562: Replace the manual for-loop in
test_valid_strategy_names_accepted with pytest's parameterization: add
`@pytest.mark.parametrize` to feed each strategy string into the single test
function, keep the test body to instantiate TaskAssignmentConfig(strategy=name)
and assert cfg.strategy == name; this will replace the loop and make failures
show the specific failing strategy and test case name.
In `@tests/unit/engine/test_assignment_strategies.py`:
- Around line 471-557: Add a new test method
test_all_agents_at_capacity_returns_none to TestMaxConcurrentTasksEnforcement
that constructs AgentTaskScorer and RoleBasedAssignmentStrategy, creates two
agents via make_assignment_agent, a task via make_assignment_task, and an
AssignmentRequest with max_concurrent_tasks set and workloads where each
AgentWorkload has active_task_count >= max_concurrent_tasks; call
strategy.assign(request) and assert result.selected is None and the
result.reason mentions capacity/threshold. Use the same helper symbols
(AgentTaskScorer, RoleBasedAssignmentStrategy, make_assignment_agent,
make_assignment_task, AssignmentRequest, AgentWorkload, SeniorityLevel,
Complexity) so it fits the existing test structure.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 208f5baf-25ef-46e3-9656-374699293681
📒 Files selected for processing (14)
.claude/skills/worktree/SKILL.mdsrc/ai_company/communication/meeting/_parsing.pysrc/ai_company/config/schema.pysrc/ai_company/engine/assignment/models.pysrc/ai_company/engine/assignment/protocol.pysrc/ai_company/engine/assignment/strategies.pysrc/ai_company/engine/workspace/git_worktree.pytests/unit/communication/meeting/test_parsing.pytests/unit/config/conftest.pytests/unit/config/test_schema.pytests/unit/engine/test_assignment_strategies.pytests/unit/engine/test_cost_optimized_assignment.pytests/unit/engine/test_strategy_registry.pytests/unit/engine/test_workspace_git_worktree.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 (5)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Do NOT usefrom __future__ import annotations— Python 3.14 has PEP 649 native lazy annotations
Useexcept A, B:(no parentheses) — ruff enforces PEP 758 except syntax on Python 3.14
Type hints required on all public functions, mypy strict mode enforced
Google style docstrings required on public classes/functions — enforced by ruff D rules
Create new objects for immutability, never mutate existing ones. For non-Pydantic internal collections, usecopy.deepcopy()at construction +MappingProxyTypewrapping for read-only enforcement.
Fordict/listfields in frozen Pydantic models, rely onfrozen=Truefor field reassignment prevention andcopy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization)
Use frozen Pydantic models for config/identity; use separate mutable-via-copy models (usingmodel_copy(update=...)) 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). Use@computed_fieldfor derived values instead of storing + validating redundant fields. UseNotBlankStrfor all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code (multiple tool invocations, parallel agent calls). Prefer structured concurrency over barecreate_task.
Line length 88 characters enforced by ruff
Functions < 50 lines, files < 800 lines
Handle errors explicitly, never silently swallow them
Validate at system boundaries (user input, external APIs, config files)
Files:
src/ai_company/config/schema.pysrc/ai_company/engine/assignment/protocol.pytests/unit/engine/test_cost_optimized_assignment.pytests/unit/engine/test_strategy_registry.pytests/unit/engine/test_assignment_strategies.pytests/unit/communication/meeting/test_parsing.pytests/unit/engine/test_workspace_git_worktree.pysrc/ai_company/communication/meeting/_parsing.pysrc/ai_company/engine/assignment/strategies.pytests/unit/config/conftest.pytests/unit/config/test_schema.pysrc/ai_company/engine/workspace/git_worktree.pysrc/ai_company/engine/assignment/models.py
src/ai_company/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/ai_company/**/*.py: Every module with business logic MUST have:from ai_company.observability import get_loggerthenlogger = get_logger(__name__). Never useimport logging/logging.getLogger()/print()in application code.
Always useloggeras variable name (not_logger, notlog)
Always use event name constants fromai_company.observability.eventsdomain-specific modules (e.g.PROVIDER_CALL_STARTfromevents.provider). Import directly and use structured kwargs:logger.info(EVENT, key=value)— neverlogger.info("msg %s", val)
All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions.
Files:
src/ai_company/config/schema.pysrc/ai_company/engine/assignment/protocol.pysrc/ai_company/communication/meeting/_parsing.pysrc/ai_company/engine/assignment/strategies.pysrc/ai_company/engine/workspace/git_worktree.pysrc/ai_company/engine/assignment/models.py
{src/ai_company/**/*.py,tests/**/*.py,**/*.yaml,**/*.yml}
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in project-owned code, docstrings, comments, tests, or config examples. Use generic names:
example-provider,example-large-001,example-medium-001,example-small-001,large/medium/smallas aliases.
Files:
src/ai_company/config/schema.pysrc/ai_company/engine/assignment/protocol.pytests/unit/engine/test_cost_optimized_assignment.pytests/unit/engine/test_strategy_registry.pytests/unit/engine/test_assignment_strategies.pytests/unit/communication/meeting/test_parsing.pytests/unit/engine/test_workspace_git_worktree.pysrc/ai_company/communication/meeting/_parsing.pysrc/ai_company/engine/assignment/strategies.pytests/unit/config/conftest.pytests/unit/config/test_schema.pysrc/ai_company/engine/workspace/git_worktree.pysrc/ai_company/engine/assignment/models.py
src/ai_company/{engine,providers}/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
RetryExhaustedErrorsignals that all retries failed — the engine layer catches this to trigger fallback chains
Files:
src/ai_company/engine/assignment/protocol.pysrc/ai_company/engine/assignment/strategies.pysrc/ai_company/engine/workspace/git_worktree.pysrc/ai_company/engine/assignment/models.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use pytest markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow
Test timeout: 30 seconds per test. Parallelism:pytest-xdistvia-n auto
Prefer@pytest.mark.parametrizefor testing similar cases
Files:
tests/unit/engine/test_cost_optimized_assignment.pytests/unit/engine/test_strategy_registry.pytests/unit/engine/test_assignment_strategies.pytests/unit/communication/meeting/test_parsing.pytests/unit/engine/test_workspace_git_worktree.pytests/unit/config/conftest.pytests/unit/config/test_schema.py
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-08T19:07:25.519Z
Learning: When review agents find valid issues (including pre-existing issues in surrounding code, suggestions, and findings adjacent to the PR's changes), fix them all. No deferring, no 'out of scope' skipping.
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-08T19:07:25.519Z
Learning: Applies to .github/workflows/**/*.{yml,yaml} : CI jobs: lint (ruff) + type-check (mypy src/ tests/) + test (pytest + coverage) run in parallel → ci-pass (gate). Matrix: Python 3.14. Coverage: Codecov integration.
📚 Learning: 2026-03-08T19:07:25.519Z
Learnt from: CR
Repo: Aureliolo/ai-company PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-08T19:07:25.519Z
Learning: Prioritize issues by dependency order, not priority labels — unblocked dependencies come first
Applied to files:
.claude/skills/worktree/SKILL.md
🧬 Code graph analysis (7)
tests/unit/engine/test_assignment_strategies.py (3)
src/ai_company/engine/assignment/strategies.py (13)
RoleBasedAssignmentStrategy(265-327)assign(227-262)assign(282-327)assign(349-429)assign(451-530)assign(711-757)assign(780-870)name(152-154)name(278-280)name(345-347)name(447-449)name(554-556)name(776-778)src/ai_company/core/enums.py (2)
SeniorityLevel(6-21)Complexity(214-220)src/ai_company/engine/assignment/models.py (2)
AssignmentRequest(65-136)AgentWorkload(17-37)
tests/unit/communication/meeting/test_parsing.py (1)
src/ai_company/communication/meeting/_parsing.py (1)
parse_action_items(127-168)
tests/unit/engine/test_workspace_git_worktree.py (4)
tests/unit/engine/conftest.py (1)
make_workspace(306-327)src/ai_company/engine/errors.py (3)
WorkspaceMergeError(82-83)WorkspaceCleanupError(86-87)WorkspaceSetupError(78-79)src/ai_company/engine/workspace/git_worktree.py (4)
merge_workspace(275-401)teardown_workspace(403-479)setup_workspace(169-273)_run_git(122-167)src/ai_company/engine/workspace/protocol.py (3)
merge_workspace(55-74)teardown_workspace(40-53)setup_workspace(21-38)
src/ai_company/engine/assignment/strategies.py (4)
src/ai_company/engine/parallel_models.py (2)
agent_id(79-81)task_id(87-89)src/ai_company/engine/assignment/models.py (1)
AssignmentCandidate(40-62)src/ai_company/core/enums.py (1)
AgentStatus(67-72)src/ai_company/engine/routing/scorer.py (1)
score(74-162)
tests/unit/config/conftest.py (1)
src/ai_company/config/schema.py (1)
TaskAssignmentConfig(361-424)
tests/unit/config/test_schema.py (1)
src/ai_company/config/schema.py (1)
TaskAssignmentConfig(361-424)
src/ai_company/engine/workspace/git_worktree.py (1)
src/ai_company/engine/errors.py (3)
WorkspaceSetupError(78-79)WorkspaceMergeError(82-83)WorkspaceCleanupError(86-87)
🪛 LanguageTool
.claude/skills/worktree/SKILL.md
[style] ~419-~419: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...dy contains everything from main). - If M behind (regardless of ahead count...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.21.0)
.claude/skills/worktree/SKILL.md
[warning] 313-313: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (27)
tests/unit/engine/test_strategy_registry.py (1)
192-193: Safe_scorerlookup preserves the assertion while satisfying mypy.This still fails if a scorer-based strategy is missing
_scorer, so the test remains strict while avoiding the protocolattr-definedissue.src/ai_company/communication/meeting/_parsing.py (1)
36-43: LGTM! Correctly tightened regex to prevent false-positive assignee extraction.The change from
assigned?(making 'd' optional) toassignedensures that phrases like "assign to bob" aren't incorrectly parsed as assigning to "bob". The regex now only matches the past-tense "assigned to" pattern, which is the semantically correct form for indicating an existing assignment.src/ai_company/engine/assignment/models.py (1)
107-114: LGTM!The
max_concurrent_tasksfield is well-designed:
- Optional with
Nonemeaning no limitge=1ensures valid positive values when provided- Clear description documents the filtering behavior
src/ai_company/engine/assignment/strategies.py (2)
82-84: LGTM!The updated docstring accurately reflects the new capacity-aware filtering behavior.
95-118: Capacity filtering logic is well-implemented.The implementation correctly:
- Only builds the workload map when both conditions are met (line 97)
- Uses
str(agent.id)for consistent key lookup againstw.agent_idstrings- Logs filtered agents with structured context for observability
Minor observation: the
request.max_concurrent_tasks is not Nonecheck on line 106 is technically redundant sinceworkload_mapwould only be non-None if that condition was true on line 97. However, this defensive style is acceptable and makes the logic self-documenting at the point of use.src/ai_company/config/schema.py (2)
374-385: LGTM!The
_VALID_STRATEGIESfrozenset properly enumerates all six assignment strategies. Using a class-levelfrozensetensures immutability while making the valid values available for validation.
408-424: LGTM!The validator correctly:
- Logs a warning with structured context before raising (per coding guidelines)
- Provides a helpful error message listing valid strategies
- Returns
Selffor proper chainingsrc/ai_company/engine/assignment/protocol.py (2)
23-37: LGTM!The error signaling contract documentation clearly distinguishes between:
- Manual strategy: raises
TaskAssignmentError/NoEligibleAgentError- Scoring strategies: returns
AssignmentResult(selected=None, ...)This explicit contract helps implementers and callers understand the expected behavior.
56-63: LGTM!The updated docstring properly documents the
Nonereturn semantics and enumerates the raised exceptions with context.tests/unit/engine/test_cost_optimized_assignment.py (2)
134-134: LGTM!Assertion correctly updated to match the new fallback reason message.
160-196: LGTM!The test correctly documents and validates:
- Incomplete cost data triggers score-only fallback
- With equal scores, sort stability determines winner (first in
available_agents)- The reason message indicates "insufficient cost data"
src/ai_company/engine/workspace/git_worktree.py (4)
49-87: LGTM!The generalized
_validate_git_reffunction:
- Uses keyword-only parameters to enforce explicit error context
- Maintains backward compatibility with sensible defaults for setup context
- Documents the exception types in the docstring
158-161: LGTM!Proper
CancelledErrorhandling that kills the subprocess and awaits its termination before re-raising. This prevents orphaned git processes when the coroutine is cancelled.
298-309: LGTM!Merge context correctly uses
WorkspaceMergeErrorandWORKSPACE_MERGE_FAILEDevent for both branch_name and base_branch validation.
421-426: LGTM!Teardown context correctly uses
WorkspaceCleanupErrorandWORKSPACE_TEARDOWN_FAILEDevent.tests/unit/engine/test_workspace_git_worktree.py (2)
595-636: LGTM!Comprehensive tests validating that context-appropriate exceptions are raised:
WorkspaceMergeErrorfor unsafe refs during mergeWorkspaceCleanupErrorfor unsafe refs during teardownWorkspaceSetupErrorfor unsafe refs during setup
644-698: LGTM!The test correctly validates
CancelledErrorhandling:
- Mocks
wait_forto raiseCancelledError- Properly closes the coroutine to avoid warnings
- Verifies both
kill()andwait()are called on the subprocess- Uses
warnings.catch_warnings()to suppress expected unraisable exception warnings from async cleanup.claude/skills/worktree/SKILL.md (5)
80-94: LGTM!Good addition of dirty working tree handling before checkout. The stash/abort prompt gives users control over how to handle local changes.
113-125: LGTM!The distinction between new branch creation (
-bflag) and reusing existing branches (no-b) is important and well-documented.
311-318: Status table format is correct.The static analysis hint (MD040) flags the code block as missing a language specifier. However, this is a plain-text status table, not code—adding a language identifier would be misleading. The current format is appropriate.
353-353: LGTM!Helpful circular dependency recovery guidance that suggests actionable solutions.
409-419: LGTM!The dual-number ahead/behind logic correctly describes:
0/0: fully up to date (skip)0/N: ahead only, main hasn't moved (skip—rebase is no-op)M/*: behind main (prompt for rebase)The repeated "If" sentence structure (flagged by static analysis) is acceptable here as it clearly delineates distinct conditions.
tests/unit/config/test_schema.py (1)
564-570: LGTM!Both tests properly validate the strategy field constraints: unknown strategies are rejected with a descriptive error, and whitespace-only values trigger
ValidationErrorfrom theNotBlankStrtype.tests/unit/config/conftest.py (2)
20-20: LGTM!Import correctly added to support
TaskAssignmentConfigusage in the factory.
75-75: LGTM!Factory field correctly initialized with default
TaskAssignmentConfig(), consistent with other config field patterns in the factory (e.g.,budget = BudgetConfig(),routing = RoutingConfig()).tests/unit/engine/test_assignment_strategies.py (2)
471-514: LGTM!The test correctly verifies that an agent exactly at the
max_concurrent_taskslimit (3 tasks with max=3) is excluded from selection, and the available agent is selected instead. The setup with workloads is thorough and assertions are clear.
516-557: LGTM!The test correctly verifies that when
max_concurrent_tasksisNone, capacity filtering is disabled and the higher-skilled agent wins despite having 99 active tasks. The inline comment at line 556 helpfully documents the expected behavior.
Greptile SummaryThis PR is a consolidation of 14 targeted post-merge fixes across five previous PRs, addressing CI failures, mypy errors, and Greptile review findings. The changes are well-scoped, thoroughly tested (10 new tests, 3988 total passing), and each fix is accompanied by a focused test that directly exercises the corrected behavior. Key changes:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Caller
participant Service as TaskAssignmentService
participant Strategy as ScoringStrategy
participant Helper as _score_and_filter_candidates
participant Git as _run_git / _validate_git_ref
Caller->>Service: assign(request)
Service->>Strategy: assign(request)
Strategy->>Helper: _score_and_filter_candidates(scorer, request, subtask)
Note over Helper: Build workload_map if<br/>max_concurrent_tasks + workloads present
loop For each ACTIVE agent
alt agent at capacity (active >= max_concurrent_tasks)
Helper-->>Helper: skip (log at_capacity)
else agent not in workload_map
Helper-->>Helper: assume 0 tasks, proceed to score
end
Helper->>Helper: scorer.score(agent, subtask)
end
Helper-->>Strategy: sorted candidates
alt candidates found
Strategy-->>Service: AssignmentResult(selected=winner)
else no candidates
Strategy-->>Service: AssignmentResult(selected=None)
end
Service-->>Caller: result
Note over Git: _validate_git_ref now accepts error_cls + event
Note over Git: merge context → WorkspaceMergeError
Note over Git: teardown context → WorkspaceCleanupError
Note over Git: _run_git catches CancelledError → kills subprocess → re-raises
|
There was a problem hiding this comment.
Pull request overview
This PR addresses Greptile post-merge review findings from PRs #170–#175, fixing CI failures (test assertion mismatches and mypy errors) and applying 14 improvements across workspace isolation, task assignment, meeting parsing, and worktree skill documentation.
Changes:
- Fixes CI-blocking test failures: corrects assertion strings to match implementation wording (
"insufficient cost data"), fixes winner assertion for sort stability in partial cost data scenario, and usesgetattr()for protocol type attribute access to resolve mypyattr-definederrors. - Improves robustness: context-appropriate exception types in
_validate_git_ref,CancelledErrorsubprocess cleanup in_run_git, strategy name validation inTaskAssignmentConfig,max_concurrent_tasksenforcement in scoring, and regex fix to prevent false-positive assignee extraction. - Enhances worktree skill documentation: dirty working tree handling, branch reuse path, ahead/behind status detection, and circular dependency recovery guidance.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/ai_company/engine/workspace/git_worktree.py |
_validate_git_ref parameterized with error_cls/event for context-specific exceptions; _run_git catches CancelledError to kill subprocess |
src/ai_company/engine/assignment/strategies.py |
_score_and_filter_candidates now filters agents at capacity using max_concurrent_tasks |
src/ai_company/engine/assignment/models.py |
New max_concurrent_tasks field on AssignmentRequest |
src/ai_company/engine/assignment/protocol.py |
Extended docstring documenting error signaling contract |
src/ai_company/config/schema.py |
Strategy name validation via _VALID_STRATEGIES frozenset and _validate_strategy_name validator |
src/ai_company/communication/meeting/_parsing.py |
Regex fix: assigned? → assigned to prevent "assign to X" false positives |
tests/unit/engine/test_workspace_git_worktree.py |
Tests for context-specific exceptions and CancelledError subprocess cleanup |
tests/unit/engine/test_cost_optimized_assignment.py |
Assertion fixes to match implementation wording |
tests/unit/engine/test_strategy_registry.py |
getattr() for _scorer access on protocol type |
tests/unit/engine/test_assignment_strategies.py |
Tests for max_concurrent_tasks enforcement |
tests/unit/config/test_schema.py |
Tests for strategy name validation |
tests/unit/config/conftest.py |
Added TaskAssignmentConfig to RootConfigFactory |
tests/unit/communication/meeting/test_parsing.py |
Test for "assign to" not matching as assignee |
.claude/skills/worktree/SKILL.md |
Enhanced docs for setup, status, rebase, and tree commands |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| max_concurrent_tasks: int | None = Field( | ||
| default=None, | ||
| ge=1, | ||
| description=( | ||
| "Maximum concurrent tasks per agent. Agents at or above " | ||
| "this limit are excluded from scoring. None = no limit." | ||
| ), | ||
| ) |
There was a problem hiding this comment.
The Attributes docstring for AssignmentRequest lists task, available_agents, workloads, min_score, required_skills, and required_role but does not include the newly added max_concurrent_tasks field. The codebase convention (Google-style docstrings) requires documenting all public attributes. Please add max_concurrent_tasks to the docstring.
src/ai_company/config/schema.py
Outdated
| _VALID_STRATEGIES: frozenset[str] = frozenset( | ||
| { | ||
| "manual", | ||
| "role_based", | ||
| "load_balanced", | ||
| "cost_optimized", | ||
| "hierarchical", | ||
| "auction", | ||
| }, | ||
| ) |
There was a problem hiding this comment.
_VALID_STRATEGIES is annotated with a plain type (frozenset[str]) on a Pydantic BaseModel. In Pydantic v2, this is implicitly treated as a private attribute (stored per-instance rather than shared as a class-level constant). This works at runtime but is semantically incorrect since the value is a class constant that doesn't vary per instance. Consider annotating it with ClassVar[frozenset[str]] (from typing) to make it a true class variable, which is also more efficient since it avoids per-instance storage. This is the same pattern used in tools/permissions.py:54 for _LEVEL_CATEGORIES, albeit on a non-Pydantic class.
.claude/skills/worktree/SKILL.md
Outdated
| If dirty, warn and ask via AskUserQuestion whether to proceed or abort. | ||
|
|
||
| c. Ensure on main and up to date: | ||
| c. Ensure on main and up to date. If checkout fails due to dirty working tree, warn and ask whether to stash changes, discard, or abort: |
There was a problem hiding this comment.
The description on this line says "warn and ask whether to stash changes, discard, or abort" but the detailed options below (lines 87-88) only list Stash and Abort — the "discard" option is missing. Either add a Discard option (e.g., git checkout -- . or git restore .) or remove "discard" from this line to keep the description and options consistent.
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive set of fixes and improvements across documentation, configuration, core logic, and testing, addressing findings from previous pull requests. Key enhancements include more robust git worktree handling with better error and cancellation management, improved configuration validation for task assignment strategies, and fixes to task assignment logic for concurrency limits and cost optimization. The documentation for worktree skills and assignment strategy protocols has been significantly clarified. The changes are of high quality and are well-supported by new and updated tests.
.claude/skills/worktree/SKILL.md
Outdated
| If dirty, warn and ask via AskUserQuestion whether to proceed or abort. | ||
|
|
||
| c. Ensure on main and up to date: | ||
| c. Ensure on main and up to date. If checkout fails due to dirty working tree, warn and ask whether to stash changes, discard, or abort: |
There was a problem hiding this comment.
The description mentions three options for handling a dirty working tree: "stash changes, discard, or abort". However, the list of actions detailed on lines 87-88 only includes "Stash" and "Abort". To maintain consistency and avoid confusion, please remove the "discard" option from this description to match the implemented options.
| c. Ensure on main and up to date. If checkout fails due to dirty working tree, warn and ask whether to stash changes, discard, or abort: | |
| c. Ensure on main and up to date. If checkout fails due to dirty working tree, warn and ask whether to stash changes or abort: |
…t, and Gemini - Forward max_concurrent_tasks in HierarchicalAssignmentStrategy._score_subordinates - Change _VALID_STRATEGIES to ClassVar[frozenset[str]] (was Pydantic ModelPrivateAttr) - Replace bare string event in _parsing.py with MEETING_PARSING_NO_SECTION constant - Narrow error_cls from type[Exception] to type[WorkspaceError] in _validate_git_ref - Add log_event param to _run_git for context-aware timeout logging - Add WARNING logs to all config validators before raising - Use sorted() instead of in-place .sort() for immutability convention - Add debug log for missing workload data in capacity filtering - Update docstrings: protocol error signaling contract, strategy class names, scoring defaults - Parametrize test_valid_strategy_names_accepted per CLAUDE.md convention - Add tests: all-agents-at-capacity, empty-workloads, merge/teardown ref validation variants - Add description assertion to test_assign_to_not_matched_as_assignee - Fix SKILL.md discard option inconsistency and left/right mapping clarity - Update DESIGN_SPEC.md sections 6.4 and 6.8 with new behavioral documentation
🤖 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
attr-definederror in strategy registry testPR #175 — Test assertion fixes (CI blockers)
"no cost data"→"insufficient cost data"to match implementation wordingunknown-dev→known-devwinner assertion (all-or-nothing fallback, sort stability)getattr()for_scoreraccess on protocol type (Windows/Linux mypy difference)PR #174 — Workspace isolation
_validate_git_refraises context-appropriate exception types (WorkspaceMergeErrorin merge,WorkspaceCleanupErrorin teardown)_run_gitcatchesasyncio.CancelledErrorto kill subprocess before re-raising (prevents orphaned git processes)PR #172 — Task assignment
TaskAssignmentConfig.strategyvalidated against 6 known strategy namesmax_concurrent_tasks_per_agentenforced via newAssignmentRequest.max_concurrent_tasksfield in_score_and_filter_candidatesTaskAssignmentStrategyprotocol docstring documents error signaling contract (raises vsselected=None)PR #171 — Worktree skill
rebaseuses--left-right --countwith triple-dot to detect behind-main worktreessetupreuse path usesgit worktree addwithout-bfor existing branchessetuphandles dirty working tree with stash/abort promptstatustable shows both ahead and behind countstreeprovides circular dependency recovery guidancePR #170 — Meeting parsing
assigned?→assignedregex fix (prevents false-positive assignee extraction from "assign to X")Test plan
Review coverage
Quick mode — automated checks only (lint, type-check, tests, coverage).
🤖 Generated with Claude Code