Skip to content

Sync Cursor pstack 0.15.5 as Open Pstack 1.5.0 #88

Description

@ericlitman

Goal

Import Cursor pstack 0.15.2 to 0.15.5 into the shared skill tree and release it as Open Pstack 1.5.0. Upstream content is the default. Keep the local Claude Code and Codex adaptations and the recorded exclusions. Deliver one PR with three commits, the same shape as PR #60 and PR #64. Closes #72.

Decisions (defaults Eric can override in a comment before execution starts)

  1. First-run panel follows upstream: Opus max, GPT-5.6 Sol max, Grok 4.7 xhigh. Judgment and prose, hardest tasks and the How explainer move from Fable max to Opus max. Fable stays a supported, selectable family with its native agents.
  2. Bug-fix, perf-issue and hillclimb stay on codex:gpt-5.6-sol@max, not upstream's Grok 4.7. This is the recorded local choice, and the existing static check enforces it.
  3. Fold, don't merge, PR Allow setup with only assigned model providers #73. Only the setup change the three-model default forces is taken: ask about roles first, then ask efforts for and probe only the assigned families. Allow setup with only assigned model providers #73 is closed with credit after this lands, on Eric's OK.

If Eric overrides 1 or 2, change only the default descriptors in commit 2 and the matching UPSTREAM.md exclusion bullet; nothing else in this ticket moves.

Pins

  • Base: open-pstack main at de67e6b40511814171e5e4c8ad7af3b79f07c9ee (Open Pstack 1.4.1). If main has moved, branch from current main and rerun the audit; the resolutions below still apply hunk by hunk.
  • Last imported upstream: f8abeddd1862dc73704e3d719dd73df0d51b8c71 (pstack 0.15.1).
  • Target: 12d587dfb20741cafc376c42c696c5f6e2a64487 (pstack 0.15.5). Keep this pin even if cursor/main has moved on.
  • Upstream commits in range:
    • f5bdd68 #362 (0.15.2): operator-neutral wording, in-chat tick status.
    • 889ec4b #365: bug-fix/perf-issue/hillclimb move to Grok.
    • 5bf2b15 #366: setup budget question.
    • 70b2dc8 #414 (0.15.3): Opus 5.5 and Grok 4.7, three-model panel, code-ready rounds, children.tsv, prompt cuts, non-truncating log.sh.
    • b42effe #416: upgrade-help wording.
    • b0b9c7a #419 (0.15.4): 19 instruction cuts, Reflect quota removal.
    • 12d587d #422 (0.15.5): role-line reads, retired roles, owner and Babysit exceptions, plan-lane regex, audit-log runs.

Out of scope

Step 0: branch, audit, mechanical merge

git fetch origin
git remote get-url cursor >/dev/null 2>&1 || git remote add cursor https://github.com/cursor/plugins.git
git fetch cursor main
git switch -c sync/cursor-pstack-0.15.5 origin/main
audit=${TMPDIR:-/tmp}/pstack-0.15.5-audit.json
python3 scripts/upstream-audit.py --port $(git rev-parse HEAD) --upstream 12d587dfb20741cafc376c42c696c5f6e2a64487 > $audit
python3 scripts/upstream-merge.py $audit

On de67e6b this produces 45 changed upstream paths:

  • 7 taken verbatim.
  • 15 clean three-way merges.
  • 20 files with 36 conflict hunks, marked <<<<<<< port … >>>>>>> upstream-target.
  • 3 unmapped paths, which stay unported: pstack/.cursor-plugin/plugin.json, pstack/docs/guide/01-setup.md, pstack/docs/guide/07-overnight.md.

Resolve every hunk from the port side and add only upstream's new behavior. Do not take an upstream side and re-translate it.

Substitutions for new upstream text

