taskflow-mcp-core 0.3.0-beta.1.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/CONTROL_GUIDE.md +113 -0
  2. package/README.md +34 -25
  3. package/dist/control/admission-service.d.ts +15 -0
  4. package/dist/control/admission-service.d.ts.map +1 -0
  5. package/dist/control/admission-service.js +64 -0
  6. package/dist/control/admission-service.js.map +1 -0
  7. package/dist/control/approval-edits.d.ts +12 -0
  8. package/dist/control/approval-edits.d.ts.map +1 -0
  9. package/dist/control/approval-edits.js +66 -0
  10. package/dist/control/approval-edits.js.map +1 -0
  11. package/dist/control/approval-service.d.ts +173 -0
  12. package/dist/control/approval-service.d.ts.map +1 -0
  13. package/dist/control/approval-service.js +342 -0
  14. package/dist/control/approval-service.js.map +1 -0
  15. package/dist/control/authorization.d.ts +94 -0
  16. package/dist/control/authorization.d.ts.map +1 -0
  17. package/dist/control/authorization.js +302 -0
  18. package/dist/control/authorization.js.map +1 -0
  19. package/dist/control/control-cli.d.ts +3 -0
  20. package/dist/control/control-cli.d.ts.map +1 -0
  21. package/dist/control/control-cli.js +279 -0
  22. package/dist/control/control-cli.js.map +1 -0
  23. package/dist/control/control-console.d.ts +17 -0
  24. package/dist/control/control-console.d.ts.map +1 -0
  25. package/dist/control/control-console.js +67 -0
  26. package/dist/control/control-console.js.map +1 -0
  27. package/dist/control/control-host.d.ts +98 -0
  28. package/dist/control/control-host.d.ts.map +1 -0
  29. package/dist/control/control-host.js +459 -0
  30. package/dist/control/control-host.js.map +1 -0
  31. package/dist/control/control-mcp.d.ts +11 -0
  32. package/dist/control/control-mcp.d.ts.map +1 -0
  33. package/dist/control/control-mcp.js +78 -0
  34. package/dist/control/control-mcp.js.map +1 -0
  35. package/dist/control/errors.d.ts +44 -0
  36. package/dist/control/errors.d.ts.map +1 -0
  37. package/dist/control/errors.js +93 -0
  38. package/dist/control/errors.js.map +1 -0
  39. package/dist/control/hello.d.ts +39 -0
  40. package/dist/control/hello.d.ts.map +1 -0
  41. package/dist/control/hello.js +80 -0
  42. package/dist/control/hello.js.map +1 -0
  43. package/dist/control/host-runtime.d.ts +32 -0
  44. package/dist/control/host-runtime.d.ts.map +1 -0
  45. package/dist/control/host-runtime.js +542 -0
  46. package/dist/control/host-runtime.js.map +1 -0
  47. package/dist/control/index.d.ts +32 -0
  48. package/dist/control/index.d.ts.map +1 -0
  49. package/dist/control/index.js +32 -0
  50. package/dist/control/index.js.map +1 -0
  51. package/dist/control/legacy-conflict.d.ts +19 -0
  52. package/dist/control/legacy-conflict.d.ts.map +1 -0
  53. package/dist/control/legacy-conflict.js +176 -0
  54. package/dist/control/legacy-conflict.js.map +1 -0
  55. package/dist/control/local-bootstrap.d.ts +21 -0
  56. package/dist/control/local-bootstrap.d.ts.map +1 -0
  57. package/dist/control/local-bootstrap.js +224 -0
  58. package/dist/control/local-bootstrap.js.map +1 -0
  59. package/dist/control/modes.d.ts +60 -0
  60. package/dist/control/modes.d.ts.map +1 -0
  61. package/dist/control/modes.js +86 -0
  62. package/dist/control/modes.js.map +1 -0
  63. package/dist/control/project-admin-cli.d.ts +3 -0
  64. package/dist/control/project-admin-cli.d.ts.map +1 -0
  65. package/dist/control/project-admin-cli.js +155 -0
  66. package/dist/control/project-admin-cli.js.map +1 -0
  67. package/dist/control/project-registry.d.ts +20 -0
  68. package/dist/control/project-registry.d.ts.map +1 -0
  69. package/dist/control/project-registry.js +181 -0
  70. package/dist/control/project-registry.js.map +1 -0
  71. package/dist/control/runtime-checkpoint.d.ts +11 -0
  72. package/dist/control/runtime-checkpoint.d.ts.map +1 -0
  73. package/dist/control/runtime-checkpoint.js +39 -0
  74. package/dist/control/runtime-checkpoint.js.map +1 -0
  75. package/dist/control/runtime-provider.d.ts +100 -0
  76. package/dist/control/runtime-provider.d.ts.map +1 -0
  77. package/dist/control/runtime-provider.js +258 -0
  78. package/dist/control/runtime-provider.js.map +1 -0
  79. package/dist/control/schema/approval.d.ts +108 -0
  80. package/dist/control/schema/approval.d.ts.map +1 -0
  81. package/dist/control/schema/approval.js +65 -0
  82. package/dist/control/schema/approval.js.map +1 -0
  83. package/dist/control/schema/commands.d.ts +663 -0
  84. package/dist/control/schema/commands.d.ts.map +1 -0
  85. package/dist/control/schema/commands.js +147 -0
  86. package/dist/control/schema/commands.js.map +1 -0
  87. package/dist/control/schema/common.d.ts +24 -0
  88. package/dist/control/schema/common.d.ts.map +1 -0
  89. package/dist/control/schema/common.js +38 -0
  90. package/dist/control/schema/common.js.map +1 -0
  91. package/dist/control/schema/coordinator.d.ts +98 -0
  92. package/dist/control/schema/coordinator.d.ts.map +1 -0
  93. package/dist/control/schema/coordinator.js +87 -0
  94. package/dist/control/schema/coordinator.js.map +1 -0
  95. package/dist/control/schema/evidence.d.ts +140 -0
  96. package/dist/control/schema/evidence.d.ts.map +1 -0
  97. package/dist/control/schema/evidence.js +64 -0
  98. package/dist/control/schema/evidence.js.map +1 -0
  99. package/dist/control/schema/header.d.ts +79 -0
  100. package/dist/control/schema/header.d.ts.map +1 -0
  101. package/dist/control/schema/header.js +66 -0
  102. package/dist/control/schema/header.js.map +1 -0
  103. package/dist/control/schema/index.d.ts +31 -0
  104. package/dist/control/schema/index.d.ts.map +1 -0
  105. package/dist/control/schema/index.js +31 -0
  106. package/dist/control/schema/index.js.map +1 -0
  107. package/dist/control/schema/plan.d.ts +291 -0
  108. package/dist/control/schema/plan.d.ts.map +1 -0
  109. package/dist/control/schema/plan.js +80 -0
  110. package/dist/control/schema/plan.js.map +1 -0
  111. package/dist/control/schema/policy.d.ts +96 -0
  112. package/dist/control/schema/policy.d.ts.map +1 -0
  113. package/dist/control/schema/policy.js +73 -0
  114. package/dist/control/schema/policy.js.map +1 -0
  115. package/dist/control/schema/run.d.ts +61 -0
  116. package/dist/control/schema/run.d.ts.map +1 -0
  117. package/dist/control/schema/run.js +56 -0
  118. package/dist/control/schema/run.js.map +1 -0
  119. package/dist/control/schema/te-mirrors.d.ts +145 -0
  120. package/dist/control/schema/te-mirrors.d.ts.map +1 -0
  121. package/dist/control/schema/te-mirrors.js +145 -0
  122. package/dist/control/schema/te-mirrors.js.map +1 -0
  123. package/dist/control/schema/transport.d.ts +479 -0
  124. package/dist/control/schema/transport.d.ts.map +1 -0
  125. package/dist/control/schema/transport.js +181 -0
  126. package/dist/control/schema/transport.js.map +1 -0
  127. package/dist/control/singleton.d.ts +135 -0
  128. package/dist/control/singleton.d.ts.map +1 -0
  129. package/dist/control/singleton.js +607 -0
  130. package/dist/control/singleton.js.map +1 -0
  131. package/dist/control/store/coordinator-store.d.ts +143 -0
  132. package/dist/control/store/coordinator-store.d.ts.map +1 -0
  133. package/dist/control/store/coordinator-store.js +620 -0
  134. package/dist/control/store/coordinator-store.js.map +1 -0
  135. package/dist/control/store/evidence-adapter.d.ts +10 -0
  136. package/dist/control/store/evidence-adapter.d.ts.map +1 -0
  137. package/dist/control/store/evidence-adapter.js +114 -0
  138. package/dist/control/store/evidence-adapter.js.map +1 -0
  139. package/dist/control/store/evidence-explanation.d.ts +55 -0
  140. package/dist/control/store/evidence-explanation.d.ts.map +1 -0
  141. package/dist/control/store/evidence-explanation.js +50 -0
  142. package/dist/control/store/evidence-explanation.js.map +1 -0
  143. package/dist/control/store/evidence-store.d.ts +143 -0
  144. package/dist/control/store/evidence-store.d.ts.map +1 -0
  145. package/dist/control/store/evidence-store.js +437 -0
  146. package/dist/control/store/evidence-store.js.map +1 -0
  147. package/dist/control/store/index.d.ts +3 -0
  148. package/dist/control/store/index.d.ts.map +1 -0
  149. package/dist/control/store/index.js +2 -0
  150. package/dist/control/store/index.js.map +1 -0
  151. package/dist/control/store/journal.d.ts +270 -0
  152. package/dist/control/store/journal.d.ts.map +1 -0
  153. package/dist/control/store/journal.js +50 -0
  154. package/dist/control/store/journal.js.map +1 -0
  155. package/dist/control/store/project-lifecycle.d.ts +49 -0
  156. package/dist/control/store/project-lifecycle.d.ts.map +1 -0
  157. package/dist/control/store/project-lifecycle.js +288 -0
  158. package/dist/control/store/project-lifecycle.js.map +1 -0
  159. package/dist/control/store/store.d.ts +93 -0
  160. package/dist/control/store/store.d.ts.map +1 -0
  161. package/dist/control/store/store.js +873 -0
  162. package/dist/control/store/store.js.map +1 -0
  163. package/dist/control/te-provider.d.ts +86 -0
  164. package/dist/control/te-provider.d.ts.map +1 -0
  165. package/dist/control/te-provider.js +131 -0
  166. package/dist/control/te-provider.js.map +1 -0
  167. package/dist/control/uds.d.ts +114 -0
  168. package/dist/control/uds.d.ts.map +1 -0
  169. package/dist/control/uds.js +456 -0
  170. package/dist/control/uds.js.map +1 -0
  171. package/dist/control/web-console/view.d.ts +5 -0
  172. package/dist/control/web-console/view.d.ts.map +1 -0
  173. package/dist/control/web-console/view.js +122 -0
  174. package/dist/control/web-console/view.js.map +1 -0
  175. package/dist/control/web-console.d.ts +50 -0
  176. package/dist/control/web-console.d.ts.map +1 -0
  177. package/dist/control/web-console.js +317 -0
  178. package/dist/control/web-console.js.map +1 -0
  179. package/dist/mcp/jsonrpc.d.ts.map +1 -1
  180. package/dist/mcp/jsonrpc.js +12 -3
  181. package/dist/mcp/jsonrpc.js.map +1 -1
  182. package/dist/mcp/server.d.ts.map +1 -1
  183. package/dist/mcp/server.js +26 -17
  184. package/dist/mcp/server.js.map +1 -1
  185. package/package.json +13 -5
