June 4, 2026
Eliminate _base refactor lands; ProcessorConfig goes explicit-mp
Today's headline is TKT-828: the eliminate-abilities/_base refactor spanning P0–P8
Today’s headline is TKT-828: the eliminate-abilities/_base refactor spanning P0–P8. The god-file dies, replaced by single-purpose modules — _ability.py (clean Ability ABC), _dispatcher.py (ToolDispatcher as the single tool-call chokepoint: match → bind → PolicyManager.wrap → _execute → ActTrail.record), _mcp_ability.py (MCP proxy), services/async_delegate_runner.py (backgrounded-tool lifecycle), services/act_trail.py (repository owning the raw-SQL trail statics), services/client_context.py (frozen locale VO), and ActEventEmitter (broadcast_to gate). P4 flipped async to a per-call decision gated on ProcessorConfig.SUPPORTS_ASYNC (UserConfig only), with the captured mp synthesizing hidden-input turns via chat.deliver_async_result — the ASYNC_CAPABLE ClassVar and dispatch_message channel param both deleted. P8 turned the opaque post_turn callable into a frozen tuple of failure-isolated PostTurnHook objects, run in an isolated loop in MessageProcessor._record.
ProcessorConfig gets a two-step refactor of its own. First, the three callable prompt-builder fields (build_user_prompt / build_user_definition / build_system_prompt) became abstract methods on an ABC+frozen dataclass; per-instance state (EAMP agent_name/project, Pattern/Geo window bounds, SuperEpisode sources/spans) moved from closures to object.setattr in each subclass init, with a new MessageProcessor.config property binding self.mp exactly once per turn. Then the self.mp indirection was deleted outright — the three abstract builders now take (self, mp) explicitly, restoring the pre-refactor data-flow and letting ProcessorConfig be a pure fully-immutable frozen dataclass again. Output strings byte-identical; the StubProcessorConfig test helper and _ActionButtonConfig (for api/chat action-buttons) bridge the two designs.
A parity-restoration commit reconciles five iter-0 regressions from the subclass→flat ProcessorConfig redesign: _loop re-wraps build_user_prompt with _wrap_with_checkpoint (TKT-818), _seed_turn_zero passes _auto=True on the memory recall seed so _handle_recall skips document/schedule fan-out (TKT-810), user/external_agent reorder input-line-before-trail and move CoT exploration to an outer prepend, and dmn/episode_encoder/super_episode/user_summary/skill_suggestion restore the user_definition prefix in build_system_prompt.
Compaction gets a finalized redesign: transcript watermark becomes the newest row with role=‘compaction’, the operating window is declared-max_tokens (capped 200k), and singleton retirement is ordered runnably. A failing feature-test commit pins the watermark + thinking-internal-tool behaviour before the implementation. Provider refactor goes mp-owned (Providers(mp) instance), with max_tokens surfaced via _PROVIDER_COLS dropping an extra cache query; param-free send/pre_flight_check/get_context_limit signal the singleton kept transitionally.
Test hygiene: 43 bloated mock-collaborator and contract/plumbing unit-test files are deleted in favour of the new feature tests on the real production hot path (test_tool_dispatcher, test_post_turn_hooks, test_async_delegate_runner, test_per_call_async, test_act_trail). Docs land in lockstep — 04-ARCHITECTURE, 13-MESSAGE-FLOW, 09-TOOLS, and the post-turn field-name fixes all reconcile to ToolDispatcher + PostTurnHook + the new PromptBuilder signatures. Skills sqlite rebuilt (76 skills, 221 entries, drift OK). .gitignore gains .scratch/ and *.egg-info/.
Full unit gate green throughout the refactor series: 1384 passed / 150 deselected, ruff clean.
-
TKT-828 eliminate-abilities/_base refactor complete (P0–P8): _ability.py ABC, ToolDispatcher dispatch chokepoint, services/act_trail.py repo, services/async_delegate_runner.py lifecycle, services/post_turn_hook.py isolated hooks, _mcp_ability.py, services/client_context.py frozen VO, ActEventEmitter
-
P8: post_turn callable → frozen PostTurnHook tuple; failure-isolated invocation in _record; 5 callables (ProactiveSuggestion, DiscloseToHuman, PatternDecay, GeoCounter, PersistUserSummary) become first-class hook classes
-
ProcessorConfig: prompt builders converted from callables to abstract methods, then re-refactored to take explicit mp arg — back to a pure fully-immutable frozen dataclass with no processor reference
-
P4 async refactor: per-call decision via input-schema
asyncboolean, gated on ProcessorConfig.SUPPORTS_ASYNC (UserConfig only); captured-mp delivery via chat.deliver_async_result; ASYNC_CAPABLE ClassVar and dispatch_message channel param deleted -
Parity restoration (TKT-810, TKT-818): _wrap_with_checkpoint re-wrap in _loop, _auto=True on seed-turn-zero memory recall, CoT exploration outer-prepend, user_definition prefix restored in five system prompts
-
Compaction redesign finalized: watermark = newest role=‘compaction’ row, declared-max_tokens window capped at 200k, runnable singleton-retirement order; providers refactored to mp-owned with _PROVIDER_COLS exposing max_tokens
-
43 bloated/mock-theater unit-test files deleted; skills sqlite rebuilt (76 skills, 221 entries); .scratch/ and *.egg-info/ gitignored
-
Full unit gate: 1384 passed / 150 deselected, ruff clean throughout the refactor series