refactor(orchestrator): extract ActivityDriver ABC + driver factory

Stage 4 of the realism migration. Lifts the driver Protocol into a
proper ABC with default plant_file/read_file methods (raise
NotImplementedError), and adds get_driver_for(action) so the
orchestrator worker can dispatch by action shape without isinstance
chains.

SSHDriver now inherits ActivityDriver and implements:
- plant_file: streams base64 via stdin (ARG_MAX-safe, mirrors
  decnet.canary.planter; commit c17b9e0). Honours mtime via touch -d
  so realism-planned files don't all stamp at wall-clock-now.
- read_file: docker exec cat with FileNotFoundError on rc=1, used by
  the upcoming EditAction (stage 3b).

EmailDriver inherits ActivityDriver. Driver alias kept for back-compat
during the migration; removed once realism stages 5-7 land.
This commit is contained in:
2026-04-27 16:09:46 -04:00
parent 0b9873982d
commit 636c057cc5
5 changed files with 329 additions and 50 deletions

View File

@@ -28,7 +28,7 @@ from email.utils import formatdate
from typing import Any, Optional
from decnet.logging import get_logger
from decnet.orchestrator.drivers.base import ActivityResult
from decnet.orchestrator.drivers.base import ActivityDriver, ActivityResult
from decnet.orchestrator.emailgen.scheduler import EmailAction
from decnet.orchestrator.emailgen.threads import new_message_id
from decnet.realism.llm import LLMBackend, LLMTimeout, get_llm
@@ -148,7 +148,7 @@ def _build_eml(
return msg.as_bytes()
class EmailDriver:
class EmailDriver(ActivityDriver):
"""Concrete driver for :class:`EmailAction`.
Stateless across calls — the LLM backend is constructed once at