Context
Issue #27 (Hermes bridge does not execute) is being closed by a dedicated wiring pass that fixes its two concrete defects:
core/BridgeExecutors.js now registers Hermes as a WorkflowRuntime executor for all 14 of its allowed task types (previously it registered only Sales Intake, Onboarding Comms, and the optional Dispute Agent).
- The dispatch handler now calls
HermesBridge.runTask() for real (the hardcoded queued short-circuit is removed), matching how the dispute-agent bridge is dispatched through its real trigger().
Issue #27 also noted: "HermesBridge.runTask() currently only returns blocked or queued; that contract should also be reviewed once the wiring itself is fixed." This issue is that review's outcome.
The remaining gap (this issue)
HermesBridge.runTask() still validates and queues — it delegates to BaseBridge.execute(), which returns blocked (validation failed) or queued (validated), and never executes the external Hermes runtime. Concretely, with the wiring now correct:
- A dispatched Hermes task returns a real, honest
queued/blocked result from runTask() (verified in tests/DispatchHermes.test.js).
- A Hermes workflow step resolves to failure (validated-but-not-executed), because
queued is not triggered — honest bookkeeping, verified in tests/BridgeExecutors.test.js.
So Hermes is now correctly wired but still does not execute. Making it actually execute is a separate, larger, security-sensitive piece and is intentionally out of scope for the #27 wiring pass.
Scope for this issue
- Give
HermesBridge a real execution path that invokes the external Hermes runtime (the hermes-agent submodule at departments/operations/hermes/hermes-agent/) via HERMES_RUNTIME_PATH / HERMES_APPLICATION_PATH, returning triggered on genuine submission and preserving blocked/failed/queued honestly.
- This requires process/runtime invocation of an external agent runtime.
SECURITY.md explicitly states Hermes is not sandboxed by this scaffold — real execution must be designed with process isolation, not bolted on. Treat sandboxing as a prerequisite, not a follow-up.
- Keep the "unconfigured runtime →
queued → workflow failure" behavior for installs that have not wired a runtime; only a configured, connected runtime should reach triggered.
- Update the Hermes doctrine (
departments/operations/hermes/*.md) once real execution exists, and add tests covering the triggered path (mocked runtime), the timeout path, and the unconfigured-queued path.
Acceptance criteria
- A configured Hermes runtime produces a real
triggered result through both the dispatch handler and a WorkflowRuntime step.
- Execution runs under explicit process isolation consistent with
SECURITY.md.
- Unconfigured installs still return honest
queued/blocked and never a false success.
- Doctrine and tests reflect the real, connected behavior.
Not this issue
The #27 wiring pass (executor registration + real dispatch call + honest queued/blocked/failure semantics + doctrine correction) is complete and does not depend on this. This issue is only the real-execution layer.
Context
Issue #27 (Hermes bridge does not execute) is being closed by a dedicated wiring pass that fixes its two concrete defects:
core/BridgeExecutors.jsnow registers Hermes as a WorkflowRuntime executor for all 14 of its allowed task types (previously it registered only Sales Intake, Onboarding Comms, and the optional Dispute Agent).HermesBridge.runTask()for real (the hardcodedqueuedshort-circuit is removed), matching how the dispute-agent bridge is dispatched through its realtrigger().Issue #27 also noted: "HermesBridge.runTask() currently only returns blocked or queued; that contract should also be reviewed once the wiring itself is fixed." This issue is that review's outcome.
The remaining gap (this issue)
HermesBridge.runTask()still validates and queues — it delegates toBaseBridge.execute(), which returnsblocked(validation failed) orqueued(validated), and never executes the external Hermes runtime. Concretely, with the wiring now correct:queued/blockedresult fromrunTask()(verified intests/DispatchHermes.test.js).queuedis nottriggered— honest bookkeeping, verified intests/BridgeExecutors.test.js.So Hermes is now correctly wired but still does not execute. Making it actually execute is a separate, larger, security-sensitive piece and is intentionally out of scope for the #27 wiring pass.
Scope for this issue
HermesBridgea real execution path that invokes the external Hermes runtime (thehermes-agentsubmodule atdepartments/operations/hermes/hermes-agent/) viaHERMES_RUNTIME_PATH/HERMES_APPLICATION_PATH, returningtriggeredon genuine submission and preservingblocked/failed/queuedhonestly.SECURITY.mdexplicitly states Hermes is not sandboxed by this scaffold — real execution must be designed with process isolation, not bolted on. Treat sandboxing as a prerequisite, not a follow-up.queued→ workflow failure" behavior for installs that have not wired a runtime; only a configured, connected runtime should reachtriggered.departments/operations/hermes/*.md) once real execution exists, and add tests covering thetriggeredpath (mocked runtime), the timeout path, and the unconfigured-queuedpath.Acceptance criteria
triggeredresult through both the dispatch handler and a WorkflowRuntime step.SECURITY.md.queued/blockedand never a false success.Not this issue
The #27 wiring pass (executor registration + real dispatch call + honest queued/blocked/failure semantics + doctrine correction) is complete and does not depend on this. This issue is only the real-execution layer.