Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ All notable changes to taskflow are documented here. This project follows [Keep

## [Unreleased]

## [0.3.0-beta.2] — 2026-08-18

> npm `beta` dist-tag. **Not GA.** Control Plane slice: S2 Unix UDS + S3-min files-only store. Does **not** implement `#137` (`/tf web`) or `#95` (adaptive-authority isolation). TypeBox contracts and `wire-freeze.md` remain **PROPOSED**. `taskflow-control` is **not** in the ten-package publish set (`publishConfig.tag` stays `next`).

### Added

- **ControlHost Unix UDS (S2).** Winner listens on a user-scoped socket; loser attaches and uses the winner fencing epoch. Auto never silently degrades to standalone. Unix-only process tests; not part of the 3-OS process-supervisor matrix.
- **Files-only project ControlStore (S3-min).** Header + `commit-seq.json` + journal + store-self projections; exclusive writer lock; hardened UUID/`wx`/fsync/rename; process-level SIGKILL crash matrix (old-complete | new-complete | fail-closed). `ControlHost.start()` opens `projectStorePath` before dispatch on winner/standalone. Read-only RPCs: `control.store.header`, `control.store.status`. MCP `taskflow_control_status` is **not** added — that would force unpublished `taskflow-control` onto the ten-package face.

### Notes

- Rebased onto `0.3.0-beta.1.1` (`8fab2c9`).
- All publishable surfaces aligned to `0.3.0-beta.2`.
- Ready / merge / tag / npm still require a new instruction.

## [0.3.0-beta.1.1] — 2026-08-18

> Hotfix on `0.3.0-beta.1`. npm `beta` dist-tag. **Not GA.** Does **not** implement `#137` (`/tf web`) or `#95` (adaptive-authority isolation).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

**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.

> **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.
> **Status: 0.3.0-beta.2 — beta channel, not GA.** Ships the Trusted Effects MVP plus a Control Plane slice: Unix UDS ControlHost listen/attach (S2) and a files-only project ControlStore (S3-min). Wire contracts remain **PROPOSED**. `taskflow-control` is workspace-only until a later 11-package decision. Does **not** implement `#137` (`/tf web`) or `#95` (adaptive-authority isolation).

## The 0.3 idea

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

**taskflow 是面向 coding-agent 工作流的声明式运行时。** 它把任务图变成可验证的执行合同,让阶段隔离运行,并把中间过程留在宿主对话之外。在 0.3 candidate 中,这份合同还可以描述每个阶段被允许提出的副作用。

> **状态:0.3.0-beta.1.1 Trusted Effects beta——beta channel,尚未 GA。** 当前 release candidate 已准备发布到 npm 的 `beta` channel;beta 包含下文所述的 Trusted Effects MVP。0.3-C Control Plane 仍是后续 candidate 轨道,不是 beta 已交付的产品表面
> **状态:0.3.0-beta.2——beta channel,尚未 GA。** 含 Trusted Effects MVP,以及 Control Plane 切片:Unix UDS ControlHost listen/attach(S2)和 files-only project ControlStore(S3 最小集)。Wire 合同仍为 **PROPOSED**。`taskflow-control` 在十一包决定之前只在 workspace。不实现 `#137`(`/tf web`)和 `#95`(权限隔离)

## 0.3 的核心想法

Expand Down
6 changes: 3 additions & 3 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Dependency order: `taskflow-mcp-core`, `taskflow-hosts`, `taskflow-dsl`, `pi-tas

## One-time repository setup

The beta release path is `v0.3.0-beta.1.1`: merge the reviewed release commit to `main`, then push the tag. `.github/workflows/publish.yml` validates the `0.3.0-beta.*` prerelease family, publishes the same ten packages to npm's `beta` dist-tag with provenance, and creates a prerelease GitHub Release. Do not publish from a workstation.
The beta release path is `v0.3.0-beta.2`: merge the reviewed release commit to `main`, then push the tag. `.github/workflows/publish.yml` validates the `0.3.0-beta.*` prerelease family, publishes the same ten packages to npm's `beta` dist-tag with provenance, and creates a prerelease GitHub Release. Do not publish from a workstation.

## Pre-flight (always)

Expand Down Expand Up @@ -77,8 +77,8 @@ the matching annotated tag:
```sh
git switch main
git pull --ff-only origin main
git tag -a v0.3.0-beta.1.1 -m "Release v0.3.0-beta.1.1"
git push origin v0.3.0-beta.1.1
git tag -a v0.3.0-beta.2 -m "Release v0.3.0-beta.2"
git push origin v0.3.0-beta.2
```

`.github/workflows/publish.yml` then performs the complete release transaction:
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The runtime has intentional hardening: `realpath`-based path containment, runId
| Version | Support |
|---------|---------|
| Latest stable npm release (`v0.2.10`) | ✅ Active |
| `0.3.0-beta.1.1` beta channel | ⚠️ Pre-release; test-only support |
| `0.3.0-beta.2` beta channel | ⚠️ Pre-release; test-only support |
| Earlier versions | ❌ Unsupported — upgrade to the latest npm release |

## Disclosure
Expand Down
194 changes: 194 additions & 0 deletions docs/internal/0.3.0-beta.2-release-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# 0.3.0-beta.2 — Control Plane 最小可跑增量

> **Status:** APPROVED — 2026-08-13 用户指令「开始,记得用 kanban」。三路审查 APPROVE-WITH-FIXES 已吸收。开工令:从 `origin/main` 拉 `rc/0.3.0-beta.2`,Kanban 链式施工;停在 Draft PR + exact-SHA CI,未经新指令不得 Ready / merge / tag / npm。
> **Date:** 2026-08-13
> **Reviews:** honesty / architecture / release-gate(`deleg_fc8005c7`)
> **Parent:** [0.3-C 作战计划](./0.3-c-control-plane-plan.md) · [P13](./p-adrs/P13-bootstrap-singleton.md) · [P14](./p-adrs/P14-controlstore-engine.md)
> **Baseline:** `origin/main` @ `561cfd3761c683e47fee5aa6d7fb7b26e69c4521`
> **Published beta.1:** annotated tag `v0.3.0-beta.1` **peels to** `561cfd3`(tag object 自身是 `6c75950`,那不是源 commit)。该 merge commit 的 subject 仍写着 candidate / do not publish,是 squash 文案残留,不以它否定 tag。
> **Not GA.** Does not move npm `latest`. Does not ship WebUI, approval, or FileBroker.

本地残留 `rc/0.3.0-trusted-effects` @ `5bbb566` **不是** `origin/main` 祖先。禁止在那棵脏树上继续写。开工命令:

```bash
git fetch origin
git switch -c rc/0.3.0-beta.2 origin/main
```

## 1. One sentence

beta.2 让 Control Plane **第一次能控**:Unix 上一个真 UDS ControlHost + 一份 files-only project store + 至少一次经 TE 提交的声明 `fs.write`;对外仍走 npm `beta`。

「能控」= 能起、能附、能把一次真实 run 记进 store、能经 TE 提交声明写。不是「能起进程、能查状态」。

## 2. Why this cut

| 事实 | 含义 |
|---|---|
| beta.1 已发布 TE MVP | 下一档不该再扩 TE 主线 |
| 0.3-C 已拍板 TE + 重写 Control Plane + WebUI | **拍板的是方向**,不是 wire 已冻结 |
| S2 现状 | 锁 / hello / fencing / TE-only provider / standalone lease / stale-endpoint **单测级已有**;**没有** `node:net` listen/accept,没有打开 project store,`projectStorePath` 未接线,`renewLease` 未挂定时器,`attached` 只是锁层标签 |
| S3–S8 未做 | 不能跳到审批或 WebUI |
| `taskflow-control` 未进十包发布面 | version 仍是 `0.3.0`,`publishConfig.tag: next`,registry E404;description 还写着 “frozen TypeBox wire contracts”,与 `wire-freeze.md` = PROPOSED 矛盾 |

历史分支 `backup/mac-0.3.0-beta.2` **不是**本档方向。

十个已发布包:`taskflow-core`、`taskflow-mcp-core`、`taskflow-hosts`、`taskflow-dsl`、`pi-taskflow`、`codex-taskflow`、`claude-taskflow`、`opencode-taskflow`、`grok-taskflow`、`hermes-taskflow`。

## 3. Decisions locked by review

原 §9 四问不再开放:

| Q | 决定 |
|---|---|
| P14 Status | **保持 Proposed**(wire 层)。本档只批准 **S3 store 引擎实施门**。可在 P14 加一行「beta.2 已批 S3 实施门」,不改 ADR Status。P15 完全不碰。 |
| 发布面 | **条件十一包**。仅当 tag 前 tarball dogfood(A8-pre)过线,才把 `taskflow-control@0.3.0-beta.2` 纳入发布面。否则只发十包,control 继续 workspace-only。禁止 `0.3.0` / `next` 出包。 |
| Dogfood 深度 | **必须**至少一次声明 `fs.write`,经 TE resources 提交(声明根内写 marker)。只读状态查询不够。 |
| S3 事件最小集 | **必须**能追加至少一条非审批 `CommandRecord`。默认载体 = A8 那次真实 run 的 `run.submit` + 同批 ControlEvents。不实现 admission、不签 Receipt、不用 approval kind。空 journal 会使 A4/A5/P14 原子批门空转。 |

另锁:

- **Registry / UserCoordinatorStore(P16 store)推迟。** 作战计划 S3 的后两块不进 beta.2。P13 `auto`「确保 registry」本档只部分满足,必须在诚实账本里写明。
- **`projections/`** 本档只重建 store 自身投影(header / commit-seq / 已提交 command 索引),不做 run 视图投影(那是 S4/S6)。

## 4. In scope

只收 **S2 收口 + S3 最小集**。

### 4.1 S2 收口 — 真 UDS 进程

已有、本档只做**进程级验证**(不是重写):禁 `auto→standalone` 静默回退;ExecutionProvider 只能 TE-backed。

必须新做:

1. Unix UDS **server**:`listen` / `accept` 绑定 `singletonPaths` 的 endpoint。
2. 败者是 **client `connect`**,走线上 hello,拿到赢者 fencing epoch。禁止只改锁层标签就叫 attach。
3. 线上 hello-before-RPC + `protocolMajor` 偏差拒绝(P13 §5.5)。
4. 两**进程**竞争同一 user singleton lock + 同一 endpoint;输者 attach 赢者,禁止 silent fork。
5. 杀赢者后 stale socket → unlink → 新进程可重新 `listen`。
6. `renewLease()` 挂定时器(代码已注明 S3 接线)。
7. socket 权限显式 `0o600`(不要只靠 umask)。
8. Unix UDS 是本档必过平台。Windows named pipe **非交付**。

### 4.2 S3 最小集 — 一份 project ledger

1. files-only ControlStore:`header` + `commit-seq.json` + `journal/` + `projections/`。`commands/` / `receipts/` 可建空目录,**不签发 Receipt、不跑审批命令**。
2. Header:`{ projectId, controlDomainId, schemaVersion, directoryBinding }`。
3. `commitSeq` 单调且永不重编号(P11)。
4. daemon / embedded / standalone 打开 **同一** project store。`projectStorePath` 必须在 `ControlHost.start()` 真正打开,且在 dispatch 前完成。
5. 单写者;第二写者对 store mutation fail closed。
6. 至少一种非审批 `CommandRecord`(`run.submit`)与其 events **同批原子提交**。
7. 崩溃恢复:重读 journal → 重建本档允许的投影;禁止未验证混合态。
8. P14 实施门本档收:原子批 crash 矩阵;temporary-path symlink 硬化(随机 UUID + 独占 `wx` + EEXIST 重试;rename 目标被换成 symlink → fail closed);recovery-racing-mutation fail closed。
9. 信任模型保持 trusted-local-disk;整根一致回滚 **不承诺**。
10. Control 可以写 **control 元数据**(`~/.taskflow/control/` lock/lease/claim/socket + project store)。**不得**写 run 声明的最终路径;那只经 `taskflow-core` resources。

### 4.3 宿主 / 发布

1. 从 `origin/main`(`561cfd3`)拉 `rc/0.3.0-beta.2`。
2. 十包版本面跟到 `0.3.0-beta.2`。下列 pin **必须**同步,否则 `publish.yml` tag 校验必挂:
- `packages/*/plugin/plugin.json`(codex / claude / grok)
- `packages/*/plugin/.mcp.json`(codex / claude / grok)
- `packages/opencode-taskflow/plugin/opencode.json`
- `packages/hermes-taskflow/plugin/hermes.config.snippet.yaml`
3. `taskflow-control`:同一提交把 `version` 改为 `0.3.0-beta.2`,`publishConfig.tag` 改为 `beta`,`description` 去掉 “frozen”,改成 proposed / planned。**无论是否进 npm 都必须改**,避免 0.3.0 游离。
4. `publish.yml` 的 `0.3.0-beta.*` 闸门 **已经**放行 beta.2。两条路径写死:
- **十包:** workflow 零功能改动,只改注释 / `RELEASE.md` 示例。
- **十一包:** 同一 release commit 扩 `RELEASE_PACKAGE_NAMES`、`publish.yml` 版本循环 / `publish_one` / `verify_one`、`smoke-packed-packages.mjs`、release-notes 兜底。走 Draft PR 人工闸门。
5. 发布决策在 **A8-pre(tarball dogfood)之后、打 tag 之前** 冻结,避免「npm 上还没有 beta.2,却要用 `@beta` 决定是否发 control」的循环。

## 5. Out of scope(硬禁区)

- S4 完整 BoundPlan admission / maxActiveRuns 竞争 / reconcile-unknown 终态协议
- S5 审批三模式 / park / CAS
- S6 完整 MCP/CLI 控制面(本档最多加 **只读** host status + store header)
- S7 WebUI
- S8 / L6 GA / npm `latest` / 正式 `0.3.0`
- Secret vault / live ServiceRef
- FileBroker / OS sandbox
- Adaptive / Retain / CharterArc 晋级
- Windows named pipe ControlHost(lock-file 协调可做;pipe **non-GA**,release notes 必须写明)
- Registry 多 mount / UserCoordinatorStore 引擎
- 搬 `feat/0.3.0` 或 `backup/mac-0.3.0-beta.2` 的旧代码

## 6. Acceptance

全部必须有命令级证据。文档绿不算过。

| ID | 门槛 | 证据 |
|---|---|---|
| A1 | TE 8 deliverables 不回退 | Draft PR 的 **exact-SHA 全矩阵**:unit + `e2e-codex-mcp-full` + packed consumer + process-supervisor 3 OS。live Codex CLI @ `4524d2d` 只算 beta.1 历史证据,不为 beta.2 背书,本档不重跑。 |
| A2 | 两进程 UDS | Unix-only CI job(**不得**进 Windows process-supervisor 腿):进程 A listen;进程 B connect + 线上 hello + 拿到 epoch;杀 A 后 stale socket 恢复;`auto` 不能静默变 `standalone`。 |
| A2b | 线上控制面 | 赢者经 UDS 回答 `control.probe`(或等价只读 RPC);败者经 socket 收到同一 `fencingEpoch`。锁层标签不够。 |
| A3 | 同一 store | standalone 写入 header / journal / 至少一条 `run.submit` 后,第二次以 daemon/embedded 打开读到同一 `projectId` / `commit-seq`。 |
| A4 | 崩溃矩阵 | **进程级 SIGKILL**,不是抛异常 seam。注入点:① header 已 fsync、journal 未开始;② journal 追加中;③ projection 重建中。每点重启后只能是:旧完整态 **或** 新完整态 **或** fail-closed(拒绝打开 / 拒绝 mutation,可观察)。禁止混合态。 |
| A5 | 单写者 | 第二进程对同一 store 的 mutation 被拒绝。 |
| A6 | 权威边界 | 声明 `fs.write` 最终路径只经 `taskflow-core` resources。control 源码对 `writeFile`/`appendFile`/`createWriteStream` 的命中必须落在 control 元数据白名单(lock/lease/claim/socket/store),并用测试钉住。`resources/*` 语义本档不改。 |
| A7 | 打包 | typecheck + build + `test:pack`。若十一包:fresh consumer 能 import `taskflow-control@0.3.0-beta.2`。 |
| A8-pre | tag 前 dogfood | 用 `.release-tarballs` 里的 hermes-taskflow tarball 装进 scratch Hermes profile:`taskflow_version` = `0.3.0-beta.2`;list / verify / run;**一次声明 `fs.write` 经 TE 提交**;能读 host status + store header。CI 以 built-MCP fixture 为主。 |
| A8-post | 发布后核验 | `verify-published-package` + `npm view` 十包(或十一包)`beta=0.3.0-beta.2`。live Hermes `@beta` 复验可选,人工。 |
| A9 | 发布诚实 | `latest` 仍为 `0.2.10`;GitHub Release = prerelease;release notes 写 Windows pipe non-GA + resolve-only 不是 OS sandbox + 无审批/Receipt/WebUI + Registry/P16 store 未交付。 |

已知 Windows process-supervisor 抖动 **不进入** beta.2 新门槛;既有 3-OS job 只回归 TE,不跑 UDS。

## 7. Honesty ledger

**允许:**

- Trusted Effects MVP 已在 `0.3.0-beta.1`(tag peel = `561cfd3`)。
- beta.2 是 Control Plane **最小可跑**增量。
- Unix 上可以起 UDS ControlHost,败者线上 attach,一份 project store,单写者,崩溃 fail-closed。
- Control 写自己的 lock/store 元数据;run 声明写仍只经 TE。
- Resolve-only 不是 OS sandbox;未声明路径仍取决于宿主策略。
- Windows ControlHost / named pipe 不是本档交付。
- Registry 与 UserCoordinatorStore 未交付。

**不许:**

- “Control Plane 已完成 / 已冻结 / 已 GA”
- “可审批 / 有 Receipt / 有 WebUI”
- “FileBroker / OS sandbox”
- “Windows named pipe 已交付”
- 把 P8 / P14 / P15 的 **Proposed** 写成 Accepted
- 把 `wire-freeze.md` 偷偷改成 frozen,却没有 TypeBox + 测试证据
- 把锁层 `attached` 说成已经有 UDS attach
- 把常量 `printf` run 说成「能控」

## 8. Implementation sequence

1. **基线** — `git switch -c rc/0.3.0-beta.2 origin/main`。刷新 scoreboard:header 日期/tip;L5 对 **beta.1** 改 PASS(tag + publish run `31621938101`);L6 仍 FAIL;L4 live-Codex 标 historical。
2. **S2 进程化** — UDS listen/accept/connect + 线上 hello + 进程级 A2/A2b。Unix-only CI job。
3. **S3 store** — `packages/taskflow-control/src/store/**`。接上 `projectStorePath` 与 lease timer。先过 A3–A6。
4. **宿主只读表面** — Hermes/MCP 暴露 host status + store header;确认 `test:e2e-hermes-mcp` 覆盖新工具。不把审批/Receipt 标成可用。
5. **诚实性文案** — README / CHANGELOG / SECURITY / website / `RELEASE.md` / `publish.yml` 头注释;**必须改** `packages/taskflow-control/package.json` description。
6. **版本面** — 十包 + pin 文件 + control version/tag。
7. **A8-pre** — tarball scratch dogfood(含声明写)。这时才决定十包还是十一包。
8. **人工闸门** — Draft PR → 审查 → 用户解锁 Ready → squash merge → **merged SHA 全矩阵绿** → 人工推 `v0.3.0-beta.2` → 只走 `publish.yml` → A8-post。

预估:S2 收口 2–3d,S3 最小集 3–4d,宿主+文案+发布链 1–2d。上限切片,不是日历承诺。

## 9. Files likely to change

- `packages/taskflow-control/src/control-host.ts`
- `packages/taskflow-control/src/singleton.ts`
- `packages/taskflow-control/src/store/**`(新)
- `packages/taskflow-control/test/**`(含 Unix 进程级)
- `packages/taskflow-control/package.json`(version / tag / description)
- `packages/taskflow-mcp-core` / `packages/hermes-taskflow`(只读状态工具)
- 宿主 pin:上述 plugin.json / `.mcp.json` / `opencode.json` / `hermes.config.snippet.yaml`
- 若十一包:`scripts/pack-release-packages.mjs`、`.github/workflows/publish.yml`、`scripts/smoke-packed-packages.mjs`
- `docs/internal/0.3.0-ga-scoreboard.md`、`CHANGELOG.md`、`RELEASE.md`、公开 README/website
- `docs/internal/p-adrs/P14-controlstore-engine.md`(只加「beta.2 已批 S3 实施门」一行)

不改:`packages/taskflow-core/src/resources/**` 的权威语义,除非发现 beta.1 回归。

## 10. Agent stop line

Status 已是 **APPROVED**。允许按 §8 开工。

本档施工停在:

- Draft PR + exact-SHA CI
- 诚实 scoreboard(L6 仍 FAIL)

未经新的人工指令,禁止 Ready / merge / tag / npm / 把 beta.2 写成 GA。
Loading
Loading