Skip to content

Design: a prompt's state dies with the prompt — one server contract and one lifecycle for the OpenClaw ACP adapter #4706

Open
3 of 5 issues completed

Description

@dezren39

Design doc: files/designs/code-acp-adapter-prompt-lifecycle.md in the keep-the-four-repos-healthy goal workspace. Audit at origin/main cf13a269456d3c4fb733af312d89dc741140836c — every defect below re-verified present at the cited sites this pass (2026-11-02, adapter and dispatch client read at that commit).

Summary

bin/opencode-acp-adapter.mjs (558 lines) lets OpenClaw's acpx runtime drive the fleet's one standing opencode serve over ACP (#1243, landed by PR #3997). PR #3997 merged as-is with four Codex review findings unresolved; they were filed on 2026-11-02 as #4614, #4616, #4617 and #4618 (source/pr-comment-review). They are one unstated contract in two halves:

Both halves are the same omission: the adapter was written against an assumed server and an assumed happy path, and neither assumption was ever stated as a contract the code is checked against.

The contract

The pinned server's v2 API is the only contract, and a prompt's state lives and dies with the prompt: scoped to its session, recorded only while the prompt is in flight, cleared on every terminal path through the one terminal function — and lost event continuity is itself a terminal path, settled by reconciling against the server's state or failing explicitly, never by waiting.

Recorded decisions (full reasoning, alternatives and risks in the design doc):

  1. Every route is v2-shaped or explicitly dispositioned. Session create and prompt submission per openclaw ACP adapter: use the standing server's v2 session API — v1 /session + prompt_async contract cannot create working sessions (#3997) #4614's acceptance, tested against a v2-shaped stub (not the v1 stub). Phase 1 also dispositions the routes openclaw ACP adapter: use the standing server's v2 session API — v1 /session + prompt_async contract cannot create working sessions (#3997) #4614 does not name — abort, permission reply, event stream — against the pinned server, and pins the v2 prompt submission semantics (blocking vs fire-and-event) that Phase 3 depends on.
  2. Offsets are scoped to (session, part) and a prompt's cleanup removes exactly its own session's entries (openclaw ACP adapter: finishPrompt clears streamed-text offsets for all sessions, duplicating the still-running session's text (#3997) #4616's acceptance, stated as the general rule).
  3. Cancellation is recorded only for an in-flight prompt and cleared on every terminal path — idle, error, submission failure, reconciliation failure — because all of them exit through the one terminal function, which clears pending entry, cancellation marker and offsets for that session together (openclaw ACP adapter: cancellation marker survives a finished prompt and mislabels the next prompt as cancelled (#3997) #4618's acceptance, stated as the general rule).
  4. Reconnect reconciles, then fails only the unprovable. On event-stream reconnect, each pending prompt is reconciled against the server's v2 session read: proven finished/idle → finished normally; state not provable → the ACP request is failed explicitly. This pins openclaw ACP adapter: pending prompts are never reconciled when the SSE event stream reconnects (#3997) #4617's either/or (reconcile or fail) as reconcile-first: stream drops are routine and the server's state is readable, so failing every pending prompt would discard completed work; waiting — the current behaviour — is the defect being fixed.

Phased breakdown

Phases adopt the four origins as sub-issues (no parallels). Phase 4 is a new closing-audit issue, gated on Phases 1–3.

Open questions (in the design doc, not filed)

Whether a prompt needs a wall-clock timeout independent of stream continuity (no filed instance; decision 4 covers the observed hang); whether sessions should be deleted server-side when an ACP client disconnects (needs a filed instance or Phase 4 evidence); whether a second server-contract version is ever supported (the header comment is the contract's home; revisit when the pin moves).

Related

Acceptance criteria

Activity

  1. added
    epicMeta-issue grouping multiple items (org Project Type=Epic)
    kind/designA design proposal (design-architect): multi-step, phased, decision-bearing
    on Nov 3, 2026
  2. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — design-architect pass 41 (2026-11-02)

    This design was originated by the design-architect pass at origin/main cf13a26: the four unresolved Codex findings from PR #3997, filed as #4614/#4616/#4617/#4618, are one unstated contract (the pinned server's v2 API + a prompt lifecycle) in a single file, bin/opencode-acp-adapter.mjs. The four origins are adopted as Phases 1–3 (no parallels filed) and labelled source/design-architect; #4707 is the new Phase 4 closing audit, enqueued as a triage packet and gated on Phases 1–3. Design doc: files/designs/code-acp-adapter-prompt-lifecycle.md in the keep-the-four-repos-healthy goal workspace; central register entry added (status: proposed). No user/review: every origin carries explicit acceptance and the four recorded decisions are the architect's to make.

  3. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    Intake review

    Related: issue #4614, issue #4616, issue #4617, issue #4618 (the four Codex findings on PR #3997 this design unifies), issue #1243 (adapter origin), pm-stack dispatch client (the v2 reference implementation cited in the design). Notes: this is a design/epic item — the phases are adopted by existing child issues, so intake does not reassign any child. Risks: Phase 3 depends on the v2 prompt-submission semantics pinned in Phase 1; landing phases out of order would re-create the unstated-contract problem the design exists to fix. Suggested approach: route as an epic; the queue works the children in phase order, and this issue closes when every child is closed or dispositioned.

    — Fleet monitor intake (protocol §5), 2026-11-03T02:29:50Z. Labels normalized and meta/enriched applied; acceptance criteria appended to the issue body.

  4. added
    priority/highImportant and time-sensitive
    effort/mMedium: expected under 1 day of work
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Nov 3, 2026
  5. 10 remaining items

  6. removed
    task/triageQueue packet kind: verify, reproduce, and route this item
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 4, 2026
  7. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · triaged

  8. dezren39 commented on Nov 8, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  9. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    on Nov 8, 2026
  10. dezren39 commented on Nov 8, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  11. added
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/triagedTriaged and routed (see agent note)
    on Nov 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

effort/mMedium: expected under 1 day of workepicMeta-issue grouping multiple items (org Project Type=Epic)kind/designA design proposal (design-architect): multi-step, phased, decision-bearingmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/highImportant and time-sensitivequeue/claimedQueue worker lifecycle statesource/design-architectFiled by the repo design architect jobstatus/in-progressQueue worker lifecycle statework/assignedQueue worker lifecycle state

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions