Skip to content

docs(pstack): port forge-neutral playbooks and Fable 5.1 defaults - #301

Merged
poteto merged 5 commits into
mainfrom
benny/port-lauren-playbooks-fable-5-1
Sep 1, 2026
Merged

docs(pstack): port forge-neutral playbooks and Fable 5.1 defaults#301
poteto merged 5 commits into
mainfrom
benny/port-lauren-playbooks-fable-5-1

Conversation

@poteto

@poteto poteto commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Why

Bring pstack's public PR workflows and TypeScript guidance up to the September 1 parity audit without importing private infrastructure. The PR flow stays portable: gh is the default, Origin is preferred when its CLI is installed and can resolve the repository, and Graphite is never required.

Scope

  • Update pstack/skills/poteto-mode/playbooks/{autopilot-full,autopilot-stack,babysit,multi-phase-plan,opening-a-pr,shipping}.md with early ready PRs and decision trails, bottom-up one-at-a-time landing, stable patch-id rechecks, base-branch stacks, forge-aware watch/reply commands, and trunk/head verification rules.
  • Align pstack/skills/poteto-mode/SKILL.md, pstack/skills/poteto-mode/references/bugbot-triage.md, pstack/README.md, and pstack/docs/guide/{06-verify-and-ship,07-overnight}.md with that forge policy.
  • Update pstack/skills/typescript-best-practices/{SKILL.md,references/patterns.md} with TypeScript path scoping, boundary branding, and schema-first validation with z.infer.
  • Upgrade 23 legacy Fable 5 slugs across 8 files plus 2 README labels. The Fable bump changes 25 references across 9 files to Fable 5.1.
  • Replace 8 solo Sol defaults across 6 files with claude-fable-5-1-thinking-max: pstack/README.md, pstack/skills/poteto-mode/SKILL.md, pstack/skills/setup-pstack/SKILL.md, and the bug-fix, perf-issue, and hillclimb playbooks.
  • Preserve 13 Sol panel seats across 7 files in Arena, Architect, How critics, Interrogate, Reflect, setup-pstack, and the README. Leave the non-model verifier: "sol" test fixture unchanged.
  • Update Fable panel peers in pstack/skills/{architect,arena,how,interrogate,reflect,setup-pstack,why}/SKILL.md, leave unrelated model lines unchanged, and bump pstack/.cursor-plugin/plugin.json to 0.14.6.

Key hunks

Tradeoffs

The bundled watch-pr implementation remains GitHub-specific. Origin babysitting uses public origin pr view, origin pr checks --watch, and origin pr thread commands instead of adding the private Origin TypeScript watcher surface.

The configured GitHub App could not resolve anysphere/everysphere; both repository and requested raw-content calls returned 404. The supplied September 1 audit was therefore the available source checklist for this port.

Blast Radius

This changes pstack agent instructions, default model routing, and plugin metadata. It does not change application runtime code. The model change affects solo bug-fix, performance, hillclimb, prose, and judgment defaults; multi-model Sol diversity remains intact.

Verification

  • Extracted the multi-phase checklist and ran check-plan.mjs: 1 PR section, 0 problems.
  • Ran the poteto-mode script suite with Bun 1.4.0: 52 passed, 0 failed; strict TypeScript typecheck passed.
  • Ran the repository plugin validator after installing its CI dependencies: all plugins validated successfully.
  • Scanned all of pstack/: no legacy Fable 5 slug or display reference remains; no gpt-5.5 reference exists; all 14 remaining text sol tokens are 13 panel model seats plus one non-model test fixture.
  • Scanned the six ported playbooks: no gt submit, gt track, gt restack, gt sync, Graphite stack, or Graphite merge-when-ready path remains.
  • Scanned added lines for the forbidden internal names, products, scripts, model slugs, and the all six typo: zero matches.
  • git diff --check origin/main...HEAD passed, and the branch is based on current origin/main.
Open in Web Open in Cursor 

cursoragent and others added 3 commits September 1, 2026 19:29
Co-authored-by: lauren <poteto@users.noreply.github.com>
Co-authored-by: lauren <poteto@users.noreply.github.com>
Co-authored-by: lauren <poteto@users.noreply.github.com>
Comment thread pstack/skills/poteto-mode/playbooks/shipping.md Outdated
Comment thread pstack/skills/poteto-mode/playbooks/babysit.md
@cursor

cursor Bot commented Sep 1, 2026

Copy link
Copy Markdown

PASS

Independent verification ran on PR head 30f00ebff1a14e6b9e5fc4544e975cf1fafa2a59, based on current main at 73f8be4873ea4ba2b7378243a036d3360c69e04d. Stable patch ID: a6aa47a3fce8cab473fd9e7d44451ec18ff5d33a. The worktree stayed clean.

Evidence:

  1. Forge policy
  • All six target playbooks state that gh is the default, select origin pr only when command -v origin succeeds and Origin resolves the repository, and state a fallback to gh.
  • A scan of those six files found no active gt submit, gt track, gt restack, gt sync, Graphite-stack, or Graphite merge-when-ready path. The remaining Graphite/gt text only says not to require or use it.
  • Real fallback probe: command -v origin returned /exec-daemon/tools/origin, but origin pr view 301 returned Repository cursor/plugins was not found on Origin. The playbooks correctly keep gh usable for this case.
  1. Model routing
  • Case-insensitive full-tree scan under pstack/: 0 legacy claude-fable-5-thinking-* slugs and 0 bare fable 5 display labels; 30 claude-fable-5-1-thinking-max occurrences.
  • bug-fix, perf-issue, and hillclimb each use Fable 5.1 as the solo default. The hardest judgment and strongest instruction-following defaults also use Fable 5.1.
  • gpt-5.6-sol-max remains in Arena, Architect, How critics, Interrogate, Reflect tooling, and setup panel definitions.
  1. TypeScript guidance
  • paths: ["**/*.ts", "**/*.tsx"] is present.
  • Branded types say to validate once at the boundary.
  • patterns.md contains Schemas before hand-rolled guards and derives type User = z.infer<typeof UserSchema>.
  1. Metadata and diff
  • pstack/.cursor-plugin/plugin.json changes 0.14.5 to 0.14.6.
  • git diff --check main...HEAD passed.
  1. Real checks
Bun 1.4.0
bun test orch watch-pr: 52 pass, 0 fail, 206 expect() calls, 4 files
bun run typecheck: exit 0
check-plan.mjs on the extracted skeleton: 1 PR sections, 0 problems
node scripts/validate-plugins.mjs: All plugins validated successfully.
GitHub “Validate plugins” check: SUCCESS at this head

No blocking findings.

Co-authored-by: lauren <poteto@users.noreply.github.com>
Comment thread pstack/skills/poteto-mode/playbooks/shipping.md Outdated
@cursor

cursor Bot commented Sep 1, 2026

Copy link
Copy Markdown

PASS+NOTES

Independent verification ran on PR head 8c59d2aab1676323acb546c16b824effca99b721, based on main at 73f8be4873ea4ba2b7378243a036d3360c69e04d. Stable patch ID of main...HEAD: 5fe66c081ded63a69882eeb5d2859b5d8f026547. This replaces the prior PASS on 30f00eb (patch ID a6aa47a3fce8cab473fd9e7d44451ec18ff5d33a), which commit 8c59d2a invalidated. The verifier did not author this PR. The worktree stayed clean and nothing was pushed.

Evidence:

  1. Forge policy
  • babysit.md step 1 and shipping.md step 1 both state: gh is the default; use origin pr ... only if command -v origin succeeds and Origin resolves the repository; otherwise stay on gh and record the fallback; never require Graphite (gt). The same text is in opening-a-pr.md, multi-phase-plan.md, autopilot-full.md, and autopilot-stack.md.
  • No gt submit, gt track, gt restack, or gt sync remains in any playbook. bugbot-triage.md no longer names gt ls -s.
  • Real fallback probe: command -v origin returned /exec-daemon/tools/origin (v2026.08.24), but origin pr view 301 returned Repository cursor/plugins was not found on Origin. The gh path is the live path for this repo.
  • Every origin pr subcommand and flag the playbooks name exists in the installed CLI: view --checks --comments, create --status open --base (--status choices are draft and open), edit --base, merge --squash --auto (Origin merge-when-ready), checks --watch, ready, thread list, and thread reply <thread-id> [target] --body-file.
  1. Bugbot terminal fixes in 8c59d2a
  • shipping.md step 8 now reads "Watch the current frontier until it merges or fails." It polls gh pr view <pr> --json state,mergedAt,mergeStateStatus,statusCheckRollup until the current bottom PR reports merged or a check or blocker fails, then runs step 7. It states: "Do not use Babysit's queued WAITING/merge-queue stop condition here." All four JSON fields are valid; gh pr view 301 --json ... returned them.
  • babysit.md step 6 stop conditions are split by forge. Origin: stop drive when checks are green, origin pr view reports mergeable with no blockers, and origin pr thread list has no unresolved blockers; Origin does not wait for READY, WAITING, ADVANCE, or COMPLETE. GitHub: READY in single or stack mode, a WAITING/merge-queue report in queued mode, or COMPLETE. Step 9, the explicit-stop paragraph, and the reply format were updated to match.
  • I checked those names against scripts/watch-pr/policy.ts and types.ts. Single and stack modes terminate with READY (exit 0). Queued mode emits a non-terminal WAITING with reason merge-queue for a blocker-free frontier and terminates only on COMPLETE, BLOCKER, or TIMEOUT. ADVANCE fires when the frontier changes. --status-only and --pretty exist. The playbook text matches the tool.
  • Both original Bugbot threads are resolved on GitHub.
  1. Model routing
  • Case-insensitive scan of pstack/: 0 claude-fable-5-thinking (non-5.1) slugs, 0 bare "Fable 5" labels, 30 claude-fable-5-1-thinking-max occurrences.
  • bug-fix.md, perf-issue.md, and hillclimb.md default to claude-fable-5-1-thinking-max. poteto-mode/SKILL.md routes both the strongest-judgment and the strongest-instruction-following roles to Fable 5.1. The README matches.
  • gpt-5.6-sol-max remains in how critics, reflect tooling, arena runners, the arena cross-judge pool, architect runners, interrogate Reviewer B, and the setup-pstack panel lines (12 occurrences).
  1. TypeScript best practices
  • paths: ["**/*.ts", "**/*.tsx"] is in the SKILL.md frontmatter. The table has a "Schemas before guards" row. patterns.md has ## Schemas before hand-rolled guards with type User = z.infer<typeof UserSchema>. Branded types now say "Validate once at the boundary".
  1. Metadata
  • pstack/.cursor-plugin/plugin.json: 0.14.5 to 0.14.6. Not bumped further.
  1. Real checks (bun 1.4.0, node 22.14)
node scripts/validate-plugins.mjs: All plugins validated successfully.
bun test orch watch-pr: 52 pass, 0 fail, 206 expect() calls, 4 files
bun run typecheck (tsc --strict on watch-pr): exit 0
watch-pr --owner cursor --repo plugins --pr 301 --status-only --pretty: STATUS terminal, exit 0, four-column table rendered
check-plan.mjs on the multi-phase-plan skeleton: 1 PR sections, 0 problems (same 27 boxes as main)
git diff --check main...HEAD: clean
GitHub "validate" check on 8c59d2a: SUCCESS

NOTES (non-blocking):

  1. Bugbot posted one new Medium finding on this head: "Shipping watch stops before merge" (shipping.md L13-14). I confirmed the mechanism independently. It is a real precision gap, not a false positive, but its blast radius is bounded.
    • Step 8 does not name the watcher mode. In single mode the tool exits READY (exit 0, terminal: true) as soon as the PR is mergeable, while the PR is still OPEN (policy.ts, runSimple -> classifyPr -> ready). An agent that reads that exit as the stop leaves before mergedAt is set. The text does say the watcher is "only an event wake" and that gh pr view reporting merged is the stop, so a careful reader lands correctly, but the tool's own output argues against that reading.
    • "a check or blocker fails" is not defined for the gh pr view poll. mergeStateStatus is BLOCKED while required checks are pending after --auto is armed. The watcher itself treats BLOCKED plus a non-failing rollup as allowed (assessGitHubMerge), but the playbook poll gives no such rule, so an agent can treat BLOCKED as a failure and stop or diagnose early.
    • Worst case is a premature stop or report, not a wrong merge or a topology change. Step 7 also self-guards ("confirm the merged SHA is present") if it is entered early.
    • Suggested fix: name the wake as watch-pr --queued-stack --stack-prs <bottom>. That mode keeps polling through WAITING/merge-queue and terminates COMPLETE when that one PR merges, or BLOCKER on a real blocker. Then define the poll predicates: merged = state is MERGED or mergedAt is set; failed = a statusCheckRollup entry with conclusion FAILURE, ERROR, CANCELLED, or TIMED_OUT, or mergeStateStatus DIRTY, or state CLOSED; BLOCKED or UNSTABLE with pending checks is a wait.
  2. Pre-existing and outside this PR: orchestrate.md step 2 seeds frontier.json with orch frontier set, which shells out to gt log short (scripts/orch/store.ts). This PR did not touch either file, but it is the last place the plugin still depends on Graphite.

No blocking findings. The two original Bugbot issues are fixed as described. Forge policy, model routing, TypeScript guidance, version, tests, typecheck, and plugin validation all hold at 8c59d2a.

Co-authored-by: lauren <poteto@users.noreply.github.com>
@poteto
poteto merged commit 23a56e2 into main Sep 1, 2026
2 checks passed
@poteto
poteto deleted the benny/port-lauren-playbooks-fable-5-1 branch September 1, 2026 20:07

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 3f27fff. Configure here.

5. **Land one PR at a time.** If the bottom PR is mergeable now, squash it with `origin pr merge <pr> --squash` or `gh pr merge <pr> --squash`. If requirements are still running and the user asked for merge-when-ready, arm only that PR with `origin pr merge <pr> --squash --auto` or `gh pr merge <pr> --squash --auto`. Origin's `--auto` is Origin merge-when-ready. GitHub's `--auto` is GitHub auto-merge. Wait for that PR to merge before preparing the next one.
6. **Do not read GitHub `autoMergeRequest` as stack readiness.** At most it says GitHub auto-merge was requested for one GitHub PR. It does not prove Origin merge-when-ready is armed, that a descendant is queued, that a patch verdict is current, or that the contiguous stack is safe. Confirm the active forge's state for the current bottom PR, and say that the state is unknown if the active forge cannot report it.
7. **Recompute after every merge.** Fetch trunk, confirm the merged SHA is present, drop the merged PR from the frozen bottom-to-top list, and inspect the new bottom PR's base, head, checks, and patch-id. A host may retarget a child automatically, but do not assume it did. Repeat steps 3 through 6 for that one PR. Independent work stays outside this chain and ships on its own.
8. **Watch the current frontier until it merges or fails. Do not mutate the queue around it.** With Origin, use `origin pr view <pr> --checks --comments` and `origin pr checks <pr> --watch`, then re-read the PR until it reports merged or blocked. With GitHub, use `scripts/watch-pr/watch-pr --queued-stack --stack-prs <bottom>` only as an event wake and poll `gh pr view <pr> --json state,mergedAt,mergeStateStatus,statusCheckRollup,autoMergeRequest` after each wake, ignoring `READY` until `mergedAt` is non-null or `state` is `MERGED`; only then run step 7. Hard-fail only when `state` is `CLOSED` with no `mergedAt`, a required check concludes `FAILURE` or `CANCELLED` and blocks merge after auto-merge is no longer pending, or `mergeStateStatus` is `UNSTABLE` or `DIRTY` with no auto-merge pending; `BLOCKED` while checks are pending or auto-merge is armed is not failure. Do not use Babysit's queued `WAITING`/`merge-queue` stop condition here. Hold the watch under `/loop` in dynamic mode. Report each merge and the new ceiling. If the queue stalls, diagnose before mutating, because a stalled requirement and a stale base can look identical from the outside.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipping watch terminals disagree

High Severity · Logic Bug

Step 8 now names watch-pr --queued-stack as the GitHub wake, then tells the agent to ignore READY and hard-fail only from a narrow gh matrix. That mode never emits READY; it does emit process-terminal BLOCKER on failing checks, threads, and conflicts. Those exits are not always a shipping hard-fail while --auto is still pending, and the step never rearms after a non-hard-fail exit, so the /loop can die on a flake or sit with no further wakes.

Fix in Cursor Fix in Web

Triggered by learned rule: Playbook terminal conditions must match tool verdict types across all modes

Reviewed by Cursor Bugbot for commit 3f27fff. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants