Skip to content

feat(workhub): add typed action gate - #3818

Open
ARE404 wants to merge 9 commits into
apache:mainfrom
ARE404:feat/workhub-action-gate
Open

feat(workhub): add typed action gate#3818
ARE404 wants to merge 9 commits into
apache:mainfrom
ARE404:feat/workhub-action-gate

Conversation

@ARE404

@ARE404 ARE404 commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements WorkHub Slice 4 from #3492 on top of the merged Slice 3 coordination-session work:

  • adds closed typed contracts for answer_here, delegate_existing, create_new, and clarify;
  • exposes a bounded Runtime-owned candidate set with opaque references;
  • introduces a deterministic Runtime Host Action Gate with fresh target validation, action replay, and non-destructive execution admission;
  • routes the production Desktop WorkHub path through that gate while keeping the R2.4 controller as a test-only regression harness.

This changes behavior: destructive cross-Session correction is deferred to Slice 5. Production recognizes correction before explicit creation, fails closed before a second delegation, and tells the user to stop the original work from its Session. Explicit creation without correction context remains available.

Refs #3492

Verification

  • Regression table was red on 89e4e20: normal variants containing please, an em dash, , or 不对 still reached create_new and failed with WorkHub Action Gate returned an unexpected disposition.
  • Production correction/create regressions: 2 passed. With an existing focus, all 6 English/Chinese correction-shaped creation cases fail closed before a second Action Gate action; without focus, the same 6 cases still execute create_new.
  • Desktop WorkHub affected suites: 108 passed.
  • Desktop main suites outside the filesystem sandbox: 1536 passed, 0 failed.
  • Desktop E2E: WorkHub defers destructive correction until linked delegation exists passed against the fixed production build (1 passed). The exact-head CI also runs the full Desktop E2E surface.
  • Runtime Host Slice 4 suites: 22 passed, including 7 Action Gate tests.
  • Desktop production renderer build passed.
  • Biome passed for all changed files; git diff --check passed.
  • Exact-head 2650a94ff5396454f0b239acced341a10273ce42 CI: test run 32948070394 / job 98113143994 passed, including the full Desktop E2E surface; windows_recovery run 32948070439 / job 98113065733 passed.

UI evidence

Before (ba1eec3): destructive correction exposed a “更正目标” control and replaced the running target.

workhub-slice4-before

After (89e4e20): the correction control is absent and production shows the Slice-5 deferral before a second delegation.

workhub-slice4-after

Both screenshots were captured from the real Electron E2E fixture using the same two-Session correction scenario. The before fixture passed 1/1 at ba1eec3; the after fixture passed 1/1 on the fixed branch.

Safety and authority boundaries

  • Strategy output cannot name arbitrary Session IDs, workspaces, tools, or permission modes.
  • Candidate discovery is scoped to the current Runtime Host and excludes archived, Coordination, side-conversation, and child Sessions.
  • The Gate refreshes candidates before admission and rejects stale or invented references, waiting targets, self-routing, invalid creation context, and conflicting action replays.
  • New ordinary Session identity is derived inside Runtime Host from the action identity; Desktop supplies only trusted workspace context.
  • Tool calls and permission elevation remain owned by the target ordinary Session. The closed WorkHub protocol cannot widen either ceiling.

Slice boundary: destructive correction is deferred to Slice 5

This PR intentionally does not expose replace or Stop through the Slice 4 Action Gate.

A destructive correction must prove durable linkage between the original delegation, the exact root Turn WorkHub owns, the correcting action, and the replacement submission. That linkage and recovery across the non-atomic Stop-to-submit seam must survive Runtime Host restart. Host-lifetime maps, TTLs, and retry lanes cannot provide that authority after restart.

Slice 4 therefore owns the typed gate, bounded candidates, fresh validation, replay, and non-destructive answer_here, clarify, delegate_existing, and create_new. Slice 5 will persist delegation/action linkage first, then add natural-language replacement and exact Stop ownership.

The decoder rejects replace; the production Gate has no Stop effect; Desktop exposes no correction picker. The legacy R2.4 correction path is test-only.

AI use

Select exactly one:

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

Tool(s) and scope: Codex implemented the Runtime Host/Desktop changes, regression tests, review fixes, and verification. Material commits include Generated-by: Codex trailers.

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 — described under Summary above
  • No

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update on b65c5c2313:

CODE NO-GO — 4×P2

  • P2-1 correction without explicit intent fails confirmation_required before Stop.
  • P2-2 dropping replace when source outside bounded set silently forks while reporting corrected.
  • P2-3 concurrent replacements lack source lock → fan-out to different targets after Stop.
  • P2-4 record 48 KiB vs retry probe 32 KiB → retry after success hits commit_outcome_unknown.

Fix: make correction carry explicit stop text or relax gate; keep replace mandatory or fail; add source lease across actions; align byte limits. Hosted test: SUCCESS does not waive these.

简体中文四处权限/一致性阻塞。

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update on 48666a0ceb:

CODE NO-GO — 3×P2

  • P2 candidate path does not write admitted.targetTurnId to local map → natural-language correction cannot send replacement (fail-closed at 814). E2E workhub-reconstruction fails (32879372758).
  • P2 Stop-then-submit with swallowed replay leaves source stopped and target unconfirmed → retry gets stop_not_owned.
  • P2 48 KiB user + 8 KiB assistant JSON record can exceed 72 KiB retry lookup after escaping → retry becomes commit_outcome_unknown.
简体中文存在路径阻塞与重放问题。

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update on f2785c5dc0:

CODE NO-GO — 2×P2 plus required check red

  • P2 Stop-then-submit with swallowed replay leaves source stopped and target unconfirmed → retry stop_not_owned.
  • P2 JSON record escaped bytes exceed 72 KiB retry lookup → retry commit_outcome_unknown.

Note: natural-language correction P2 from prior head is now closed (gated receipt saved). Hosted test: FAILURE on format check (new test ternary).

简体中文仍有两处阻塞,另需格式化修复。

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update on 05d3d26e20:

CODE NO-GO — 2×P2 (carry-over, formatting fix only)

  • P2 Stop-then-submit without replay on target failure → retry stop_not_owned.
  • P2 JSON escaped record may exceed 72 KiB retry lookup → commit_outcome_unknown.

Formatting failure from prior head fixed; logic unchanged. Hosted test: QUEUED — not green.

简体中文仍有两处阻塞。

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update on 92d0947890:

[P2] #replacementRecoveries can exhaust to Host-wide outage

Capacity 256 is only released on Stop failure or target success. After Stop succeeds, permanent target rejections (e.g. session_busy) keep the recovery forever with no TTL/reaper — 256 failures exhaust replacements Host-wide as host_not_ready until restart.

Fix: give recoveries reconciled lifecycle / TTL for permanent failures.

Checks on 92d0947890d2aeec9a6363f17b68ff0850deb5b0 are test: SUCCESS — code is NO-GO.

简体中文异常恢复容量会耗尽。

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this head and found no blocking issues.

Fixes replacement recovery lifecycle (typed failure releases checkpoint, unknown retains fingerprint with 5-min TTL) — closes prior 256-capacity outage; definitive/unknown regression tests pass. Hosted test: SUCCESS (32924223915).

No new P0-P3.

简体中文该头无新增阻断。

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.

@ARE404
ARE404 force-pushed the feat/workhub-action-gate branch from 3beac53 to 9532d2d Compare August 26, 2026 03:53

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this head and found no blocking issues.

Fixes Action Gate classification to check correction before explicit new-session creation; replace/Stop removed from production. Hosted test: SUCCESS (32935316010) and windows_recovery: SUCCESS.

No P0-P3.

简体中文该头无阻断。

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.

@jackwener
jackwener force-pushed the feat/workhub-action-gate branch from c9d74e5 to 2650a94 Compare August 26, 2026 08:30

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this head and found no blocking issues.

Completes typed Action Gate: opaque candidateRef with fresh validation, idempotent replay with fingerprint conflict, self-route/target-waiting fail-closed; hosted test+windows_recovery SUCCESS.

No P0-P3.

简体中文该头无阻断。

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.

@M4n5ter
M4n5ter force-pushed the feat/workhub-action-gate branch from 2650a94 to 781a12f Compare August 26, 2026 09:45
ARE404 added 9 commits August 26, 2026 17:52
Preserve Runtime-admitted root receipts for natural-language corrections and avoid deleting newer ownership after a concurrent Stop.\n\nGenerated-by: Codex
Resume the exact target submission after a replacement Stop and budget summary replay reads for worst-case JSON escaping.\n\nGenerated-by: Codex
Release recovery checkpoints after definitive target failures and expire uncertain outcomes after a bounded reconciliation window.\n\nGenerated-by: Codex
Recognize correction cues independently from punctuation, politeness, and the creation clause so focused corrections fail closed without weakening no-focus creation.

Generated-by: Codex
@M4n5ter
M4n5ter force-pushed the feat/workhub-action-gate branch from 781a12f to 3844445 Compare August 26, 2026 09:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants