Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
e69e8ea
docs: approve 0.3.0-beta.2 control-plane slice plan
Aug 13, 2026
ce058e3
feat(control): Unix UDS ControlHost listen/attach (beta.2 S2)
Aug 13, 2026
e4bc49b
feat(control): files-only project ControlStore (beta.2 S3)
Aug 18, 2026
bee8586
docs: freeze 0.3.0-beta.2 and honest Control Plane slice claims
Aug 18, 2026
8f7909b
docs: refresh 0.3 scoreboard after beta.2 Draft PR #142 CI
Aug 18, 2026
4bf3b50
fix(pi): expose owning Taskflow run identity to children
heggria Sep 30, 2026
57f2e5c
fix(ci): consolidate dependency upgrades and retain deep scans
heggria Sep 30, 2026
19da0e2
fix(control): harden draft persistence and merge current main
heggria Sep 30, 2026
ee455ef
Merge remote-tracking branch 'origin/fix/maintenance-dependencies-act…
Oct 2, 2026
12a327e
Merge remote-tracking branch 'origin/fix/pi-run-identity-172' into re…
Oct 2, 2026
a332b42
fix(control): isolate projects and preserve failed journals
Oct 2, 2026
dadef9f
test(control): cover existing project attach rejection
Oct 2, 2026
3637013
feat: prepare complete Taskflow 1.0 release and repair Pi lifecycle r…
Oct 2, 2026
008f403
fix: close release security gates and date authorized 1.0 release
Oct 2, 2026
170dc8d
docs: finalize Taskflow 1.0 installation and support contract
Oct 2, 2026
5dec238
fix(control): harden transport and preserve uncertain execution state
Oct 2, 2026
fb73309
fix(runtime): persist checkpoints and safely recover interrupted appr…
Oct 2, 2026
7467f64
test(control): budget for sequential malformed UDS clients
heggria Oct 3, 2026
c9cde1d
docs(release): reconcile PR 142 with the unreleased 1.0 track
heggria Oct 7, 2026
1c8886e
chore(control): preserve owner work for isolated full-A recovery
Oct 7, 2026
04e96ad
feat(control): add durable evidence and fenced receipt storage
Oct 2, 2026
6c87cec
feat(control): add authenticated loopback console surface
Oct 2, 2026
57c93ca
fix(control): fence evidence disclosure and detect path replacement
Oct 3, 2026
a5a07fc
fix(control): revalidate console sessions across asynchronous work
Oct 3, 2026
0c0df53
fix(core): bind persistent mutex queues and ticket cleanup
Oct 3, 2026
4687b54
fix(core): recover interrupted mutex initialization safely
Oct 3, 2026
ef96e37
test(control): preserve public malformed-client watchdog limits
Oct 7, 2026
a98e386
feat(control): complete durable multi-project execution and recovery
Oct 7, 2026
40f61a3
merge(release): reconcile PR 142 with full control candidate
Oct 8, 2026
c9a2fba
merge(main): retain landed identity fix and scan diagnostics
Oct 8, 2026
7048c79
test: generate ephemeral security fixture values
Oct 8, 2026
ca247ac
test: generate remaining synthetic owner and result fixtures
Oct 8, 2026
472bb98
fix(control): close operator delivery and Pi compatibility gaps
Oct 8, 2026
0c008be
docs(release): reconcile final 1.0 implementation and authorization
Oct 8, 2026
086185b
fix(release): close audit findings and prepare dated 1.0 notes
Oct 8, 2026
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
70 changes: 58 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: "22"
Expand Down Expand Up @@ -53,7 +53,7 @@ jobs:

# pnpm via corepack — the version is pinned by the `packageManager` field
# in package.json, so every contributor and CI run use the same pnpm.
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
Expand All @@ -70,14 +70,57 @@ jobs:
- name: Unit tests
run: pnpm test

pi-peers:
name: pi adapter (SDK ${{ matrix.pi }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
pi: ["0.80.3", "0.85.1", "1.0.4"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: "22"
cache: "pnpm"
- name: Install locked dependencies
run: pnpm install --frozen-lockfile --registry https://registry.npmjs.org/
# The regular Node 22/24 suite and packed smoke retain locked 1.0.0 peers.
# Change only this disposable job's adapter peers; verify their direct
# resolution before claiming the selected SDK was actually exercised.
- name: Install exact adapter peers
run: >-
pnpm --filter pi-taskflow add --save-dev --save-exact
@earendil-works/pi-agent-core@${{ matrix.pi }}
@earendil-works/pi-ai@${{ matrix.pi }}
@earendil-works/pi-coding-agent@${{ matrix.pi }}
@earendil-works/pi-tui@${{ matrix.pi }}
--registry https://registry.npmjs.org/
- name: Verify resolved SDK and run complete adapter suite
run: pnpm run test:pi:peers
env:
PI_TEST_PEER_VERSION: ${{ matrix.pi }}
- name: Build core and Pi extension against selected SDK
run: |
pnpm --filter taskflow-core build
pnpm --filter pi-taskflow build
- name: Real Pi compatibility and MCP allowlist controls
run: node --experimental-strip-types packages/pi-taskflow/test/e2e-pi-compat.mts
- name: Real Pi 1.0.4 lifecycle, approvals, usage, and crash recovery
if: matrix.pi == '1.0.4'
run: |
pnpm run test:e2e-pi
pnpm run test:e2e-pi-crash-resume

e2e:
# Required status context: keep this literal stable; the job now covers all MCP hosts.
name: e2e (codex MCP, network-free)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
Expand All @@ -93,6 +136,9 @@ jobs:
- name: Build all packages
run: pnpm run build

- name: DSL built and clean-installed CLI E2E
run: pnpm --filter taskflow-dsl run test:e2e

# The codex MCP e2e spawns the real bin over stdio and drives the full
# handshake + tool calls — no live model / no network. The other e2e
# (test:e2e-codex) needs a live codex session, so it stays manual.
Expand Down Expand Up @@ -133,7 +179,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
Expand All @@ -155,7 +201,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
Expand All @@ -172,10 +218,10 @@ jobs:
- name: Build, pack, install, and smoke test all published packages
run: pnpm run test:pack

# Private CharterArc is not a release package. Still pack it with its
# only dependency and smoke defineProject/runProject from a clean npm
# consumer so the private artifact stays directly runnable.
- name: Pack and smoke private CharterArc consumer
# CharterArc retains its separate experimental release. Pack it with its
# dependencies and smoke defineProject/runProject from a clean npm
# consumer without adding it to the ten stable release packages.
- name: Pack and smoke experimental CharterArc consumer
run: pnpm run test:pack-charterarc

website:
Expand All @@ -187,7 +233,7 @@ jobs:
# The docs source records last-modified timestamps from git history.
fetch-depth: 0

- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
Expand All @@ -213,7 +259,7 @@ jobs:
security-events: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4
- uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
with:
languages: javascript-typescript
- uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4
- uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
4 changes: 2 additions & 2 deletions .github/workflows/deploy-website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
# in the root package.json, so CI uses the same pnpm as local dev. The
# website is a pnpm workspace member (pnpm-workspace.yaml), so one
# `pnpm install` at the root installs every package including the website.
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
Expand Down Expand Up @@ -76,4 +76,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
15 changes: 13 additions & 2 deletions .github/workflows/plugin-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,29 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- uses: hashgraph-online/ai-plugin-scanner-action@55616c962cf86368423f7673b2ecdfdbe613d1af # v1
- uses: hashgraph-online/ai-plugin-scanner-action@484da6f8e99a057233b939ab50450a14a68f5a1c # v1.2.624
with:
plugin_dir: "."
mode: scan
# v1.2.624 makes Cisco opt-in; retain the previous deep-scan coverage.
install_cisco: "true"
cisco_skill_scan: "on"
cisco_policy: balanced
online: "false"
submission_enabled: "false"
pr_comment: "off"
format: json
output: plugin-security-report.json
pr_comment: "off"
min_score: 80
fail_on_severity: high
# Always print the full finding payload, even when the gate fails. Keep
# detailed evidence in this job rather than suppressing or baselining it.
- name: Show complete scanner findings
if: always()
run: |
if [ -f plugin-security-report.json ]; then
cat plugin-security-report.json
fi
- name: Require completed Cisco deep scanning
if: always()
run: node scripts/verify-plugin-scan-coverage.mjs plugin-security-report.json
2 changes: 1 addition & 1 deletion .github/workflows/publish-charterarc-experimental.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
echo "PUBLISH_SHA=$TAG_COMMIT" >> "$GITHUB_ENV"
echo "Verified $EXPECT at $TAG_COMMIT is reachable from origin/main"

- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: "22"
Expand Down
16 changes: 11 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
exit 1
fi
echo "Verified $GITHUB_REF_NAME at $TAG_COMMIT is reachable from origin/main"
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: "22"
Expand All @@ -58,6 +58,9 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile --registry https://registry.npmjs.org/

- name: Verify complete release contract
run: node scripts/verify-release-contract.mjs --published

- name: Typecheck
run: pnpm run typecheck

Expand Down Expand Up @@ -88,8 +91,8 @@ jobs:
exit 1
fi
VERSION="${TAG#v}"
if [[ "$VERSION" == *-* && "$VERSION" != 0.3.0-beta.* ]]; then
echo "::error::Only 0.3.0-beta.* prereleases are supported by this beta workflow (got $VERSION)"
if [[ "$VERSION" == *-* && ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-beta\.[0-9]+(\.[0-9]+)*$ ]]; then
echo "::error::Only numbered beta prereleases are supported by this workflow (got $VERSION)"
exit 1
fi
if grep -Fqx "## [$VERSION] — Unreleased" CHANGELOG.md; then
Expand Down Expand Up @@ -243,6 +246,9 @@ jobs:
verify_one opencode-taskflow
verify_one grok-taskflow
verify_one hermes-taskflow
# Artifact existence/provenance is insufficient when a registry tag
# was changed. Fail closed before the dependent GitHub Release job.
node scripts/verify-release-dist-tags.mjs "$VERSION" "$NPM_TAG"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_TRUSTED_OWNERS: "heggria,muyun"
Expand Down Expand Up @@ -284,8 +290,8 @@ jobs:
if RELEASE_JSON="$(gh api "repos/${GITHUB_REPOSITORY}/releases/tags/${TAG_PATH}" 2>"$ERROR_FILE")"; then
RELEASE_TAG="$(jq -er '.tag_name' <<<"$RELEASE_JSON")"
RELEASE_TARGET="$(jq -er '.target_commitish' <<<"$RELEASE_JSON")"
RELEASE_DRAFT="$(jq -er '.draft' <<<"$RELEASE_JSON")"
RELEASE_PRERELEASE="$(jq -er '.prerelease' <<<"$RELEASE_JSON")"
RELEASE_DRAFT="$(jq -er '.draft | if type == "boolean" then tostring else error("release draft must be boolean") end' <<<"$RELEASE_JSON")"
RELEASE_PRERELEASE="$(jq -er '.prerelease | if type == "boolean" then tostring else error("release prerelease must be boolean") end' <<<"$RELEASE_JSON")"
if [ "$RELEASE_TAG" != "$GITHUB_REF_NAME" ]; then
echo "::error::Existing release tag $RELEASE_TAG does not match $GITHUB_REF_NAME"
exit 1
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ dist/
# Generated at build time from the root README (single source of truth)
packages/*/README.md
!packages/charterarc/README.md
packages/taskflow-mcp-core/CONTROL_GUIDE.md

# Runtime state (never commit)
data/
Expand Down
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,47 @@ All notable changes to taskflow are documented here. This project follows [Keep

- HOL plugin-scanner highs: dummy test credentials use scanner placeholders / short literals; no `eval (` in comments; smoke/runner no longer place a `${…}` template within 30 chars of `spawn`. Local scan 81/100, 0 high. **Not GA.**

## [1.0.0] — 2026-10-08

### Added

- Authenticated multi-project Control Plane: durable project/domain registry, real runtime admission, global concurrency reservations, command-result replay, scoped artifacts, terminal Receipts and evidence explanations.
- Durable approval park/CAS, output and plan edits, restart readmission, and local WebUI for runs, approvals and evidence. Plan edits preserve the DAG.
- Public `taskflow-control` and `taskflow-project-admin` binaries bundled in `taskflow-mcp-core`, including fresh default-auto bootstrap and an installed guide. The release remains ten public packages; the private control source workspace is not a runtime dependency.
- Explicit operator provisioning with a separate credential and live project policy. CLI/MCP capacity changes and acknowledged force release retain durable audit/replay; forced release marks accounting operator-overridden without claiming execution stopped or creating a terminal Receipt.

### Fixed

- Preserve project isolation, reject corrupt or identity-less ledgers without overwriting them, and isolate malformed/bounded UDS clients. Validate copied/moved/replaced store identities before recovery.
- Retain monotonic singleton fencing across crash recovery and graceful restart; validate complete legacy coordinator evidence before migrating homes without an epoch floor.
- Let Pi finish transient retries and compaction before terminal failure, count tool-reported usage once, and use supported RPC approval dialogs with cancellation and unavailable-dialog rejection.
- Persist every Pi/MCP checkpoint. Recover approval checkpoints only after proven dead ownership, matching physical project identity and a safe DAG barrier; fork a new run and preserve parent bytes.
- Restrict ambient Pi 1.0.4 MCP server and native resource tools for explicit tool allowlists while preserving explicit selectors. Actual 0.80.3/0.85.1/1.0.0/1.0.4 compatibility evidence is versioned separately.
- Preserve deterministic ten-package packing, exact internal dependency pins, npm owner/provenance/source/integrity verification and release dist-tag gates. Release reruns verify existing artifacts rather than replacing them.

### Support boundaries

- The existing twelve-phase DAG runtime, TypeScript DSL, planning, retry/budget contracts, context isolation, background execution, resume/recompute/replay and declared filesystem resource transactions remain the stable contract.
- Pi interactive approval and the separate authenticated Control MCP durable-approval route are supported. Ordinary host MCP/headless approval phases reject automatically. Grok rejects budgets when usage is unavailable.
- Control uses Unix UDS; Windows named pipes remain non-GA. Resolve-only containment is not an OS sandbox. Unknown effects retain capacity unless explicitly overridden; arbitrary in-flight recovery is not promised.
- Secret/service references have no live backend. Event-kernel fallback and physical journal capacity limits remain explicit. Unavailable live hosts are recorded as unverified rather than inferred from fixtures.
- Final source/installed verification and release records are tracked in `docs/internal/1.0.0-ga-scoreboard.md`. A dated changelog alone does not establish completed npm or GitHub publication.

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

> **Historical unpublished candidate; superseded by the 1.0.0 target above.** The intended channel was npm `beta`; no `v0.3.0-beta.2` tag or publication occurred. **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.2] — 2026-08-20

> Hotfix on `0.3.0-beta.1.1`. npm `beta` dist-tag. **Not GA.** Does **not** implement `#137` (`/tf web`) or `#95` (adaptive-authority isolation). Does **not** steal `0.3.0-beta.2`.
Expand Down
Loading
Loading