Skip to content
Merged
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
11 changes: 9 additions & 2 deletions .codex/release-gate.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ env = { ACPX_NPM_CACHE = "/tmp/codex-acpx-release-npm-cache", NPM_CONFIG_CACHE =
[[stages]]
name = "co-engineer-unit"
kind = "unit_tests"
command = ["npm", "--prefix", "plugins/plumbob-harness-control", "test"]
command = ["npm", "--prefix", "plugins/codex-co-engineer", "test"]
failure_class = "product_test_failed"
timeout_seconds = 300
quiet_seconds = 30
Expand Down Expand Up @@ -61,6 +61,13 @@ command = ["node", "scripts/process-boundary-preflight.mjs"]
failure_class = "environment_blocked"
timeout_seconds = 30

[[stages]]
name = "codex-mcp-environment"
kind = "integration_tests"
command = ["node", "scripts/mcp-environment-preflight.mjs"]
failure_class = "environment_blocked"
timeout_seconds = 30

[[stages]]
name = "acpx-reproducible-build"
kind = "build"
Expand All @@ -80,7 +87,7 @@ env = { ACPX_NPM_CACHE = "/tmp/codex-acpx-release-npm-cache", NPM_CONFIG_CACHE =
[[stages]]
name = "co-engineer-package-inventory"
kind = "artifact_verification"
command = ["npm", "pack", "./plugins/plumbob-harness-control", "--dry-run", "--ignore-scripts", "--offline", "--json"]
command = ["npm", "pack", "./plugins/codex-co-engineer", "--dry-run", "--ignore-scripts", "--offline", "--json"]
failure_class = "product_test_failed"
timeout_seconds = 60

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ jobs:
- run: node scripts/release-prerequisites.mjs
- run: node scripts/validate-release.mjs
- run: npm --prefix tools/acpx-vendor ci --ignore-scripts --no-audit --no-fund
- run: npm --prefix plugins/plumbob-harness-control test
- run: npm --prefix plugins/codex-co-engineer test
- run: npm --prefix plugins/cursor-cloud-control test
- run: npm --prefix tools/acpx-vendor run test:publish-provenance
- run: node scripts/inspector-preflight.mjs
- run: npm --prefix tools/acpx-vendor run test:reproducible
- run: npm --prefix tools/acpx-vendor run verify:publish-provenance
- run: npm pack ./plugins/plumbob-harness-control --dry-run --ignore-scripts --offline --json
- run: npm pack ./plugins/codex-co-engineer --dry-run --ignore-scripts --offline --json
- run: npm pack ./plugins/cursor-cloud-control --dry-run --ignore-scripts --offline --json
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,48 @@

## [Unreleased]

## [3.0.2] - 2026-08-19

### Fixed

- Project a compact live `last_event` / `progress` snapshot from the
append-only event log so `task` and `status` no longer stay stale while
ACP workers are streaming. `task.json` is still not rewritten on every
text delta.
- Extend `task` with optional bounded `wait_ms` and `cursor` wait
arguments so Codex can wait for meaningful progress or a terminal state
instead of hammering empty polls. Waits are event-driven; text deltas
are coalesced and event-log catch-up is memory-bounded. Unsolicited
stdio callbacks across assistant turns are not available.
- Read the configured `remote.origin.url` for Cursor Cloud so host
`insteadOf` credential rewrites cannot leak into receipts or fail
dispatch.

### Changed

- Adopt `codex-co-engineer` as the package, plugin, MCP server, skill, and
repository-path identifier. Human-facing branding is Codex-Co-Engineer.
- Remove leftover environment fallbacks and vendor package names from the
previous identity.
- Rewrite the root and plugin READMEs around the current 3.x supervisor,
provider matrix, workspace model, and discovery/install paths.

## [3.0.1] - 2026-08-19

### Fixed

- Forward the user-session runtime and D-Bus locators required by transient
`systemd --user` services when Codex applies the plugin environment
allowlist.
- Report local process-boundary readiness through `status` and fail local
providers closed before creating a worktree, task receipt, or prompt file.
- Wait for the `systemd-run` client result so queueing failures are classified
accurately instead of surfacing as a later unit-inspection failure.
- Keep the stdio server alive while its newly connected client prepares the
first JSON-RPC frame.
- Exercise the exact manifest-filtered MCP environment in the authoritative
release gate.

## [3.0.0] - 2026-08-19

### Added
Expand Down
7 changes: 4 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ host boundary.

```bash
node --version
npm --prefix plugins/plumbob-harness-control test
npm --prefix plugins/codex-co-engineer test
node scripts/validate-release.mjs
node scripts/inspector-preflight.mjs
git diff --check
Expand All @@ -32,8 +32,9 @@ after the provider-free gate.

## Public contract

- Preserve `plumbob-harness-control` as the stable MCP identifier and keep
the five-tool surface small.
- Preserve `codex-co-engineer` as the stable MCP/package identifier, present
the product as Codex-Co-Engineer, and keep the five-tool surface small.
Extend `task` in place for live wait/progress; do not add a sixth tool.
- Local tasks use ACP first and may use the same provider's CLI only when ACP
fails before prompt dispatch. Never replay an accepted prompt.
- `workspace_mode: "managed"` is the default for local tasks and creates one
Expand Down
178 changes: 115 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,57 @@
# Codex-Co-Engineer

Codex-Co-Engineer is a small stdio MCP supervisor that lets Codex delegate
real review and implementation work to authenticated peer coding agents:

- Grok Build on the local host
- Cursor Local
- Cursor Cloud
- DeepSeek Harness (DSH) with Muse Spark

Codex remains the chief engineer, reviewer, and merge authority. Providers
retain their normal coding capabilities, persistent logins, shell access, and
dependency installation. Co-Engineer adds lifecycle tracking, optional local
worktree isolation, bounded cancellation, and useful receipts—not another
sandbox or policy engine.

The stable plugin identifier is `plumbob-harness-control`. Version 3 exposes
five tools: `status`, `delegate`, `task`, `tasks`, and `cancel`.
**Codex-Co-Engineer** is a small stdio [MCP](https://modelcontextprotocol.io/)
supervisor that lets Codex delegate real review and implementation work to
authenticated peer coding agents.

Codex stays the chief engineer, reviewer, and merge authority. The peers keep
their normal coding capabilities, persistent logins, shell access, and
dependency installation. Codex-Co-Engineer adds lifecycle tracking, optional
local worktree isolation, bounded cancellation, and inspectable receipts. It
is not another sandbox or policy engine.

The stable machine identifier is `codex-co-engineer`. The bundled skill is
`control-codex-co-engineer-agents`. Version 3.0.2 exposes five tools:
`status`, `delegate`, `task`, `tasks`, and `cancel`. `task` can wait
with optional `wait_ms` and `cursor`; it does not push unsolicited stdio
callbacks across assistant turns.

## What Codex-Co-Engineer is for

Use Codex-Co-Engineer when you want Codex to:

- run a review or implementation on Grok Build, Cursor Local, Cursor Cloud, or
DeepSeek Harness (DSH) / Muse Spark
- keep one writer per managed local worktree and branch
- wait on a durable receipt instead of a fire-and-forget shell job
- cancel an owned local process group or Cursor Cloud run
- inspect the result before Codex pushes, opens a PR, or merges

Do not use it as a security sandbox, a credential broker, or a replacement for
the provider's own login and approval flow.

## Provider matrix

| Provider | Identifier | Transport | Workspace | Local process boundary |
| --- | --- | --- | --- | --- |
| Grok Build | `grok` | ACP first; CLI fallback only before prompt dispatch | Managed worktree by default, or explicit `direct` | Required |
| Cursor Local | `cursor-local` | ACP first; CLI fallback only before prompt dispatch | Managed worktree by default, or explicit `direct` | Required |
| DeepSeek Harness / Muse | `dsh` | Official rc.7 ACP composition through ACPX | Managed worktree by default, or explicit `direct` | Required |
| Cursor Cloud | `cursor-cloud` | Official Cursor SDK | Remote provider branch; no local worktree | Not used |

Roles are `review` and `implement`. An accepted prompt is never replayed
through another transport. ACPX does not provide an authoritative prompt-sent
acknowledgement, so a DSH task is marked `dispatch_uncertain` as soon as ACPX
spawns and is never replayed through CLI.

## Install

Requirements:

- Node.js 24 or newer. The release gate is intentionally pinned to Node 24.
- Git and the `worktree-bootstrap` CLI/skill for managed local workspaces.
- Linux with a working `systemd --user` manager, `systemd-run` 244 or
newer, and a unified cgroup v2 hierarchy for local providers.
- Linux with a working `systemd --user` manager, `systemd-run` 244 or newer,
and a unified cgroup v2 hierarchy for local providers.
- Authenticated Grok Build and Cursor Local CLIs.
- A Cursor Cloud API key in its normal owner-only configuration file.
- The DSH/Muse model credential in its normal owner-only configuration file.
Expand All @@ -34,7 +61,7 @@ installed plugin package directory—the directory containing `package.json`
and `bin/setup.mjs`. In this source checkout that directory is:

```bash
cd plugins/plumbob-harness-control
cd plugins/codex-co-engineer
npm run setup
npm run setup:check
```
Expand All @@ -55,45 +82,41 @@ bin/set-model-api-key

`npm run setup:check` validates the DSH/ACPX composition and CLI, Cursor SDK,
and `worktree-bootstrap` dependency. It does not install or authenticate Grok
or Cursor Local, validate their CLIs, validate the Cursor Cloud key, or prove
that the Linux systemd/cgroup process boundary is usable. Call the `status`
tool after setup to check provider readiness; the release gate and live host
acceptance must validate the process boundary before starting local agents.

Cursor Cloud uses `CURSOR_API_KEY`,
`CURSOR_API_KEY_FILE`, or the existing owner-only
`~/.config/cursor-cloud-control/api-key`. The DSH key defaults to the
owner-only `~/.config/codex-co-engineer/model-api-key`. Never put credentials
in MCP arguments or prompts.

## Delegation model

Local Grok and Cursor tasks use ACP. DSH uses the official rc.7 ACP
composition through ACPX. Cursor Cloud uses the official Cursor SDK. A local
CLI fallback is allowed only when ACP fails before prompt dispatch; an
accepted prompt is never replayed through another transport. ACPX does not
provide an authoritative prompt-sent acknowledgement, so a DSH task is marked
`dispatch_uncertain` as soon as ACPX spawns and is never replayed through CLI.

Every local worker is launched as a manager-owned transient `systemd --user`
service with `KillMode=control-group` solely so cancellation reaches detached
or Cursor Local or validate the Cursor Cloud key. Call `status` after setup:
its `local_boundary` result verifies the Linux systemd/cgroup prerequisite in
the MCP process's actual environment, and local providers are reported
unavailable when that boundary is unavailable. The release gate also launches
the MCP through the manifest's exact environment allowlist before accepting a
local-provider release.

Cursor Cloud uses `CURSOR_API_KEY`, `CURSOR_API_KEY_FILE`, or the existing
owner-only `~/.config/cursor-cloud-control/api-key`. The DSH key defaults to
the owner-only `~/.config/codex-co-engineer/model-api-key`. Never put
credentials in MCP arguments or prompts.

## Safety and workspace model

Local workers are launched as manager-owned transient `systemd --user`
services with `KillMode=control-group` solely so cancellation reaches detached
descendants and the worker survives the launching client. This is a
lifecycle/cleanup boundary, not a sandbox: providers inherit the normal
environment, network, filesystem, credentials, and shell capabilities. Local
dispatch fails closed when the Linux systemd/cgroup prerequisite is not
available. Cursor Cloud runs in the provider's remote environment.
available. The check occurs before Codex-Co-Engineer creates a managed
worktree, task receipt, or prompt file. Cursor Cloud runs in the provider's
remote environment and does not depend on the local process boundary.

Cursor Local and DSH's official fallback CLIs take the prompt positionally,
so it may be visible to other processes running as the same Unix user for the
Cursor Local and DSH's official fallback CLIs take the prompt positionally, so
it may be visible to other processes running as the same Unix user for the
duration of that fallback. Grok fallback uses an owner-only prompt file.

### Local workspace modes

Local providers accept `workspace_mode`:

- `managed` (default) creates and locks one
`worktree-bootstrap` worktree and branch per task. This is the normal mode
for parallel implementation and review.
- `managed` (default) creates and locks one `worktree-bootstrap` worktree and
branch per task. This is the normal mode for parallel implementation and
review.
- `direct` runs against the supplied checkout. Use it only when you
explicitly accept direct mutation of that checkout.

Expand All @@ -104,9 +127,9 @@ one task → one worktree → one branch → one writer
```

If `worktree-bootstrap` fails before returning an authoritative receipt and
path, Co-Engineer does not guess at or delete an unknown worktree. Inspect the
repository with `git worktree list` and the `worktree-bootstrap` lock tooling;
clean only an exact task/lock that the tooling identifies.
path, Codex-Co-Engineer does not guess at or delete an unknown worktree.
Inspect the repository with `git worktree list` and the `worktree-bootstrap`
lock tooling; clean only an exact task/lock that the tooling identifies.

### Cursor Cloud requirements

Expand All @@ -128,7 +151,9 @@ tasks reject it. A local implementation returns its branch and handoff for
Codex to inspect; Codex may push and open a PR only after confirming that real
commits exist. Codex controls the final merge.

Example local review:
## Examples

Local review:

```json
{
Expand All @@ -142,7 +167,7 @@ Example local review:
}
```

Example Cursor Cloud implementation:
Cursor Cloud implementation:

```json
{
Expand All @@ -156,14 +181,11 @@ Example Cursor Cloud implementation:
}
```

Providers are `grok`, `cursor-local`, `cursor-cloud`, and `dsh`. Roles
are `review` and `implement`.

## Handoff and cleanup

Terminal managed tasks retain their worktree and branch for Codex inspection;
they are not silently deleted. Poll `task`, then run the authoritative
handoff from the recorded worktree:
they are not silently deleted. Watch with `task` (optionally `wait_ms` +
`cursor`), then run the authoritative handoff from the recorded worktree:

```bash
worktree-bootstrap handoff TASK --repo /absolute/worktree --format markdown
Expand Down Expand Up @@ -194,16 +216,46 @@ normal authenticated environment because they are trusted peer coding agents.

Task prompts, events, logs, runtime identities, local paths, branch names, and
opaque provider IDs are stored under the owner-only state directory, normally
`$XDG_STATE_HOME/codex-co-engineer` or
`~/.local/state/codex-co-engineer`. Task directories are `0700`; files are
`0600`. Prompts and session data are retained for inspection until the
operator removes the exact terminal task state. See
[data handling](docs/data-handling.md).
`$XDG_STATE_HOME/codex-co-engineer` or `~/.local/state/codex-co-engineer`.
Task directories are `0700`; files are `0600`. Prompts and session data are
retained for inspection until the operator removes the exact terminal task
state. See [data handling](docs/data-handling.md).

## Troubleshooting

**How do I check whether Codex-Co-Engineer can dispatch locally?**
Call `status`. Local providers are ready only when `local_boundary.ready` is
true. If it is false, the MCP process is missing Linux `systemd --user`,
`systemd-run` 244+, unified cgroup v2, or the forwarded user-session locators
(`XDG_RUNTIME_DIR`, `DBUS_SESSION_BUS_ADDRESS`).

**Setup passed, but local providers are unavailable.**
`setup:check` does not prove the MCP environment. Re-run `status` from the
actual MCP server process, then confirm the plugin `.mcp.json` allowlist
forwards `HOME`, `PATH`, `XDG_*`, and `DBUS_SESSION_BUS_ADDRESS`.

**Where is the installed plugin?**
Use the package path reported by Codex or its plugin manager. In this
repository the source package is `plugins/codex-co-engineer`.

**A managed worktree appeared without a receipt.**
Do not guess or delete it. Inspect `git worktree list` and
`worktree-bootstrap lock inspect`, then clean only an exact identified
task/lock.

**Cursor Cloud returned HTTP 400 for a valid SHA.**
Treat it as a provider visibility failure. Make the commit reachable from an
open PR or the default branch, then retry. Do not replay a prompt that was
already dispatched.

**Can I put API keys in the MCP tool arguments?**
No. Use normal provider login or the owner-only key files. Credentials must
not appear in MCP arguments, prompts, receipts, fixtures, or Git.

## Development and release

```bash
npm --prefix plugins/plumbob-harness-control test
npm --prefix plugins/codex-co-engineer test
node scripts/validate-release.mjs
node scripts/inspector-preflight.mjs
```
Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ controls.
## Supported versions

Security fixes target the latest release on the default branch. Report the
stable MCP identifier `plumbob-harness-control` together with the public
stable MCP identifier `codex-co-engineer` together with the public
package version.

## Report privately
Expand Down
Loading
Loading