You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Planning base: 0479b3b1e6a3de08fb7d9de515a3efde80e7fe91; implementation base is the exact accepted C0 feedback commit recorded before handoff
Stack position: F1; parallel with F3, F4, F5, and F6; provider prerequisite for F2, L7, and L8
Readiness: blocked only until C0's accepted feedback SHA is recorded and present in the branch; no provider, identity, persistence, locking, or replay choice is delegated to the Implementor
Purpose and observable outcome
An ephemeral Actions-side XMD client can select one durable run from immutable GitHub issue identity, acquire exclusive execution through one authenticated connection, transact against remote WorkflowRun and Workspace state, disappear, and later resume on another runner from exactly the committed frontier.
Authoritative behavior
One SQLite-backed Cloudflare Durable Object owns each run's WorkflowRun record and journal, Workspace roots and content-addressed bytes, Agent-session mappings/checkpoints, pending answers, and executor acquisition.
Run ID is base32(sha256("github-issue-v1\0" + githubHost + "\0" + issueNodeId)) after an authenticated issue reread. Mutable repository names, issue numbers, Project fields, branches, revisions, comments, and definition SHAs are excluded.
Executor ownership is the lifetime of one authenticated Durable Object WebSocket connection. There is no application lease, expiry, renewal, or heartbeat authority.
Every authoritative request travels through that connection and validates the acquisition plus expected Workspace root inside the mutation transaction.
Git, evidence processes, and Agent clients remain on the ephemeral runner; the Durable Object stores and commits state but runs none of them.
Actions artifacts are immutable exports only. Completed replay attaches no provider.
Current state
packages/cli/src/deno-workflow.ts selects local XMD_WORKFLOW_RUNS storage. packages/workflow/src/deno/provider.ts, database.ts, run-host.ts, lock.ts, answers.ts, and workspace/** implement one-process/local-filesystem topology with local SQLite and advisory/connection ownership. The existing provider-neutral WorkflowHost, retained-run, Workspace, answer, Agent-session, strict-parse, transaction, and replay contracts are the seams to preserve; no remote Cloudflare host assembly exists.
Affected modules and public contracts
Add the runtime-specific Cloudflare Durable Object implementation under packages/workflow/src/cloudflare/** and the runtime-named public entrypoint packages/workflow/cloudflare.ts; Cloudflare APIs stay out of shared modules and existing Deno/Node/Bun entrypoints.
Extend the provider-neutral client/host transport only where remote start, lookup, execute, answer, inspect, and completed replay require it; do not fork WorkflowRun or Workspace semantics into a Cloudflare-only model.
Add Actions-side remote host selection in packages/cli/src/remote-workflow.ts, installed explicitly by the Deno/compiled assemblies while preserving local Deno behavior and Node/Bun refusal behavior.
Reuse the retained record parsers and transaction rules from packages/workflow; add explicit remote protocol records only when C0 names them.
Add provider contract tests under packages/workflow/tests/ and CLI selection/configuration tests under packages/cli/tests/ using explicit files because process/network/Workers boundaries are not discoverable from imports.
Update architecture.md, specs/workflow-spec.md, specs/workflow-workspace-spec.md, specs/executable-mdx-spec.md, public exports, and the construct/test inventory in the same feedback commit wherever the remote host makes the C0 contract concrete.
Ordered implementation plan
Extract or expose the smallest provider-neutral storage/host operations needed by both the existing local host and the remote adapter without changing their retained meanings.
Implement stable issue identity validation and run-ID derivation at the authenticated admission boundary; route that ID to one Durable Object and refuse issue-transfer identity drift.
Implement SQLite-backed run, Workspace, Agent-session, and answer storage in the Durable Object using the existing strict schemas or the exact new versions frozen by C0.
Implement authenticated WebSocket acquisition and bind every read/mutation request to its live acquisition; a second live executor follows/refuses without advancing.
Implement atomic root/journal publication and content-addressed transfer so a runner materializes only the selected retained root and submits bounded changes.
Add Actions OIDC verification and fail-closed host configuration at runtime-named entrypoints; keep claims, endpoints, and credentials out of durable data and public errors.
Add remote inspection, answer delivery, recovery, and completed replay through the existing WorkflowHost behavior.
Add real Workers-runtime integration coverage plus deterministic transport fakes for interruption points; do not claim Durable Object/WebSocket behavior from an in-process map alone.
Failure, cancellation, teardown, and replay
A foreign, stale, replaced, or closed acquisition; wrong expected root; malformed request; unknown retained version; unsupported issue transfer; invalid OIDC claims; and content-address mismatch refuse before protected state or credentials are read or mutated. Cancellation closes the client connection and operation scope, which releases executor ownership; it invents no completion. A killed runner can leave only the last committed transaction. The next connection recovers SQLite and resumes from that frontier. Completed replay reaches no Durable Object attachment, Git, Agent, process, or GitHub provider.
Frozen evidence matrix
Duplicate authenticated admission for the same issue node selects one run ID, one Durable Object, and one retained lifecycle.
Two runner processes overlap; only one advances, the other cannot publish, and connection loss lets a later runner acquire without a timer.
Every mutation with a foreign acquisition or stale Workspace root refuses before state changes.
Kill points before, during, and after root/journal publication expose either the old complete frontier or the new complete frontier, never a mixture.
Workspace bytes, Agent sessions, and answers round-trip through a second runner with exact retained identities.
Invalid OIDC, malformed protocol, strict-schema mismatch, digest mismatch, and issue-transfer drift fail closed without secret-bearing diagnostics.
Local Deno host behavior and Node/Bun unsupported-host behavior remain unchanged.
Completed replay contacts no remote host and allocates no provider resources.
Focused feedback evidence
Add explicit files such as packages/workflow/tests/cloudflare-run-host.test.ts, packages/workflow/tests/cloudflare-executor.test.ts, packages/workflow/tests/cloudflare-recovery.test.ts, and packages/cli/tests/remote-workflow-host.test.ts. Run those exact files, then deno task test --changed. If a Workers test dependency or deployment manifest changes dependency layout, run deno task setup after the explicit lock update and include the smallest dependency-specific checks. Commit when the focused files and changed-test selection pass; report the exact SHA and every command.
Delivery verification
Run deno task lint, deno task check, and deno task check:jsr if public exports move. Run deno task verify:clean only if this story changes dependency layout, build inputs, generated Workers artifacts, or shared cache ownership, and only from the feedback commit or a later committed revision. CI owns exhaustive Deno/Node/Bun suites unless the new runtime adapter changes shared test setup.
Exclusions
No GitHub webhook/form ingress, Project/comment mutation, factory stage logic, Git merge, evidence process, alternative storage provider, timed lock, artifact-backed live state, runtime detection in shared modules, permissive migration, or Agent access to the provider.
Risks and recovery
Remote protocol drift is a public persistence boundary. A failed schema or transaction design is corrected in this story before descendants consume it; no descendant invents a compatibility reader. Deployment credentials and a production Cloudflare account are operator inputs, not test fixtures; absence of production credentials does not weaken the real-runtime local contract suite.
Handoff
Before implementation, replace the implementation-base placeholder with C0's exact accepted feedback SHA and confirm the branch contains it. Implement only this provider boundary, freeze the evidence above, commit as soon as it passes, and return the exact F1 feedback SHA for F2 and the foundation integration branch.
Parent: #633
Architecture ancestry: PR #630
Planning base:
0479b3b1e6a3de08fb7d9de515a3efde80e7fe91; implementation base is the exact accepted C0 feedback commit recorded before handoffStack position: F1; parallel with F3, F4, F5, and F6; provider prerequisite for F2, L7, and L8
Readiness: blocked only until C0's accepted feedback SHA is recorded and present in the branch; no provider, identity, persistence, locking, or replay choice is delegated to the Implementor
Purpose and observable outcome
An ephemeral Actions-side XMD client can select one durable run from immutable GitHub issue identity, acquire exclusive execution through one authenticated connection, transact against remote WorkflowRun and Workspace state, disappear, and later resume on another runner from exactly the committed frontier.
Authoritative behavior
base32(sha256("github-issue-v1\0" + githubHost + "\0" + issueNodeId))after an authenticated issue reread. Mutable repository names, issue numbers, Project fields, branches, revisions, comments, and definition SHAs are excluded.Current state
packages/cli/src/deno-workflow.tsselects localXMD_WORKFLOW_RUNSstorage.packages/workflow/src/deno/provider.ts,database.ts,run-host.ts,lock.ts,answers.ts, andworkspace/**implement one-process/local-filesystem topology with local SQLite and advisory/connection ownership. The existing provider-neutralWorkflowHost, retained-run, Workspace, answer, Agent-session, strict-parse, transaction, and replay contracts are the seams to preserve; no remote Cloudflare host assembly exists.Affected modules and public contracts
packages/workflow/src/cloudflare/**and the runtime-named public entrypointpackages/workflow/cloudflare.ts; Cloudflare APIs stay out of shared modules and existing Deno/Node/Bun entrypoints.packages/cli/src/remote-workflow.ts, installed explicitly by the Deno/compiled assemblies while preserving local Deno behavior and Node/Bun refusal behavior.packages/workflow; add explicit remote protocol records only when C0 names them.packages/workflow/tests/and CLI selection/configuration tests underpackages/cli/tests/using explicit files because process/network/Workers boundaries are not discoverable from imports.architecture.md,specs/workflow-spec.md,specs/workflow-workspace-spec.md,specs/executable-mdx-spec.md, public exports, and the construct/test inventory in the same feedback commit wherever the remote host makes the C0 contract concrete.Ordered implementation plan
WorkflowHostbehavior.Failure, cancellation, teardown, and replay
A foreign, stale, replaced, or closed acquisition; wrong expected root; malformed request; unknown retained version; unsupported issue transfer; invalid OIDC claims; and content-address mismatch refuse before protected state or credentials are read or mutated. Cancellation closes the client connection and operation scope, which releases executor ownership; it invents no completion. A killed runner can leave only the last committed transaction. The next connection recovers SQLite and resumes from that frontier. Completed replay reaches no Durable Object attachment, Git, Agent, process, or GitHub provider.
Frozen evidence matrix
Focused feedback evidence
Add explicit files such as
packages/workflow/tests/cloudflare-run-host.test.ts,packages/workflow/tests/cloudflare-executor.test.ts,packages/workflow/tests/cloudflare-recovery.test.ts, andpackages/cli/tests/remote-workflow-host.test.ts. Run those exact files, thendeno task test --changed. If a Workers test dependency or deployment manifest changes dependency layout, rundeno task setupafter the explicit lock update and include the smallest dependency-specific checks. Commit when the focused files and changed-test selection pass; report the exact SHA and every command.Delivery verification
Run
deno task lint,deno task check, anddeno task check:jsrif public exports move. Rundeno task verify:cleanonly if this story changes dependency layout, build inputs, generated Workers artifacts, or shared cache ownership, and only from the feedback commit or a later committed revision. CI owns exhaustive Deno/Node/Bun suites unless the new runtime adapter changes shared test setup.Exclusions
No GitHub webhook/form ingress, Project/comment mutation, factory stage logic, Git merge, evidence process, alternative storage provider, timed lock, artifact-backed live state, runtime detection in shared modules, permissive migration, or Agent access to the provider.
Risks and recovery
Remote protocol drift is a public persistence boundary. A failed schema or transaction design is corrected in this story before descendants consume it; no descendant invents a compatibility reader. Deployment credentials and a production Cloudflare account are operator inputs, not test fixtures; absence of production credentials does not weaken the real-runtime local contract suite.
Handoff
Before implementation, replace the implementation-base placeholder with C0's exact accepted feedback SHA and confirm the branch contains it. Implement only this provider boundary, freeze the evidence above, commit as soon as it passes, and return the exact F1 feedback SHA for F2 and the foundation integration branch.