Skip to content

port pstack 0.15.32 (#791 through #807) - #26

Merged
caelaxie merged 1 commit into
mainfrom
cursor/port-pstack-0.15.32-cef8
Oct 24, 2026
Merged

caelaxie merged 1 commit into
mainfrom
cursor/port-pstack-0.15.32-cef8

Conversation

@caelaxie

@caelaxie caelaxie commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

port upstream pstack from 4ec7ffa1 (#779) through e73df471 (#807). version goes from 0.15.30 to 0.15.32. cursor-team-kit stays 1.2.0.

upstream commits on pstack/:

  • 076f4b2f feat(pstack): bring the statechart skill up to date, with the Pele renderer (#791)
  • 642289e6 chore(pstack): bump to 0.15.31 (#792)
  • 00d5decc feat(pstack): tell generated verify skills to read each model-check result with /statechart (#794)
  • 3c0fdb4e feat(pstack): add the ketchup-video skill (#797)
  • b1a12989 chore(pstack): bump to 0.15.32 (#798)
  • 7054003c fix(pstack): route reflect edits out of the plugin cache (#800)
  • 96dec8ee fix(watch-pr): distinguish fork heads during stack discovery (#801)
  • fe096ef3 fix(watch-pr): cap polling sleeps at the deadline (#802)
  • 86c2448d fix(pstack): recognize matching inline code delimiters (#803)
  • 3c596e70 fix(orch): prefer active PR over branch history (#804)
  • f83fbe69 fix(pstack): read transcript mtimes with GNU stat and date in worktree-audit (#805)
  • a0b0ad99 docs(pstack): note Claude Code auto-update is off for third-party marketplaces (#806)
  • e73df471 fix(pstack): renumber swarm's Phase A and fix its dangling table reference (#807)

cursor-team-kit/ has no commits in this range. kit stays 1.2.0. commits outside pstack/ were not ported.

grok-only:

  • the version lives in root plugin.json. this port has no .cursor-plugin/plugin.json. the #792 and #798 bumps land as 0.15.32 there.
  • the readme port note pins e73df471cd4bd918367e99f3dd9c51bd53ddf5f0 for pstack and for cursor-team-kit.
  • #806's claude code auto-update paragraph is not copied. this readme's install section is the grok install and has no claude code block.
  • #800 tells reflect not to edit installed-plugins/, and to copy into .grok/skills/<skill>/ or ~/.grok/skills/<skill>/. upstream says plugins/cache/, .cursor/skills/, and ~/.cursor/skills/.
  • swarm's renumber (steps 3 and 4, and "the step 3 model") and "a result table" sit on the existing grok spawn wording.
  • worktree-audit's gnu stat/date fix sits on the existing grok transcript path.
  • ketchup-video, the guide paragraph, the readme and poteto-help rows, create-formal-verification-skill, statechart, watch-pr, orch, and check-plan are verbatim.

harness, grok 1.0.67, head 3d70ed216c75c67959e5668b3e03e1abdb61b71e. installed from https://github.com/pstack-ports/grok-pstack@cursor/port-pstack-0.15.32-cef8. grok plugin list shows pstack 0.15.32. installed HEAD is that commit. grok inspect loads ketchup-video, statechart, reflect, swarm, poteto-help, and create-formal-verification-skill (userInvocable: true), 61 skills. installed watch-pr, orch, and check-plan tests: 82 pass, 0 fail. installed statechart tests: 147 pass, 0 fail, 3 skipped (no mise, no Type 1 font, no Nimbus Sans), tla2tools 1.7.4. local ci: validated 61 skills, 2 agents, 23 playbooks, and 82 script tests. github ci: https://github.com/pstack-ports/grok-pstack/actions/runs/40049656350

full command output: #26 (comment)

statechart result from that installed copy: #26 (comment)

installed text of the changed and new skills: #26 (comment)

installed skills/statechart/SKILL.md in full: #26 (comment)

Open in Web Open in Cursor 

Port the upstream pstack commits since 4ec7ffa1. cursor-team-kit stays 1.2.0.

Co-authored-by: Kaitian Xie <caelaxie@users.noreply.github.com>

@caelaxie caelaxie left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

changes requested (comment review, since author = reviewer account).

checked at head 3d70ed2 against upstream e73df471:

  • minimum changes: skills/statechart, ketchup-video, poteto-mode/scripts/watch-pr, poteto-mode/scripts/orch, check-plan.mjs + test, and create-formal-verification-skill/SKILL.md are git-sha identical to upstream. readme, guide, and poteto-help rows match upstream text. reflect (#800) swaps only plugins/cache/ and .cursor/skills/ for the grok paths, swarm (#807) and worktree-audit (#805) apply the upstream hunks on the existing grok wording. ok.
  • layout/target: no .cursor/ paths added. ok.
  • parity: no upstream skill file missing from the port; plugin.json at 0.15.32, kit 1.2.0. ok.
  • ci: Validate plugin green. ok.
  • linkage: no open issue to close. ok.

blocking:

  • harness proof missing. this pr adds a skill and ships new statechart scripts, so it needs the real grok run on this exact head: grok plugin install --trust from 3d70ed2 (or whatever head you land), then grok plugin list / validate showing pstack 0.15.32, plus evidence ketchup-video and the new statechart/scripts/* are in the installed copy. post it as a pr comment or in the body and i'll re-review.

@caelaxie

Copy link
Copy Markdown
Contributor Author

Harness proof for head 3d70ed216c75c67959e5668b3e03e1abdb61b71e on cursor/port-pstack-0.15.32-cef8. gh pr view 26 --json headRefOid still returns that sha (the 3d70ed2 reviewed in #26 (review)). No code changes.

Grok CLI installed the same way .github/workflows/ci.yml does: version from https://x.ai/cli/stable, then curl -fsSL https://x.ai/cli/install.sh | bash -s "$version". Plugin commands used a fresh HOME=/tmp/grok-proof-home.xrgY8o. grok plugin validate . ran in a clean checkout of that sha (/tmp/grok-pstack-26). Install used https://github.com/pstack-ports/grok-pstack@cursor/port-pstack-0.15.32-cef8. git rev-parse HEAD below is the installed copy.

$ version="$(curl -fsSL https://x.ai/cli/stable | tr -d '[:space:]')"
$ echo "resolved version: [$version]"
resolved version: [1.0.67]

$ curl -fsSL https://x.ai/cli/install.sh | bash -s "$version"
Installing Grok 1.0.67 (linux-x86_64)...
  Downloading grok 1.0.67...
  Binary linked to /home/ubuntu/.grok/bin/grok and /home/ubuntu/.grok/bin/agent.
Grok 1.0.67 installed to /home/ubuntu/.grok/bin/grok
  Updated /home/ubuntu/.grok/bin in PATH in /home/ubuntu/.bashrc.

Run 'grok' or 'agent' to get started!

$ grok --version
grok 1.0.67 (2fe064390d07)

$ git rev-parse HEAD
3d70ed216c75c67959e5668b3e03e1abdb61b71e

$ git rev-parse --abbrev-ref HEAD
cursor/port-pstack-0.15.32-cef8

$ HOME="/tmp/grok-proof-home.xrgY8o" grok --version
grok 1.0.67 (2fe064390d07)

$ HOME="/tmp/grok-proof-home.xrgY8o" grok plugin validate .
Plugin manifest is valid.
  name: pstack
  version: 0.15.32
  description: if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence.
  components: 1 skill dir(s), 0 command dir(s), 1 agent dir(s)

$ HOME="/tmp/grok-proof-home.xrgY8o" grok plugin install https://github.com/pstack-ports/grok-pstack@cursor/port-pstack-0.15.32-cef8 --trust
Installed 1 plugin(s) from https://github.com/pstack-ports/grok-pstack@cursor/port-pstack-0.15.32-cef8: pstack

$ HOME="/tmp/grok-proof-home.xrgY8o" grok plugin list --json
[
  {
    "status": "installed",
    "name": "pstack",
    "repo_key": "grok-pstack-619a4a2c",
    "version": "0.15.32",
    "path": "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c",
    "source": "https://github.com/pstack-ports/grok-pstack",
    "marketplace": null
  }
]

$ git -C "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c" rev-parse HEAD
3d70ed216c75c67959e5668b3e03e1abdb61b71e

$ git -C "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c" status -sb
## cursor/port-pstack-0.15.32-cef8...origin/cursor/port-pstack-0.15.32-cef8

$ git -C "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c" rev-parse --abbrev-ref HEAD
cursor/port-pstack-0.15.32-cef8

$ git -C "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c" log -1 --format='%H%n%s'
3d70ed216c75c67959e5668b3e03e1abdb61b71e
port pstack 0.15.32 from 4ec7ffa1 through e73df471

$ HOME="/tmp/grok-proof-home.xrgY8o" grok plugin validate "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c"
Plugin manifest is valid.
  name: pstack
  version: 0.15.32
  description: if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence.
  components: 1 skill dir(s), 0 command dir(s), 1 agent dir(s)

$ ls -la "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c/skills/ketchup-video/SKILL.md"
-rw-r--r-- 1 ubuntu ubuntu 2880 Oct 24 01:27 /tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c/skills/ketchup-video/SKILL.md

$ ls -la "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c/skills/statechart/scripts"
total 248
drwxr-xr-x 3 ubuntu ubuntu  4096 Oct 24 01:27 .
drwxr-xr-x 3 ubuntu ubuntu  4096 Oct 24 01:27 ..
-rw-r--r-- 1 ubuntu ubuntu  3122 Oct 24 01:27 bug-states.mjs
-rw-r--r-- 1 ubuntu ubuntu  2498 Oct 24 01:27 chart-edges.mjs
-rw-r--r-- 1 ubuntu ubuntu   612 Oct 24 01:27 chart-parts.mjs
-rw-r--r-- 1 ubuntu ubuntu  7859 Oct 24 01:27 chart-to-tla.mjs
-rw-r--r-- 1 ubuntu ubuntu  2293 Oct 24 01:27 compare-charts.mjs
-rw-r--r-- 1 ubuntu ubuntu 34169 Oct 24 01:27 lib.mjs
-rw-r--r-- 1 ubuntu ubuntu  3445 Oct 24 01:27 map-view.mjs
-rw-r--r-- 1 ubuntu ubuntu  2390 Oct 24 01:27 property-loop.mjs
-rw-r--r-- 1 ubuntu ubuntu  2872 Oct 24 01:27 read-check.mjs
-rw-r--r-- 1 ubuntu ubuntu 10920 Oct 24 01:27 regions-chart.mjs
-rw-r--r-- 1 ubuntu ubuntu 19149 Oct 24 01:27 render.mjs
-rw-r--r-- 1 ubuntu ubuntu  3339 Oct 24 01:27 rule-book.mjs
-rw-r--r-- 1 ubuntu ubuntu  4855 Oct 24 01:27 second-replay.mjs
-rw-r--r-- 1 ubuntu ubuntu  2031 Oct 24 01:27 snapshot.mjs
-rw-r--r-- 1 ubuntu ubuntu  5875 Oct 24 01:27 spec-text.mjs
-rw-r--r-- 1 ubuntu ubuntu 26502 Oct 24 01:27 statechart-help.mjs
-rw-r--r-- 1 ubuntu ubuntu 36109 Oct 24 01:27 statechart.mjs
drwxr-xr-x 2 ubuntu ubuntu  4096 Oct 24 01:27 test
-rw-r--r-- 1 ubuntu ubuntu  2136 Oct 24 01:27 tlc-to-chart-args.mjs
-rw-r--r-- 1 ubuntu ubuntu 30156 Oct 24 01:27 tlc-to-chart.mjs
-rw-r--r-- 1 ubuntu ubuntu  3362 Oct 24 01:27 tlc-tools.mjs
-rw-r--r-- 1 ubuntu ubuntu  3077 Oct 24 01:27 ways-in.mjs

grok inspect --json was run from an empty directory (/tmp/grok-inspect-cwd) with that same HOME, so the loaded skills come from the installed plugin. Filtered to the plugin record and ketchup-video:

$ HOME="/tmp/grok-proof-home.xrgY8o" grok inspect --json > /tmp/grok-inspect.json
$ jq '[.plugins[], (.skills[] | select(.name=="ketchup-video") | {name, source, description})]' /tmp/grok-inspect.json
[
  {
    "name": "pstack",
    "scope": "user",
    "path": "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c",
    "enabled": true,
    "provides": {
      "skills": 61,
      "agents": 1,
      "hooks": false,
      "mcpServers": 0
    }
  },
  {
    "name": "ketchup-video",
    "source": {
      "type": "plugin",
      "plugin_name": "pstack",
      "path": "/tmp/grok-proof-home.xrgY8o/.grok/installed-plugins/grok-pstack-619a4a2c/skills/ketchup-video/SKILL.md"
    },
    "description": "Catch the user up like /ketchup, with a short silent video of slides for what happened and the waiting calls as text under it. Use for /ketchup-video."
  }
]

A headless model turn against that install exited 1, blocked on auth:

$ HOME="/tmp/grok-proof-home.xrgY8o" grok -p 'Reply with exactly: ok' --max-turns 1 --output-format plain
Not signed in. To authenticate without a browser, run:
  grok login --device-code

Alternatively, set the XAI_API_KEY environment variable or run `grok login` on a machine with a browser.
Error: Not signed in. To authenticate without a browser, run:
  grok login --device-code

Alternatively, set the XAI_API_KEY environment variable or run `grok login` on a machine with a browser.

@caelaxie caelaxie left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

pass. content matches upstream through e73df471, version 0.15.32, ci green on 3d70ed2, and harness proof (validate + install --trust + list --json, installed HEAD = 3d70ed2, ketchup-video + statechart scripts in the installed copy; live turn auth-blocked) is on the pr. squash-merging.

@caelaxie
caelaxie merged commit 36ed381 into main Oct 24, 2026
1 check passed
@caelaxie
caelaxie deleted the cursor/port-pstack-0.15.32-cef8 branch October 24, 2026 01:30
@cursor
cursor Bot restored the cursor/port-pstack-0.15.32-cef8 branch October 24, 2026 01:33
@cursor

cursor Bot commented Oct 24, 2026

Copy link
Copy Markdown

harness proof for head 3d70ed216c75c67959e5668b3e03e1abdb61b71e. grok 1.0.67. installed from https://github.com/pstack-ports/grok-pstack@cursor/port-pstack-0.15.32-cef8.

grok plugin list shows pstack 0.15.32. installed HEAD is 3d70ed216c75c67959e5668b3e03e1abdb61b71e. grok inspect loads ketchup-video, statechart, reflect, swarm, poteto-help, and create-formal-verification-skill (userInvocable: true), 61 skills.

installed script tests: watch-pr, orch, and check-plan, 82 pass, 0 fail. statechart from the installed copy: 150 tests, 147 pass, 0 fail, 3 skipped (no mise, so the real-mise test skips; no Type 1 font and no Nimbus Sans). tla2tools 1.7.4 at /tmp/tla2tools.jar, java 21. full statechart TAP is the next comment. installed text of the changed and new skills is the comment after that.

The command transcript below is the installed copy at that head, before bun install added gitignored node_modules under the scripts directory.

===== grok --version =====
grok 1.0.67 (2fe064390d07)

===== grok plugin install https://github.com/pstack-ports/grok-pstack@cursor/port-pstack-0.15.32-cef8 --trust =====
Installed 1 plugin(s) from https://github.com/pstack-ports/grok-pstack@cursor/port-pstack-0.15.32-cef8: pstack

===== grok plugin list =====
  grok-pstack-619a4a2c: pstack [git: https://github.com/pstack-ports/grok-pstack]

===== grok plugin list --json =====
[
  {
    "status": "installed",
    "name": "pstack",
    "repo_key": "grok-pstack-619a4a2c",
    "version": "0.15.32",
    "path": "/home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c",
    "source": "https://github.com/pstack-ports/grok-pstack",
    "marketplace": null
  }
]

installed_path=/home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c

===== git -C installed rev-parse HEAD =====
3d70ed216c75c67959e5668b3e03e1abdb61b71e
expected 3d70ed216c75c67959e5668b3e03e1abdb61b71e
===== git status -sb =====
## cursor/port-pstack-0.15.32-cef8...origin/cursor/port-pstack-0.15.32-cef8
===== git log -1 --oneline =====
3d70ed2 port pstack 0.15.32 from 4ec7ffa1 through e73df471

===== installed plugin.json version =====
0.15.32

===== grok inspect --json plugin entry and changed skills =====
{
  "name": "pstack",
  "scope": "user",
  "path": "/home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c",
  "enabled": true,
  "provides": {
    "skills": 61,
    "agents": 1,
    "hooks": false,
    "mcpServers": 0
  }
}

[
  {
    "name": "create-formal-verification-skill",
    "description": "Generate a project-local skill that formally verifies the code where a bug costs the most and tests reach the least, in any language, with whichever verification tool fits. Use for /create-formal-verification-skill, \"model-check this race\", \"prove this invariant\", or when concurrency, retries, state machines, parsers, or unsafe code need more than tests.",
    "source": {
      "type": "plugin",
      "plugin_name": "pstack",
      "path": "/home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c/skills/create-formal-verification-skill/SKILL.md"
    },
    "userInvocable": true
  },
  {
    "name": "ketchup-video",
    "description": "Catch the user up like /ketchup, with a short silent video of slides for what happened and the waiting calls as text under it. Use for /ketchup-video.",
    "source": {
      "type": "plugin",
      "plugin_name": "pstack",
      "path": "/home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c/skills/ketchup-video/SKILL.md"
    },
    "userInvocable": true
  },
  {
    "name": "poteto-help",
    "description": "Guides users through pstack setup, /poteto-mode, and picking the skill, playbook, or principle for a task. Type /poteto-help with a question.",
    "source": {
      "type": "plugin",
      "plugin_name": "pstack",
      "path": "/home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c/skills/poteto-help/SKILL.md"
    },
    "userInvocable": true
  },
  {
    "name": "reflect",
    "description": "Spawn three parallel review subagents over the active transcript, surface learnings, and route each to a concrete edit on an existing skill. Use when the user says reflect.",
    "source": {
      "type": "plugin",
      "plugin_name": "pstack",
      "path": "/home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c/skills/reflect/SKILL.md"
    },
    "userInvocable": true
  },
  {
    "name": "statechart",
    "description": "Draw how any system moves between states, such as a product flow, a protocol, or a service, as a Mermaid statechart from a TLA+ model. Each bug is a numbered path with blue borders to a state that breaks a rule. Use for /statechart, to show a bug as a path through states, or to turn an agreed chart into a TLA+ skeleton.",
    "source": {
      "type": "plugin",
      "plugin_name": "pstack",
      "path": "/home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c/skills/statechart/SKILL.md"
    },
    "userInvocable": true
  },
  {
    "name": "swarm",
    "description": "Fan out N parallel workers, drain them, and return one report. Use for /swarm, 'swarm this', or parallel coverage, races, gauntlets, and exploration.",
    "source": {
      "type": "plugin",
      "plugin_name": "pstack",
      "path": "/home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c/skills/swarm/SKILL.md"
    },
    "userInvocable": true
  }
]

pstack skill count:
61

===== node statechart.mjs --help (installed) =====
Usage: node statechart.mjs from-spec SPEC.tla [--config FILE] [--fixed FIXED.tla [--fixed-config FILE] | --against AGREED.tla [--against-config FILE]] [--label TEXT] [--map FILE] [--expect-broken RULE]... [--title TEXT] [--out DIR] [--cover] [--png [--theme NAME]]
       node statechart.mjs from-chart CHART.mmd [--module NAME] [--expect-broken RULE]... [--title TEXT] [--out DIR] [--png [--theme NAME]]
       node statechart.mjs render CHART.mmd [--theme NAME] [--out FILE]
       node statechart.mjs [from-spec|from-chart|render] --help

(help text continues in the installed `statechart.mjs --help` run; full help is in the transcript file on the agent. the installed help printed the from-spec, from-chart, render, PNG, TLC, and exit-code sections.)

===== bash -n worktree-audit.sh and a run (installed) =====
# base: HEAD
SIZE	AGE	MERGED	DIRTY	REMOTE	PR	LAST_CHAT	BUCKET	WORKTREE

===== bun install, typecheck, test (installed scripts) =====
bun install v1.4.4 (38afee6c8)

+ bun-types@1.3.14
+ typescript@7.0.2
+ commander@14.0.0

6 packages installed [7.00ms]
$ tsc --project watch-pr/tsconfig.json --noEmit --strict
$ bun test orch watch-pr check-plan.test.ts
bun test v1.4.4 (38afee6c8)

check-plan.test.ts:
(pass) accepts ordinary, indented, and longer closing fences [135.77ms]
(pass) accepts nested backticks and tilde info strings [49.36ms]
(pass) keeps mismatched, shorter, and suffixed closers inside the fence [73.66ms]
(pass) rejects headings and prose outside a proper close [75.16ms]
(pass) rejects backtick info strings containing a backtick [24.30ms]
(pass) ignores prose punctuation inside matching multi-backtick code spans [74.81ms]
(pass) checks prose following a multi-backtick span and unmatched delimiters [51.14ms]

orch/orch.test.ts:
(pass) Store > initializes an idempotent plain-file store and releases its lock [4.18ms]
(pass) Store > composes unit add, set, get, list, and counts [3.88ms]
(pass) Store > records, replaces, checks, and summarizes typed ledger verdicts [1.89ms]
(pass) Store > pushes, peeks, and atomically drains inbox pointers [2.25ms]
(pass) Store > replaces a stale lock whose holder pid is dead [2.12ms]
(pass) Store > blocks a writer and steals the pid lock only with force [1.40ms]
(pass) Store > parks gates, stores standing orders, and renders status [4.28ms]
(pass) Store > resolves the ordered frontier from the gh base chain and validates an optional pin [95.09ms]
(pass) Store > resolves a replacement gh PR alongside closed branch history [97.41ms]
(pass) Store > still rejects multiple active gh PRs on one branch [39.70ms]
(pass) Store > rejects unparseable gh output loudly [40.22ms]
(pass) Store > resolves the ordered frontier from the origin base chain and validates an optional pin [90.71ms]
(pass) Store > resolves a replacement origin PR alongside closed branch history [98.48ms]
(pass) Store > still rejects multiple active origin PRs on one branch [40.27ms]
(pass) Store > rejects unparseable origin output loudly [39.84ms]
(pass) Store > names the missing pull request when a chain branch has none [38.55ms]
(pass) Store > rejects malformed TSV, verdict, frontier, and inbox data [1.47ms]
(pass) Store > rejects operations after close [1.17ms]
(pass) orch CLI > prints commander help and rejects invalid parsing with exit 1 [97.46ms]
(pass) orch CLI > accepts ORCH_STORE and emits complete JSON [43.78ms]
(pass) orch CLI > maps user and not-found outcomes to the preserved exit codes [100.48ms]

watch-pr/policy.test.ts:
(pass) readiness truth table > covers every specified row and every UNKNOWN rollup value [0.07ms]
(pass) readiness truth table > turns a clean visible list plus GitHub refusal into an explicit CI blocker [0.75ms]
(pass) snapshot query planning > does not query commit rollups while queued checks are pending [0.11ms]
(pass) snapshot query planning > queries rollups for settled and failed lists [0.09ms]
(pass) snapshot query planning > short-circuits merged rows before threads and checks [0.04ms]
(pass) scans stacks tier-major so an upstack conflict outranks frontier CI [0.13ms]
(pass) attributes a stack wait to the PR whose checks are pending, not the bottom [0.10ms]
(pass) waits on a draft while checks are pending, then reports the draft gate [0.08ms]
(pass) queued-stack cadence > drops a sweep head only after its snapshot succeeds [0.24ms]
(pass) queued-stack cadence > resumes the sweep at the PR whose read failed [0.94ms]
(pass) queued-stack cadence > emits a completed sweep only after its final successful snapshot [0.13ms]
(pass) queued-stack cadence > ADVANCE continues directly to the new frontier without sleeping [0.34ms]
(pass) queued-stack cadence > deduplicates identical waits and schedules the next due sweep [0.14ms]
(pass) uses the specified retry floor and cap [0.01ms]
(pass) polling deadline sleeps > caps single sleeps at the configured deadline [0.44ms]
(pass) polling deadline sleeps > caps queued-stack sleeps at the configured deadline [0.07ms]
(pass) polling deadline sleeps > caps query-retry sleeps at the configured deadline [0.05ms]
(pass) polling deadline sleeps > preserves the polling interval when the deadline is disabled [0.17ms]

watch-pr/github.test.ts:
(pass) checks fallback chain > uses a non-empty fast-path result without a rollup query [0.07ms]
(pass) checks fallback chain > paginates GraphQL when the fast path is unusable [0.10ms]
(pass) checks fallback chain > falls back when valid fast-path JSON represented an empty list [0.06ms]
(pass) checks fallback chain > fails closed when both paths are empty [0.10ms]
(pass) rollup node mapping > maps terminal and non-terminal CheckRun states fail closed [0.14ms]
(pass) rollup node mapping > classifies an in-progress Code Review Gate from the rollup as the gate [0.02ms]
(pass) rollup node mapping > classifies a Code Review Gate waiting on an owner approval as the gate [0.01ms]
(pass) rollup node mapping > classifies a fast-path Code Review Gate waiting on an owner approval as the gate [0.04ms]
(pass) rollup node mapping > maps StatusContext states and drops unknown typenames [0.02ms]
(pass) closed enum parsing > accepts mergeStateStatus CONFLICTING [0.07ms]
(pass) closed enum parsing > reads gh's empty reviewDecision as no decision rather than a parse failure [0.01ms]
(pass) closed enum parsing > still rejects an unknown reviewDecision [0.06ms]
(pass) closed enum parsing > rejects unknown enum values as retryable errors carrying the raw value [0.03ms]
(pass) annotates Bugbot threads with distinct review-pass counts [0.33ms]
(pass) review thread pagination > keeps walking pages until the cursor is exhausted [0.10ms]
(pass) review thread pagination > sees an unresolved thread that sits past the first page [0.05ms]
(pass) review thread pagination > stops after a single page when the cursor is exhausted [0.05ms]
(pass) review thread pagination > counts Bugbot review passes across every page [0.10ms]
(pass) review thread pagination > drops resolved threads from later pages too [0.06ms]
(pass) review thread pagination > rejects a page that omits pageInfo instead of assuming one page [0.05ms]
(pass) context and stack discovery > returns a fully explicit context without any reader call [0.20ms]
(pass) context and stack discovery > uses the local origin before currentPr for an explicit number [0.06ms]
(pass) context and stack discovery > orders the connected stack bottom-to-top [0.16ms]
(pass) context and stack discovery > does not use a fork's same-named head as a stack parent [0.04ms]
(pass) context and stack discovery > does not attach upstream branch children to a fork head [0.03ms]
(pass) context and stack discovery > terminates when an unrelated fork opens main against main [6.65ms]
(pass) context and stack discovery > requests and parses fork identity from gh before stack discovery [12.28ms]

watch-pr/cli.test.ts:
(pass) parseArgs > uses the specified defaults [1.45ms]
(pass) parseArgs > parses a frozen queued stack bottom-to-top [0.59ms]
(pass) parseArgs > rejects every invalid mode and numeric shape as usage [2.04ms]
(pass) rendering > emits compact valid JSON by default [0.07ms]
(pass) rendering > renders the Markdown table from the same verdict only [0.14ms]
(pass) main > returns EX_USAGE 64 and writes usage errors only to stderr [0.19ms]
(pass) main > bypasses the queue machine for queued-stack status-only [0.36ms]
(pass) main > returns exit 4 for a hidden GitHub-side CI refusal [0.31ms]
(pass) main > shows help without touching the reader [2.61ms]

 82 pass
 0 fail
 282 expect() calls
Ran 82 tests across 5 files. [1383.00ms]

statechart result from the same installed run: # tests 150, # pass 147, # fail 0, # skipped 3, # duration_ms 357183.045705. full TAP follows in the next comment.

@cursor

cursor Bot commented Oct 24, 2026

Copy link
Copy Markdown

statechart tests from the installed copy at /home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c, head 3d70ed216c75c67959e5668b3e03e1abdb61b71e. command: TLA2TOOLS=/tmp/tla2tools.jar JAVA=/usr/bin/java node --test skills/statechart/scripts/test/statechart.test.mjs. tla2tools 1.7.4, checksum 936a262061c914694dfd669a543be24573c45d5aa0ff20a8b96b23d01e050e88. java 21.

result: 150 tests, 147 pass, 0 fail, 3 skipped.

skipped:

  • statechart.mjs finds TLC with the real mise when an untrusted mise.toml is next to the spec and above TMPDIR — needs TLC from mise, not from TLA2TOOLS. mise is not installed.
  • a font that resvg cannot read keeps Pele's widths, so the chart keeps every label — cannot find a Type 1 font.
  • a bold or italic face that resvg cannot read is measured in its regular face, so the chart keeps every label — needs Nimbus Sans with an OpenType regular face and Type 1 bold and italic faces.

every other test passed, including the TLC from-spec and from-chart runs. duration 357183 ms.

the line-by-line TAP is 150 ok records. the three skips are tests 50, 69, and 70. the closing summary from that run:

1..150
# tests 150
# suites 0
# pass 147
# fail 0
# cancelled 0
# skipped 3
# todo 0
# duration_ms 357183.045705

HARNESS_OK

@cursor

cursor Bot commented Oct 24, 2026

Copy link
Copy Markdown

installed text of the changed and new skills, from /home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c, head 3d70ed216c75c67959e5668b3e03e1abdb61b71e.

skills/ketchup-video/SKILL.md is new and matches upstream e73df471 verbatim.

skills/statechart/SKILL.md matches upstream verbatim.

skills/create-formal-verification-skill/SKILL.md matches upstream verbatim, including the /statechart paragraph.

skills/reflect/SKILL.md has the grok cache paths. the new paragraph is: never edit a skill under installed-plugins/. destination is .grok/skills/<skill>/ or ~/.grok/skills/<skill>/.

skills/swarm/SKILL.md has the renumber on the existing grok wording. phase A steps are 1, 2, 3, 4. fan-out says the step 3 model. the report says a result table.

skills/poteto-help/SKILL.md adds the ketchup-video row. the rest of the grok wording is unchanged.

full installed text:

skills/ketchup-video/SKILL.md

---
name: ketchup-video
description: "Catch the user up like /ketchup, with a short silent video of slides for what happened and the waiting calls as text under it. Use for /ketchup-video."
disable-model-invocation: true
---

# Ketchup video

Follow [`/ketchup`](../ketchup/SKILL.md), but show what happened in a short silent video instead of its summary and visuals. Its window starts at the last message the user wrote before `/ketchup-video`, not before any earlier `/ketchup`. Writing and rendering the video, outside the repo, is the one exception to its read-only rule. The reply is ketchup's opening sentence, the embedded video, one line naming any work left that you can do yourself, and the action items. When the video shows a call's options, call each option by the name the video gives it. If the render fails, say so in one line and give only the calls.

## Slides

Use the screenshots, recordings, diffs, and data the work produced, not the chat's prose about them. Before you draw, write the one sentence the user should leave with and one line per slide. Drop each slide that does not change what the user knows. Use at most 10 slides, and fewer is better. Neither note goes in the reply.

Each slide makes one point. Build the slides on one picture and change it from slide to slide, rather than cut to an unrelated one. A color or shape means the same thing on every slide. Show the work in pictures, such as how a system works, a PR stack with each PR's state, a before and after of a fix, or options side by side. Point at what changed with arrows, highlights, and motion. A slide is never a bullet list, a status list, a table, or boxes with nothing connecting them.

Keep text to the minimum. Put each label on the thing it names, in plain words a person would say, not tags like "Tests: pass". Never caption what a picture shows, and never give a fact twice, across slides or in the text under them.

Show what came of each thing the user asked for, and whether it is done, still running, failed, or not checked. Never show something done that still waits on the user. Show any bug found and fixed on the way. If a visible change has no screenshot, say so on its slide and name what changed on screen. Draw only from facts you have. Never invent a number, and never draw a screen you did not capture.

## Render

Render one silent landscape video, such as an mp4, with motion between slides. Every frame is the slide itself, edge to edge. Make the frames from the slides, never by recording a screen. Hold each slide long enough to read its words, at least one second for each three words it adds. Words inside a screenshot do not count. Before you embed the video, look at one frame from each slide in the rendered file, and count the words it adds against its hold in that file. Fix any slide you cannot read in that time, render again, and check again.

skills/statechart/SKILL.md

The installed file is the upstream skill at e73df471, 37 lines of body after the frontmatter. opening lines:

---
name: statechart
description: "Draw how any system moves between states, such as a product flow, a protocol, or a service, as a Mermaid statechart from a TLA+ model. Each bug is a numbered path with blue borders to a state that breaks a rule. Use for /statechart, to show a bug as a path through states, or to turn an agreed chart into a TLA+ skeleton."
disable-model-invocation: true
---

# Statechart

The chart shows how a system moves between states, in the words of the person who reads it. The scripts call that person the reader, as in `readerActions` and reader steps. The reader decides whether the behavior is right. The reader can be a PM who reads a product flow, an engineer who reads a protocol or a service, or a reviewer who reads a design. Label each state with what the reader can observe or cares about, such as "Paying" in an app or "Lease held, write pending" in a lock service. Label each step with the event that moves the system, such as "tap Pay" in an app, "the request reads the count" in a service, or "the lease expires" in a lock service. Keep variable and action names out of labels.

Run `node <skill dir>/scripts/statechart.mjs --help` for the commands and for how to read a chart. Work in a scratch folder outside the repo. The command writes its files next to its input. The first run installs TLC and Java with mise, which downloads about 305 MB and needs the network. The help's TLC section tells how to use a TLC and Java that you have.

sha256sum of the installed skills/statechart/SKILL.md matches the workspace file, which matches upstream pstack/skills/statechart/SKILL.md at e73df471. the full file is in the install at skills/statechart/SKILL.md and was read during the harness. it is the same bytes as upstream. sections: Pick the direction, Spec to chart, Chart to spec, Hand off.

skills/reflect/SKILL.md

the new apply paragraph, from the installed file:

Never edit a skill under `installed-plugins/`. Before approval, show its destination, `.grok/skills/<skill>/` or `~/.grok/skills/<skill>/`. After approval, copy the skill folder there and edit the copy. Never open a PR or push.

skills/swarm/SKILL.md

installed phase A and the report line:

1. State the done predicate and the artifact or report the swarm must return.
2. Choose the shape. Partition into slices, race N workers on identical briefs, or mix both. For a race or mixed shape, declare `first pass`, `rank all`, or `best-of` before spawning.
3. Pick the worker model from the `swarm workers` line in `~/.grok/rules/pstack-models.md`. If the rule or that line is missing, use `grok-4.6` at `xhigh`. For `auto` or `inherit-parent`, omit `model` so the workers run on the parent model. If `spawn_subagent` has no `model` argument, omit it for this session so the child inherits the parent, and apply step 1 of **setup-pstack** so the next session can pass `model`. If it rejects a slug, use the closest slug from `grok models` and say so. For a model race, name each arm's model up front. Pick each subagent's reasoning effort for the job, per the Subagents section.
4. 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.

fan-out uses the step 3 model. report: Return one consolidated in-chat report with a result table, issue one-liners, gaps or dropouts, and the race rule when used.

skills/poteto-help/SKILL.md

installed row:

| Catch up like `/ketchup`, in a short silent video of slides, with the waiting calls as text under it | [`/ketchup-video`](../ketchup-video/SKILL.md) |

skills/create-formal-verification-skill/SKILL.md

installed paragraph:

If the check is a TLA+ model, tell the next agent to read every result with the pstack [`/statechart`](../statechart/SKILL.md) skill. It shows each invariant violation the checker finds as its shortest path in plain words, and which of those violations a change fixes. When the check passes, `/statechart` draws a chart of how the system moves between states. Refer to `/statechart` by name. Its commands, options, and file paths change between releases and machines, so copy none of them into the generated skill or its scripts.

@cursor

cursor Bot commented Oct 24, 2026

Copy link
Copy Markdown

full installed skill files from /home/ubuntu/.grok/installed-plugins/grok-pstack-619a4a2c at head 3d70ed216c75c67959e5668b3e03e1abdb61b71e. these are the bytes on disk in that checkout.

skills/ketchup-video/SKILL.md is already in full in #26 (comment)

skills/statechart/SKILL.md

---
name: statechart
description: "Draw how any system moves between states, such as a product flow, a protocol, or a service, as a Mermaid statechart from a TLA+ model. Each bug is a numbered path with blue borders to a state that breaks a rule. Use for /statechart, to show a bug as a path through states, or to turn an agreed chart into a TLA+ skeleton."
disable-model-invocation: true
---

# Statechart

The chart shows how a system moves between states, in the words of the person who reads it. The scripts call that person the reader, as in `readerActions` and reader steps. The reader decides whether the behavior is right. The reader can be a PM who reads a product flow, an engineer who reads a protocol or a service, or a reviewer who reads a design. Label each state with what the reader can observe or cares about, such as "Paying" in an app or "Lease held, write pending" in a lock service. Label each step with the event that moves the system, such as "tap Pay" in an app, "the request reads the count" in a service, or "the lease expires" in a lock service. Keep variable and action names out of labels.

Run `node <skill dir>/scripts/statechart.mjs --help` for the commands and for how to read a chart. Work in a scratch folder outside the repo. The command writes its files next to its input. The first run installs TLC and Java with mise, which downloads about 305 MB and needs the network. The help's TLC section tells how to use a TLC and Java that you have.

## Pick the direction

Use `from-spec` when a TLA+ model exists, or when the code or design is concrete enough to model. Use `from-chart` when there is no model, and the people who own the behavior should agree on it before anyone builds or changes it.

If the code already has a TLA+ spec, start from a copy of that spec. Add the variables that the labels and rules need, and keep the spec's existing invariants. To audit the code against that spec, make the copy model what the code does, and pass the spec unchanged as `--against`. Check it with the config that its authors say it passes, and pass that config as `--against-config` unless it has the spec's file name. One mapping labels both models, so label states and steps from variables that both have. A label that reads a variable that only the copy has must test `"name" in v` first, and label the spec's states another way. When a model describes code, tie every variable and action to code that a reviewer can open, and take its name from that code. Make each action one indivisible step in the code. Put the file and line of the code that checks each condition of an action in a comment on that condition, as in `\* pay.ts:120`.

## Spec to chart

1. Choose the chart's states. When the reader cares about something that a label would hide, put it in the label, such as "Paying, charged twice" when the screen still says "Paying" after a second charge. Start with few states. Split a state when the split separates two bugs, or when the reader must see a step that leaves the label the same, such as a request that reads a count, because the chart does not draw such a step.
2. Write each rule that the reader agrees to as one invariant, with the reader's sentence as its comment. A rule can be about any state in the model: what a screen shows, what a request returns, a stored value, or a message between parts. When the model describes code, the rule also names the code that can change that state. If the model has no variable for what a rule is about, add the variable. Do not drop the rule. For a rule that applies once everything settles, define `Settled == ~ENABLED System`, where `System` is the disjunction of the actions that happen without the reader. For a rule that applies at a narrower point, such as after each request finishes, write a predicate for that point and make the rule hold where it is true. For a goal that the system must be able to reach, write a rule that says the goal never happens, and pass that rule with `--expect-broken`. The path that breaks it is then a way to the goal. The chart still draws the goal as a state that breaks a rule, and `stories.md` tells it as a bug, so name each goal rule in the hand-off. Report each other broken rule as a bug. Never weaken a rule to make the chart pass.
3. Run `from-spec`, then fill in the mapping file it writes. Put the labels in `state` and `step`. When the chart must separate what the reader does from what happens around the reader, list the reader's actions in `readerActions` by action name. Leave the list empty when every action counts the same. When the overview is too large to read, add `--cover`. The overview then keeps only the shortest path to each settled state, plus every bug path, and the command lists what it leaves out. When two bugs end in the same state for different reasons, add `cause` and make it name each reason. To color the states by what the reader cares about, such as "Order shipped", return that group from `group`. The legend names the groups, and in the PNG a state that breaks a rule is red in place of its group color.
4. If there is a proposed fix, model it and pass that model as `--fixed`.
5. Render each chart with `--png` and look at every PNG. Check that each numbered path reads in order. If a label reads like code, fix `state` or `step` and run the command again.
6. When the model describes code, replay each bug's story against the real code, as a test or a live repro, one step per model action. Drive only entry points that a user, a client, or another part of the system reaches, and assert only what they can observe. A test that asserts a flag that it sets, or that searches the source text, proves nothing. When a run proves part of the story and reading the code proves the rest, say which part each proves. When the test copies code that it cannot import, give the commit and line range of the copy, and list what the copy leaves out. If a bug does not reproduce, assume the model is wrong until you show otherwise. Fix the model, not the rule. For a design with no code yet, the TLC trace is the evidence, and the hand-off must say so.

## Chart to spec

1. Draw the chart that the reader agrees to. Use one region for each part that changes independently, such as a device's connection and the job that the device runs. Add one `%% never` line per rule, with the reader's sentence. Draw an event that stops or restarts a part, such as "the app closes" or "the process restarts", as an edge to the state that comes next. Run `render CHART.mmd` to get a PNG of the chart for the reader.
2. Run `from-chart`. If a rule breaks, the agreed chart has a design bug. Take the bug to the people who agreed to the chart.
3. Add the real code's guards and variables to the spec that `from-chart` wrote, and run `from-chart` again. For each difference it prints, ask the reader whether the code is wrong or the chart needs a correction.

## Hand off

Give the PNG and the Mermaid source of each chart to the person who must decide. Add one line per bug with the rule it breaks, its steps as the chart numbers them, whether it reproduced, and whether the proposed fix fixes it. A broken PROPERTY has no path on the chart, so give the TLC counterexample that `stories.md` names for it. With `--against`, also say whether the spec already lists it: in the configs that `stories.md` names, in the spec's notes on what the model leaves out, or not at all. When the model describes code, do not report that a rule holds while the command lists conditions with no file and line. Take every count you quote from `summary.json`. Attach `stories.md` and the command that regenerates everything. Say what the model leaves out.

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