These are the port's existing translations (see CHANGES.md):

  • ~/.cursor/rules/pstack-models.mdc or “the rule” → the current harness's pstack model sheet
  • claude-opus-5-5-max → claude:opus@max; gpt-5.6-sol-max → codex:gpt-5.6-sol@max; grok-4.7-xhigh-fast → grok:grok-4.7@xhigh
  • Task, subagent_type: generalPurpose, readonly, environment: cloud, run_in_background → the port's provider-dispatch sentence (read-only or isolated-write)
  • AskQuestion → AskUserQuestion
  • “arm a /goal” → write the objective into the standing orders and todolist
  • one Cursor cloud agent per PR → one background subagent per PR in its own worktree
  • control-cli / control-ui from cursor-team-kit → the run skill for CLIs and TUIs, verify for UIs
  • git show origin/main:pstack/... → re-read skills/... from the installed plugin
  • terminal /loop with a sleep, or cloud-sleeper → /loop in dynamic mode
  • agent-transcripts/ and ~/.cursor/projects/*/ → ~/.claude/projects/<encoded-cwd>/
  • “agent id” → session id; the program's agent list → the parent's background task list
  • deslop from cursor-team-kit → the deslop skill
  • “opens the PR ready, never draft” → Opening a PR's readiness rule
  • bare git push --force-with-lease → the captured-SHA lease in Autopilot-full step 2 and Shipping step 4
  • “the repo's AGENTS.md files and rules” → the repo's instruction files (AGENTS.md, CLAUDE.md)

Two things upstream adds must never land. The first is the rejected-slug fallback (“If the Task tool rejects … family's default … closest valid slug”); AGENTS.md forbids a weaker-model fallback. The second is “passes its expected runtime” as a stuck test; AGENTS.md forbids an implicit timeout.

Commit 1: sync: port Cursor pstack 0.15.2-0.15.5 skill content

Keep every model default at its current port value in this commit; commit 2 changes the defaults. Paths below are under plugins/pstack/skills/ unless noted.

Keep the merge result with no edits:

  • README-UPSTREAM.md (repo root)
  • how/references/explorer-prompt.md
  • interrogate/references/{code-quality-review,reviewer-prompt,rubric}.md, including #419's two deleted What-to-Avoid bullets
  • poteto-mode/playbooks/{pause-safely,opening-a-pr}.md
  • show-me-your-work/scripts/log.sh (mode 100755)
  • blast-radius, figure-it-out, tdd, technical-writing, unslop
  • principle-{guard-the-context-window,never-block-on-the-human,outcome-oriented-execution,prove-it-works,sequence-verifiable-units}
  • reflect/references/{divergent,judgment,tooling}-reviewer.md

Clean merge that needs one edit: in poteto-mode/playbooks/babysit.md step 4, change “publishes it with git push --force-with-lease per playbooks/autopilot-full.md step 2” to “publishes it through the disarm and captured-SHA lease steps in playbooks/autopilot-full.md step 2”.

Conflicted files:

  • poteto-mode/scripts/check-plan.mjs: run git checkout origin/main -- plugins/pstack/skills/poteto-mode/scripts/check-plan.mjs. Its LANE_SENTENCE already reads the configured swarm workers role.

  • architect/SKILL.md: replace the hunk with one line:

    Take the runners from architect runners in the current harness's pstack model sheet, in place of Arena's arena runners. If the sheet or that line is missing, use claude:fable@max, codex:gpt-5.6-sol@max, grok:grok-4.6@xhigh, claude:opus@xhigh.

    Do not add the “Alias and rejected entries” sentence.

  • arena/SKILL.md, interrogate/SKILL.md, poteto-mode/playbooks/hillclimb.md, poteto-mode/playbooks/perf-issue.md: port side. Upstream changed only models, fallback text and Cursor wording there.

  • how/SKILL.md: port side, with two wording changes. “your configured how-explorer descriptor” becomes “the how explorer descriptor”. Both occurrences of “your configured how-explainer descriptor” become “the how explainer descriptor”.

  • why/SKILL.md: port side. “your configured why-investigators descriptor” and “your configured why-synthesizer descriptor” both become “the why investigators, synthesizer descriptor”. Defaults stay inherit-parent.

  • reflect/SKILL.md: port side. “your configured reflect-judgment choice”, “your configured reflect-tooling choice” and “your configured reflect-judgment descriptor” all become “the reflect tooling, judgment, divergent, synthesizer descriptor”. Defaults stay inherit-parent.

  • swarm/SKILL.md: port side for steps 3 and 4 and Phase B. Step 5 becomes:

    Give each worker its own writable output when it writes. When workers verify or measure commits, each brief names the exact SHAs. A measurement brief also names the method (sample count, what one sample is, order). The worker records both in its result.

    Keep the clean-merged Phase B ISSUES text and the Phase C drop, rerun-once and gap rules.

  • show-me-your-work/SKILL.md: keep the clean-merged run and start-row paragraph, changing “such as its agent id” to “such as its session id”. Resolve the hunk to:

    At the end of the run, before handing back, check the log told the truth. Read this run's transcript under Claude Code's per-project transcripts directory at ~/.claude/projects/<encoded-cwd>/. Don't glob across ~/.claude/projects/. That reads unrelated private chats. Walk this run's rows against what actually happened. Each stretch of them begins at one of this run's start rows, or at the first row if this run created the log, and ends at the next start row of another run:

    Keep the clean-merged “Check that…” bullets and the supersede-only paragraph.

  • poteto-mode/SKILL.md:

    1. Keep the port line that starts “About to AskUserQuestion”. Append upstream's four sentences from “Under a full-autonomy grant, decide a call that the grant covers” through “still need the operator.”
    2. Keep the port paragraph “Defaults for every delegation”. Insert this before its final inherit-parent sentence: “Each code playbook's configured model comes from its line (feature, refactoring, bug-fix, perf-issue, or hillclimb), and the hardest changes read hardest tasks. Prose and judgment read judgment and prose.”
    3. Take upstream's Autopilot-full catalog line (“swarm-verifies each PR”). For the Autopilot-stack catalog line, keep the port line and change “the operator lands herself.” to “the operator lands.”
  • poteto-mode/playbooks/bug-fix.md:

    • Step 1 becomes:
      1. Reproduce it yourself on the matching surface via the driver skill (run for CLIs/TUIs, verify for UIs) (Non-negotiables), even when a debug or instrumentation protocol says to ask the user to reproduce. Ask the user only with a stated, specific reason the control surface cannot reach the target, and only after driving it as far as it goes. If it won't reproduce directly, synthesize the trigger, tighten conditions, or instrument until it fires.
    • Step 2: port side.
    • Step 3: port side without “Review the diff.”
    • Delete the line “Investigation fans out how + why as parallel subagents.” and the blank line after it.
    • Reply line: port side (the local Sync Cursor pstack 0.14.3 verified multi-PR checklist #17 wording).
  • poteto-mode/playbooks/feature.md: keep the clean step-2 cut. In step 4, keep the port text but remove “Review its diff yourself.” Keep “The delegate owns the diff directly and never waits on or launches a nested agent.”

  • poteto-mode/playbooks/refactoring.md: step 5 is the port text without its final “Review the diff yourself.” Step 6 is the port's driver-skill text without “Own the verification yourself. Do not trust a delegate's 'looks good' summary.”

  • poteto-mode/playbooks/shipping.md: port side for every step. In step 3, replace “Re-verify when the patch changed.” with:

    When the two patches differ only in tests, docs, or lint config, build what each lane ran. Build it twice at <verdict-sha> and once at <current-head>. A difference is noise if the two builds at <verdict-sha> also show it, or if it is an embedded commit SHA. Judge each difference, not each file, and report each kind of noise with its files. If only noise differs, that lane's result stays valid, and checks and a review of the change run fresh. Do not reuse a lane result from a dev server or from anything else with no build output. Rerun that lane. Re-verify anything else when the patch changed.

  • poteto-mode/playbooks/autopilot-full.md: start from the port text.

    • Step 1. “stay hers. She reviews and she clicks” becomes “stay with the operator. The operator reviews and clicks”. “When she asks” becomes “When the operator asks”. “on her explicit go” becomes “on the operator's explicit go”. Keep the standing-orders sentence.

    • Step 2.

      • After “Keep decisions.tsv uncommitted and return it with the reports.” add: “As soon as a subagent starts, the owner adds its retained handle (Agent task, background Bash task, Codex agent or session ID, or runner receipt path) and its state to a children.tsv kept the same way.”
      • “Before babysit, a self-contained PR” becomes “Before the code-ready report and babysit, whether or not trunk has drifted, a self-contained PR”. Keep every command and its order.
      • Replace “It then runs the babysit loop to green (playbooks/babysit.md) and owns the merge itself.” with:

        When the shipped code is final, after the slop-strip and /no-comments, it reports the code-ready head SHA, and the SHA of each later push that changes the patch. Self-proof, CI, and the babysit loop (playbooks/babysit.md) then run in parallel with the swarm. The owner reports merge-ready with the head SHA when they finish, and owns the merge itself. Before a push that starts a round, run the pre-review checks that the repo's instruction files (AGENTS.md, CLAUDE.md) name for the touched paths, on the committed head. A hook pass is not proof.

      • Replace “The required rebase always precedes babysit and never waits for drift or conflicts.” with:

        In fix rounds, the owner keeps that merge base. It rebases again only at merge prep (step 5), on a git merge-tree conflict with trunk, or on a CI failure that comes from a change on trunk, each time through the disarm, captured-SHA, and lease steps above. Never force-push a shared branch.

    • Step 4. Use upstream's step 4 text, with the heading “Swarm-verify every round before its merge.” Write its live lane as “(the run skill for CLIs and TUIs, verify for UIs, or a named driver where neither fits)”.

    • Step 5. Keep the port text. After “The owner merges only from a head freshly rebased onto trunk.” insert:

      Merge prep never comes before a round's lanes start, and it ends with a rebase onto current trunk right before the merge. After the merge-prep rebase, the owner reports the new head SHA. CI must pass on that head before the merge, and the patch-id rule decides whether the round's verdict still holds.

      Keep all the expected-head landing sentences. “wait for her click” becomes “wait for the operator's click”.

    • Step 6.

      • After “granted only after verifier proof.” insert upstream's four sentences, from “If the operator's grant or standing orders cover approvals, that countersign is the approval.” through “The root never gives or bypasses an approval that the forge enforces.”
      • Keep the port tick text: dynamic /loop, installed-plugin re-read, retained handles, affirmative-failure stand-down.
      • Replace “Cancel through the retained handle before dispatching a replacement.” with:

        Each tick also runs this stuck test over the parent's background task list and every owner's children.tsv. Cancel a stuck lane through its retained handle. Whether or not the cancel succeeds, the root has the owner record it as stuck in children.tsv and, if its work is still needed, replace it. Each replacement that fails gets the same steps. The root takes both steps when the owner cannot. A stall never proves or drops the work.

      • After the retro sentence add: “End the tick only when no delegated work is left, even after the last merge.”
    • Step 7. “Her hold” becomes “The operator's hold”. “until she releases them” becomes “until the operator releases them”.

  • poteto-mode/playbooks/autopilot-stack.md: start from the port text.

    • Intro. The last clause becomes “then hand the operator one linear stack to review and land.”

    • Step 1. Append “Owners also keep the children.tsv of Autopilot-full step 2.”

    • Step 2. Append “Probe all subagents and end the tick per Autopilot-full step 6.” Keep the port's installed-plugin re-read, dynamic /loop, affirmative-failure and cancel-before-replace sentences.

    • Step 3. “On her explicit go” becomes “On the operator's explicit go”. “On her stop” becomes “On the operator's stop”.

    • Step 4. Use upstream's “Verify each round.” text: the owner reports code-ready, then STACK-READY, and the root verifies each round per Autopilot-full step 4 with STACK-READY in place of merge-ready.

    • Step 7. Replace the sentences from “Compare the stable git patch-id” through “goes back through step 4 before delivery.” with:

      Apply the patch-id rule in playbooks/shipping.md step 3 at each verdict SHA, using each PR's recorded patch-base-to-head diff. Anything no longer valid goes back through step 4 before delivery.

      Keep “step 6's captured-SHA lease flow” and the mergeability/CI rerun sentence.

    • Steps 5, 6 and 8. Port side.

  • poteto-mode/playbooks/multi-phase-plan.md:

    • Keep the port lane sentences in the Verification paragraph and in Verify, live. Keep the port Arm-the-program block and the port Bugbot line.
    • Tick prompt: keep the port text through “dispatch its replacement in the same tick.” Then replace the old status sentence with upstream's text, from “Then post a short status message to the operator in chat only when the audit found a tracked change” through “The row names the items reported, or none.”
    • The rebase line becomes:
      • Rebase each independent PR and stack root onto current trunk before the code-ready report and babysit. Rebase each unmerged stack child onto its parent's exact tip. Keep that merge base in fix rounds. Rebase again only at merge prep, on a git merge-tree conflict with trunk, or on a CI failure that comes from a change on trunk. After its parent merges, use Shipping's explicit old-base-to-trunk rebase before the child's merge-ready report.
    • The first two Verdict lines become:
      • At the code-ready head SHA and at each later push that changes the patch, run the swarm per skills/swarm/SKILL.md. One gates lane. The ten live lanes from the PR's Verify, live block. The perf lane from its Verify, perf block. Two or more audit lanes, each with its own focus, that read the diff and the receipts and distrust the PR body. The root audits the receipts in the merge-ready report before the verdict.
      • Clean only when every lane is PASS. Findings go back to the owner, including a defect that a lane filed as a note. A new head gets a fresh swarm and a fresh verdict, except for results that stay valid under the patch ID rule in skills/poteto-mode/playbooks/shipping.md.
    • Keep the port merge-rule placeholder line.
  • setup-pstack/SKILL.md: take the port side of all four hunks, so there is no budget, no .mdc file and no AskQuestion. Then take #422's retired-role rule:

    • In step 2, replace “A duplicate or unknown role row is inconsistent state; report it and resolve it before probing.” with:

      A duplicate role row is inconsistent state; report it and resolve it before probing. A row whose role is not in the step 7 role map, such as how critics, is from a retired role. Drop it and list it at confirmation.

    • In step 3, “duplicate role, or unknown role is inconsistent state” becomes “or duplicate role is inconsistent state”.
    • In step 7, append “and any retired-role rows dropped in step 2” to the first sentence.

After commit 1, run the checks below. They must pass with the old defaults.

Commit 2: defaults: Opus/Sol/Grok 4.7 first-run panel; setup probes assigned families

poteto-mode/references/provider-dispatch.md:

  • Keep the row order fable, sol, grok, opus and leave the sol row unchanged. Set the other rows to:
    • | fable | - | claude | fable | max | low medium high xhigh max | fable |
    • | grok | grok-4.7-xhigh-fast | grok | grok-4.7 | xhigh | low medium high xhigh max | - |
    • | opus | opus | claude | opus | max | low medium high xhigh max | opus |
  • After “First-run requested efforts are the Default effort cell of each row.” add: “The first-run panel is Opus, Sol, and Grok, in that order. Fable stays selectable, but no first-run role uses it.”
  • “pins the current CLI model grok-4.6” becomes “pins the current CLI model grok-4.7”.

setup-pstack/SKILL.md. The three-model default forces this change, and it closes #72.

  • Frontmatter description. “Verifies native and external Claude, Codex, and Grok lanes before writing the override sheet.” becomes “Verifies the assigned native and external lanes before writing the override sheet.” In the intro, “Choose one requested effort per matrix family.” becomes “Choose one requested effort per assigned matrix family.”
  • Step 2. Move the step 6 paragraph that starts “After effort selection, ask whether to keep” to the end of step 2, reworded as:

    Then ask whether to keep these role-to-family assignments or change named roles. Keeping them is the default. Apply only role changes the operator names; never offer a reset of a customized sheet to the first-run assignments. A changed role may use any model-matrix family, inherit-parent, or auto.

  • Step 3. Replace “A family with no non-alias occurrence is unassigned; use its matrix Default effort as the proposed value and label it unassigned rather than calling it current.” with:

    A family with no non-alias occurrence is unassigned: do not ask for its effort, check its CLI, or probe it. A family that a step 2 role change newly assigns takes its matrix Default effort as the proposed value.

  • Step 4. The paragraph becomes:

    Ask one effort question for each assigned family. Name each model, its current or proposed value, and the Selectable efforts from its matrix row. Empty input keeps that value. On a first run, state the assigned families' matrix defaults before asking. On a rerun, state the parsed values without offering to reset customized role lanes.

  • Step 5. The heading becomes ### 5. Probe the requested pairs. Its first two sentences become “Probe only the selected provider:model@effort pair of each assigned family. Run one probe per family in the role map, even when two families share a provider.” Keep the four-row route table and the rest of the step.
  • Step 6.
    • Append “, with the step 2 role changes applied” to the first-run bullet.
    • In the rerun bullet, insert “, with the step 2 role changes applied,” after “normalized complete role map from step 2”.
    • Delete the paragraph “Require the final role map to contain at least one descriptor from each matrix family. …” (both sentences).
    • “a model other than the four matrix families” becomes “a model outside the model matrix”.
  • Step 8. “only after all four probes pass” becomes “only after every requested pair passes”.
  • Step 9. “all four chosen descriptors” becomes “every distinct chosen descriptor”.
  • First-run sheet (the fenced block): keep the heading and preamble. The rows become:
feature, refactoring: grok:grok-4.7@xhigh
bug-fix: codex:gpt-5.6-sol@max
perf-issue: codex:gpt-5.6-sol@max
hillclimb: codex:gpt-5.6-sol@max
judgment and prose: claude:opus@max
hardest tasks: claude:opus@max
how explorer: grok:grok-4.7@xhigh
how explainer: claude:opus@max
why investigators, synthesizer: inherit-parent
reflect tooling, judgment, divergent, synthesizer: inherit-parent
arena runners: claude:opus@max, codex:gpt-5.6-sol@max, grok:grok-4.7@xhigh
arena cross-judge pool: claude:opus@max, codex:gpt-5.6-sol@max, grok:grok-4.7@xhigh
swarm workers: grok:grok-4.7@xhigh
architect runners: claude:opus@max, codex:gpt-5.6-sol@max, grok:grok-4.7@xhigh
interrogate reviewers: claude:opus@max, codex:gpt-5.6-sol@max, grok:grok-4.7@xhigh

Do not add an inherited-alias probe, a setup-time Architect minimum, panel-removal rules, a smoke-failure loop, or a test document; those come from #73 and are not taken.

Defaults elsewhere:

  • arena/SKILL.md step 3: “Otherwise default to one each on claude:opus@max, codex:gpt-5.6-sol@max, grok:grok-4.7@xhigh.” Keep the cross-judge sentence (“otherwise from the runner defaults above”) so the Grok descriptor appears on exactly one line.
  • architect/SKILL.md: the same three descriptors on its one runner line.
  • interrogate/SKILL.md: “Reviewer A/B/C/D labels” becomes “Reviewer A/B/C labels”. The table is A claude:opus@max, B codex:gpt-5.6-sol@max, C grok:grok-4.7@xhigh; delete the Reviewer D row.
  • how/SKILL.md: the explorer default becomes grok:grok-4.7@xhigh and both explainer defaults become claude:opus@max.
  • swarm/SKILL.md: the step 4 default becomes grok:grok-4.7@xhigh.
  • poteto-mode/playbooks/feature.md step 4 and refactoring.md step 5: grok:grok-4.6@xhigh becomes grok:grok-4.7@xhigh. Leave bug-fix, perf-issue and hillclimb on codex:gpt-5.6-sol@max.
  • poteto-mode/SKILL.md, Defaults paragraph: replace the sentence that starts “Upstream defaults use Grok 4.6 xhigh” with the text below. Use prose only, no descriptors, in this meta-file (see CHANGES.md).

    Defaults use Grok 4.7 xhigh for feature/refactoring, exploration, and swarm work; GPT-5.6 Sol max for bug fixes, performance work, and hillclimbing; Opus max for judgment, prose, explanation, and hardest tasks; and the three-model Opus, Sol, and Grok panel for model-diverse judgment.

  • poteto-mode/references/codex-tools.md line 45: the example descriptors become claude:opus@max, codex:gpt-5.6-sol@max and grok:grok-4.7@xhigh. The last sentence becomes “The default panel runs one model from each of three providers and contains no older GPT or Claude substitute.”

Existing tests. Edit only these:

  • poteto-mode/scripts/runner/model-matrix.test.ts:
    • Add const FIRST_RUN_PANEL = ["opus", "sol", "grok"] as const; next to FAMILY_ORDER.
    • Change defaultDescriptors(rows) to take a family list and return families.map(...) of each family's row as ${provider}:${model}@${defaultEffort}. It should throw on a missing family.
    • const quad = defaultDescriptors(rows) becomes const panel = defaultDescriptors(rows, FIRST_RUN_PANEL), and expectedPanel = panel.join(", ").
    • ["opus", "xhigh"] becomes ["opus", "max"].
    • In SETUP_SECTION_ORDER, "### 5. Probe the four requested pairs" becomes "### 5. Probe the requested pairs".
    • Change nothing else. FAMILY_ORDER stays fable, sol, grok, opus.
  • tests/skill-collision-repro.sh:
    • Replace the awk block that builds canon_quad from every matrix row with canon_panel="$( { grep -m1 '^arena runners:' "$setup" || true; } | quad_of)". The || true matters: the script runs under set -euo pipefail, and without it a missing row aborts the script before the named failure message prints.
    • Update the comment to say that setup-pstack's first-run arena runners row is the default panel, and that the other panel rows and the arena, architect and interrogate defaults copy it verbatim.
    • Rename quad to panel in variable names, comments and messages. “could not read the canonical quad from $dispatch” becomes “… panel from $setup”, and “Reviewer A/B/C/D” becomes “Reviewer A/B/C”.
    • Keep dispatch=, because the sol-row check uses it. Change nothing else in the file.

Commit 3: release: sync Cursor pstack 0.15.5 as Open Pstack 1.5.0

  • Version. Set 1.5.0 in .claude-plugin/marketplace.json, plugins/pstack/.claude-plugin/plugin.json and plugins/pstack/.codex-plugin/plugin.json. .agents/plugins/marketplace.json has no version field; leave it alone.
  • UPSTREAM.md.
    • Table: commit 12d587dfb20741cafc376c42c696c5f6e2a64487, upstream 0.15.5, open-pstack 1.5.0.
    • Sentence: “Open Pstack 1.5.0 imports this 0.15.5 sync.”
    • The git log / git diff ranges start at 12d587dfb20741cafc376c42c696c5f6e2a64487.
    • Exclusions: rewrite the 23a56e2 bullet and add four more:
      • “The default-model hunks for bug-fix, perf-issue, and hillclimb from 23a56e2, 889ec4b, and 70b2dc8 are not applied. Those frequent code-writing roles stay on codex:gpt-5.6-sol@max.”
      • “5bf2b15's setup budget question, its # budget line, and its step down to a lower detected effort are not applied. Setup already asks one requested effort per assigned family, and the step-down would silently lower a requested effort.”
      • “12d587d's rule that reruns a rejected configured entry on its family default or the closest valid slug is not applied. An unavailable model stays a named dropout per provider-dispatch.md.”
      • “The expected-runtime column in 70b2dc8's children.tsv and its expected-runtime stuck test are not applied. A lane is stuck only on affirmative failure evidence.”
      • “The explicit Grok, Opus, and Sol defaults for the Why and Reflect roles are not applied. Those roles stay on inherit-parent because the external runner omits the parent's MCP servers.”
  • CHANGES.md. Add a top section “## 1.5.0 syncs to Cursor pstack 0.15.5” with two short paragraphs:
    • The defaults: the trio panel; Opus max for judgment/prose, hardest tasks and the How explainer; Grok 4.7 xhigh for feature/refactoring, the How explorer and swarm; Sol max kept on bug-fix/perf-issue/hillclimb; Why and Reflect kept on inherit-parent; Fable still in the matrix with its native agents. Setup asks about roles first, then asks efforts for and probes only assigned families (the ordering follows PR Allow setup with only assigned model providers #73 by @arjitj2). It drops and lists retired-role rows such as how critics.
    • What was imported and what was not. Imported: the neutral wording, tick status only on change, code-ready rounds with 2+ audit lanes and one fix-forward, rebases at the code-ready report and at merge prep, children.tsv, the owner Babysit exception, countersign-as-approval, Architect reading architect runners, Swarm SHA/method briefs, Shipping build-noise lane reuse, decision-trail start rows and supersede-only corrections, the non-truncating log.sh, and the #419 cuts. Not applied: the five exclusions above, the Cursor manifest and docs/guide/. Then: existing sheets are not rewritten; delete role lines and rerun setup to take the new defaults; a grok:grok-4.6 row keeps running until setup asks for its replacement; with no sheet, the new defaults apply on update.
    • In the Maintenance paragraph, replace the sentences about the canonical default panel quad with: “The canonical default panel is the arena runners row of the setup-pstack first-run sheet. It is copied into the other three panel rows and into arena, architect, and interrogate. Keep those copies grep-identical when models change. The static test reads the panel from that row, and model-matrix.test.ts pins its families and checks each effort against the matrix.”
  • NOTICE.md. After the 0.15.1 row, add:

    | plugins/pstack/skills/ (0.15.2 to 0.15.5 changes: three-model defaults, code-ready rounds, owner authority, prompt cuts, decision-trail runs, show-me-your-work/scripts/log.sh), README-UPSTREAM.md | cursor/plugins/pstack @ 12d587d | (c) 2026 Lauren Tan | MIT | LICENSE |

  • README.md.
    • “For the full four-model review” becomes “For the full three-model review”.
    • “The current default group uses Fable, GPT-5.6 Sol, Grok 4.6, and Opus.” becomes “The default review panel uses Opus, GPT-5.6 Sol, and Grok 4.7, and setup probes only the models your roles use. Fable remains available.”
    • After the rolling-alias paragraph, add: “A model sheet from an earlier release keeps its panel. To take the new defaults, delete those role lines and run setup again; setup fills missing roles from the defaults. A grok:grok-4.6 entry keeps running until the next setup run asks you to replace it.”
    • “one requested effort per model family” becomes “one requested effort per model family you assign”.
    • The version line becomes Open Pstack 1.5.0, pstack 0.15.5, commit 12d587dfb20741cafc376c42c696c5f6e2a64487.
  • docs/reference.md.
    • Line 5: version 1.5.0, Cursor pstack v0.15.5, commit 12d587dfb20741cafc376c42c696c5f6e2a64487.
    • Line 89: “per frontier family” becomes “per assigned family”. The first-run panel sentence becomes “The first-run panel is Opus max, GPT-5.6 Sol max, and Grok 4.7 xhigh; Fable stays selectable with its native agents.” “instead of upstream's Fable default because Sol costs less for these frequent delegated code roles” becomes “instead of upstream's Grok 4.7 default”.
    • Line 91: “fan out the frontier quad” becomes “fan out the configured panel”.
    • Line 128: “four different models” becomes “several different models”.
    • Line 196: “Provider dispatch runs the upstream three-model panel: claude:opus@max, codex:gpt-5.6-sol@max, grok:grok-4.7@xhigh. Same-provider lanes stay native; external lanes use the bundled runner.”
    • Line 214: “Solo code defaults (upstream 23a56e2 moved them to Fable; 889ec4b and 70b2dc8 move them to Grok 4.7). Open Pstack keeps bug-fix, perf-issue, and hillclimb on codex:gpt-5.6-sol@max.”

Checks (after each commit, and before the PR leaves draft)

(cd plugins/pstack/skills/poteto-mode/scripts && bun install --frozen-lockfile && bun run test && bun run typecheck)
bun -e 'for (const path of [".claude-plugin/marketplace.json", ".agents/plugins/marketplace.json", "plugins/pstack/.claude-plugin/plugin.json", "plugins/pstack/.codex-plugin/plugin.json"]) JSON.parse(await Bun.file(path).text())'
PSTACK_STATIC_ONLY=1 bash tests/skill-collision-repro.sh
claude plugin validate .
claude plugin validate plugins/pstack
git diff --check origin/main...HEAD
git grep -nE '^(<<<<<<<|>>>>>>>) ' -- plugins README-UPSTREAM.md   # must print nothing
git diff origin/main...HEAD -- plugins/pstack | grep '^+' | grep -nE 'pstack-models\.mdc|~/\.cursor|AskQuestion|subagent_type|generalPurpose|cloud-sleeper|cursor-team-kit|control-(cli|ui)|git show origin/main|agent-transcripts|agent id|claude-opus-5-5|closest valid slug|expected runtime|arm a `/goal`'   # must print nothing

The static test already pins the shipping and fork safeguards, the sol-row rule, the rolling aliases, principle visibility, model-invocable routed skills, make-bot-ui exclusion and version agreement. Make it pass. Never weaken a guard to make a merge pass.

Live gate (AGENTS.md; the PR stays draft until this is recorded)

Install the exact PR head in each harness.

  • Claude Code. Check out the PR head in a worktree and start a fresh session with claude --plugin-dir <worktree>/plugins/pstack, as PR release: sync Cursor pstack 0.15.1 as Open Pstack 1.4.1 #64 did. Leave ~/.claude/pstack-models.md absent. You can tell the candidate by its behavior: 1.4.1 proposes Fable and four lanes. If 1.4.1 answers, run claude plugin disable pstack@open-pstack for the check and re-enable it afterward.
  • Codex. Copy ~/.codex/config.toml and ~/.codex/AGENTS.md to *.bak-live-gate. In ~/.codex/config.toml, change ref = "v1.2.1" under [marketplaces.open-pstack] to the PR branch name. Then run codex plugin marketplace upgrade open-pstack and codex plugin add pstack@open-pstack, and confirm ~/.codex/plugins/cache/open-pstack/pstack/1.5.0 exists. (codex plugin marketplace add only adds sources; it does not re-point an existing one.)

Claude Code checks:

  • C1. Run /pstack:setup-pstack with no sheet.
    • It proposes the 15-row first-run sheet above.
    • It asks exactly three effort questions (Opus, Sol, Grok) and none for Fable.
    • Probes pass for native pstack-opus-max, Sol through codex exec, and Grok grok-4.7 through the runner.
    • Decline at confirmation. ~/.claude/pstack-models.md is still absent afterward.
  • C2. Run /pstack:interrogate on a one-file diff in a scratch repo. Expect three reviewer lanes: native Opus, a Sol runner receipt, and a Grok runner receipt whose reportedModel starts with grok-4.7. There is no Fable lane.
  • C3. In a scratch repo, ask for “full autopilot for these two items: ; state the protocol and wait”. The statement describes code-ready rounds, a children.tsv of handles and states with no expected runtime, the merge-prep rebase and the owner Babysit exception. Nothing is written.

Codex checks (against Eric's existing sheet):

  • X1. ~/.codex/pstack-models.md does not exist on either host; Eric's rows live only in the bounded block of ~/.codex/AGENTS.md. Setup reads the sheet file, so seed it first: write the exact bytes between the <!-- pstack:models:begin --> and <!-- pstack:models:end --> lines (markers excluded) to ~/.codex/pstack-models.md. Record shasum -a 256 ~/.codex/pstack-models.md ~/.codex/AGENTS.md. Then run pstack:setup-pstack.
    • It lists how critics as a dropped retired role.
    • It reports the grok:grok-4.6 rows as unmatched and asks for a replacement.
    • After you answer Grok family, it asks efforts only for the families the map uses, and its probes pass, including grok:grok-4.7 through the runner.
    • Decline at confirmation. Both hashes are unchanged afterward.

Record each check in the PR template's Live evidence section with the fields AGENTS.md names (installed version, surface, action, observed result) plus the candidate commit.

Acceptance

  1. All 45 upstream paths are accounted for: 42 are resolved as above, the 3 unmapped paths stay unported, and no conflict markers remain.
  2. No added line under plugins/pstack introduces a Cursor primitive, a rejected-slug fallback or an expected-runtime stuck test. The grep above prints nothing.
  3. Local behavior is intact:
    • tests/skill-collision-repro.sh passes with only the panel-derivation edit.
    • check-plan.mjs is identical to main.
    • git diff --stat origin/main...HEAD -- plugins/pstack/skills/poteto-mode/scripts ':!*model-matrix.test.ts' is empty.
  4. The CI commands, both claude plugin validate runs and git diff --check pass. The PR reports the test and assertion counts.
  5. UPSTREAM.md, the three manifests, README.md, docs/reference.md, CHANGES.md and NOTICE.md agree on 1.5.0, 0.15.5 and 12d587d.
  6. Live checks C1-C3 and X1 are recorded in the PR template, and the PR stays draft until they are.
  7. Eric merges the reviewed head (or says go). Then v1.5.0 is tagged from the merged main commit, and the release is published and read back.

Release and closeout

Notes

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions