Task 5 (concurrent teammates with skills) was failing because
import-finder hit max_turns=8 before writing results. Increased to
max_turns=20 and timeout=120s. Both teammates now pass (37s).
Three-layer compaction system faithfully translated from reference:
1. Microcompact: clear old tool results (COMPACTABLE_TOOLS set) keeping
recent N results. Cheap, no LLM call. Saved ~7500 tokens in testing.
2. Full compact: LLM-based summarization with structured 9-section prompt
(analysis + summary tags). Formats and injects summary message.
3. Auto-compact: integrated into query loop, checks token threshold each
turn. Fires microcompact first, falls back to full compact if needed.
Circuit breaker after 3 consecutive failures.
Key constants from reference: AUTOCOMPACT_BUFFER_TOKENS=13K,
MAX_OUTPUT_TOKENS_FOR_SUMMARY=20K, keep_recent=5, 4/3 token padding.
Tested: 5 tasks on shared engine against AutoAgent project (60K tokens)
without hitting Kimi 4MB limit. Previously crashed at Task 4.
- Replace minimal system prompt with reference-faithful version covering:
system guidance, task execution, action safety, tool usage, tone/style
- Change default max_turns from 8 to 200 for large task support
- Add health_check() to BackendRegistry (found during live testing)
- Fix mailbox.py async I/O (wrap blocking ops with run_in_executor)
All changes validated with real Kimi K2.5 API: 5 large tasks passed including
deep architecture analysis (27 tool calls), multi-turn debug+fix, cross-module
trace, code generation with ruff validation.
The _run_query_loop was passing a raw string to ConversationMessage(content=...)
which expects a list. Use the from_user_text() factory method instead.
Found during real E2E testing with Kimi K2.5 model.
- Add _kill_orphaned_teammate_panes() to team_lifecycle, mirroring TS
killOrphanedTeammatePanes: kills pane-backed teammate processes before
directory removal on ungraceful shutdown (SIGINT/SIGTERM)
- Update cleanup_session_teams() to kill orphaned panes first, then clean
directories — matches TS cleanupSessionTeams two-phase teardown
Both permission_sync.py and team_lifecycle.py now faithfully translate
all exported and internal functions from permissionSync.ts / teamHelpers.ts.
Expand get_coordinator_system_prompt() to match the full TypeScript source
(coordinatorMode.ts ~237 lines):
- Section 2: add subscribe_pr_activity tool mention and inline task-notification
example showing the full coordinator-turn / user-notification flow
- Section 4 Stopping Workers: add code block with stop+continue pattern
- Section 5: add "Add a purpose statement" guidance, "Choose continue vs. spawn
by context overlap" table, "Continue mechanics" with code examples, and
complete good/bad prompt examples with git operation specifics
- Section 6 (new): Example Session with realistic XML task-notification flow
Expand AgentDefinition (Pydantic model) from 7 fields to 25+ to match
TypeScript BaseAgentDefinition:
- disallowed_tools, skills, mcp_servers, required_mcp_servers, hooks
- color (validated against AGENT_COLORS frozenset)
- effort (str "low"/"medium"/"high" or positive int)
- permission_mode (PERMISSION_MODES tuple)
- max_turns (positive int turn limit)
- background, initial_prompt, memory (MEMORY_SCOPES), isolation (ISOLATION_MODES)
- filename, base_dir, critical_system_reminder, pending_snapshot_update, omit_claude_md
Update built-in agents to match TS builtInAgents.ts:
- general-purpose: tools=['*'], enriched system prompt
- Explore: disallowed_tools, model='haiku', omit_claude_md=True
- Plan: disallowed_tools, model='inherit', omit_claude_md=True
- verification (renamed from verifier): color='red', background=True,
model='inherit', disallowed_tools, critical_system_reminder, full
verification system prompt with adversarial probes and output format
- worker: implementation-focused prompt
Update _parse_agent_frontmatter() to use yaml.safe_load (supports nested
structures for hooks, mcpServers), with simple key:value fallback.
Update load_agents_dir() to parse all new frontmatter fields with validation
(camelCase and snake_case aliases, type coercion, debug logging for invalids).
Add has_required_mcp_servers() and filter_agents_by_mcp_requirements() helpers
matching TS equivalents.
Add AGENT_COLORS, EFFORT_LEVELS, PERMISSION_MODES, MEMORY_SCOPES, ISOLATION_MODES
module-level constants.
Phase 2.3 - adds TeamMember, TeamFile, and TeamLifecycleManager.
Teams are persisted to ~/.openharness/teams/<name>/team.json using
the same directory layout as the mailbox system.
Replace the 23-LOC stub with a complete AgentDefinition Pydantic model,
5 built-in agents (general-purpose, Explore, Plan, worker, verifier),
YAML-frontmatter loader for user-defined .md agent files, and public
API functions get_all_agent_definitions() / get_agent_definition().
On Windows, asyncio.create_subprocess_exec("npm") fails with
FileNotFoundError because the executable is npm.cmd. Use
shutil.which("npm") to resolve the correct path on all platforms.
Fixes#2