PR
MotleyAI2026-10-27查看 1682复制 1755
分配给代理的任务的规范驱动的变更流程。拉入当前 git 分支所属的跟踪器问题(Linear 或 GitHub,根据 `living-architecture.yaml`),并将其与用户在调用技能时输入的任何内容相结合。补充上下文,检测当前阶段,并将技能分配给该阶段 la:pr-plan → la:pr-tests → la:pr-implement → la:pr-review。
📘如何使用这个技能
- 1复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
- 2打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
- 3粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
- 4直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景
💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。
SKILL.md12572 chars
---
name: pr
description: Spec-driven change flow for a task given to an agent. Pulls in the tracker issue (Linear or GitHub, per `living-architecture.yaml`) that the current git branch belongs to, and combines it with whatever the user typed when invoking the skill. Rehydrates context, detects the current stage, and dispatches to the stage skills la:pr-plan → la:pr-tests → la:pr-implement → la:pr-review.
---
**Preflight:** run `la-doctor --plugin <this skill's base directory> --require-config` once per session before using any `la-*` or `dr-*` command. If it reports the missing-config finding (the one naming `/la:init`), run the fast path of the `la:init` skill, then re-run this preflight; stop and show the user its output on anything it still reports, or on any other failure.
I want a detailed spec-driven flow. The brief is the union of:
1. The tracker issue tied to the current branch (see "Rehydrate" below), AND
2. Whatever I just typed when invoking this skill.
## The four stages
The flow runs as four stage skills in this fixed order, and I reset the
session (`/clear`) between stages. Each stage ends at a hard stop; everything
a fresh session needs is on disk or in the tracker, so any stage can resume from
just the branch name:
1. **`pr-plan`** — interview me, Codex-review the plan (when
`reviewers.codex` is on), emit the
OpenSpec change (OpenSpec repos only), make the plan durable.
Ends at 🛑 reset point 1 (before tests).
2. **`pr-tests`** — write the full failing test suite for the plan,
Codex-review the tests against the plan (when `reviewers.codex` is on).
Ends at 🛑 reset point 2 (before implementation).
3. **`pr-implement`** — implement until every test passes, then (with my
go-ahead) commit, push, and open the PR.
Ends at 🛑 reset point 3 (just after the PR is created).
4. **`pr-review`** — run `/la:process-reviews` until converged, then
archive the OpenSpec change (OpenSpec repos only) so I can merge.
This skill does NO stage work itself. It only: rehydrates context (below),
detects which stage we're at, and invokes that stage's skill (`la:<stage>`) via
the Skill tool. Run exactly ONE stage per session — when its hard stop is reached, STOP;
never chain into the next stage, even if it looks quick.
## Stopping policy
Each stage skill ends with its own **hard stop** so I can reset your context.
At a hard stop: say which reset point we're at, then STOP and wait — do not
start the next stage. I'll `/clear` and re-invoke `/la:pr` (possibly with
"continue on branch `<BRANCH>`"); rehydration + stage detection below take it
from there.
**Within a stage, run autonomously — do NOT stop or ask permission to
proceed.** The only other permitted pauses are:
- the **`pr-plan` interview** (its whole point is questioning me);
- a **nontrivial design decision** — a real fork with more than one reasonable
option — raised with explicit PROS/CONS + RECOMMENDATION (per the interview
rule in `pr-plan`). A choice with an obvious default is NOT this:
take the default and move on;
- the standing **go-ahead gate before push/PR** (`pr-implement`): never
push or open a PR without my explicit go-ahead;
- a **suspected unrelated gap** — a failure, restriction, or missing capability
that looks pre-existing or outside this change's scope (a bind-level refusal, an
allowlist, a fixture that cannot express a scenario, …). Whether it is unrelated
and what to do about it is MY call, never yours: STOP and ask, presenting what
you found, the existing tracker issues you searched for (search first, cite ids
and titles), and the options (treat as in-scope / xfail against an EXISTING issue
/ narrow the scenario) with a recommendation. NEVER create a tracker issue, mark a
scenario xfail, or narrow a scenario on your own to route around it — even when a
tasks.md line or an earlier plan says "file its own issue".
Never stop just to report progress, to confirm an obvious next step, or to ask
something you can determine yourself.
## The plan is frozen once pr-plan ends
The plan — the OpenSpec change folder (proposal, design, tasks, delta specs) or,
without OpenSpec, the finalized-plan comment on the tracker issue — is MINE once
`pr-plan` reaches its hard stop. In EVERY later stage, NEVER change it without
my explicit confirmation of the exact edit: no added or amended decisions, no
rewritten or added scenarios, no "corrections" after a probe, no re-scoping, no
notes folded into tasks. If a stage finds the plan wrong, incomplete, or
contradicted by an axiom or a probe, STOP, present the exact proposed diff with
the reason, and wait. The one self-serve edit is flipping a task's `[ ]` to `[x]`
when it was completed exactly as written.
## Nothing the next stage needs lives in chat
Sessions `/clear` between stages, so the stop message reaches no future stage.
Anything the next stage must know therefore has to be **persisted where that
stage will discover it naturally** during its own rehydration and work — NEVER a
turn-final "heads-up", "note for next time", "FYI for pr-implement", or a
caveat tacked onto the stop message. Such text is gone the instant I `/clear`, so
it only masquerades as a hand-off. If you catch yourself about to write one,
STOP and put it in one of these instead:
- **tasks.md** — an open sub-task, a gotcha, or a calibration note on a step
(the next stage works through this file);
- **design.md / proposal.md / the spec delta** — a decision, rationale, or a
constraint on how something must be built;
- **the tracker issue** — the spec in the body, resume state and probe outcomes
in a handoff comment;
- **the code itself** — a test's assertions plus a terse comment, or a
pointer to a FUTURE issue that will change it (the only issue reference
allowed in code) — for anything about how the code must behave.
A hard stop then states only which reset point we're at: everything the next
stage needs is already on disk or in the tracker, by construction.
## Commit at the end of every stage
At each stage's hard stop — after the stage's work is done, just before you
STOP — commit the files that stage created or changed, **without asking**. This
overrides any standing "don't commit, I'll commit" / "ask me each time"
preference, and it supersedes any "do NOT commit" wording in the stage
skills. What still holds:
- Stage with **specific named paths** (`git add <path>`, one at a time) — NEVER
`git add -A`, `git add .`, or a whole directory.
- **Commit only** — pushing and opening the PR still need my explicit go-ahead
(`pr-implement` Step 3 / the stopping policy above); the end-of-stage
commit does not.
## Normative harnesses (living-architecture repos)
In a repo with an `architecture/` directory at its root,
`architecture/**/*.arc42.md`, `architecture/model.c4` and `architecture/views.c4`
files are normative harnesses, exactly like tests. This applies at EVERY stage of the flow —
planning, writing tests, implementing, and fixing review findings:
- **Read them first.** Before doing the stage's work, read
`architecture/index.yaml` plus **every** `*.arc42.md` file relevant to the
modules the change touches — the node file of each touched node AND
`system.arc42.md` (cross-cutting principles) — plus the LikeC4 view of every
touched node (see the `la:living-architecture` skill).
- **Obey them.** Every plan, test, implementation, and review fix MUST obey the
node principles and the model's import law — or explicitly include the
model + arc42 update as part of the change.
- **Flag, never deviate.** If anything in an arc42 file seems wrong,
contradictory, or makes the task impossible or substantially harder, FLAG IT
TO ME EXPLICITLY and wait for my call — NEVER silently deviate from,
reinterpret, or ignore a principle, and never produce work that quietly
conflicts with one.
- **Keep them normative and minimal.** When work strains a principle, first make
the code comply; propose an edit only when the principle genuinely forbids
something needed, in the smallest general wording — never descriptive text or
implementation detail (function names, mechanisms).
- **Never edit without per-change approval.** NEVER create, modify, or delete
one without my explicit approval for each specific change — present the
exact edit and wait for my OK. A broader approved plan that mentions the
edit does NOT count; the concrete edit itself needs the OK.
## Rehydrate — pull in the tracker issue for the current branch
Read the repo's decisions from its config: `TRACKER=$(la-config get tracker)`
(`linear`, `github` or `none`) and `la-config get openspec`. Capture
`BRANCH=$(git rev-parse --abbrev-ref HEAD)`.
**`TRACKER=linear`.** Look up the Linear issue whose `gitBranchName` equals
`BRANCH` **exactly**. I create branches by clicking "Copy git branch name" in
the Linear issue UI and `git checkout -b`-ing them, so the local branch name is
byte-equal to the issue's `gitBranchName`. That equality is the join key.
1. Try the cheap path first: Linear's auto-generated branch name is
`<user>/<lowercased-key>-<title-slug>` (e.g.
`alice/abc-123-add-storage-layer`). Pull out the `<key>` chunk
(`abc-123`), uppercase it (`ABC-123`), and call
`mcp__linear__get_issue(id="ABC-123")`.
2. If that returns an issue **and** the returned issue's `gitBranchName`
equals `BRANCH` exactly, use it. Otherwise fall back to
`mcp__linear__list_issues(team="<KEY-PREFIX>", query="<key-or-slug>",
includeArchived=false)` (`<KEY-PREFIX>` = the key's team part, e.g. `ABC`)
and walk the results, comparing each issue's
`gitBranchName` to `BRANCH`. Pick the unique exact match.
3. Once a match is confirmed, read the issue body in full
(`mcp__linear__get_issue` already returns it) plus any comments via
`mcp__linear__list_comments`.
**`TRACKER=github`.** GitHub's "Create a branch" names the branch
`<N>-<title-slug>`, so take the leading `<N>-` of `BRANCH` (after any
`<user>/` segment). The issue is `#<N>` iff `gh issue develop --list <N>` lists
`BRANCH` among its linked branches; GitHub has no reverse lookup, so this is
the only join. Read the issue with `gh issue view <N> --comments`.
**`TRACKER=none`.** There is no issue: the brief is my typed input alone.
If no issue maps to the branch (Linear: 0 exact matches; GitHub: no leading
number, or the branch is not linked to that issue), tell me so and ask whether
to proceed with only my typed input as the brief. If Linear gives >1 exact
matches, list them and ask which one.
**Set the change-id and OpenSpec.** `CHANGE_ID` = `$BRANCH` with any leading
`<user>/` segment stripped (`alice/abc-123-add-storage-layer` gives
`CHANGE_ID=abc-123-add-storage-layer`; OpenSpec change ids forbid underscores,
so replace any with `-`). This keeps issue ↔ git branch ↔ OpenSpec change
1:1:1. `OPENSPEC=1` iff `la-config get openspec` prints `true` (the preflight
already checked that `openspec/` agrees); otherwise `OPENSPEC=0`, and skip
everything marked *"OpenSpec repos only"* in the stage skills.
## Detect the stage
Work out which stage this session should run — first match wins:
1. **Open PR for `BRANCH`?** Check with `gh pr view --json state,url`.
If an open PR exists → **`pr-review`**.
2. **No durable plan yet?** The plan is durable iff:
- `OPENSPEC=1`: `openspec/changes/<CHANGE_ID>/` exists and
`openspec validate <CHANGE_ID> --strict` passes; or
- `OPENSPEC=0`: the tracker issue has a comment containing the finalized
plan (Linear: `mcp__linear__list_comments`; GitHub: `gh issue view <N>
--comments`).
If not durable → **`pr-plan`**.
3. **No tests for this change yet?** Look for test files added/changed for
this change: the working tree (`git status`) plus commits since the
merge-base with the default branch
(`git diff --name-only $(git merge-base HEAD <default-branch>)..HEAD`).
If none → **`pr-tests`**.
4. **Otherwise** → **`pr-implement`** (plan and tests exist, no PR yet;
this stage also covers the "all tests already pass, awaiting my
commit/push/PR go-ahead" case).
If the evidence is ambiguous (e.g. test files changed but they don't obviously
belong to this change), say what you found and ask me which stage to run.
## Dispatch
Tell me in one line which stage was detected and why, then invoke that stage's
skill (`la:pr-plan` / `la:pr-tests` / `la:pr-implement` / `la:pr-review`)
via the Skill tool and follow it to its hard stop. If I explicitly named a stage
when invoking `/la:pr`, that overrides detection.