@@ -0,0 +1,113 @@
1
+ # Taskflow control plane
2
+
3
+ The implementation lives in a private workspace, but its compiled control and
4
+ project-administration binaries ship inside the existing `taskflow-mcp-core`
5
+ public package. No `taskflow-control` registry package is needed. The current
6
+ 1.0.0 candidate is unreleased; publication and new-head CI remain separate gates.
7
+
8
+ A local candidate can be installed from its `taskflow-core` and
9
+ `taskflow-mcp-core` tarballs plus TypeBox, with npm lifecycle scripts disabled.
10
+ The control entry is `node_modules/taskflow-mcp-core/dist/control/control-cli.js`,
11
+ also linked as `node_modules/.bin/taskflow-control`. This guide is shipped as
12
+ `taskflow-mcp-core/CONTROL_GUIDE.md`. After authorized publication, install with
13
+ `npm install --save-exact taskflow-mcp-core@1.0.0 typebox@1.3.30`.
14
+
15
+ The control service mounts explicitly configured projects and routes requests by
16
+ their durable project identity. It authenticates local clients, rereads policy,
17
+ persists command results, coordinates capacity, and executes through the existing TE
18
+ runtime. Durable approval waits can survive an owner crash without repeating completed
19
+ phases. Receipts and explanations come from the project journal and runtime evidence.
20
+
21
+ ## Local use
22
+
23
+ Use Node 22.19 or later. Keep the control home outside every execution project.
24
+
25
+ ```sh
26
+ taskflow-control run --root /path/project --flow /path/flow.json --control-home /path/control-home
27
+ taskflow-control serve --root /path/project --root /path/another --control-home /path/control-home --console
28
+ taskflow-control status --root /path/project --control-home /path/control-home
29
+ taskflow-control mcp --root /path/project --control-home /path/control-home
30
+ ```
31
+
32
+ `auto` starts an owner or attaches to the existing owner. `coordinated` requires an
33
+ existing owner; it does not silently start a standalone service. The console prints
34
+ a private handoff-file path. Its one-use browser token is not placed in a URL or
35
+ printed to stdout. Local policy files under the control home are checked on each
36
+ operation. The CLI runs scripts; embedded callers must configure an agent runner
37
+ for agent phases. MCP exposes the same authenticated Host operations.
38
+
39
+ Approval output edits use validated text artifacts. Plan edits are restricted to
40
+ unstarted downstream phase bodies in the same dependency graph; completed phases,
41
+ top-level settings, and resource declarations cannot be rewritten. Plan edits are
42
+ compiled again before readmission. The existing runtime executes the continuation.
43
+
44
+ ## Explicit coordinator operators
45
+
46
+ Normal bootstrap credentials cannot change capacity or force-release reservations.
47
+ An OS owner must explicitly provision the separate operator credential and a
48
+ project-scoped operator policy. The key is never printed; the output identifies
49
+ its principal and policy file. Provisioning does not overwrite an existing policy.
50
+
51
+ ```sh
52
+ taskflow-control operator-provision --root /path/project --control-home /path/control-home
53
+ taskflow-control coordinator-status --root /path/project --control-home /path/control-home --mode auto --operator
54
+ taskflow-control set-max-active-runs --root /path/project --control-home /path/control-home --mode auto --operator --command-id UUID --max-active-runs 4
55
+ taskflow-control force-release --root /path/project --control-home /path/control-home --mode auto --operator --command-id UUID --reservation UUID --acknowledge-risk --reason "operator reviewed retained effects"
56
+ taskflow-control mcp --root /path/project --control-home /path/control-home --operator
57
+ ```
58
+
59
+ Replace each `UUID` with an actual identifier. Reuse the same command ID and
60
+ identical payload for a retry; a changed payload conflicts, and revocation is
61
+ checked again before replay. Mutations default to `coordinated`; the examples
62
+ explicitly permit `auto` to start the shared owner if absent. Capacity is a
63
+ user-global admitted-run limit, while reservation identifiers and force release
64
+ remain bound to the authenticated project. Reducing capacity below active use is
65
+ rejected. Status shows global aggregate counts and only authorized project rows.
66
+
67
+ Operator credentials grant project read plus the two coordinator mutations;
68
+ they do not inherit run submission or approval authority. Only an explicit
69
+ `mcp --operator` exposes the two operator mutation tools. A caller-supplied role
70
+ or credential label cannot replace the separate HMAC proof. The protected
71
+ `operator-policies` file is reread on each operation; removing a grant or revoking
72
+ the principal also rejects existing sessions and retries. Deleting/replacing
73
+ `operator.key` invalidates sessions; restart clients after deliberate key rotation.
74
+ Possession of that OS-user-protected key is the trust boundary, not isolation
75
+ from arbitrary processes running as the same OS user.
76
+
77
+ Force release frees accounting capacity without proving side effects have stopped.
78
+ It requires both explicit acknowledgement and a nonempty reason, persists the
79
+ request and `CoordinatorCommandRecord`, and records `operator-overridden`.
80
+ It does not fabricate a terminal Run or Receipt. Investigate unknown effects
81
+ before making this explicit decision.
82
+
83
+ ## Offline project administration
84
+
85
+ ```sh
86
+ taskflow-project-admin move-rebind --store /moved/project/.taskflow/control
87
+ taskflow-project-admin clone --store /source/.taskflow/control --destination /new/project/.taskflow/control
88
+ taskflow-project-admin export --store /project/.taskflow/control --output /private/export.json --kind readonly
89
+ ```
90
+
91
+ Stop project writers before an offline filesystem move. `move-rebind` verifies the
92
+ same directory device/inode, absence of the old path, writer exclusion, and settled
93
+ history before preserving identity. `clone` creates a fresh, empty project/domain;
94
+ it does not copy authoritative run history. Export preserves source bytes, including
95
+ damaged journal evidence, and always states `executePromise: false`.
96
+
97
+ ## Recovery boundaries
98
+
99
+ Missing or damaged headers, incomplete journals, ambiguous effects, unknown owners,
100
+ and changed directory identities fail closed. An interrupted script can leave a
101
+ dirty TE mutation even after its process exits: status remains `unknown`, capacity
102
+ is retained, and no terminal Receipt is fabricated. SIGINT first records a versioned
103
+ cancellation; a bounded process shutdown fallback still reaps owned children.
104
+
105
+ Legacy conflict detection covers observable core run records and locks. It stops
106
+ new attempts and never kills external writers. The trusted local
107
+ `LegacyConflictGuard.acknowledgeStopped()` API requires captured writers to be dead.
108
+ Invisible unmanaged writers require external service-manager exclusion. The managed
109
+ legacy mutex migration helper applies only to its directly supervised child writers.
110
+
111
+ The provider reports resolve-only containment and admission-time revocation. This
112
+ does not claim an OS sandbox, arbitrary in-flight recovery, cross-domain transfer,
113
+ or general DAG editing. Logical compaction retains the physical evidence journal.
package/README.md CHANGED
@@ -11,23 +11,23 @@
11
11
 
12
12
  **English** · [简体中文](https://github.com/heggria/taskflow/blob/main/README.zh-CN.md)
13
13
 
14
- [0.3 overview](#taskflow-03-trusted-effects) · [Quickstart](#quickstart) · [Docs](https://heggria.github.io/taskflow/en/docs) · [Examples](https://github.com/heggria/taskflow/blob/main/examples) · [Changelog](https://github.com/heggria/taskflow/blob/main/CHANGELOG.md)
14
+ [1.0 overview](#taskflow-10-declarative-coding-agent-workflows) · [Quickstart](#quickstart) · [Docs](https://heggria.github.io/taskflow/en/docs) · [Examples](https://github.com/heggria/taskflow/blob/main/examples) · [Changelog](https://github.com/heggria/taskflow/blob/main/CHANGELOG.md)
15
15
 
16
16
  </div>
17
17
 
18
18
  ---
19
19
 
20
- # taskflow 0.3: make agent side effects inspectable
20
+ # taskflow 1.0: declarative coding-agent workflows
21
21
 
22
- **taskflow is a declarative runtime for coding-agent workflows.** It turns a graph into a verifiable execution contract, runs phases in isolation, and keeps intermediate work out of the host conversation. In the 0.3 candidate, the contract also describes the effects a phase is allowed to propose.
22
+ **taskflow is a declarative runtime for coding-agent workflows.** It turns a graph into a verifiable execution contract, runs phases in isolation, and keeps intermediate work out of the host conversation. In Taskflow 1.0, the contract also describes the effects a phase is allowed to propose.
23
23
 
24
- > **Status: 0.3.0-beta.1.1 Trusted Effects beta — beta channel, not GA.** This release candidate is prepared for npm's `beta` channel; the beta ships the Trusted Effects MVP described below. The 0.3-C Control Plane remains a follow-on candidate track; it is not a shipped beta surface.
24
+ > **Taskflow 1.0.0** includes the DAG runtime, trusted filesystem effects and complete Control Plane (CLI/MCP/WebUI). [GitHub Releases](https://github.com/heggria/taskflow/releases) and npm establish publication; see the [acceptance scoreboard](https://github.com/heggria/taskflow/blob/main/docs/internal/1.0.0-ga-scoreboard.md) for verified scope and limits.
25
25
 
26
- ## The 0.3 idea
26
+ ## The declared-effect contract
27
27
 
28
28
  An agent can propose content. It should not become the mutation authority merely because it can run a command.
29
29
 
30
- For admitted, declared filesystem-write targets, taskflow 0.3 makes the path explicit and routes the final mutation through the resources transaction:
30
+ For admitted, declared filesystem-write targets, taskflow 1.0 makes the path explicit and routes the final mutation through the resources transaction:
31
31
 
32
32
  ```text
33
33
  flow / .tf.ts
@@ -47,39 +47,40 @@ flow / .tf.ts
47
47
 
48
48
  This is **not** an OS sandbox. Resolve-only hosts cannot prevent every write to an undeclared path. Secret and service references are typed and fail closed in this cut; they do not imply a vault or network backend.
49
49
 
50
- ## What is in the candidate
50
+ ## The 1.0 target and current implementation
51
51
 
52
- | Layer | What it does | Candidate status |
52
+ | Layer | What it does | Support boundary |
53
53
  |---|---|---|
54
- | **Taskflow runtime** | Declarative DAGs, 12 phase types, budgets, retries, approvals, isolation, resume, replay, trace, and recompute | Existing 0.2 foundation |
55
- | **Trusted Effects** | Closed `EffectIR`, `PathRef` / `SecretRef` / `ServiceRef`, confidentiality/integrity labels, effect validation, overlap checks, and ledger-backed `why-*` explainers | 0.3 MVP implementation |
56
- | **Resource transaction** | Snapshot → lease → durable intent/permit → stage → commit, or restore and reject | 0.3 MVP implementation |
54
+ | **Taskflow runtime** | Declarative DAGs, 12 phase types, budgets, retries, approvals, isolation, resume, replay, trace, and recompute | Stable runtime contract |
55
+ | **Trusted Effects** | Closed `EffectIR`, `PathRef` / `SecretRef` / `ServiceRef`, confidentiality/integrity labels, effect validation, overlap checks, and ledger-backed `why-*` explainers | Declared-target contract |
56
+ | **Resource transaction** | Snapshot → lease → durable intent/permit → stage → commit, or restore and reject | Declared-target contract |
57
57
  | **Host adapters** | Pi, Codex, Claude Code, OpenCode, Grok Build, and Hermes Agent use the same flow contract | Existing host surface; support remains host-specific |
58
- | **Control Plane** | ControlHost scaffold, proposed wire contracts, singleton/fencing, and hello negotiation; future stores, approvals, receipts, and coordination | Active 0.3-C track; not shipped and not the 0.3 MVP GA claim |
59
- | **WebUI** | Runs, approvals, receipts, and evidence browsing | Planned in the 0.3-C sequence; not shipped in this candidate |
58
+ | **Control Plane** | Authenticated multi-project admission, global concurrency, durable replay, approvals/CAS, Receipts and operator CLI/MCP | Bundled in public `taskflow-mcp-core`; Unix UDS, Windows pipes non-GA |
59
+ | **WebUI** | Runs, approval edits, Receipts and evidence browsing | Local token login, live authorization and project isolation |
60
60
 
61
- The normative MVP definition is [`docs/internal/0.3.0-trusted-effects-mvp.md`](https://github.com/heggria/taskflow/blob/main/docs/internal/0.3.0-trusted-effects-mvp.md). The 0.3-C Control Plane plan is [`docs/internal/0.3-c-control-plane-plan.md`](https://github.com/heggria/taskflow/blob/main/docs/internal/0.3-c-control-plane-plan.md).
61
+ The [1.0 release plan](https://github.com/heggria/taskflow/blob/main/docs/internal/1.0.0-release-plan.md) defines the stable scope and acceptance gates. The filesystem-transaction details are in [`docs/internal/0.3.0-trusted-effects-mvp.md`](https://github.com/heggria/taskflow/blob/main/docs/internal/0.3.0-trusted-effects-mvp.md). The 0.3-C Control Plane plan is [`docs/internal/0.3-c-control-plane-plan.md`](https://github.com/heggria/taskflow/blob/main/docs/internal/0.3-c-control-plane-plan.md).
62
62
 
63
63
  ## Quickstart
64
64
 
65
- The 0.3 beta can be installed from npm, or exercised from a clean source checkout. Use Node.js **≥ 22.19.0**:
65
+ Use Node.js **≥ 22.19.0**. To run from the 1.0 source checkout:
66
66
 
67
67
  ```bash
68
68
  git clone https://github.com/heggria/taskflow.git
69
69
  cd taskflow
70
- git checkout rc/0.3.0-trusted-effects
70
+ git checkout v1.0.0
71
71
  pnpm install
72
72
  pnpm run typecheck
73
73
  pnpm test
74
74
  ```
75
75
 
76
- The beta commands below become usable after the tag workflow completes; until then they are release-target examples, not proof of registry availability.
76
+ Install the matching 1.0.0 package set after confirming the release is available:
77
+
77
78
  ```bash
78
- npm install --global pi-taskflow@beta
79
- npm install --global codex-taskflow@beta
79
+ npm install --global pi-taskflow@1.0.0
80
+ npm install --global codex-taskflow@1.0.0
80
81
  ```
81
82
 
82
- The host-specific plugin and MCP commands remain in the [host guides](https://heggria.github.io/taskflow/en/docs/guides/). Stable 0.2.x installs remain available through exact stable pins.
83
+ The host-specific plugin and MCP commands remain in the [host guides](https://heggria.github.io/taskflow/en/docs/guides/).
83
84
 
84
85
  Run the no-LLM Trusted Effects vertical-slice fixture:
85
86
 
@@ -88,7 +89,15 @@ pnpm exec node --conditions=development --experimental-strip-types --test \
88
89
  packages/taskflow-core/test/effects-e2e-fixture.test.ts
89
90
  ```
90
91
 
91
- This exercises the checked-in `examples/trusted-effects-write.json` path without a live LLM. For an interactive run, use the host guide for the adapter you already run. The stable 0.2 installation path remains documented separately in the [host guides](https://heggria.github.io/taskflow/en/docs/guides/).
92
+ This exercises the checked-in `examples/trusted-effects-write.json` path without a live LLM. For an interactive run, use the host guide for the adapter you already run. The [release guide](https://github.com/heggria/taskflow/blob/main/RELEASE.md) covers packed-consumer validation and release gates.
93
+
94
+ ### Local Control Console
95
+
96
+ In Pi, run `/tf web` to start the bundled local Control Console and open the default browser. If browser opening fails, the command shows a manual loopback URL. Use the one-use token in the reported private (0600) handoff file to log in; tokens are never included in the URL or command notifications.
97
+
98
+ The console shows Control Plane runs, approvals, Receipts and existing evidence. Legacy Pi run transcripts are outside this view. Repeating the command in the same project reuses its service; changing projects or leaving the Pi session stops only the console process started by that session. Unix local transport is required. If another host already owns the Control home, stop that owner explicitly before launching this console.
99
+
100
+ See [Pi compatibility](https://github.com/heggria/taskflow/blob/main/docs/pi-compatibility.md) for the tested SDK matrix and the distinction between real-process fixtures and live-provider acceptance.
92
101
 
93
102
  ## Declare an effect
94
103
 
@@ -191,7 +200,7 @@ Host support is not a blanket security guarantee. Read the [host support baselin
191
200
  - Writes to undeclared paths remain host-policy dependent under resolve-only execution.
192
201
  - `SecretRef` and `ServiceRef` are typed handles only; no vault or live service adapter ships in this cut.
193
202
  - There is no FileBroker or full OS sandbox claim in 0.3 MVP.
194
- - Control Plane stores, approvals, receipts, and WebUI are future 0.3-C stages, not proof that 0.3 is released or GA.
203
+ - Control Plane admission, authorized replay, durable approvals, Receipts, global coordination and WebUI are implemented. Public `taskflow-mcp-core` provides the control binaries; operator actions require an explicitly provisioned separate credential. Request audit fields never grant authority.
195
204
 
196
205
  ## Development
197
206
 
@@ -210,13 +219,13 @@ The monorepo contains the host-neutral `taskflow-core`, Trusted Effects and reso
210
219
 
211
220
  | Start here | Use it for |
212
221
  |---|---|
213
- | [0.3 overview](https://heggria.github.io/taskflow/en/docs) | Candidate scope, status, and the honest security boundary |
222
+ | [1.0 overview](https://heggria.github.io/taskflow/en/docs) | 1.0 scope, support, and the security boundary |
214
223
  | [Getting Started](https://heggria.github.io/taskflow/en/docs/getting-started) | First flow and host setup |
215
224
  | [Core Concepts](https://heggria.github.io/taskflow/en/docs/concepts/) | DAGs, isolation, verification, resume, and evidence |
216
225
  | [Compiler & Runtime](https://heggria.github.io/taskflow/en/docs/compiler-runtime/) | JSON, TypeScript DSL, FlowIR, replay, and recompute |
217
226
  | [Host Guides](https://heggria.github.io/taskflow/en/docs/guides/) | Pi, Codex, Claude Code, OpenCode, Grok, and Hermes |
218
227
  | [Examples](https://github.com/heggria/taskflow/blob/main/examples) | Runnable flow definitions, including Trusted Effects |
219
- | [Changelog](https://github.com/heggria/taskflow/blob/main/CHANGELOG.md) | Release history and candidate notes |
228
+ | [Changelog](https://github.com/heggria/taskflow/blob/main/CHANGELOG.md) | Release history and version notes |
220
229
 
221
230
  ## License
222
231
 
@@ -226,6 +235,6 @@ The monorepo contains the host-neutral `taskflow-core`, Trusted Effects and reso
226
235
 
227
236
  **Declare the effect. Verify the path. Commit through one authority.**
228
237
 
229
- [Read the docs](https://heggria.github.io/taskflow/en/docs) · [Try the candidate](#quickstart) · [View releases](https://github.com/heggria/taskflow/releases)
238
+ [Read the docs](https://heggria.github.io/taskflow/en/docs) · [Install Taskflow 1.0](#quickstart) · [View releases](https://github.com/heggria/taskflow/releases)
230
239
 
231
240
  </div>
@@ -0,0 +1,15 @@
1
+ import type { ConcurrencyReservation } from "./schema/coordinator.ts";
2
+ import type { ControlStore } from "./store/store.ts";
3
+ import type { CoordinatorAdmissionDecision, CoordinatorAdmissionObservation, CoordinatorAdmissionProof } from "./store/coordinator-store.ts";
4
+ export declare class ProjectAdmissionService {
5
+ #private;
6
+ constructor(store: ControlStore);
7
+ readAdmission(reservation: ConcurrencyReservation): CoordinatorAdmissionObservation;
8
+ abandonAdmissionIfAbsent(reservation: ConcurrencyReservation): CoordinatorAdmissionDecision;
9
+ admit(reservation: ConcurrencyReservation, expectedRunVersion: number): CoordinatorAdmissionProof;
10
+ /** Called by the host at its dispatch boundary after live authorization and
11
+ * a current coordinator read. This is a binding check, not a replacement for
12
+ * the host's epoch/provider dispatch fence. No await occurs in this check. */
13
+ assertDispatch(reservation: ConcurrencyReservation): CoordinatorAdmissionProof;
14
+ }
15
+ //# sourceMappingURL=admission-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admission-service.d.ts","sourceRoot":"","sources":["../../../taskflow-control/src/admission-service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAuC,MAAM,kBAAkB,CAAC;AAC1F,OAAO,KAAK,EAAE,4BAA4B,EAAE,+BAA+B,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAE7I,qBAAa,uBAAuB;;IAEnC,YAAY,KAAK,EAAE,YAAY,EAA0B;IAEzD,aAAa,CAAC,WAAW,EAAE,sBAAsB,GAAG,+BAA+B,CAIlF;IAED,wBAAwB,CAAC,WAAW,EAAE,sBAAsB,GAAG,4BAA4B,CAG1F;IAED,KAAK,CAAC,WAAW,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,GAAG,yBAAyB,CAMhG;IAED;;kFAE8E;IAC9E,cAAc,CAAC,WAAW,EAAE,sBAAsB,GAAG,yBAAyB,CAY7E;CAQD"}
@@ -0,0 +1,64 @@
1
+ /** Project-side admission arbitration. ADMIT and ABANDON are decisions in the
2
+ * actual ControlStore journal, serialized by its writer fence. No side files or
3
+ * observer callbacks carry admission authority. */
4
+ import { ControlError } from "./errors.js";
5
+ export class ProjectAdmissionService {
6
+ #store;
7
+ constructor(store) { this.#store = store; }
8
+ readAdmission(reservation) {
9
+ this.#binding(reservation);
10
+ const decision = this.#store.readAdmission(binding(reservation));
11
+ return decision ? proof(decision) : null;
12
+ }
13
+ abandonAdmissionIfAbsent(reservation) {
14
+ this.#binding(reservation);
15
+ return proof(this.#store.abandonAdmissionIfAbsent(binding(reservation)));
16
+ }
17
+ admit(reservation, expectedRunVersion) {
18
+ this.#binding(reservation);
19
+ if (reservation.state !== "reserved")
20
+ conflict("admission requires a reserved coordinator binding");
21
+ const decision = this.#store.admitRun(binding(reservation), expectedRunVersion);
22
+ if (decision.status !== "admitted")
23
+ conflict("reservation was durably abandoned; a fresh reservation is required");
24
+ return proof(decision);
25
+ }
26
+ /** Called by the host at its dispatch boundary after live authorization and
27
+ * a current coordinator read. This is a binding check, not a replacement for
28
+ * the host's epoch/provider dispatch fence. No await occurs in this check. */
29
+ assertDispatch(reservation) {
30
+ this.#binding(reservation);
31
+ if (reservation.state !== "committed")
32
+ conflict("dispatch requires a committed coordinator reservation");
33
+ const decision = this.#store.readAdmission(binding(reservation));
34
+ if (!decision || decision.status !== "admitted" || decision.decisionCommitSeq !== reservation.projectAdmitCommitSeq) {
35
+ conflict("dispatch requires the exact durable project admission");
36
+ }
37
+ const run = this.#store.readRun(reservation.runId);
38
+ if (!run || run.status !== "running" || !["admitted", "executing"].includes(run.stage)
39
+ || run.requiresReadmission || run.reservationId !== reservation.reservationId
40
+ || run.projectAdmitCommitSeq !== decision.decisionCommitSeq)
41
+ conflict("run no longer authorizes this dispatch");
42
+ return proof(decision);
43
+ }
44
+ #binding(reservation) {
45
+ const header = this.#store.header;
46
+ if (reservation.projectId !== header.projectId || reservation.projectControlDomainId !== header.controlDomainId) {
47
+ conflict("admission reservation belongs to another project or control domain");
48
+ }
49
+ }
50
+ }
51
+ function proof(decision) {
52
+ const binding = { reservationId: decision.reservationId, projectId: decision.projectId,
53
+ projectControlDomainId: decision.projectControlDomainId, runId: decision.runId, runVersion: decision.runVersion };
54
+ return decision.status === "admitted" ? { ...binding, projectAdmitCommitSeq: decision.decisionCommitSeq }
55
+ : { ...binding, status: "abandoned", abandonmentCommitSeq: decision.decisionCommitSeq };
56
+ }
57
+ function conflict(message) {
58
+ throw new ControlError("TF_ADMISSION_BINDING_CONFLICT", message, { recoveryAction: "operator", sideEffects: "none" });
59
+ }
60
+ function binding(reservation) {
61
+ return { reservationId: reservation.reservationId, projectId: reservation.projectId,
62
+ projectControlDomainId: reservation.projectControlDomainId, runId: reservation.runId };
63
+ }
64
+ //# sourceMappingURL=admission-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admission-service.js","sourceRoot":"","sources":["../../../taskflow-control/src/admission-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /** Bounded approval edits: typed UTF-8 output, or replacement of unstarted
2
+ * downstream phase bodies in the already admitted graph. */
3
+ import { type RunState, type Taskflow } from "taskflow-core";
4
+ import type { ArtifactRef } from "./schema/evidence.ts";
5
+ export declare const MAX_APPROVAL_EDIT_BYTES: number;
6
+ export declare function decodeApprovalEdit(bytes: Uint8Array, artifact: ArtifactRef, kind: "output" | "plan"): string;
7
+ export declare function validateApprovalOutputEdit(state: RunState, phaseId: string, text: string): string;
8
+ export declare function validateApprovalPlanEdit(state: RunState, phaseId: string, candidate: unknown): Promise<{
9
+ flow: Taskflow;
10
+ irHash: string;
11
+ }>;
12
+ //# sourceMappingURL=approval-edits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-edits.d.ts","sourceRoot":"","sources":["../../../taskflow-control/src/approval-edits.ts"],"names":[],"mappings":"AAAA;4DAC4D;AAC5D,OAAO,EAA8F,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzJ,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,eAAO,MAAM,uBAAuB,QAAc,CAAC;AAGnD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAO5G;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAUjG;AAED,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBhJ"}
@@ -0,0 +1,66 @@
1
+ /** Bounded approval edits: typed UTF-8 output, or replacement of unstarted
2
+ * downstream phase bodies in the already admitted graph. */
3
+ import { compileTaskflowToIR, isQuiescentApprovalCheckpoint, transitiveDownstream, validateTaskflow } from "taskflow-core";
4
+ import { contractViolations } from "taskflow-core/contract";
5
+ import { ControlError } from "./errors.js";
6
+ import { commandRequestHash } from "./schema/commands.js";
7
+ export const MAX_APPROVAL_EDIT_BYTES = 1024 * 1024;
8
+ function invalid(message) { throw new ControlError("TF_COMMAND_FAILED", message); }
9
+ export function decodeApprovalEdit(bytes, artifact, kind) {
10
+ if (bytes.byteLength > MAX_APPROVAL_EDIT_BYTES || artifact.storageClass !== "project" || artifact.redactionClass !== "internal")
11
+ invalid("approval edit requires a project/internal artifact of at most 1 MiB");
12
+ if (kind === "output" ? !/^text\/plain(?:;\s*charset=utf-8)?$/i.test(artifact.mediaType) : !/^application\/json(?:;\s*charset=utf-8)?$/i.test(artifact.mediaType))
13
+ invalid("approval edit artifact media type does not match its edit kind");
14
+ let text;
15
+ try {
16
+ text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
17
+ }
18
+ catch {
19
+ return invalid("approval edit must be valid UTF-8");
20
+ }
21
+ if (text.includes("\0"))
22
+ invalid("approval edit must not contain NUL");
23
+ return text;
24
+ }
25
+ export function validateApprovalOutputEdit(state, phaseId, text) {
26
+ const phase = state.def.phases.find(item => item.id === phaseId);
27
+ if (phase?.type !== "approval")
28
+ invalid("output edit target is not an approval phase");
29
+ const output = text.trim();
30
+ if (!output)
31
+ invalid("approval output edit must not be empty");
32
+ // Core approval outputs are text (edit.note), so validate that exact value
33
+ // against its OutputContract before admitting any downstream work.
34
+ const violations = contractViolations(output, phase.expect ?? { type: "string" });
35
+ if (violations.length)
36
+ invalid(`approval output contract failed: ${violations.join("; ")}`);
37
+ return output;
38
+ }
39
+ export async function validateApprovalPlanEdit(state, phaseId, candidate) {
40
+ const check = validateTaskflow(candidate);
41
+ if (!check.ok)
42
+ invalid(`approval plan is invalid: ${check.errors.join("; ")}`);
43
+ if (!state.foregroundOwner?.approvalWait?.includes(phaseId) || !isQuiescentApprovalCheckpoint(state, state.foregroundOwner.approvalWait))
44
+ throw new ControlError("TF_RECONCILE_REQUIRED", "plan edit requires its quiescent approval checkpoint");
45
+ const flow = structuredClone(candidate);
46
+ const { phases: originalPhases, ...originalTop } = state.def, { phases: nextPhases, ...nextTop } = flow;
47
+ if (commandRequestHash(originalTop) !== commandRequestHash(nextTop))
48
+ invalid("plan edit cannot change top-level settings or resource declarations");
49
+ if (commandRequestHash(originalPhases.map(phase => phase.id)) !== commandRequestHash(nextPhases.map(phase => phase.id)))
50
+ invalid("plan edit cannot add, remove, or reorder phases");
51
+ const downstream = new Set(transitiveDownstream(originalPhases, phaseId));
52
+ for (let i = 0; i < originalPhases.length; i++) {
53
+ const previous = originalPhases[i], next = nextPhases[i];
54
+ if (commandRequestHash(previous) === commandRequestHash(next))
55
+ continue;
56
+ if (!downstream.has(previous.id) || state.phases[previous.id] !== undefined)
57
+ invalid("plan edit cannot rewrite completed, active, or non-downstream phases");
58
+ if (commandRequestHash([previous.dependsOn, previous.from, previous.join]) !== commandRequestHash([next.dependsOn, next.from, next.join]))
59
+ invalid("plan edit cannot change phase dependencies or joins");
60
+ }
61
+ const compiled = await compileTaskflowToIR(flow);
62
+ if (!compiled.hash || compiled.usedFallbackHash || compiled.errors.length)
63
+ invalid("edited plan cannot be linked to a content-addressed IR");
64
+ return { flow, irHash: compiled.hash };
65
+ }
66
+ //# sourceMappingURL=approval-edits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-edits.js","sourceRoot":"","sources":["../../../taskflow-control/src/approval-edits.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ import { type CommandRecord, type ControlEventPayload } from "./schema/commands.ts";
2
+ import { type ApprovalRequest, type ApprovalMode, type ApprovalDecision } from "./schema/approval.ts";
3
+ import { type ArtifactRef } from "./schema/evidence.ts";
4
+ import { type BoundFragment } from "./schema/plan.ts";
5
+ import type { RunSnapshot } from "./schema/run.ts";
6
+ import type { ExecutionOwner } from "./schema/te-mirrors.ts";
7
+ import type { ConcurrencyReservation } from "./schema/coordinator.ts";
8
+ export type ApprovalRun = RunSnapshot & {
9
+ runVersion: number;
10
+ boundPlanHash: string;
11
+ boundFragmentHash?: string;
12
+ policyHash: string;
13
+ authorityEpoch: number;
14
+ reservationId?: string;
15
+ owner?: ExecutionOwner;
16
+ };
17
+ export type DurableApprovalRequest = ApprovalRequest;
18
+ export interface ApprovalQuiescence {
19
+ proofId: string;
20
+ projectId: string;
21
+ projectControlDomainId: string;
22
+ runId: string;
23
+ projectAdmitCommitSeq: number;
24
+ providerNoLiveProcessTree: boolean;
25
+ noAmbiguousJobs: boolean;
26
+ noPendingResourceIntents: boolean;
27
+ reconcileTimeoutOnly: boolean;
28
+ }
29
+ export type ApprovalReleaseIntent = {
30
+ kind: "approval.release";
31
+ intentId: string;
32
+ approvalRequestId: string;
33
+ runId: string;
34
+ reservationId: string;
35
+ evidence: ApprovalQuiescence;
36
+ complete: boolean;
37
+ };
38
+ export type ApprovalReadmissionIntent = {
39
+ kind: "approval.readmission";
40
+ intentId: string;
41
+ approvalRequestId: string;
42
+ runId: string;
43
+ reservation: ConcurrencyReservation;
44
+ owner: ExecutionOwner;
45
+ fragment: BoundFragment;
46
+ policyHash: string;
47
+ authorizationContextHash: string;
48
+ projectAdmitCommitSeq: number;
49
+ complete: boolean;
50
+ };
51
+ export type ApprovalOutbox = ApprovalReleaseIntent | ApprovalReadmissionIntent;
52
+ export type ApprovalJournalEvent = {
53
+ eventId: string;
54
+ recordedAt: number;
55
+ payload: ControlEventPayload;
56
+ };
57
+ export interface ApprovalJournalState {
58
+ run: ApprovalRun;
59
+ approvals: DurableApprovalRequest[];
60
+ outbox: ApprovalOutbox[];
61
+ }
62
+ export interface ApprovalMutation extends ApprovalJournalState {
63
+ command?: CommandRecord;
64
+ responseJson?: string;
65
+ events: ApprovalJournalEvent[];
66
+ }
67
+ export interface ApprovalCommit extends ApprovalJournalState {
68
+ commitSeq: number;
69
+ responseJson?: string;
70
+ }
71
+ export type CommandBinding = Pick<CommandRecord, "commandId" | "kind" | "requestHash" | "callerPrincipal" | "projectId" | "controlDomainId">;
72
+ export interface ApprovalStorage {
73
+ readCommittedCommand?(binding: CommandBinding): {
74
+ record: CommandRecord;
75
+ responseJson: string;
76
+ } | undefined;
77
+ readRun(runId: string): ApprovalRun | undefined;
78
+ readApproval(approvalRequestId: string): DurableApprovalRequest | undefined;
79
+ listApprovals(): DurableApprovalRequest[];
80
+ readOutbox(runId: string): ApprovalOutbox[];
81
+ /** Synchronous, writer-locked CAS; journal fsync precedes observable state.
82
+ * The adapter checks runVersion and commits the complete batch atomically. */
83
+ mutateRun(runId: string, expectedRunVersion: number, build: (state: ApprovalJournalState, meta: {
84
+ commitSeq: number;
85
+ }) => ApprovalMutation, binding?: CommandBinding): ApprovalCommit;
86
+ }
87
+ export type ApprovalOperation = "request" | "read" | "decide" | "cancel" | "expire" | "park" | "readmit";
88
+ export type ApprovalAuthorization = {
89
+ callerPrincipal: string;
90
+ authorizationContextHash: string;
91
+ };
92
+ export interface ApprovalAuthority<C> {
93
+ /** Context is issued by the host's trusted identity authority; wire identity
94
+ * labels are never an input to authorization. Must evaluate current policy. */
95
+ authorize(context: C, scope: {
96
+ operation: ApprovalOperation;
97
+ run: ApprovalRun;
98
+ request?: DurableApprovalRequest;
99
+ }): Promise<ApprovalAuthorization>;
100
+ validateRequest(context: C, run: ApprovalRun, nodeInstanceId: string): Promise<void>;
101
+ /** Evaluate actual host offers and this authenticated caller's handshake. */
102
+ negotiateDurability(context: C, run: ApprovalRun, mode: ApprovalMode): Promise<boolean>;
103
+ quiescence(context: C, run: ApprovalRun): Promise<ApprovalQuiescence>;
104
+ validateEdit(context: C, run: ApprovalRun, request: DurableApprovalRequest, edit: {
105
+ kind: "output" | "plan";
106
+ artifact: ArtifactRef;
107
+ }): Promise<void>;
108
+ /** Output edits are contract-checked; plan edits must re-Link. Both obtain
109
+ * current policy/capabilities and a new attenuated BoundFragment. */
110
+ prepareReadmission(context: C, run: ApprovalRun, request: DurableApprovalRequest): Promise<{
111
+ fragment: BoundFragment;
112
+ owner: ExecutionOwner;
113
+ policyHash: string;
114
+ authorizationContextHash: string;
115
+ }>;
116
+ validateReadmission(context: C, run: ApprovalRun, intent: ApprovalReadmissionIntent): Promise<void>;
117
+ reserve(context: C, run: ApprovalRun, owner: ExecutionOwner): Promise<ConcurrencyReservation>;
118
+ commitReservation(context: C, intent: ApprovalReadmissionIntent): Promise<void>;
119
+ normalRelease(context: C, intent: ApprovalReleaseIntent): Promise<void>;
120
+ }
121
+ export interface ApprovalRequestInput {
122
+ runId: string;
123
+ expectedRunVersion: number;
124
+ nodeInstanceId: string;
125
+ mode: ApprovalMode;
126
+ allowedDecisions: ApprovalDecision[];
127
+ owner: string;
128
+ audience?: string[];
129
+ requiredPrincipals?: string[];
130
+ deadline: number;
131
+ timeoutPolicy: ApprovalRequest["timeoutPolicy"];
132
+ }
133
+ export interface ApprovalDecisionInput {
134
+ commandId: string;
135
+ runId: string;
136
+ approvalRequestId: string;
137
+ expectedRunVersion: number;
138
+ decision: ApprovalDecision;
139
+ editArtifactRef?: ArtifactRef;
140
+ editKind?: "output" | "plan";
141
+ }
142
+ export declare class ApprovalService<C = unknown> {
143
+ #private;
144
+ readonly storage: ApprovalStorage;
145
+ readonly authority: ApprovalAuthority<C>;
146
+ constructor(storage: ApprovalStorage, authority: ApprovalAuthority<C>);
147
+ read(context: C, approvalRequestId: string): Promise<DurableApprovalRequest>;
148
+ request(context: C, input: ApprovalRequestInput): Promise<DurableApprovalRequest>;
149
+ decide(context: C, input: ApprovalDecisionInput): Promise<DurableApprovalRequest>;
150
+ expireDue(context: C): Promise<number>;
151
+ cancel(context: C, input: {
152
+ commandId: string;
153
+ runId: string;
154
+ expectedRunVersion: number;
155
+ }): Promise<ApprovalRun>;
156
+ /** Re-prove quiescence after a non-quiescent pause; never infer it from status. */
157
+ park(context: C, input: {
158
+ runId: string;
159
+ expectedRunVersion: number;
160
+ }): Promise<ApprovalRun>;
161
+ /** Terminal status may precede process/TE settlement. Once settlement is
162
+ * proven, discharge capacity without reopening or changing terminal history. */
163
+ releaseTerminal(context: C, input: {
164
+ runId: string;
165
+ expectedRunVersion: number;
166
+ }): Promise<ApprovalRun>;
167
+ drainReleases(context: C, runId?: string): Promise<void>;
168
+ readmit(context: C, input: {
169
+ approvalRequestId: string;
170
+ expectedRunVersion: number;
171
+ }): Promise<ApprovalRun>;
172
+ }
173
+ //# sourceMappingURL=approval-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-service.d.ts","sourceRoot":"","sources":["../../../taskflow-control/src/approval-service.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAyB,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7H,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAKtE,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACtE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,cAAc,CAAC;CAC3F,CAAC;AACF,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAC;AACrD,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,sBAAsB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAClF,qBAAqB,EAAE,MAAM,CAAC;IAAC,yBAAyB,EAAE,OAAO,CAAC;IAAC,eAAe,EAAE,OAAO,CAAC;IAC5F,wBAAwB,EAAE,OAAO,CAAC;IAAC,oBAAoB,EAAE,OAAO,CAAC;CACjE;AACD,MAAM,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IACrF,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;CACvE,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,sBAAsB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IACzF,WAAW,EAAE,sBAAsB,CAAC;IAAC,KAAK,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC;IACpF,UAAU,EAAE,MAAM,CAAC;IAAC,wBAAwB,EAAE,MAAM,CAAC;IAAC,qBAAqB,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;CACvG,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,qBAAqB,GAAG,yBAAyB,CAAC;AAC/E,MAAM,MAAM,oBAAoB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,CAAC;AACzG,MAAM,WAAW,oBAAoB;IAAG,GAAG,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,sBAAsB,EAAE,CAAC;IAAC,MAAM,EAAE,cAAc,EAAE,CAAA;CAAE;AACzH,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAAG,OAAO,CAAC,EAAE,aAAa,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,oBAAoB,EAAE,CAAA;CAAE;AACjJ,MAAM,WAAW,cAAe,SAAQ,oBAAoB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE;AACzG,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,MAAM,GAAG,aAAa,GAAG,iBAAiB,GAAG,WAAW,GAAG,iBAAiB,CAAC,CAAC;AAC7I,MAAM,WAAW,eAAe;IAC/B,oBAAoB,CAAC,CAAC,OAAO,EAAE,cAAc,GAAG;QAAC,MAAM,EAAE,aAAa,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,GAAG,SAAS,CAAC;IAC1G,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAChD,YAAY,CAAC,iBAAiB,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAAC;IAC5E,aAAa,IAAI,sBAAsB,EAAE,CAAC;IAC1C,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAAC;IAC5C;kFAC8E;IAC9E,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAClD,KAAK,EAAE,CAAC,KAAK,EAAE,oBAAoB,EAAE,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,gBAAgB,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,CAAC;CAClI;AACD,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AACzG,MAAM,MAAM,qBAAqB,GAAG;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,wBAAwB,EAAE,MAAM,CAAA;CAAE,CAAC;AAClG,MAAM,WAAW,iBAAiB,CAAC,CAAC;IACnC;mFAC+E;IAC/E,SAAS,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE;QAAE,SAAS,EAAE,iBAAiB,CAAC;QAAC,GAAG,EAAE,WAAW,CAAC;QAAC,OAAO,CAAC,EAAE,sBAAsB,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACnJ,eAAe,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF,6EAA6E;IAC7E,mBAAmB,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxF,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACtE,YAAY,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,sBAAsB,EAAE,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;QAAC,QAAQ,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrJ;yEACqE;IACrE,kBAAkB,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC;QAC1F,QAAQ,EAAE,aAAa,CAAC;QAAC,KAAK,EAAE,cAAc,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,wBAAwB,EAAE,MAAM,CAAC;KACrG,CAAC,CAAC;IACH,mBAAmB,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpG,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC9F,iBAAiB,CAAC,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,aAAa,CAAC,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AACD,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IACtF,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IACxG,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;CAClE;AACD,MAAM,WAAW,qBAAqB;IACrC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAC;IACxF,QAAQ,EAAE,gBAAgB,CAAC;IAAC,eAAe,CAAC,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CACxF;AAsBD,qBAAa,eAAe,CAAC,CAAC,GAAG,OAAO;;IACvC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;IACzC,YAAY,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAKpE;IA6BK,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAIjF;IACK,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAkCtF;IACK,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAwCtF;IAIK,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAe3C;IACK,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAyBtH;IACD,mFAAmF;IAC7E,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAcjG;IACD;oFACgF;IAC1E,eAAe,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAa5G;IACK,aAAa,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB7D;IACK,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CA4BhH;CAuBD"}