pi-gauntlet 7.28.0 → 7.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +15 -7
  3. package/agents/loop-implementer.md +51 -0
  4. package/bin/gauntlet-performance.mjs +5 -1
  5. package/bin/gauntlet-performance.test.mjs +19 -3
  6. package/bin/gauntlet-telemetry-seal.mjs +2 -2
  7. package/extensions/lib/gauntlet-settings.test.ts +10 -0
  8. package/extensions/lib/gauntlet-settings.ts +8 -0
  9. package/extensions/lib/plan-check.test.ts +63 -0
  10. package/extensions/lib/plan-check.ts +42 -0
  11. package/extensions/lib/telemetry-record.test.ts +19 -0
  12. package/extensions/lib/telemetry-record.ts +5 -3
  13. package/extensions/phase-tracker.test.ts +40 -0
  14. package/extensions/phase-tracker.ts +6 -2
  15. package/extensions/telemetry.test.ts +58 -4
  16. package/extensions/telemetry.ts +21 -12
  17. package/package.json +2 -2
  18. package/skills/brainstorming/SKILL.md +11 -7
  19. package/skills/brainstorming/gatherer.md +33 -2
  20. package/skills/brainstorming/reference/amendment-surface.md +6 -6
  21. package/skills/brainstorming/reference/pr-subject.md +51 -0
  22. package/skills/brainstorming/reference/spec-finalization.md +22 -6
  23. package/skills/brainstorming/reference/ticket-acceptance.md +2 -2
  24. package/skills/finishing-a-development-branch/SKILL.md +68 -11
  25. package/skills/gauntlet-handoff/SKILL.md +1 -2
  26. package/skills/gauntlet-resume/SKILL.md +7 -4
  27. package/skills/gauntlet-resume/reference/brief-contract.md +35 -11
  28. package/skills/gauntlet-resume/reference/reconstruction.md +24 -5
  29. package/skills/loop-implementation/SKILL.md +124 -0
  30. package/skills/using-git-worktrees/SKILL.md +3 -3
  31. package/skills/using-git-worktrees/reference/pr-head.md +74 -0
  32. package/skills/verification-before-completion/SKILL.md +3 -1
  33. package/skills/writing-plans/SKILL.md +5 -1
  34. package/skills/writing-plans/reference/plan-contract.md +4 -0
@@ -0,0 +1,74 @@
1
+ # PR-head worktree
2
+
3
+ ## Select home and stop before writes
4
+
5
+ For a caller passing PR values, follow this reference instead of `using-git-worktrees/SKILL.md` Steps 0 and 1. Derive ROOT from the absolute git common directory as in Step 0, applying its submodule guard. Resolve the worktree home through the existing overrides/native-tool/wrapper contract; default to `$ROOT/.worktrees/<name>`. Set `<name>` to `headRefName` with every `/` replaced by `-`. Never adopt the session's linked tree unless it is the selected home on `headRefName`.
6
+
7
+ Run `git -C "$ROOT" fetch origin`, then check these stops in order before creating or modifying any file in the primary or a worktree, or running `git worktree add`.
8
+
9
+ | Observable case | Exact stop |
10
+ |---|---|
11
+ | `isCrossRepository` true | `PR #N's head lives on fork <headRepository.nameWithOwner>; rework needs an in-repo branch.` |
12
+ | `headRefName` listed by `git -C "$ROOT" worktree list --porcelain` at another path, including `.worktrees/pr-<N>` | `branch <headRefName> is checked out at <path>; finish or remove that worktree first.` |
13
+ | `git -C "$ROOT" rev-parse --verify -q <headRefOid>^{commit}` fails after fetch, or `origin/<headRefName>` differs from `headRefOid` | `PR #N head <headRefOid7> is not reachable (origin/<headRefName> is at <sha7>); the branch moved.` |
14
+ | Local branch exists and `git -C "$ROOT" merge-base --is-ancestor <headRefName> origin/<headRefName>` exits 1 | `local branch <headRefName> is at <sha7>, not an ancestor of origin/<headRefName> (<sha7>); rework needs the PR head.` |
15
+
16
+ ## Provision the exact head
17
+
18
+ Apply the first matching row after all stops pass. Keep the process cwd unchanged and carry WORKTREE as a value.
19
+
20
+ | State | Action |
21
+ |---|---|
22
+ | Selected home is already on `headRefName` | Run Step 3's dirty-tree ask first; do not stash or clean automatically. Then run `git -C "$WORKTREE" merge --ff-only origin/<headRefName>` and require HEAD equal to `headRefOid`; otherwise stop naming both SHAs. |
23
+ | No worktree, local branch exists | Only after ancestry proof, run `git -C "$ROOT" update-ref refs/heads/<headRefName> origin/<headRefName>`, then `git -C "$ROOT" worktree add "<home>" <headRefName>`. Never use `git -C "$ROOT" branch -f`. |
24
+ | No worktree, no local branch | Run `git -C "$ROOT" worktree add "<home>" <headRefName>`. Git's unique-remote DWIM resolves exactly one matching remote-tracking branch as `--track -b <headRefName> "<home>" origin/<headRefName>`; do not substitute the generic new-branch `-b` creation path. |
25
+
26
+ For fresh creation, apply Step 3's source-clean ask and the existing home safety checks after the ordered stops. Respect the resolved home and native tool/wrapper, but use an overrides `create:` only when it takes `<branch>` as an existing branch and contains no `-b`/`-B`. Otherwise run the built-in checkout above and add `create: override skipped (contains -b)` to the report. Resolve tokens and surface wrapper failures through the existing contract.
27
+
28
+ Verify `git -C "$WORKTREE" rev-parse HEAD` equals `headRefOid`. On a post-create head race, leave the tree intact and stop naming its path and both SHAs. Capture `PRE_REWORK_HEAD=<headRefOid>` and `BASE_SHA=$(git -C "$ROOT" rev-parse origin/<baseRefName>)` as full SHAs. In the Step 4 report use `Base: <headRefName> @ <sha7>` and add immediately after it:
29
+
30
+ ```text
31
+ PR: <owner/repo#N>
32
+ Pre-rework head: <sha>
33
+ Base SHA: <sha7>
34
+ ```
35
+
36
+ ## Preserve pre-rework history
37
+
38
+ Advance by merge: preserve every commit reachable from PRE_REWORK_HEAD. Never `git rebase`, or use `reset` or `commit --amend` to replace a commit at or below that boundary. Keep the flow's appended-spec approval `commit --amend --no-edit` in `brainstorming/reference/spec-finalization.md` and appended-wave fold `reset --soft "$WAVE_BASE_SHA"` in `subagent-driven-development/SKILL.md` unchanged; require WAVE_BASE_SHA to descend from PRE_REWORK_HEAD.
39
+
40
+ ## Merge the fetched base
41
+
42
+ Run `git -C "$WORKTREE" merge --no-ff --no-edit origin/<baseRefName>` and record the matching outcome:
43
+
44
+ | Outcome | Record and continuation |
45
+ |---|---|
46
+ | Base already an ancestor | `merge: no-op - head contains origin/<base>`; no commit. |
47
+ | Clean merge | `merge: <sha7>`; this merge is the first rework commit. |
48
+ | Conflicts | Follow the helper recipe below. |
49
+
50
+ Snapshot `git -C "$WORKTREE" status --porcelain` before helper dispatch. Get conflicted paths with `git -C "$WORKTREE" diff --name-only --diff-filter=U`. Dispatch one fresh foreground `implementer`, `cwd` the worktree, `async: false`, with that exact file list, fetched base, and SCOPED_TEST_COMMANDS. Require resolution of every listed file preserving both sides' intent, exactly the supplied scoped commands, and `git -C "$WORKTREE" add` for every resolved file. Require return `done`, or `done - contract exception: <why>` when resolution changes a PR or bound-ticket obligation. Forbid helper commits, aborts, and edits outside the list.
51
+
52
+ Read the first-found overrides file from BASE_SHA, not the conflicted tree: `git -C "$ROOT" show <BASE_SHA>:<overrides path>`. Use SCOPED_TEST_COMMANDS only from a documented file-scoped runner under `## PR gate` or `## verification-before-completion` with `requires credentials` not `true`. Missing runner or `requires credentials: true` means `none`, with the reason recorded as `none run (<reason>)`. Never infer file scope from a full-suite script such as `npm test`.
53
+
54
+ Continue only with an empty unmerged index (`git -C "$WORKTREE" diff --name-only --diff-filter=U`), every listed file staged (`git -C "$WORKTREE" diff --cached --name-only`), and the `git -C "$WORKTREE" status --porcelain` delta contained in the listed paths. Then complete with `git -C "$WORKTREE" commit --no-edit` and record `merge: <sha7>, <n> file(s) resolved, scoped tests <green | red in <file>: <tests> | none>`. Land a reported contract exception and name it in the spec's `## Rework record` `Changes:`.
55
+
56
+ For any failed helper/completion checks, run `git -C "$WORKTREE" merge --abort`, record `merge: unresolved - <files>`, and continue on the original unmerged head. Open the spec's Design with `merge origin/<base> and resolve <files>` as eventual Task 1. On every outcome, require the base-SHA constraint reads owned by `brainstorming/reference/pr-subject.md`.
57
+
58
+ Treat this merge, helper edits to the conflict list, and scoped conflict tests as the sole preapproval write/run exception outside spec directories. Run no other brainstorming tests, dispatch no reviewer, and push nothing; leave review of the merge to end-of-flow code review.
59
+
60
+ ## Fetch unresolved review threads
61
+
62
+ Run this query; callers cite this owner rather than copying it:
63
+
64
+ ```
65
+ gh api graphql --paginate -f query='query($o:String!,$r:String!,$n:Int!,$endCursor:String){repository(owner:$o,name:$r){pullRequest(number:$n){reviewThreads(first:100,after:$endCursor){pageInfo{hasNextPage endCursor} nodes{id isResolved isOutdated path line originalLine comments(first:100){pageInfo{hasNextPage endCursor} totalCount nodes{url body author{login} createdAt}}}}}}}' -F o=<owner> -F r=<repo> -F n=<N>
66
+ ```
67
+
68
+ Merge every reviewThreads page and filter to `isResolved == false`. For each thread whose comments report `hasNextPage: true` (with `totalCount` exceeding the first page), fetch the remaining pages by thread id with a separate comment cursor:
69
+
70
+ ```
71
+ gh api graphql --paginate -f query='query($id:ID!,$endCursor:String){node(id:$id){... on PullRequestReviewThread{comments(first:100,after:$endCursor){pageInfo{hasNextPage endCursor} nodes{url body author{login} createdAt}}}}}' -F id=<thread id>
72
+ ```
73
+
74
+ Start that thread's follow-up query at its first comment page, then replace its initial comments with the complete paginated connection to avoid duplicates. Keep each thread's comment cursor separate from the reviewThreads cursor and fetch until its last page. Carry all comments in order: read the first request and every reply because replies can change the request. Render location as `<path>:<line>`, else `<path>:<originalLine> (outdated)`, else `<path>`. On fetch failure carry `threads: not fetched (<reason>)` to the gather draft and `Threads: not fetched (<reason>)` to the record; continue. On successful empty fetch record `Threads: none`.
@@ -46,7 +46,7 @@ BEFORE claiming any status or expressing satisfaction:
46
46
  Skip any step = lying, not verifying
47
47
  ```
48
48
 
49
- Evidence is proportionate to the claim: a task or wave claim is proven by the commands the plan declares for it — a scoped run is **complete** evidence for a scoped claim. Phase-completion and ship claims require the project's full verification entrypoint (tests + style + format), run once at verify before the conformance gate.
49
+ Evidence is proportionate to the claim: a task or wave claim is proven by the commands the plan declares for it - a scoped run is **complete** evidence for a scoped claim. For phase-completion and ship claims, use the project's full verification entrypoint (tests + style + format), run once at verify before the conformance gate. For an approved spec carrying `## Rework record`, instead prove the scoped claim with the union of every plan task's `Tests:` commands plus the header's documented lint and format commands; treat `none - PR subject, scoped` as no header command, not an executable command. Keep freshness, conformance and phase gates intact; an open PR without that spec record does not select this policy.
50
50
 
51
51
  ## Common Failures
52
52
 
@@ -160,6 +160,8 @@ Defaults recognise `make ci`, `make test`, `npm test`, `pnpm test`, `yarn test`,
160
160
 
161
161
  Before running the verification gate, call `phase_tracker({ action: "start", phase: "verify" })`.
162
162
 
163
+ Run the plan header's full verification command set at verify. For an approved spec carrying `## Rework record`, instead run the union of every task's `Tests:` commands plus the header's documented lint and format commands, omitting task `none:` entries and the non-executable header sentinel `none - PR subject, scoped`. Read all task blocks, including the merge task; the lint/format-only header alone is not the verification set. Do not run the full test entrypoint on this PR-subject path or copy task commands into the header. Keep ordinary ticket/free-text verification unchanged and pass through the same freshness, conformance and phase gates; change no settings, runner or implement-phase gate.
164
+
163
165
  When all verification passes, finish and await the required `plan_tracker` updates before marking verify complete. Reconcile accepted work on its existing indices; never clear or reinitialize to obtain closure. In a direct verification path, complete only after those updates have actually returned.
164
166
 
165
167
  ```
@@ -178,12 +178,16 @@ Each step is **one action, 2-5 minutes**:
178
178
  ---
179
179
  ```
180
180
 
181
+ **PR-subject header.** Detect a PR subject only from `## Rework record` in the approved spec. For that subject, replace the header's full verification command set with only the overrides' documented lint and format commands. With neither documented, write `**Verification:** none - PR subject, scoped`; this sentinel is not a command. Keep every task's `Tests:` command out of the header: copying it there makes it a full-suite duplicate rejected by `plan_check`. Keep the original spelling; resolve duplication by separating the task tests from header lint/format, not by disguising commands. Read the PR specialization in [reference/plan-contract.md](reference/plan-contract.md#pr-subject-verification).
182
+
181
183
  The full verification entrypoint appears only on the `**Verification:**` line — see [reference/plan-contract.md § Header-only entrypoint](reference/plan-contract.md). The verify phase reads it from the plan; execution runs `Tests:` commands only. Execution runs it in the worktree via the subshell form `(cd "<abs worktree path>" && <command>)`; the process cwd stays in the primary checkout, and dispatch `cwd` is the worktree path. The `**Happy path:**` line is optional: present only when File Structure selected a row, with the row label, the row's command in backticks, and the row's `Timeout` as `(~<duration>)` (omit the suffix when the cell is absent or malformed). Like `Verification`, the happy-path command appears only on this header line - never in a task's `Tests:` or `Run:` block and never as free text in wave scope; `plan_check` enforces both.
182
184
 
183
185
  ## Task Structure
184
186
 
185
187
  Each task uses `- [ ]` checkbox steps so execution tools (and humans) can track progress.
186
188
 
189
+ **PR-subject tasks.** Read the approved spec's `## Rework record`. When its base merge is `unresolved`, make merging the named base and resolving the listed files Task 1, before thread fixes; preserve the original commits. Make each `fix` thread exactly one task whose title carries that thread id. Name the thread's request in its `Tests:` block through the scoped command and `via:` seam that exercises it. Keep `keep open` and `decline: <reason>` as recorded dispositions, not repair tasks. Apply the existing file-disjoint wave, spec-anchor, baseline and checker rules to these tasks without changing executor or spec-commit mechanics.
190
+
187
191
  ```markdown
188
192
  ### Task N: [Component Name]
189
193
 
@@ -276,7 +280,7 @@ If a decision is genuinely open, put it in an explicit **Open Questions** sectio
276
280
  The plan-writer runs Baseline, the deterministic checker, then the judgment checks before replying.
277
281
 
278
282
  - **Baseline.** Execute the numbered procedure below for task `Tests:` commands only; leave header `**Verification:**` to verify. Never author baseline evidence without execution.
279
- 1. Read provenance: `BASE=$(git -C "<abs worktree path>" rev-parse --short HEAD)` and `git -C "<abs worktree path>" status --porcelain --untracked-files=all`. Match every `XY <path>` entry (including `??`) against the worktree-relative plan and spec paths, plus only the parent-supplied `In-flight:` paths on an `Amend:` re-dispatch; never infer that set. Also allow untracked paths already recorded in existing baseline bullets' ` - artifacts:` suffixes in the plan at the plan path, excluding every plan `Create:` or `Test:` path. Keep those suffixes on retained bullets. Any other entry blocks all commands: collect `- Baseline: worktree dirty on <BASE>: <paths>`. Allowed in-flight paths outside the spec and plan directories are source edits: collect `- Baseline: in-flight source edits on <BASE>: <paths>` and run nothing. Allow doc-only workflow edits. For plain jj (no `.git`, VCS kind `jj`), use `BASE=$(jj -R "<abs worktree path>" log -r @- --no-graph -T 'commit_id.short()')` and `jj -R "<abs worktree path>" diff --summary`; classify one-letter status and relative paths identically (`A` includes new files). Never revert or clean anything.
283
+ 1. Read provenance: `BASE=$(git -C "<abs worktree path>" rev-parse --short HEAD)` and `git -C "<abs worktree path>" status --porcelain --untracked-files=all`. Match every `XY <path>` entry (including `??`) against the worktree-relative plan and spec paths, plus only the parent-supplied `In-flight:` paths on an `Amend:` re-dispatch; never infer that set. Also allow untracked paths already recorded in existing baseline bullets' ` - artifacts:` suffixes in the plan at the plan path, excluding every plan `Create:` or `Test:` path. Keep those suffixes on retained bullets. Any other entry blocks all commands: collect `- Baseline: worktree dirty on <BASE>: <paths>`. Allowed in-flight paths outside the spec and plan directories are source edits: collect `- Baseline: in-flight source edits on <BASE>: <paths>` and run nothing. Allow doc-only workflow edits. For plain jj (no `.git`, VCS kind `jj`), use `BASE=$(jj -R "<abs worktree path>" log -r @- --no-graph -T 'commit_id.short()')` and `jj -R "<abs worktree path>" diff --summary`; classify one-letter status and relative paths identically (`A` includes new files). Never revert or clean anything. Record a short baseline provenance note with the initial per-file inventory, BASE, and which exact paths were admitted before running commands; retain it even when a later run is contaminated or blocked.
280
284
  2. On Findings/Amend, retain a bullet only for unchanged command text on the same base; rerun commands with missing/invalid bullets, changed text, or different recorded SHA. `Findings: rerun baseline` reruns all commands. Never rewrite recorded SHAs without execution. For each command, split on the contract's separators (`&&`, `||`, `;`, `|`) and classify anchor tokens (a `Test:` path alone or with `::`/`#`/`:` filters) and selectors independently:
281
285
 
282
286
  | Command anchors/selectors | Baseline action |
@@ -47,6 +47,10 @@ The header value's backtick spans (else the raw value) are split on `&&`, `||`,
47
47
 
48
48
  The optional `**Happy path:**` line's backticked command is a second header entrypoint under the same rule: its segments join the header segment set, and its whole command may not appear in wave prose.
49
49
 
50
+ ## PR-subject verification
51
+
52
+ Detect this specialization only from `## Rework record` in the approved spec. Put only the overrides' documented lint and format commands in `**Verification:**`, or the literal `none - PR subject, scoped` when neither is documented. Treat the sentinel as no header command. Keep scoped tests in task `Tests:` blocks, never copy them into the header or change their spelling to evade `header-entrypoint` or `tests-block` rejection. Retain baseline evidence and all existing checker grammar. At verify, run the union of every task's `Tests:` commands plus the header's lint/format commands; omit `none:` entries and the sentinel from executable commands. This policy specializes the command set, not freshness, conformance or phase gates. Without the record, keep the ordinary full verification entrypoint.
53
+
50
54
  ## Happy path line (`header-happy-path`)
51
55
 
52
56
  Optional. When present, the header line reads `**Happy path:** <label> - \`<command>\`` with an optional ` (~<duration>)` suffix, `<duration>` matching `\d+(s|m|h)`. A present line that does not parse is a finding; absence is never a finding. The label names the row of the overrides file's `## Happy path` table the plan selected; the verify phase reads the line from the plan and re-derives the row from the real diff.