feat(agent): Wave 3 strategic coupling (G5/G6) #6

Merged
fischer merged 7 commits from feat/agent-wave3-strategic into main 2026-06-30 09:17:20 +08:00

7 Commits

Author SHA1 Message Date
chiguyong f50d3485ea fix(review): Wave 3 code review fixes
Test / backend-test (pull_request) Has been cancelled Details
Test / frontend-unit (pull_request) Has been cancelled Details
Test / api-e2e (pull_request) Has been cancelled Details
Test / frontend-e2e (pull_request) Has been cancelled Details
P1: bash/shell tool name mismatch. PhasePolicy whitelist used "bash" but
ShellTool registers as "shell". The bash_command_filter was dead code
(never matched the real tool name). Fixed in phase.py whitelist,
react.py filter check, agentkit.yaml config, and all tests.

P1: AdvancePhaseTool missing import in tools/__init__.py. Was in
__all__ but never imported. Added the import.

P2: chat.py phase policy error message echoed verbatim to WS client.
Truncated to 200 chars to match nearby error paths and avoid leaking
config internals.

P2: policy_from_config rebuilt PhasePolicy 3x via full-field copy.
Replaced with dataclasses.replace() so new PhasePolicy fields are not
silently dropped in future reconstructions.

ce-code-review (mode:agent) step of LFG pipeline.
2026-06-30 09:13:07 +08:00
chiguyong 5a0554b27f refactor(advance_phase): simplify previous_phase capture
Remove over-engineered _previous_value static method that did index
math on a hardcoded phase list. Instead, capture the previous phase
before the transition — clearer intent, fewer lines, same behavior.

ce-simplify-code step of LFG pipeline.
2026-06-30 09:13:06 +08:00
chiguyong da4eef1349 feat(U4): G6 PLAN_EXEC wiring at chat WebSocket path
- PLAN_EXEC branch builds PhasePolicy from ServerConfig.plan_exec
- Empty config → default_policy(); enabled=False → falls back to REACT
- Bad config → error event sent, returns early (no engine constructed)
- ReActEngine created with phase_policy; AdvancePhaseTool registered
- phase_changed events emitted on phase transitions (PLAN_EXEC only)
- REST send_message with execution_mode=plan_exec → HTTP 501 (KTD4)
- REWOO/REFLEXION/TEAM_COLLAB still fall back to REACT (no regression)
- 9 unit tests covering REST 501, characterization, happy path, edge cases, error path, phase_changed events
2026-06-30 09:13:06 +08:00
chiguyong 6efd5957f6 feat(U3): G6 AdvancePhaseTool + ReActEngine phase enforcement
- AdvancePhaseTool calls engine.advance_phase(), returns new phase or error
- ReActEngine.__init__ accepts phase_policy param (None = no enforcement, backward compat)
- _current_phase + _steps_in_phase fields track state machine
- advance_phase() transitions PLANNING → BUILDING → VERIFICATION → DELIVERY
- _check_phase_permission() returns structured error dict if tool blocked
- _execute_tool checks phase before dispatch (advance_phase name bypasses)
- Auto-advance safety net via _maybe_auto_advance() + auto_advance_after_steps
- Phase reset in reset() method
- 27 unit tests covering characterization, permission, transitions, auto-advance, tool integration
2026-06-30 09:13:06 +08:00
chiguyong be4ac797b2 feat(U2): G6 PhaseState + PhasePolicy + ServerConfig.plan_exec
- PhaseState enum (PLANNING/BUILDING/VERIFICATION/DELIVERY) with next_of/from_string
- PhasePolicy dataclass with whitelist + bash_command_filter + auto_advance_after_steps
- default_policy() factory — KTD5 whitelist matching R24 (Planning: search/read_file;
  Building: write_file; Delivery: wildcard)
- bash_command_filter blocks rm/mv/cp/>/>> in PLANNING/VERIFICATION phases
- policy_from_config() parses plan_exec YAML section (R26) with override merge
- ServerConfig.plan_exec field + from_dict parsing (extends Wave 1/2 pattern)
- agentkit.yaml gains commented plan_exec section (opt-in)
- 37 unit tests covering PhaseState, default_policy, is_tool_allowed,
  bash filter, config parsing, and ServerConfig integration
2026-06-30 09:13:06 +08:00
chiguyong 58ef1719cb feat(U1): G5 SymbolExtractor + ReadFileTool with symbol slicing
- SymbolExtractor protocol + SymbolSpan dataclass
- AstSymbolExtractor for Python (stdlib ast, no tree-sitter dep — KTD1)
- RegexSymbolExtractor for TS/JS/Go/Rust/Java (language-aware regex)
- ReadFileTool with path/symbol/start_line/end_line params
- symbol=None returns full file (characterization baseline matching _FakeTool)
- symbol='foo' returns first matching symbol's line range
- symbol not found returns available_symbols list (soft error)
- Unsupported extension returns full file with note
- Manual start_line/end_line overrides symbol
- 66 unit tests covering R22/R23 + characterization + edge cases
2026-06-30 09:13:06 +08:00
chiguyong e3f69f963c docs(plan): Wave 3 strategic coupling plan (G5/G6) 2026-06-30 09:13:06 +08:00