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
34 changes: 30 additions & 4 deletions .claude/skills/crypter-change/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ docker exec crypter-pipeline test -d /plans/{run-id} && \
A container created before these existed picks them up on
`docker compose -f .devcontainer/docker-compose.yml up -d --force-recreate`.

Then make the workspace the container builds in. It is a clone of your repository, taken from
the read-only `/host-git` mount, and it lasts exactly as long as this run:

```bash
git fetch origin
docker exec crypter-pipeline crypter-workspace create {run-id}
```

Fetch first — the workspace takes `upstream/stable` from your `origin/stable`, so a stale
remote-tracking ref puts the whole run on an old base. **If either fails, stop and say so.**

The workspace holds only committed history. Uncommitted work in your checkout is not visible to
the container and never reaches the branch.

## 1. Plan

Invoke `crypter-step-plan` with the requirement verbatim and the output path
Expand All @@ -57,7 +71,7 @@ It settles the plan with the user itself. **Do not continue until they have appr
## 2. Build

```bash
docker exec -w /work/Crypter crypter-pipeline \
docker exec -w /work/{run-id} crypter-pipeline \
claude --permission-mode auto -p "/crypter-devcontainer-implement {run-id} {branch}"
```

Expand All @@ -66,7 +80,7 @@ Keep the title and description it reports; `crypter-step-open-pull-request` need
## 3. Examine

```bash
docker exec -w /work/Crypter crypter-pipeline \
docker exec -w /work/{run-id} crypter-pipeline \
claude --permission-mode auto -p "/crypter-devcontainer-examine {run-id} {branch} /plans/{run-id}/plan.md"
```

Expand All @@ -92,7 +106,7 @@ them.
Where anything was accepted:

```bash
docker exec -w /work/Crypter crypter-pipeline \
docker exec -w /work/{run-id} crypter-pipeline \
claude --permission-mode auto -p "/crypter-devcontainer-remediate {run-id} {branch} /runs/{run-id}/triage.md"
```

Expand Down Expand Up @@ -122,7 +136,19 @@ Stop immediately, without spending an attempt, where `ci-watcher` reports that n
for the commit. Nothing to fix has been established yet, and a push that starts no checks is a
setup problem rather than a code one.

## 8. Report
## 8. Tear down and report

The branch is on the fork and the artifacts are on your disk, so the workspace has nothing left
to hold:

```bash
docker exec crypter-pipeline crypter-workspace remove {run-id}
```

Remove it on every exit path, including the ones where you stopped early. Nothing under `/runs`
or `.claude/plans` is touched by this — those are the record of the run and they stay.

Then report:

- The pull request URL and whether its checks are green. It is a draft; taking it out of draft
is the user's.
Expand Down
25 changes: 12 additions & 13 deletions .claude/skills/crypter-devcontainer-examine/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: Review a diff in the pipeline container and write findings to the h
Review a diff and leave hard artifacts behind. You do not write code and you do not decide what
gets acted on; your caller triages what you find.

The ref already exists in `/work/Crypter/.git`.
The ref already exists in the run's workspace at `/work/{run-id}`.

## Setup

Expand All @@ -34,25 +34,28 @@ judgement, and a later pass can read them to verify the claims they make.
either is missing, stop and say so** rather than creating it — a directory made on this side is
one the host cannot clean up.

## 1. Worktree on the ref
## 1. Put the workspace on the ref

The workspace at `/work/{run-id}` already exists; the host created it. **If it is missing, stop
and say so** rather than creating one.

```bash
git -C /work/Crypter worktree add --detach /work/Crypter/.claude/worktrees/{run-id} {ref}
git -C /work/{run-id} checkout --detach {ref}
```

`--detach` because you only read. A worktree that claims the branch collides with anything else
holding it, and reviewing never needs it claimed. **If this fails, stop and say so.**
`--detach` because you only read. Leaving the branch unclaimed keeps a later stage free to check
it out and commit to it. **If this fails, stop and say so.**

Every agent gets this worktree path and works by absolute path inside it. Never `cd`.
Every agent gets the workspace path and works by absolute path inside it. Never `cd`.

## 2. Plan adherence

Given a plan path, invoke `conformance-auditor` with it, the worktree, and
Given a plan path, invoke `conformance-auditor` with it, the workspace, and
`/runs/{run-id}/conformance.md`. It reports where the diff and the plan diverge.

## 3. Code review

Invoke `reviewer` once per lens, in parallel — they do not interact. Each gets the worktree and
Invoke `reviewer` once per lens, in parallel — they do not interact. Each gets the workspace and
`/runs/{run-id}/findings/{lens}.md`.

| Lens | Brief |
Expand All @@ -75,8 +78,4 @@ drift, and which findings you would look at first. Name the files you wrote.

Leave the judgement to the host. Reporting a finding is not accepting it.

```bash
git -C /work/Crypter worktree remove /work/Crypter/.claude/worktrees/{run-id}
```

Remove it on every exit path.
Leave the workspace as it is. The host removes it when the run ends.
35 changes: 17 additions & 18 deletions .claude/skills/crypter-devcontainer-implement/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ description: Build an approved plan into commits on a new branch, inside the pip

Turn an approved plan into commits on a branch.

The workspace is an anonymous clone of the org repository with a single remote, `upstream`,
which has no push url. Commit locally and stop there; the branch is fetched out and pushed once
you return.
The workspace at `/work/{run-id}` is a clone of the host repository, taken from a read-only
mount. It has no push url and no credential. Commit locally and stop there; the branch is
fetched out and pushed once you return.

The plan is the specification. The user approved it before this ran, and this runs unattended.

Expand All @@ -20,38 +20,37 @@ You are given a run id and a branch name: `/crypter-devcontainer-implement {run-
Read `/plans/{run-id}/plan.md` first. It is a read-only mount of the host's `.claude/plans`.
**If it is absent, stop and say so** — the host session owns that file.

## 1. Sync and branch
`/work/{run-id}` already exists; the host created it. **If it is missing, stop and say so**
rather than creating one — the host owns the workspace for the whole run and removes it at the
end.

Build on current code:
## 1. Branch

The workspace is checked out at `upstream/stable`, so build from there:

```bash
git -C /work/Crypter fetch upstream
git -C /work/Crypter worktree add /work/Crypter/.claude/worktrees/{run-id} -b {branch} upstream/stable
git -C /work/{run-id} checkout -b {branch} refs/remotes/upstream/stable
```

**If either fails, stop and say so.** A quietly skipped sync leaves the diff and the eventual
pull request on the wrong base, and nothing downstream will notice.
**If this fails, stop and say so.** A branch cut from the wrong base leaves the diff and the
eventual pull request on the wrong base, and nothing downstream will notice.

Work by absolute path inside the worktree. Never `cd`.
Work by absolute path inside the workspace. Never `cd`.

## 2. Implement

Invoke `implementer` with `/plans/{run-id}/plan.md` and the worktree path. Give it nothing about
Invoke `implementer` with `/plans/{run-id}/plan.md` and the workspace path. Give it nothing about
how the plan was reached — the plan is the specification.

Read its report. If it says a step could not be done, that is not a failure to paper over:
say so plainly in your own report.

## 3. Hand off

```bash
git -C /work/Crypter worktree remove /work/Crypter/.claude/worktrees/{run-id}
```

Remove it on every exit path. The branch ref lives in `/work/Crypter/.git` and survives, which
is what the host fetches.
Leave the workspace as it is, with `{branch}` checked out and its commits on it. The host fetches
the branch out of it and removes it when the run ends.

Then report back to the host session:
Report back to the host session:

- The branch name and the commits on it.
- A title and description for the pull request. Title reads like a commit subject: imperative,
Expand Down
27 changes: 13 additions & 14 deletions .claude/skills/crypter-devcontainer-remediate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ description: Apply a report to a branch the pipeline already built, whether tria

Take a report of what is wrong with a branch this container already built, and fix it.

The branch exists in `/work/Crypter/.git`. Commit locally; the result is fetched out and pushed
once you return.
The branch exists in the run's workspace at `/work/{run-id}`. Commit locally; the result is
fetched out and pushed once you return.

The report is triaged review findings or a CI failure. Both are the same job: a description of
what is wrong, an existing branch, and commits that address it.
Expand All @@ -25,31 +25,30 @@ Read `/plans/{run-id}/plan.md` too where one exists. The fix stays inside what t
to do; a repair that reaches into the plan's non-goals belongs in your report rather than in a
commit.

## 1. Worktree on the existing branch
## 1. Claim the existing branch

The workspace at `/work/{run-id}` already exists; the host created it. **If it is missing, stop
and say so** rather than creating one.

```bash
git -C /work/Crypter fetch upstream
git -C /work/Crypter worktree add /work/Crypter/.claude/worktrees/{run-id} {branch}
git -C /work/{run-id} checkout {branch}
```

No `-b` — the branch is already there, carrying the commits the host has pushed. **If this
fails, stop and say so.**
No `-b` — the branch is already there, carrying the commits an earlier stage put on it. **If
this fails, stop and say so.**

## 2. Fix

Invoke `implementer` with the report path and the worktree path. Each fix is its own commit on
Invoke `implementer` with the report path and the workspace path. Each fix is its own commit on
the branch.

Read its report. If it says the failure could not be addressed, say so plainly in your own
report rather than reporting success.

## 3. Hand off

```bash
git -C /work/Crypter worktree remove /work/Crypter/.claude/worktrees/{run-id}
```

Remove it on every exit path. The branch keeps the new commits.
Leave the workspace as it is, with the new commits on `{branch}`. The host fetches them out and
removes the workspace when the run ends.

Then report back to the host session: what the report described, what changed, and which commits
Report back to the host session: what the report described, what changed, and which commits
now sit on the branch. The host fetches those commits and pushes them.
20 changes: 10 additions & 10 deletions .claude/skills/crypter-devcontainer-verify/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ description: Rule on each finding in a report against the code, one verifier per

Take a list of findings somebody left on a diff and decide which of them are true.

The ref already exists in `/work/Crypter/.git`. You write verdicts and nothing else — no fixes,
The ref already exists in the run's workspace at `/work/{run-id}`. You write verdicts and
nothing else — no fixes,
and no findings of your own.

## Setup
Expand All @@ -21,19 +22,22 @@ is absent, stop and say so.**
`/runs/{run-id}/verification/` already exists; the caller creates it. **If it is missing, stop
and say so** rather than creating it.

## 1. Worktree on the ref
## 1. Put the workspace on the ref

The workspace at `/work/{run-id}` already exists; the host created it. **If it is missing, stop
and say so** rather than creating one.

```bash
git -C /work/Crypter worktree add --detach /work/Crypter/.claude/worktrees/{run-id}-verify {ref}
git -C /work/{run-id} checkout --detach {ref}
```

`--detach` because you only read. **If this fails, stop and say so.**

Every agent gets this worktree path and works by absolute path inside it. Never `cd`.
Every agent gets the workspace path and works by absolute path inside it. Never `cd`.

## 2. Verify

Invoke `finding-verifier` once per finding, in parallel. Each gets one finding, the worktree
Invoke `finding-verifier` once per finding, in parallel. Each gets one finding, the workspace
path, and `/runs/{run-id}/verification/{finding-id}.md`.

One finding per agent, and each sees only its own. A verifier that reads the whole report starts
Expand All @@ -46,8 +50,4 @@ Never give a finding to the agent that raised it.
For each finding: its id, the verdict, and one line of evidence. Then the counts — how many held,
how many did not, how many are unsettled. Name the files you wrote.

```bash
git -C /work/Crypter worktree remove /work/Crypter/.claude/worktrees/{run-id}-verify
```

Remove it on every exit path.
Leave the workspace as it is. The host removes it when the run ends.
26 changes: 18 additions & 8 deletions .claude/skills/crypter-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,28 @@ Read its title, description and diff with whatever GitHub access this session ha
CLI, or the GitHub MCP server's `pull_request_read`. What the author says it does is context for
reading the diff, and worth carrying into your report where the two disagree.

## 2. Fetch it into the container
## 2. Fetch it into a workspace

Pull request heads are public refs on the org repository, so the container reaches them
anonymously:
The container has no network remote. It clones from your repository through a read-only mount,
so the pull request head goes into your repository first and travels across from there:

```bash
docker exec crypter-pipeline \
git -C /work/Crypter fetch upstream +pull/{number}/head:pr-{number}
git fetch origin +refs/pull/{number}/head:refs/pr/{number}
docker exec crypter-pipeline crypter-workspace create pr-{number} \
'+refs/pr/{number}:refs/heads/pr-{number}'
```

The refspec is forced, so reviewing a pull request again after its author rebased or amended
picks up the new head instead of being rejected.

**If this fails, stop and say so.**
**If either fails, stop and say so.**

The workspace lasts for this review and no longer.

## 3. Examine

```bash
docker exec -w /work/Crypter crypter-pipeline \
docker exec -w /work/pr-{number} crypter-pipeline \
claude --permission-mode auto -p "/crypter-devcontainer-examine pr-{number} pr-{number}"
```

Expand Down Expand Up @@ -99,7 +102,14 @@ produced it.
A line comment that the API rejects for being outside the diff goes in the body instead. **Do not
retry it against a different line.**

## 6. Report
## 6. Tear down and report

```bash
docker exec crypter-pipeline crypter-workspace remove pr-{number}
```

Remove it on every exit path, including the ones where you stopped early. The findings under
`.claude/runs/pr-{number}` are the record and they stay.

Tell the user the review URL, what you kept and dropped, which findings you checked against the
code yourself and stand behind, and where the artifacts are.
4 changes: 2 additions & 2 deletions .claude/skills/crypter-step-open-pull-request/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ You are given a run id and a branch name: `/crypter-step-open-pull-request {run-

## 1. Fetch the branch out of the container

The branch lives in the container's clone. `git` reaches it over `docker exec`:
The branch lives in the run's workspace. `git` reaches it over `docker exec`:

```bash
git -c protocol.ext.allow=user fetch \
"ext::docker exec -i crypter-pipeline git upload-pack /work/Crypter" {branch}:{branch}
"ext::docker exec -i crypter-pipeline git upload-pack /work/{run-id}" {branch}:{branch}
```

`protocol.ext.allow` is passed per command and stays out of your config. **If this fails, stop
Expand Down
Loading
Loading