Stage 386: PR #2575
This commit is contained in:
commit
629ebf45f7
3 changed files with 93 additions and 12 deletions
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Documentation
|
||||
|
||||
- **PR #TBD** by @Michaelyklam (refs #1925) — Advance the runtime-adapter RFC to the Slice 4 runner/sidecar planning gate after #2560 shipped the queue-staging clarification. The RFC now marks queue routing as staged by default, defines Slice 4a as a docs/test contract before any runner code lands, and pins default-off feature-flagging, restart/reattach success criteria, control parity, profile/workspace payload isolation, and explicit non-goals for legacy-backend removal or server-side queue scheduler work.
|
||||
|
||||
## [v0.51.92] — 2026-05-19 — Release BP (stage-385 — 7-PR full sweep batch — RFC Slice 3c clarification + workspace tree icon alignment + project move cache refresh + auto-compression handoff metadata + Grok OAuth provider catalog + anonymous custom endpoint picker fallback + PWA standalone reload + pull-to-refresh)
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ The immediate goal is not to build a sidecar. The immediate goal is to define th
|
|||
browser contract, classify current runtime state, and gate the first reversible
|
||||
journal slice.
|
||||
|
||||
## Current Gate State — 2026-05-18
|
||||
## Current Gate State — 2026-05-19
|
||||
|
||||
Slice 1 is now past the first active validation gate:
|
||||
|
||||
|
|
@ -90,14 +90,17 @@ adapter-seam work:
|
|||
`HERMES_WEBUI_RUNTIME_ADAPTER=legacy-journal` is enabled, while preserving the
|
||||
legacy-direct response shape and leaving post-turn goal evaluation in the
|
||||
existing agent loop.
|
||||
- #2560 shipped the queue-staging clarification in v0.51.92. The RFC now treats
|
||||
`queue_message(...)` as a staged protocol method only; `/queue` remains
|
||||
browser-side queue/drain behavior, and no server-side queue endpoint or queue
|
||||
scheduler should be added merely for adapter symmetry.
|
||||
|
||||
The next gate is still not the runner/sidecar by default. Slice 3c's goal route
|
||||
is shipped, and `queue_message(...)` remains a staged protocol method. Queue /
|
||||
continue routing needs an explicit follow-up contract because the legacy `/queue`
|
||||
path is browser-side queue/drain behavior today; no new server-side queue endpoint
|
||||
or queue scheduler should be added just for adapter symmetry. If maintainers want
|
||||
queue/continue to move before Slice 4, that follow-up should specify the exact
|
||||
legacy entry point, response shape, and ordering/idempotency contract first.
|
||||
The next gate is the runner/sidecar planning contract, not queue implementation
|
||||
by default. Queue / continue routing should only move before Slice 4 if a future
|
||||
maintainer decision identifies an existing server-side legacy entry point and
|
||||
pins its response shape, ordering, and idempotency contract. Otherwise, keeping
|
||||
`queue_message(...)` staged is the honest boundary while execution ownership
|
||||
moves out of the main WebUI request process.
|
||||
|
||||
## Goals
|
||||
|
||||
|
|
@ -670,8 +673,19 @@ Non-goals for Slice 3c:
|
|||
|
||||
### Slice 4: Runner process / sidecar boundary
|
||||
|
||||
Explicitly deferred until Slice 1 has worked in production for at least one
|
||||
release cycle and the adapter surface has review approval.
|
||||
Slice 4 is the first gate that may move active execution ownership out of the
|
||||
main WebUI request process. It should start as a docs/test contract PR before any
|
||||
runner code lands. Slice 1's journal/replay layer has shipped and passed active
|
||||
validation, Slice 2's default-off adapter seam has shipped, and Slice 3's
|
||||
cancel/approval/clarify/goal control routing has proven the protocol-translator
|
||||
pattern. Queue remains staged unless maintainers explicitly ask for a separate
|
||||
pre-runner queue route.
|
||||
|
||||
The Slice 4 implementation must not make the adapter a new runtime surrogate.
|
||||
The runner boundary may own active execution, process supervision, run lifecycle,
|
||||
and callback state, but those responsibilities must be centralized behind the
|
||||
adapter/runner contract rather than recreated as scattered globals in the main
|
||||
WebUI server.
|
||||
|
||||
Scope:
|
||||
|
||||
|
|
@ -683,6 +697,55 @@ Scope:
|
|||
|
||||
Revert path: disable runner backend and fall back to journaled legacy backend.
|
||||
|
||||
#### Slice 4a: Runner contract gate
|
||||
|
||||
Before runner code lands, define a narrow contract that covers:
|
||||
|
||||
1. **Backend selection and rollback.** The existing `legacy-direct` and
|
||||
`legacy-journal` paths remain available. Any new runner backend is
|
||||
feature-flagged, default-off, and revertible by switching the adapter mode back
|
||||
to `legacy-journal` without deleting sessions or journal files.
|
||||
2. **Process ownership.** The runner, not the main WebUI request process, owns
|
||||
`AIAgent` construction/reuse, active run execution, cancellation flags,
|
||||
approval/clarify callback wait state, and post-turn continuation evaluation
|
||||
for runs assigned to that backend.
|
||||
3. **Durable observation.** The main WebUI server observes through
|
||||
`RuntimeAdapter.observe_run(...)`, `get_run(...)`, and the journal cursor. A
|
||||
WebUI restart must not be required for the runner to finish writing ordered
|
||||
events and terminal state.
|
||||
4. **Restart/reattach success criterion.** Start a long-running run, restart only
|
||||
`hermes-webui.service`, reload the session, rediscover the active or terminal
|
||||
runner-owned run, replay/catch up from cursor without duplicate transcript /
|
||||
tool / reasoning state, and preserve cancel if the run is still active.
|
||||
5. **Control parity.** Cancel, approval, clarify, goal status/control, and any
|
||||
accepted queue/continue behavior route through adapter methods with stable
|
||||
browser response shapes. Unsupported controls return bounded `ControlResult`
|
||||
states instead of silently falling back to stale in-process state.
|
||||
6. **Profile/workspace isolation.** Runner startup receives explicit profile,
|
||||
workspace, attachments, model/provider, toolset, and source metadata rather
|
||||
than relying on process-global environment mutation in the WebUI server.
|
||||
|
||||
Suggested contract tests before implementation:
|
||||
|
||||
- source/RFC tests proving Slice 4 remains feature-flagged and default-off;
|
||||
- a fake-runner adapter test that simulates WebUI restart by discarding server
|
||||
process-local state while preserving runner/journal state, then verifies
|
||||
`get_run` and replay recover the same terminal state;
|
||||
- a control-parity fixture proving unsupported runner controls return bounded
|
||||
`ControlResult` values and do not fall back to legacy `STREAMS` /
|
||||
`CANCEL_FLAGS` state;
|
||||
- a profile/workspace payload test proving runner requests carry explicit context
|
||||
fields without mutating global `os.environ` in the main WebUI process.
|
||||
|
||||
Non-goals for Slice 4a:
|
||||
|
||||
- no removal of the legacy in-process backend;
|
||||
- no default-on runner mode;
|
||||
- no public chat-start/status response-shape expansion;
|
||||
- no new server-side queue endpoint or scheduler just for adapter symmetry;
|
||||
- no dependency on Hermes Agent shipping `/v1/runs` before WebUI can validate the
|
||||
local runner boundary.
|
||||
|
||||
## First Meaningful Success Criteria
|
||||
|
||||
The first meaningful milestones are deliberately split.
|
||||
|
|
|
|||
|
|
@ -309,7 +309,22 @@ def test_rfc_distinguishes_goal_routing_from_queue_route_staging():
|
|||
rfc = (routes.Path(__file__).parent.parent / "docs" / "rfcs" / "hermes-run-adapter-contract.md").read_text(encoding="utf-8")
|
||||
|
||||
assert "#2544 shipped the first Slice 3c implementation" in rfc
|
||||
assert "#2560 shipped the queue-staging clarification" in rfc
|
||||
assert "route now uses `RuntimeAdapter.update_goal(...)`" in rfc
|
||||
assert "`queue_message(...)` remains a staged protocol method" in rfc
|
||||
assert "`queue_message(...)` as a staged protocol method only" in rfc
|
||||
assert "no new server-side queue endpoint" in rfc
|
||||
assert "or queue scheduler should be added just for adapter symmetry" in rfc
|
||||
assert "no server-side queue endpoint or queue\n scheduler should be added merely for adapter symmetry" in rfc
|
||||
|
||||
|
||||
def test_rfc_defines_slice4_runner_contract_before_runner_code():
|
||||
routes = importlib.import_module("api.routes")
|
||||
rfc = (routes.Path(__file__).parent.parent / "docs" / "rfcs" / "hermes-run-adapter-contract.md").read_text(encoding="utf-8")
|
||||
|
||||
assert "#### Slice 4a: Runner contract gate" in rfc
|
||||
assert "docs/test contract PR before any\nrunner code lands" in rfc
|
||||
assert "feature-flagged, default-off" in rfc
|
||||
assert "The runner, not the main WebUI request process, owns" in rfc
|
||||
assert "restart only\n `hermes-webui.service`" in rfc
|
||||
assert "profile,\n workspace, attachments, model/provider, toolset, and source metadata" in rfc
|
||||
assert "no removal of the legacy in-process backend" in rfc
|
||||
assert "no default-on runner mode" in rfc
|
||||
|
|
|
|||
Loading…
Reference in a new issue