Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7d455cc
fix(runtime): judge each edit by its own worktree and follow worktree…
Hyper-AI-Lab Oct 28, 2026
e6debe7
fix(runtime): keep session baselines in the clone's git directory
Hyper-AI-Lab Oct 28, 2026
cc374df
fix(runtime): ask before skipping git hooks, and catch deploys with g…
Hyper-AI-Lab Oct 28, 2026
26b3154
fix(runtime): protect CI actions and git-hook manager configuration b…
Hyper-AI-Lab Oct 28, 2026
90adddb
fix(runtime): a new test baseline cannot absorb a change to the froze…
Hyper-AI-Lab Oct 28, 2026
92e8da0
feat(runtime): close a task only when it is finished, and say what to…
Hyper-AI-Lab Oct 28, 2026
688f864
feat(runtime): short gate output with the full log in the task folder…
Hyper-AI-Lab Oct 28, 2026
75918d3
feat(runtime): a review input that holds the whole change and points …
Hyper-AI-Lab Oct 28, 2026
cc97b45
feat(runtime): tell protected configuration a merge brought in from t…
Hyper-AI-Lab Oct 28, 2026
2faaec0
feat(runtime): link a task to its work item with paacm task start --ref
Hyper-AI-Lab Oct 28, 2026
ee43faa
feat(cli): doctor finds check programs that are not installed, and a …
Hyper-AI-Lab Oct 28, 2026
5ecd5e4
docs(content): cover every file change, the finishing rules, --quiet,…
Hyper-AI-Lab Oct 28, 2026
0b4580b
docs: release 3.5.0 — ADR 0021, ALGORITHM, guides, requirements and c…
Hyper-AI-Lab Oct 28, 2026
8cf2925
fix(runtime): stop-gate nudges are guidance, not hook errors; approve…
Hyper-AI-Lab Oct 28, 2026
c66ea60
fix(runtime): the stop gate keeps the result of the gate it ran itself
Hyper-AI-Lab Oct 28, 2026
01228f7
fix(runtime): leaving a worktree never releases a failing gate; check…
Hyper-AI-Lab Oct 28, 2026
031c38e
fix(runtime): FAST next steps include phase 7; a missing tool means B…
Hyper-AI-Lab Oct 28, 2026
0167c15
fix(runtime): a branch merged locally stays the task's own in the audit
Hyper-AI-Lab Oct 28, 2026
7f3d94a
fix(runtime): a new task cannot be started over a blocked task's chan…
Hyper-AI-Lab Oct 28, 2026
1956e58
fix(runtime): a sturdier review diff
Hyper-AI-Lab Oct 28, 2026
087b4f6
fix(runtime): close the review's ways around the skip-git-hooks rule
Hyper-AI-Lab Oct 28, 2026
8114ca1
fix(cli): doctor reads check commands without false warnings
Hyper-AI-Lab Oct 28, 2026
d436fdc
fix(runtime): protect every lefthook configuration file, and bound th…
Hyper-AI-Lab Oct 28, 2026
df0d83e
docs: describe the fixes from the release review
Hyper-AI-Lab Oct 28, 2026
f12ad4d
fix(runtime): close the shell-guard gaps the audit found
Hyper-AI-Lab Oct 28, 2026
824ad36
fix(runtime): a symbolic link in the task folder no longer hides the …
Hyper-AI-Lab Oct 28, 2026
e8e2ce4
fix(runtime): a configuration change through a merge stays a warning …
Hyper-AI-Lab Oct 28, 2026
46d2954
fix(runtime): a nested .agent/paacm.json is not a second set of prote…
Hyper-AI-Lab Oct 28, 2026
00d28dc
fix(runtime): a non-git session folder protects every checkout below it
Hyper-AI-Lab Oct 28, 2026
cac63c5
fix(runtime): a blocked task's changed frozen files hold every worktr…
Hyper-AI-Lab Oct 28, 2026
ebaa6c3
docs: say what the runtime enforces after the audit fixes
Hyper-AI-Lab Oct 28, 2026
721883c
fix(runtime): recognise a missing command on Windows
Hyper-AI-Lab Oct 28, 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
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{
"name": "paacm",
"description": "PAACM: the Verified Single-Writer Loop for agentic coding. One writer agent, read-only explorer and reviewer subagents, tests protected after approval, and completion gated on executed checks.",
"version": "3.4.1",
"version": "3.5.0",
"source": "./plugins/paacm"
}
]
Expand Down
2 changes: 1 addition & 1 deletion .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{
"name": "paacm",
"description": "PAACM: the Verified Single-Writer Loop for agentic coding. One writer agent, read-only explorer and reviewer subagents, tests protected after approval, and completion gated on executed checks.",
"version": "3.4.1",
"version": "3.5.0",
"source": "plugins/paacm"
}
]
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## 3.5.0 — Finishing, worktrees and shared machines

Running 3.4.1 on a team project (several people on one server, linked worktrees, headless agent runs) showed where the runtime enforced less than the method asks. Each fix is covered by tests that failed before it ([ADR 0021](docs/method/adr/0021-finishing-worktrees-and-shared-machines.md)).

- **A task finishes through the runtime.** `paacm task done` now also requires the route's last phase (review for STANDARD and DEEP, verify for FAST), approved tests, a passing gate at the route's tier, and a `REPORT.md` that begins with `OUTCOME: done`. The stop gate nudges once, never twice in a row, when an open task's gate is green and when a STANDARD or DEEP task changes files while still triaged; in Claude Code its nudges are guidance (`additionalContext`), not hook errors; a gate below the route's tier no longer counts. Before, agents stopped with tasks still triaged and without a report.
- **The runtime says what to read next.** `task start`, `task phase` and a passing `gate` name the reference (and the project extension) for the next step.
- **Worktrees.** The hooks follow the agent into a worktree of the same repository (Claude Code keeps `CLAUDE_PROJECT_DIR` at the original root), and the protect hook judges every edit by the worktree the file is in, with that worktree's configuration and task. Before, an edit in a sibling worktree was not checked, and every edit in a worktree under `.claude/worktrees/` needed approval as agent configuration. The runtime never climbs out of a worktree into the checkout that contains it, and finds the task from inside a submodule. Moving into a worktree never releases the session's own failing gate: the stop gate judges both. When the session's folder is not a git repository (a folder holding several checkouts), a file in any checkout below it is judged by that checkout's rules wherever the agent's current directory is, and the stop gate also judges each checkout directly inside the folder that the session edited. A nested `.agent/paacm.json` does not set up a second set of rules; it is protected configuration at any depth.
- **Shared machines.** Session baselines live in the worktree's git directory, readable only by their owner (file modes on Linux and macOS; on Windows the folder has the access rules of the `.git` directory), instead of a shared temporary folder where a second account's session start failed and lost its whole context. A baseline that cannot be written is a warning.
- **Frozen tests stay frozen.** `approve-tests` refuses to take a new baseline over a test, `.agent/checks.conf` or `.agent/paacm.json` changed since the approval, even when the change was committed; that needs `reopen-tests`, which the human confirms. A new task cannot be started over a blocked task with such a change either, in any worktree whose commit has the change, and another worktree cannot approve tests over it. Approving moves the task from testing to implementing.
- **Review input.** New untracked files are reviewed with their content (files git is told to skip stay out, and a path git cannot add is listed instead of failing the review); diffs of generated files (`linguist-generated`) and very large diffs go to `review-diffs/`; the fence cannot be closed by the diff; a diff too large for git's buffer is an error, never an empty review. The evidence names the gate log, the configuration warnings and the files the writer saved for the reviewer, who has no shell. A level-2 heading inside a code block no longer ends the reviewer checklist.
- **Gate output.** `paacm gate --quiet` and `paacm check --quiet` print only the check lines and a failing check's last lines; the gate saves its full output as `gate.log` in the task folder. A check that cannot find a command (exit 127; on Windows, cmd's "is not recognized" message) is reported as a missing tool, not as failing code: the agent stops with `BLOCKED:` trigger 2 instead of changing code.
- **Audit.** A configuration warning says when the change arrived through a merge of commits a remote-tracking branch has, such as the base branch (`through a merge`, `origin` in JSON), so the report can say where it was reviewed. It stays a warning the report accounts for: git cannot tell who made a remote-tracking ref. A branch made and merged locally counts as the task's own. Violations stay strict either way.
- **Shell guard and protected paths.** The guard asks before skipping git hooks (`--no-verify`, `git commit -n`, `core.hooksPath`, `HUSKY=0`, `SKIP=`, `LEFTHOOK=0`, quoted or not) and before moving a ref directly (`git update-ref`), and catches deploys with global options (`terraform -chdir=… apply`, `kubectl --context … apply`) and `docker build --push`. `.github/actions/**`, `.husky/**`, `.pre-commit-config.yaml` and the lefthook files are protected configuration by default.
- **Work items.** `paacm task start --ref <work item>` links a task to an issue number, a tracker key, `owner/repo#N` or a URL, shown in the status, the session context, the review input and the report.
- **doctor** warns about a check whose program is not installed, and about a review extension without a `## Reviewer checklist`.
- **Instructions.** The always-on rules cover every change to the repository's files, documentation included, and add a rule to follow the phases to the end and run each runtime command on its own; no reference recommends a compound command any more. Tests-first runs the fixers on the tests and updates the lists a change makes wrong before approval. The setup guide explains running the checks in CI and what stays per person on a shared machine.

**Upgrading.** `paacm upgrade` updates an untouched `.agent/paacm.json`. If yours lists `protect.config` explicitly, add `".github/actions/**"`, `".husky/**"`, `".pre-commit-config.yaml"`, `"lefthook.*"`, `".lefthook.*"`, `"lefthook-local.*"` and `".lefthook-local.*"` yourself if they apply. A task started with 3.4.1 can be finished with 3.5.0; `paacm task done` now asks for its last phase, approved tests and a report. Rules your project added to work around the 3.4.1 behaviour (for example "run every file change through PAACM", "run the gate without pipes" or "a task ends with REPORT.md and `task done`") are now part of the kit and can be removed.

## 3.4.1 — Hardening from an audit

An audit of 3.4.0 found ways around the gates. Each is fixed and covered by a test in `test/hardening.test.mjs`.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ The [user guide](docs/guide/README.md) covers setup, writing requests, supportin

## Status and limits

PAACM 3.4.1 is a complete implementation of the specification for Claude Code and Cursor, including project extensions for adapting it to a repository's own conventions ([guide](docs/guide/extending.md)). Markdown instructions are guidance; the enforcement comes from the hooks, the IDE's permissions and its sandbox. Use the power layer or a plugin when enforcement matters. The method's evidence comes from published studies and vendor guidance, not from your code: [evaluate it](docs/guide/evaluation.md) on tasks from your own history before relying on a claim that it helps.
PAACM 3.5.0 is a complete implementation of the specification for Claude Code and Cursor, including project extensions for adapting it to a repository's own conventions ([guide](docs/guide/extending.md)). Markdown instructions are guidance; the enforcement comes from the hooks, the IDE's permissions and its sandbox. Use the power layer or a plugin when enforcement matters. The method's evidence comes from published studies and vendor guidance, not from your code: [evaluate it](docs/guide/evaluation.md) on tasks from your own history before relying on a claim that it helps.

Upgrading from PAACM 2.0.0: see [upgrading-from-2.md](docs/guide/upgrading-from-2.md).

Expand Down
2 changes: 1 addition & 1 deletion docs/guide/extending.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ What an extension may contain:

- **Additions only.** Steps, fields, sources to read, reviewers to run and checks to apply.
- **No gate removals.** It never removes or weakens a gate: the human approvals, frozen tests, the gate and its retry cap, the escalation triggers, approval of consequential actions. If an extension conflicts with a gate, the agent follows the gate and tells you.
- **`## Reviewer checklist`** in `08-review.md` is special. `paacm task review-input` copies that section into the review input, so the fresh-context reviewer checks every item. Write each item as something the reviewer can confirm against a diff.
- **`## Reviewer checklist`** in `08-review.md` is special. `paacm task review-input` copies that section into the review input, so the fresh-context reviewer checks every item. Write each item as something the reviewer can confirm against a diff. Only this section reaches the reviewer: put every reviewer rule under it, using `###` subheadings if needed, and keep the other sections for instructions to the writer. `paacm doctor` warns when the section is missing and names the sections that stay with the writer. The reviewer has no shell: if it needs a tool's output, have the writer save it in the task folder, where the review input lists it.
- **Explorer requirements.** The explorer subagent does not read extensions. The explore reference tells the writer to put the requirements of `03-explore.md` (sources to search, conventions to report) into the explorer's brief.

Extensions are protected configuration (`.agent/extensions/**`), like the checks and the hooks. The agent does not edit them during a task without your approval. Change them in a reviewed pull request, as you would any process change.
Expand Down
25 changes: 24 additions & 1 deletion docs/guide/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,28 @@ Run the checks yourself to see that they work:
npx github:Hyper-AI-Lab/hyper-agents check --tier quick
```

`doctor` warns about a check whose program is not installed on this machine, because the gate would stop there with exit code 127. A check whose tool cannot be installed where the agent runs belongs in CI only.

### Run the checks in CI

Run the same manifest in your CI, so that every pull request passes the same commands, whoever made it. Use `check`, not `gate`: the gate belongs to a task on the agent's machine. Install the tools the checks call before this step. In a project install the runtime is in the repository:

```yaml
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
- run: node .claude/skills/paacm/scripts/paacm.mjs check --tier full
```

With the plugin, the repository has no copy of the runtime; pin the kit's version instead:

```yaml
- run: npx github:Hyper-AI-Lab/hyper-agents#v3.5.0 check --tier full
```

Add `--quiet` to show only the check lines and the end of a failing check's output. Held-out acceptance tests for high-stakes work ([phase 7](../method/ALGORITHM.md#phase-7-verify)) also run in CI, outside the agent's workspace.

### Add a mutation check (optional)

Once tests are approved for a task they are frozen, so the gate is only as strong as their ability to catch faults. Coverage does not measure that. A mutation tool does: it changes the code in small ways and counts the changes that no test notices. Add one to the `full` tier and set the score below which it fails, for example with StrykerJS for TypeScript:
Expand Down Expand Up @@ -190,6 +212,7 @@ With `--autonomy L2` or `L3` and the power layer, Claude Code runs shell command
PAACM works the same on a server that several people use over SSH. The agent acts with the operating-system account it runs in, so set the machine up per person, not per project:

- **One account per person.** The agent uses the account's Claude Code login and user settings (`~/.claude/`), its git author, its `gh` login and its cloud credentials. When people share an account, their commits and pull requests carry one identity, a rule that someone else must approve a pull request no longer means anything, and one person's user settings change everyone's sessions.
- **One clone or worktree per person.** Task state lives in the working tree (`.agent/tasks/`), and `paacm task start` refuses while another task is active there. Two people in one working tree block each other's tasks and mix their changes.
- **One clone or worktree per person.** Task state lives in the working tree (`.agent/tasks/`), and `paacm task start` refuses while another task is active there. Two people in one working tree block each other's tasks and mix their changes. Each linked worktree, next to the clone or nested in it (for example under `.claude/worktrees/`), has its own task, and the hooks judge every edit by the worktree the file is in.
- **Nothing per-person in shared folders.** PAACM keeps each session's baseline in `paacm-sessions/` in the worktree's git directory (`.git/paacm-sessions/` in a main checkout), readable only by its owner (file modes on Linux and macOS; on Windows the folder has the access rules of `.git`) and never in `/tmp`, so a cleanup of the shared temporary folder or another account cannot break or read it. Keep your own scratch files and review inputs in private folders too.
- **No long-lived cloud keys where agents run.** An agent can run any command its account can, within the permission rules, and deny rules for shell commands are not a security boundary. Keep deployment and administrator credentials in CI, for example GitHub Actions with OpenID Connect. Give agent accounts short-lived or read-only access, or none.
- **Not as root.** Root can read every account's files and credentials, so an agent running as root can too. File permissions between ordinary accounts are what keep one person's projects and keys away from another person's agent.
Loading
Loading