Skip to content

feat(workhub): resume delegated work from the coordination conversation - #4713

Open
ARE404 wants to merge 3 commits into
apache:mainfrom
ARE404:feat/workhub-resume
Open

feat(workhub): resume delegated work from the coordination conversation#4713
ARE404 wants to merge 3 commits into
apache:mainfrom
ARE404:feat/workhub-resume

Conversation

@ARE404

@ARE404 ARE404 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

WorkHub could delegate work, watch it, correct it and stop it, but not carry it on. When an interruption left delegated work unfinished, the only way to resume was to leave the conversation, open the target Session and use its own interrupted-turn banner. Slice 5's exit asks for resume from the coordination transcript.

The capability already exists. Resume composes the two operations that banner uses — ask the Host whether this Session has a continuation to make, then make it — and adds no recovery machinery of its own.

Refs #3492

What it does

Resume Payments / 恢复支付任务 names one Session; the Host resolves which delegation that Session owns, and carries it on.

Three answers, all reported as themselves. resume_started began a continuation. already_running means the work never stopped, so there was nothing to resume. parked is the Host declining, and its reason is its own — nothing the client does changes it. The last two are outcomes, not failures.

Design notes

It goes through the Action Gate, because it changes execution state and that is where such changes are admitted. It carries no confirmation: it destroys nothing and grants no authority a delegation did not already grant, so it proves only that the words named one Session and that the Session still owns one link.

A repeat is safe. The continuation Turn identity is derived from the delegation and the source run rather than minted, so two attempts name the same Turn and the Host parks a continuation that already exists rather than forking a second one.

Stop and resume share one matcher. They ask the same question of the same words — which visible Session does this reference name — so two copies would be two chances for Resume Payments and Stop Payments to disagree about which Session they mean.

They diverge on what an unnamed reference means, deliberately. A stop must answer it: stopping is destructive, so Stop it is met with a question rather than a guess. A resume must not: 继续这个工作 is how someone carries on with the Session they are already in, and answering it would take an ordinary instruction away from ordinary routing. Resuming nothing costs nothing, so an unnamed resume falls through and only a named one becomes an action.

Compatibility

RUNTIME_HOST_COMPATIBILITY_EPOCH 109 → 110. An older peer's closed decoder rejects both the resume_work disposition it does not know and the result kind it cannot read, so mismatched peers are refused at the handshake.

One durable vocabulary change, no migration. WorkHubActionOperation gains resume so one action identity still means one operation, as it does for every other disposition. The column already exists and this is another legal value in it. It is a downgrade hazard rather than a wire one: a Host that predates this value refuses to read a claim carrying it, and such a row only exists once a resume has been admitted.

Verification

Run locally, all green:

  • npm run build, npm run typecheck, npm run lint, npm run format:check, npm run check:asf-headers
  • @maka/core 802 pass / 0 fail
  • @maka/runtime-host 1678 pass / 0 fail
  • @maka/storage 1098 pass / 0 fail
  • Desktop WorkHub controller 75 pass / 0 fail

New tests cover the reader (both languages, anaphora, questions, negation, unterminated quotes, and that stop and resume never read as each other), the Gate (a normal resume, a named command required, refusal when the Session owns zero or several delegations, and each Host answer reported faithfully), and the renderer (submission shape with no confirmation, the Gate's refusal becoming a clarification, and resume-shaped ordinary work still routing normally).

Not run locally: the repo-wide suite and packaging jobs. Left to CI.

AI use

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code wrote the implementation and tests in this PR under human direction and review.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — a named resume in WorkHub now carries on interrupted delegated work
  • No

Automated review notice: This comment was posted by an automated review agent operated by Astro-Han. It is not an independent human review and does not replace one.

Resume asks the Host to carry on work an interruption left unfinished.
It is admitted on the same terms as a stop — a direct speech act naming
one existing Session — so it reuses the stop reader's rules: a question
is not a command, a malformed literal is refused, and an anaphoric target
carries the cue without claiming a target so the surface can ask which
work rather than guess.

English covers resume / continue / restart and Chinese 继续 / 恢复 /
接着跑 / 重新开始, the same colloquial range each language already has for
stop. A cue alone resumes nothing: the reference must still resolve to a
Session, which is what keeps `continue with the refactor` ordinary work.

This is the reader only. The disposition that consumes it lands with the
Gate admission in the same change.

Generated-by: Claude Opus
Stop was the only way WorkHub could change delegated execution, so work an
interruption left unfinished could only be restarted by leaving the
conversation, opening the Session and using its own banner. Slice 5 asks
for resume from the coordination transcript, and the capability to do it
already exists.

Resume composes the two operations that banner uses — ask the Host whether
this Session has a continuation to make, then make it — and adds no
recovery machinery of its own. A repeat is safe because the Host parks a
continuation that already exists rather than forking a second one, so the
Turn identity is derived from the delegation and the source run rather
than minted, and two attempts name the same Turn.

It goes through the Gate for the same reason every other disposition does:
it changes execution state, and the Gate is where that is admitted. It
carries no confirmation, because it destroys nothing and grants no
authority a delegation did not already grant — it proves only that the
words named one Session and that the Session still owns one link.

`WorkHubActionOperation` gains `resume` so one action identity still means
one operation. That is a durable vocabulary change with no migration: the
column already exists, and only a Host that predates this value would
refuse to read a claim carrying it.

Refs apache#3492

Generated-by: Claude Opus
The Host could resume interrupted work, but only its own Session could ask:
the user had to leave WorkHub, open the Session and use its banner. This
wires the conversation to the disposition the Gate already admits.

Stop and resume ask the same question of the same words — which visible
Session does this reference name — so they now ask it with one matcher.
Two copies would be two chances for `Resume Payments` and `Stop Payments`
to disagree about which Session they mean.

They diverge on what an unnamed reference means, and that asymmetry is the
point. A stop must answer it: stopping is destructive, so `Stop it` has to
be met with a question rather than a guess. A resume must not: `继续这个工作`
is how someone carries on with the Session they are already in, and
answering it would take an ordinary instruction away from ordinary
routing. Resuming nothing costs nothing, so an unnamed resume falls
through and only a named one becomes an action.

The three answers the Host can give are all reported as themselves.
`already_running` and `parked` are outcomes, not failures: the first says
the work never stopped, and the second is the Host declining, whose reason
is its own.

Refs apache#3492

Generated-by: Claude Opus
@github-actions github-actions Bot added the effort/L Under 1000 readable lines label Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/L Under 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant