pg-implement — Phase 3 of the PG planner suite
The third stage. Brainstorm narrowed the design space; Plan made it
implementable; Implement walks the plan phase-by-phase while
enforcing the discipline rules.
The pairing:
- Phase 1 —
pg-feature-brainstorm (sketch)
- Phase 2 —
pg-feature-plan (heavy plan)
- Phase 3 —
pg-implement (this skill, executes the plan)
When to use vs the generic /implement
| Project |
Use |
Anything PG-related with a planning/<slug>/plan.md |
/pg-implement |
| Generic project plan, not PG |
Generic /implement |
| Ad-hoc PG coding, no plan |
Neither — write a plan first via /pg-plan |
The PG variant exists because PG implementation has unusual
constraints the generic /implement doesn't enforce:
- Per-phase test runs against the dev cluster
- File:line citation discipline (knowledge corpus must stay accurate)
- Plan-linked commit messages (commits reference the plan + phase)
- Upstream-vs-meta commit-message-style split
- Catalog/catversion/WAL-format pre-flight before any touching edit
/pg-restart cadence after backend code changes
Inputs
- Slug (required): the planning directory under
planning/<slug>/.
Examples in this repo: sp2-pgstr-maxalloc, cb1-pgcrypto-bomb,
sp7-tablefunc-quoting. The dev/ branch mirrors the slug
(e.g. feature_sp2_pgstr_maxalloc, feature_server_side_vars).
- Must contain
plan.md produced by pg-feature-plan.
- May contain
brainstorm.md (Phase 1 sketch); read for context, not
for procedure.
- May contain
notes.md (running log; appended to during this run).
Output
- Code changes inside
dev/ on a feature branch (NOT in
postgres-claude/'s knowledge/).
planning/<slug>/notes.md — one section per phase, appended as we
go: what was edited, what tests ran, what surprised us, what's
deferred.
- Per-phase commits with the plan-linked message format (§5 below).
- Optionally at the end: a draft commit / patch series under
dev/
ready for patch-submission.
Strict rules — see .claude/rules/pg-implement-discipline.md
This skill is the procedure. The rules file is the constitution.
Read both. Where they disagree, the rules win. The non-negotiables:
- One phase at a time. No interleaving phases. Each phase is
self-contained per the plan's "Phase-end check".
- Verify before edit (R2). Spot-check 3-5 file:line citations from
the plan against current source before phase 1. Drift signals:
citations off by more than ~20 lines, or naming a since-removed
symbol. If drift > 10% of the spot-checked sample, STOP — re-run
/pg-plan to refresh; do not push through with a stale plan.
- Phase-end check must pass before the next phase starts. Don't
carry breakage forward.
- Per-phase commit. Each phase ends with a commit using the plan-
linked message format. No phase ends uncommitted.
- Cite or don't claim applies to commit messages too — any
"fixes" / "addresses" claim must point to a specific file:line or
plan-section.
- No scope creep (R7). If a phase reveals a needed change outside
the plan's §3 file table, STOP and pick from R7's three paths
(small+coupled → update plan +
Sites: trailer; separate concern →
defer to follow-up + record in notes.md; invalidates the phase
boundary → escalate for re-plan). Never silently expand scope.
Why per-phase = per-commit + per-test
Two operational reasons every phase ends with a green-tested, plan-
linked commit (not "WIP" or "TODO"):
- Bisectability.
git bisect across a multi-phase patch series
is only useful if every commit individually builds and passes the
declared phase-end check. A broken commit in the middle of the
series poisons bisect for the lifetime of this code.
- Per-commit reviewability. When the series eventually goes to
pgsql-hackers via
format-patch, reviewers read commits one at a
time. Upstream PG convention is that each commit in a posted
series compiles and passes tests on its own — a known-broken
"WIP" commit, even one tagged TODO, is grounds for the patch
being bounced before review starts.
This is why R3 (no interleaving), R4 (phase-end check before commit),
and the anti-pattern list (no WIP commits, no --amend across
phases) act as one rule, not three.
Forbidden patterns (mirrors rules §Anti-patterns)
- "WIP" commits. Every commit in
dev/ is a complete phase. No
wip: more of phase 3.
--amend to fix a previous phase's commit. Use a NEW commit
with a Fixes: <sha> trailer if you genuinely need to correct.
- Committing without a
Plan: trailer in dev/. If you're
committing in dev/, you're implementing a plan — name it.
- Cherry-picking individual phases. All phases or none.
- Mixing meta-repo +
dev/ writes in one bash invocation (R10).
Method
For each phase in planning/<slug>/plan.md §8 "Phased implementation":
Step 0 — verify hooks installed (once per session)
Before phase 1, confirm dev/.git/hooks/pre-commit exists and contains
the # pg-precommit-guard v1 marker. If not, run /pg-install-hooks
(idempotent; safe to re-run). The hook is what enforces R4 +
R13's format-check + scoped-test gate automatically — without it, the
per-phase commit step still works but the guarantees in R4 are
back to "Claude remembers". Re-cloning dev/ (/pg-reclone-dev) wipes
dev/.git/hooks/ and the next /setup-pg reinstalls automatically.
Pre-phase (5 min)
- Read the phase's "Files this phase touches" + "5-10 concrete edits"
- Spot-check the file:line citations against current source. Grep for
any function name or symbol cited; verify line numbers within ±20.
If drift, escalate to user before continuing.
- Re-read the relevant subsystem doc (
knowledge/subsystems/X.md) and
the per-file docs for files being edited. Note any invariants
(INV-* tags) that the phase touches.
- Confirm the dev cluster is stopped if a postmaster restart will be
needed (catalog edits, GUC additions). Otherwise leave it running
for fast feedback.
Edit (the main work)
- Make the 5-10 edits per the phase plan. Use
Edit (not Write)
wherever possible — preserves surrounding context and reviews
cleanly.
- After each edit, run a quick build if the file is in
src/backend:
cd dev/build-debug && ninja install 2>&1 | tail -5. Catch
compile errors immediately, not at phase end.
- Track every edit in
planning/<slug>/notes.md as you go:
- File + line range + one-sentence what.
- Anything that surprised you (e.g. "comment at line 234 mentioned
a constraint I had to honor").
- Anything that drifted from the plan (e.g. "plan said 5 edits;
I needed 6 because of helper X").
Phase-end check
- Run the test scope named in the plan's phase-end check:
- Most phases:
meson test --no-rebuild regress/regress.
- Catalog/WAL phases: regress +
meson test --no-rebuild --suite isolation.
- Replication phases: above + the relevant TAP test under
meson test --no-rebuild --suite recovery.
- If anything fails, fix-in-place — DON'T commit the breakage and
"follow up". Failures during this phase belong to this phase.
- Once green, run
git -C dev status and verify the changed files
match the plan's §3 file table for this phase. Flag any extras to
the user before committing.
Per-phase commit
Stage the phase's files: git -C dev add <files>.
Compose the commit message per the format below.
Use commit-message-style (upstream PG style — no Co-Authored-By,
imperative, wrapped at 76 cols) since this commit lives in dev/
and may eventually be format-patched upstream.
The pre-commit hook runs automatically: stage A runs pg-format.sh --check against every staged C/H/Perl file (commit fails on dirty;
fix in place with bash .claude/hooks/pg-format.sh <file>), then
stage B runs meson test --no-rebuild --suite <X> for the R13
scope pg-phase-detect.sh infers from the staged paths and the
Plan-phase trailer in notes.md. On test red, inspect
dev/build-debug/meson-logs/testlog.txt. Override scope only with
PG_PRECOMMIT_SCOPE=regress (or rarely skip); --no-verify is
forbidden per R4.
Plan-linked commit message format
<one-line imperative title, max ~72 cols, no prefix>
<wrapped paragraph body, explaining the WHY of this phase>
Plan: planning/<slug>/plan.md (phase <N>: <phase title>)
Sites: <file:line>, <file:line>, ...
- Title is for the phase, NOT for the whole feature.
- Body is one or two paragraphs, plain prose, no bullets.
Plan: trailer is required and points to the plan + phase.
Sites: trailer lists the principal sites touched (3-5 max; don't
enumerate every line).
- No
Co-Authored-By (this is upstream style).
- No emoji, no conventional-commits prefix, no ticket numbers.
Phase-end log
Append to planning/<slug>/notes.md:
## Phase <N> — <title> — <date> <time>
**Status:** done | partial | deferred
**Commit:** <short-sha> "<title>"
**Tests run:** <scope> — <result>
### What changed
- <one-line summary per site>
### Surprises / drift
- <anything that wasn't in the plan>
### What this phase did NOT do
- <items deferred to later phases>
Plan-phase: <N>
The trailing Plan-phase: <N> line is parsed by
.claude/hooks/pg-phase-detect.sh to identify the current phase
when the pre-commit hook scopes its meson test run. Keep the
Plan-phase: token verbatim — that's the grep target.
Status field values (R8):
done — phase-end check green, commit landed.
partial — phase ended with known follow-ups inside the same
phase scope (rare; requires user agreement per R7 path-1).
deferred — phase stopped before its phase-end check could run
green; branch parks here until the blocker is resolved. The
next session reads this status first.
Tell the user the phase is done, name the next phase, ask whether
to continue immediately or pause. Some phases naturally end the
session.
End-of-implementation (after all phases done)
- Final
meson test --no-rebuild (full suite). Document any
pre-existing flakes (e.g. macOS recovery/040_* etc.).
- Run
git -C dev log --oneline <base>..HEAD and verify N commits
for N phases, each with a Plan: trailer.
- If destined upstream: hand off to
patch-submission skill.
- If staying local: tell the user, leave the branch, append a
final summary to
notes.md.
- End-of-session: invoke
memory-keeping to update progress/STATE.md
with the planning slug + status (done / deferred / abandoned).
Boundaries vs other skills
pg-feature-plan (Phase 2): the upstream. If scope shifts, escalate
back — don't reshape the plan mid-implementation.
commit-message-style (upstream PG style): used for every per-phase
commit (since these may go upstream).
meta-commit-style (meta-repo style): NOT used here. Reserved for
commits inside postgres-claude/. If implementation reveals a knowledge
corpus gap, fix it in a SEPARATE meta-repo commit using that style.
patch-submission: takes over at the end for upstream-bound work.
review-checklist: pre-submission gate. Run at the end before
format-patching.
memory-keeping: end-of-session bookkeeping.
testing: when adding test cases mid-phase, consult for the right
flavor (regress vs isolation vs TAP).
build-and-run + /pg-restart + /pg-test + /pg-psql:
the dev-loop commands.
When to escalate to the user
- Plan drift > 10% (file:line citations significantly stale).
- A phase reveals a needed change outside §3 file table (scope creep).
- A test fails for reasons not in the plan's §13 risks.
- Catalog or WAL format change wasn't anticipated by the plan.
- The change touches an invariant tagged in a subsystem doc.
In every escalation: stop, propose the resolution path (update plan,
defer to follow-up, abandon phase), ask. Don't push through.
Agent rate-limit recovery (when delegating phases)
For long multi-phase runs, each phase is often delegated to a focused
subagent (Agent tool with a tight per-phase brief; main loop verifies
the commit + writes notes). Subagents can hit Anthropic rate / quota
limits mid-phase, leaving partial uncommitted work in the worktree.
This is recoverable — treat it as a routine signal, not a failure.
Recovery protocol when a subagent reports a rate-limit or returns
without a commit:
- Check
git status in the worktree immediately. Staged but
uncommitted state is the agent's progress — it's a recoverable
asset. Files in the staging area + the agent's prior context are
enough to finish.
- Inspect the diff with
git diff --cached --stat + key file
diffs. Decide whether the agent's approach is sound. If yes:
either resume the agent, or finish the work yourself (use the
staged state as the starting point — the agent's intent is encoded
there).
- Resume the agent via
SendMessage to the agent ID returned in
the prior spawn. The agent's prior context is preserved; pass a
"continue from the staged state — here's what's left" message that
names the specific remaining edits + the acceptance criteria. This
is faster than starting a new agent from scratch.
- Finish manually if the remaining work is bounded. When the
agent has done ~70-80% of a phase and the remaining edits are
well-scoped (e.g. just the executor side of a parser+executor
phase), driving the rest from the main loop is often faster than
round-tripping through another agent. Verify the build + run the
phase-end check + commit per the normal R5 + R8 protocol.
- Don't roll back staged work without inspection. Even if the
agent's approach has issues, the staged edits typically encode a
sound design — fix the specific problem, don't blow it away.
Origin: sesvars_v3 phases 8 + FU#1, where both implementation agents
rate-limited mid-phase. Phase 8 finished manually from the agent's
~100-line gram.y staging; FU#1 resumed via SendMessage. Both landed
clean commits without re-planning. See F24 in
sessions/2026-06-22-sesvars-v3-retro.md.
Style
- Be terse in
notes.md. It's a working log, not a write-up.
- Be specific in commit messages (R6). "fix bug" is forbidden; "set
dropPin = false for non-MVCC scans (plan phase 2, site
nbtree.c:421)" is right. Any "addresses" / "fixes" / "implements"
claim must point to a file:line in source/ (for plan-cited sites)
or a specific plan section (§4 Catalog impact, etc.).
- Cite the plan from the commit; cite the corpus from the plan; cite
source from the corpus. The full chain stays linked.
Where the artifacts live
- Code:
dev/ on a feature branch (e.g. feature_server_side_vars).
- Working log:
planning/<slug>/notes.md (in postgres-claude/).
- Plan-linked commits: the
Plan: trailer is the link from commit
back to plan.
Cross-references
.claude/rules/pg-implement-discipline.md — the binding constitution. This skill is the procedure; the rules are the invariants. R1–R12 win wherever they disagree with this skill.
.claude/skills/pg-feature-plan/SKILL.md — Phase 2 upstream. If scope shifts, escalate back; don't reshape the plan mid-implementation.
.claude/skills/pg-feature-brainstorm/SKILL.md — Phase 1 read for context, not procedure.
.claude/skills/commit-message-style/SKILL.md — per-phase commit format (upstream PG style; no Co-Authored-By because these commits may go upstream).
.claude/skills/meta-commit-style/SKILL.md — used for the separate meta-repo commit if implementation surfaces a corpus gap (R10 two-repo separation).
.claude/skills/build-and-run/SKILL.md — dev-loop fundamentals (ninja install, /pg-restart, build profiles).
.claude/skills/testing/SKILL.md — pick the right test flavor for each phase's phase-end check.
.claude/skills/patch-submission/SKILL.md — invoked at end-of-implementation if upstream-bound.
.claude/skills/review-checklist/SKILL.md — pre-submission gate (R12).
.claude/skills/memory-keeping/SKILL.md — end-of-implementation STATE.md update (R12 invokes this explicitly).
.claude/commands/pg-implement.md — slash-command wrapper.
1---2name: pg-implement3description: Execute a PostgreSQL `planning/<slug>/plan.md` phase-by-phase under upstream-grade discipline — Phase 3 of the PG planner suite. Per-phase commits, per-phase regress/iso/TAP runs, plan-linked commit messages, and a running notes log; enforces .claude/rules/pg-implement-discipline.md (R1-R12 — every commit references the plan slug + phase number; every code claim has a file:line cite; phase-end check must pass before the next phase starts). Use when the user says "/pg-implement <slug>", "implement the plan", "let's start implementing the X plan", "execute the planning/<slug>/plan.md", or has a finalized planning/<slug>/plan.md ready to execute. Skip for ad-hoc coding without a plan (no phase structure), non-PG implementation (app code, infra, scripts), the generic /implement flow (multi-project, doesn't enforce PG R1-R12 rules), and exploratory hacking where the plan is still being shaped (use pg-feature-plan instead).4---56# pg-implement — Phase 3 of the PG planner suite78The third stage. Brainstorm narrowed the design space; Plan made it9implementable; **Implement walks the plan phase-by-phase** while10enforcing the discipline rules.1112The pairing:13- Phase 1 — `pg-feature-brainstorm` (sketch)14- Phase 2 — `pg-feature-plan` (heavy plan)15- **Phase 3 — `pg-implement`** (this skill, executes the plan)1617## When to use vs the generic `/implement`1819| Project | Use |20|---|---|21| Anything PG-related with a `planning/<slug>/plan.md` | **`/pg-implement`** |22| Generic project plan, not PG | Generic `/implement` |23| Ad-hoc PG coding, no plan | Neither — write a plan first via `/pg-plan` |2425The PG variant exists because PG implementation has unusual26constraints the generic `/implement` doesn't enforce:2728- Per-phase test runs against the dev cluster29- File:line citation discipline (knowledge corpus must stay accurate)30- Plan-linked commit messages (commits reference the plan + phase)31- Upstream-vs-meta commit-message-style split32- Catalog/catversion/WAL-format pre-flight before any touching edit33- `/pg-restart` cadence after backend code changes3435## Inputs3637- **Slug** (required): the planning directory under `planning/<slug>/`.38 Examples in this repo: `sp2-pgstr-maxalloc`, `cb1-pgcrypto-bomb`,39 `sp7-tablefunc-quoting`. The `dev/` branch mirrors the slug40 (e.g. `feature_sp2_pgstr_maxalloc`, `feature_server_side_vars`).41- Must contain `plan.md` produced by `pg-feature-plan`.42- May contain `brainstorm.md` (Phase 1 sketch); read for context, not43 for procedure.44- May contain `notes.md` (running log; appended to during this run).4546## Output4748- Code changes inside `dev/` on a feature branch (NOT in49 `postgres-claude/`'s `knowledge/`).50- `planning/<slug>/notes.md` — one section per phase, appended as we51 go: what was edited, what tests ran, what surprised us, what's52 deferred.53- Per-phase commits with the plan-linked message format (§5 below).54- Optionally at the end: a draft commit / patch series under `dev/`55 ready for `patch-submission`.5657## Strict rules — see `.claude/rules/pg-implement-discipline.md`5859This skill is the procedure. The rules file is the constitution.60Read both. Where they disagree, the rules win. The non-negotiables:61621. **One phase at a time.** No interleaving phases. Each phase is63 self-contained per the plan's "Phase-end check".642. **Verify before edit (R2).** Spot-check 3-5 file:line citations from65 the plan against current source before phase 1. **Drift signals:**66 citations off by more than ~20 lines, or naming a since-removed67 symbol. If drift > 10% of the spot-checked sample, STOP — re-run68 `/pg-plan` to refresh; do not push through with a stale plan.693. **Phase-end check must pass** before the next phase starts. Don't70 carry breakage forward.714. **Per-phase commit.** Each phase ends with a commit using the plan-72 linked message format. No phase ends uncommitted.735. **Cite or don't claim** applies to commit messages too — any74 "fixes" / "addresses" claim must point to a specific file:line or75 plan-section.766. **No scope creep (R7).** If a phase reveals a needed change outside77 the plan's §3 file table, STOP and pick from R7's three paths78 (small+coupled → update plan + `Sites:` trailer; separate concern →79 defer to follow-up + record in `notes.md`; invalidates the phase80 boundary → escalate for re-plan). Never silently expand scope.8182### Why per-phase = per-commit + per-test8384Two operational reasons every phase ends with a green-tested, plan-85linked commit (not "WIP" or "TODO"):86871. **Bisectability.** `git bisect` across a multi-phase patch series88 is only useful if every commit individually builds and passes the89 declared phase-end check. A broken commit in the middle of the90 series poisons bisect for the lifetime of this code.912. **Per-commit reviewability.** When the series eventually goes to92 pgsql-hackers via `format-patch`, reviewers read commits one at a93 time. Upstream PG convention is that **each commit in a posted94 series compiles and passes tests on its own** — a known-broken95 "WIP" commit, even one tagged TODO, is grounds for the patch96 being bounced before review starts.9798This is why R3 (no interleaving), R4 (phase-end check before commit),99and the anti-pattern list (no WIP commits, no `--amend` across100phases) act as one rule, not three.101102### Forbidden patterns (mirrors rules §Anti-patterns)103104- **"WIP" commits.** Every commit in `dev/` is a complete phase. No105 `wip: more of phase 3`.106- **`--amend` to fix a previous phase's commit.** Use a NEW commit107 with a `Fixes: <sha>` trailer if you genuinely need to correct.108- **Committing without a `Plan:` trailer in `dev/`.** If you're109 committing in `dev/`, you're implementing a plan — name it.110- **Cherry-picking individual phases.** All phases or none.111- **Mixing meta-repo + `dev/` writes in one bash invocation** (R10).112113## Method114115For each phase in `planning/<slug>/plan.md` §8 "Phased implementation":116117### Step 0 — verify hooks installed (once per session)118119Before phase 1, confirm `dev/.git/hooks/pre-commit` exists and contains120the `# pg-precommit-guard v1` marker. If not, run `/pg-install-hooks`121(idempotent; safe to re-run). The hook is what enforces R4 +122R13's format-check + scoped-test gate automatically — without it, the123per-phase commit step still works but the guarantees in R4 are124back to "Claude remembers". Re-cloning `dev/` (`/pg-reclone-dev`) wipes125`dev/.git/hooks/` and the next `/setup-pg` reinstalls automatically.126127### Pre-phase (5 min)1281291. Read the phase's "Files this phase touches" + "5-10 concrete edits"130 + "Phase-end check".1312. Spot-check the file:line citations against current source. Grep for132 any function name or symbol cited; verify line numbers within ±20.133 If drift, escalate to user before continuing.1343. Re-read the relevant subsystem doc (`knowledge/subsystems/X.md`) and135 the per-file docs for files being edited. Note any invariants136 (`INV-*` tags) that the phase touches.1374. Confirm the dev cluster is stopped if a postmaster restart will be138 needed (catalog edits, GUC additions). Otherwise leave it running139 for fast feedback.140141### Edit (the main work)1421435. Make the 5-10 edits per the phase plan. Use `Edit` (not Write)144 wherever possible — preserves surrounding context and reviews145 cleanly.1466. After each edit, run a quick build if the file is in `src/backend`:147 `cd dev/build-debug && ninja install 2>&1 | tail -5`. Catch148 compile errors immediately, not at phase end.1497. Track every edit in `planning/<slug>/notes.md` as you go:150 - File + line range + one-sentence what.151 - Anything that surprised you (e.g. "comment at line 234 mentioned152 a constraint I had to honor").153 - Anything that drifted from the plan (e.g. "plan said 5 edits;154 I needed 6 because of helper X").155156### Phase-end check1571588. Run the test scope named in the plan's phase-end check:159 - Most phases: `meson test --no-rebuild regress/regress`.160 - Catalog/WAL phases: regress + `meson test --no-rebuild --suite161 isolation`.162 - Replication phases: above + the relevant TAP test under163 `meson test --no-rebuild --suite recovery`.1649. If anything fails, fix-in-place — DON'T commit the breakage and165 "follow up". Failures during this phase belong to this phase.16610. Once green, run `git -C dev status` and verify the changed files167 match the plan's §3 file table for this phase. Flag any extras to168 the user before committing.169170### Per-phase commit17117211. Stage the phase's files: `git -C dev add <files>`.17312. Compose the commit message per the format below.17413. Use `commit-message-style` (upstream PG style — no Co-Authored-By,175 imperative, wrapped at 76 cols) since this commit lives in `dev/`176 and may eventually be format-patched upstream.177178 The pre-commit hook runs automatically: stage A runs `pg-format.sh179 --check` against every staged C/H/Perl file (commit fails on dirty;180 fix in place with `bash .claude/hooks/pg-format.sh <file>`), then181 stage B runs `meson test --no-rebuild --suite <X>` for the R13182 scope `pg-phase-detect.sh` infers from the staged paths and the183 `Plan-phase` trailer in `notes.md`. On test red, inspect184 `dev/build-debug/meson-logs/testlog.txt`. Override scope only with185 `PG_PRECOMMIT_SCOPE=regress` (or rarely `skip`); `--no-verify` is186 forbidden per R4.187188### Plan-linked commit message format189190```191<one-line imperative title, max ~72 cols, no prefix>192193<wrapped paragraph body, explaining the WHY of this phase>194195Plan: planning/<slug>/plan.md (phase <N>: <phase title>)196Sites: <file:line>, <file:line>, ...197```198199- Title is for the phase, NOT for the whole feature.200- Body is one or two paragraphs, plain prose, no bullets.201- `Plan:` trailer is **required** and points to the plan + phase.202- `Sites:` trailer lists the principal sites touched (3-5 max; don't203 enumerate every line).204- No `Co-Authored-By` (this is upstream style).205- No emoji, no conventional-commits prefix, no ticket numbers.206207### Phase-end log20820914. Append to `planning/<slug>/notes.md`:210211 ```markdown212 ## Phase <N> — <title> — <date> <time>213214 **Status:** done | partial | deferred215 **Commit:** <short-sha> "<title>"216 **Tests run:** <scope> — <result>217218 ### What changed219 - <one-line summary per site>220221 ### Surprises / drift222 - <anything that wasn't in the plan>223224 ### What this phase did NOT do225 - <items deferred to later phases>226227 Plan-phase: <N>228 ```229230 The trailing `Plan-phase: <N>` line is parsed by231 `.claude/hooks/pg-phase-detect.sh` to identify the current phase232 when the pre-commit hook scopes its meson test run. Keep the233 `Plan-phase:` token verbatim — that's the grep target.234235 **Status field values (R8):**236 - `done` — phase-end check green, commit landed.237 - `partial` — phase ended with known follow-ups inside the same238 phase scope (rare; requires user agreement per R7 path-1).239 - `deferred` — phase stopped before its phase-end check could run240 green; branch parks here until the blocker is resolved. The241 next session reads this status first.24224315. Tell the user the phase is done, name the next phase, ask whether244 to continue immediately or pause. Some phases naturally end the245 session.246247## End-of-implementation (after all phases done)24824916. Final `meson test --no-rebuild` (full suite). Document any250 pre-existing flakes (e.g. macOS `recovery/040_*` etc.).25117. Run `git -C dev log --oneline <base>..HEAD` and verify N commits252 for N phases, each with a `Plan:` trailer.25318. If destined upstream: hand off to `patch-submission` skill.25419. If staying local: tell the user, leave the branch, append a255 final summary to `notes.md`.25620. End-of-session: invoke `memory-keeping` to update `progress/STATE.md`257 with the planning slug + status (done / deferred / abandoned).258259## Boundaries vs other skills260261- **`pg-feature-plan`** (Phase 2): the upstream. If scope shifts, escalate262 back — don't reshape the plan mid-implementation.263- **`commit-message-style`** (upstream PG style): used for every per-phase264 commit (since these may go upstream).265- **`meta-commit-style`** (meta-repo style): NOT used here. Reserved for266 commits inside `postgres-claude/`. If implementation reveals a knowledge267 corpus gap, fix it in a SEPARATE meta-repo commit using that style.268- **`patch-submission`**: takes over at the end for upstream-bound work.269- **`review-checklist`**: pre-submission gate. Run at the end before270 format-patching.271- **`memory-keeping`**: end-of-session bookkeeping.272- **`testing`**: when adding test cases mid-phase, consult for the right273 flavor (regress vs isolation vs TAP).274- **`build-and-run`** + **`/pg-restart`** + **`/pg-test`** + **`/pg-psql`**:275 the dev-loop commands.276277## When to escalate to the user278279- Plan drift > 10% (file:line citations significantly stale).280- A phase reveals a needed change outside §3 file table (scope creep).281- A test fails for reasons not in the plan's §13 risks.282- Catalog or WAL format change wasn't anticipated by the plan.283- The change touches an invariant tagged in a subsystem doc.284285In every escalation: stop, propose the resolution path (update plan,286defer to follow-up, abandon phase), ask. Don't push through.287288## Agent rate-limit recovery (when delegating phases)289290For long multi-phase runs, each phase is often delegated to a focused291subagent (Agent tool with a tight per-phase brief; main loop verifies292the commit + writes notes). Subagents can hit Anthropic rate / quota293limits mid-phase, leaving partial uncommitted work in the worktree.294This is recoverable — treat it as a routine signal, not a failure.295296Recovery protocol when a subagent reports a rate-limit or returns297without a commit:2982991. **Check `git status` in the worktree immediately.** Staged but300 uncommitted state is the agent's progress — it's a recoverable301 asset. Files in the staging area + the agent's prior context are302 enough to finish.3032. **Inspect the diff with `git diff --cached --stat` + key file304 diffs.** Decide whether the agent's approach is sound. If yes:305 either resume the agent, or finish the work yourself (use the306 staged state as the starting point — the agent's intent is encoded307 there).3083. **Resume the agent via `SendMessage`** to the agent ID returned in309 the prior spawn. The agent's prior context is preserved; pass a310 "continue from the staged state — here's what's left" message that311 names the specific remaining edits + the acceptance criteria. This312 is faster than starting a new agent from scratch.3134. **Finish manually if the remaining work is bounded.** When the314 agent has done ~70-80% of a phase and the remaining edits are315 well-scoped (e.g. just the executor side of a parser+executor316 phase), driving the rest from the main loop is often faster than317 round-tripping through another agent. Verify the build + run the318 phase-end check + commit per the normal R5 + R8 protocol.3195. **Don't roll back staged work without inspection.** Even if the320 agent's approach has issues, the staged edits typically encode a321 sound design — fix the specific problem, don't blow it away.322323Origin: sesvars_v3 phases 8 + FU#1, where both implementation agents324rate-limited mid-phase. Phase 8 finished manually from the agent's325~100-line gram.y staging; FU#1 resumed via SendMessage. Both landed326clean commits without re-planning. See F24 in327`sessions/2026-06-22-sesvars-v3-retro.md`.328329## Style330331- Be terse in `notes.md`. It's a working log, not a write-up.332- Be specific in commit messages (R6). "fix bug" is forbidden; "set333 `dropPin = false` for non-MVCC scans (plan phase 2, site334 `nbtree.c:421`)" is right. Any "addresses" / "fixes" / "implements"335 claim must point to a file:line in `source/` (for plan-cited sites)336 or a specific plan section (`§4 Catalog impact`, etc.).337- Cite the plan from the commit; cite the corpus from the plan; cite338 source from the corpus. The full chain stays linked.339340## Where the artifacts live341342- Code: `dev/` on a feature branch (e.g. `feature_server_side_vars`).343- Working log: `planning/<slug>/notes.md` (in `postgres-claude/`).344- Plan-linked commits: the `Plan:` trailer is the link from commit345 back to plan.346347## Cross-references348349- `.claude/rules/pg-implement-discipline.md` — **the binding constitution.** This skill is the procedure; the rules are the invariants. R1–R12 win wherever they disagree with this skill.350- `.claude/skills/pg-feature-plan/SKILL.md` — Phase 2 upstream. If scope shifts, escalate back; don't reshape the plan mid-implementation.351- `.claude/skills/pg-feature-brainstorm/SKILL.md` — Phase 1 read for context, not procedure.352- `.claude/skills/commit-message-style/SKILL.md` — per-phase commit format (upstream PG style; no `Co-Authored-By` because these commits may go upstream).353- `.claude/skills/meta-commit-style/SKILL.md` — used for the *separate* meta-repo commit if implementation surfaces a corpus gap (R10 two-repo separation).354- `.claude/skills/build-and-run/SKILL.md` — dev-loop fundamentals (`ninja install`, `/pg-restart`, build profiles).355- `.claude/skills/testing/SKILL.md` — pick the right test flavor for each phase's phase-end check.356- `.claude/skills/patch-submission/SKILL.md` — invoked at end-of-implementation if upstream-bound.357- `.claude/skills/review-checklist/SKILL.md` — pre-submission gate (R12).358- `.claude/skills/memory-keeping/SKILL.md` — end-of-implementation STATE.md update (R12 invokes this explicitly).359- `.claude/commands/pg-implement.md` — slash-command wrapper.