Skip to content

Merge pstack-claude 0.9.102 into the Herdr fork (0.9.103) - #23

Merged
TiewKH merged 39 commits into
mainfrom
sync/pstack-claude-0.9.102
Oct 23, 2026
Merged

TiewKH merged 39 commits into
mainfrom
sync/pstack-claude-0.9.102

Conversation

@TiewKH

@TiewKH TiewKH commented Oct 23, 2026

Copy link
Copy Markdown
Owner

Summary

Merges michael-denyer/pstack-claude 0.9.80 through 0.9.102 (37 commits) into the fork and bumps the version to 0.9.103.

Upstream brings in:

  • the Muse native plugin port
  • effort as a field on the dispatch, replacing the ten generated effort agents
  • the formal verification skills, plus /ketchup, /in-your-own-words, and /sharpen
  • the thermos skills
  • the cursor/plugins pin moving to 7b353f7 (v0.15.27)
  • a Sonnet worker tier for feature and refactoring delegates
  • transcript and plugin paths that follow CLAUDE_CONFIG_DIR
  • fixes in the worktree audit, orch, the Pi agents, and the skill link validator

Conflict resolution (all Herdr capabilities kept)

  • Skill pointers (12 skills + poteto-mode): upstream's new Muse pointer and the fork's Herdr pointer landed on the same line. Each skill keeps both, with Herdr after Muse. poteto-mode's Platform Adaptation names both runtimes.
  • setup-pstack: keeps the Herdr setup / Native setup split under the new Muse pointer.
  • tools/forks.json: takes upstream's longer poteto-mode and reflect descriptions and keeps the Herdr-pointer clause.
  • CI / scripts: the scripts job runs orch watch-pr check-plan.test.ts herdr. The scripts package.json keeps the fork's bun test, which runs everything.
  • README / reference / CONTRIBUTING: take upstream's Muse, Other harnesses, and Configure sections using this fork's clone URL. They drop the retired effort-agent wording and update the pin and counts (65 skills: 41 public, 24 principles). The Herdr rows, the Herdr version in bug reports, and the fork notes are kept.
  • CHANGES.md: new 0.9.103 - pstack-herdr: merge pstack-claude 0.9.102 entry. Upstream's entries go under it as ### pstack-claude subsections, because upstream's 0.9.80 collides with the fork's.

Follow-ups for upstream changes

  • herdr-tools.md: the effort row said Claude's Agent had no equivalent. It now maps the Agent call's effort field to the dispatcher's --effort override.
  • herdr/dispatch.ts: reworded a comment to ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/projects/.... Upstream's new claude-config-dir invariant flagged the bare $CLAUDE_CONFIG_DIR/projects form. The code already resolved the home through configHome.

Test plan

  • bun tools/generate.mjs --check: 85 generated files current
  • node tests/herdr-runtime.test.mjs: passes
  • bun test tests/: 1316 pass, 1 fail. The failure is log.test.mjs "40 concurrent writers" timing out at 5s. It fails identically on a pristine upstream/main checkout on this machine, and the PR doesn't change the test or log.sh.
  • Forks dry-run sync (bun tools/sync.mjs <component> <sha> --dry-run) exits 0 for pstack, cursor-team-kit, and thermos
  • Scripts: bun run typecheck clean; bun test orch watch-pr check-plan.test.ts herdr: 365 pass
  • markdownlint on the changed docs and skills: 0 errors

Merge with a merge commit, not a squash, so the next sync starts from 356c6e0.

🤖 Generated with Claude Code

mshk and others added 30 commits October 9, 2026 13:32
…#245)

* test(poteto-mode): catch stale base ref OIDs

* fix(poteto-mode): read current base ref targets

* style(poteto-mode): format base ref regression

* refactor(watch-pr): unwrap GraphQL once and drop the gh pr view leftovers

GhGitHubReader reads every GraphQL envelope through one graphql() method,
which checks errors and returns data.repository.pullRequest for all four
queries. Before, only the PR facts query checked errors.

An open PR's landing revision narrows the parsed facts with text() instead
of re-parsing a copy of the raw response under the old baseRefOid key.
ship-pr inspect builds its revision from the GraphQL fields directly.
parseLandingRevision parses the saved record only, so its optional context
parameter goes.

The empty-string review decision came from gh pr view, which the facts
reader no longer runs. GraphQL returns null, and an empty string is
rejected like any other unknown value. The transport fake's pr view branch
and the baseRefOid decoys in shared fixtures go with it.

---------

Co-authored-by: mshk <[email protected]>
Co-authored-by: Michael Denyer <[email protected]>
…enyer#247)

* fix(shipping): inspect terminal PRs after base deletion

* fix(pi): retry orphan cleanup after inspection recovers
Asks for a test run, a scoped issue link, and the generator and catalog checks that CONTRIBUTING.md requires, so a PR that skips them is quick to spot.
principle-attack-the-premise and principle-test-behavior-not-implementation return to upstream df58112 text. The 0.9.34 forks replaced upstream's census and undefined-imports checks with judgement calls, which an agent that has already failed can satisfy with a weak check. Each skill keeps one added line: a falsifying check for premises not about actors, and keep-list entries for proven absence tests and constants promised to users. The poteto-mode index lines return to upstream's wording.
Pi 1.0.0's shrinkwrap pins pi-ai 1.0.0, whose catalog has no claude-haiku-5-5. Pi 1.1.0 needs pi-ai ^1.1.0 and ships no shrinkwrap, so --before holds its dependency tree to the versions published by 2026-10-11.
…r#256)

The catalog test checked a pi-ai beside the Pi package before the copy nested under it, the reverse of Node's order. It now uses piDependency, moved out of piCompilerPaths, and names the pi-ai version in the test.
…denyer#252)

The Pi anthropic table pointed haiku at claude-haiku-4-5, one generation behind the opus, fable, and sonnet rows. claude-haiku-5-5 is in the pi-ai 1.1.0 catalog, which Pi 1.1.0 installs. CI pins Pi 1.1.0 since michael-denyer#255.

Fixes michael-denyer#251
* Release 0.9.82

* Point CONTRIBUTING's Pi checks at Pi 1.1

* Add michael-denyer#252 to the 0.9.82 changelog
brew install pi-coding-agent keeps Pi's npm tree under $(brew --prefix)/opt/pi-coding-agent/libexec, outside npm's global root, so findPiPackage returned null and the catalog, runtime, and typecheck checks skipped or failed without PI_PACKAGE_DIR. The lookup now checks Homebrew after npm and before bun.
…ichael-denyer#262)

* Sync to upstream 997ffc7 (v0.15.21): add /ketchup

* Carry upstream's thermos skills and review subagents

* Read any review bot where thermos names Bugbot

* docs(notice): count three upstream sources

* chore(manifest): describe the root plugin.json for every runtime

* chore(scripts): keep upstream's wrapping in fakes.test-helper.ts

Upstream stopped formatting the file with Prettier at 997ffc7, so the port's
Prettier run added ten formatting-only lines to the fork.

* refactor(watch-pr): share one cursor-advance guard between page loops

resolveChecks and resolveReviewThreads carried the same five-line guard.
advanceCursor holds it once, and the review-thread loop gains the test the
rollup loop already had.

* fix(watch-pr): refuse a thread page that promises more pages without a cursor

Before the sync the reader threw on a page with hasNextPage true and no
cursor. The synced parser read it as the last page, so later threads would
have gone unread.

* test(pstack): name every plugin agent in each runtime's subagent list

* docs(changes): record the review follow-ups in 0.9.83
…#266)

Remove the root plugins/pstack/plugin.json that 0.9.83 added: Codex reads its Agent Plugins manifest ahead of .codex-plugin/plugin.json and loads no plugin hooks for that format. The generator now fails when the file exists, with regression tests for Codex hook discovery and the generator check. The worktree-audit tests skip their unreadable-directory cases where chmod cannot deny a read, as under root.

Fixes michael-denyer#265

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01FjegkzeJ2LfmAPv7oLnP16
)

The bug form requires the pstack version, the runtime version, the reproduction steps, and a confirmation that the report reproduces on the latest release. Blank issues are off, and the chooser links the private vulnerability form.
…denyer#271)

The plugin icon and README overview each carried a caBX chunk with an image generator's signed C2PA manifest, whose certificate and signature text a plugin directory text screen can read as a credential. Pixels are unchanged; a test fails on any tracked PNG with a caBX chunk.
…pen, release 0.9.86 (michael-denyer#272)

* Sync to upstream c86f349

* Translate upstream's effort, cloud-agent, and driver sentences as substitution rules

* Sync to upstream 99743e9 (v0.15.25), add /in-your-own-words and /sharpen, release 0.9.85

* Reword the currentBranch comment in orch/store.ts

* Leave fork pull requests out of the orch gh frontier chain

* Test the orch gh chain against fork-hosted stacks and a 1000-PR list

Rows carry headRepository, the fixture repo has an origin remote, and new cases cover a foreign fork, a deleted fork, a push remote other than origin, and a checkout with no push remote. These fail until store.ts matches head repositories to the branch's push remote.

* Keep a stack pushed from the checkout's fork in the orch gh chain

gh pr list --head and --base match the branch name alone, and dropping every cross-repository row also dropped a user's own pull requests when their stack lives in a fork. The chain now keeps the rows whose headRepository.nameWithOwner is the repository the current branch pushes to, read from branch.<name>.pushRemote, remote.pushDefault, branch.<name>.remote, or origin, and names the rows it left out when a branch has no other. Each gh call lists up to 1000 pull requests instead of gh's default 30.

* Translate .cursor-plugin/plugin.json to the port's manifest path

Upstream's new fallback in poteto-agent.md picks the newest install by .cursor-plugin/plugin.json, a directory the sync excludes and the port never ships. A substitution rule derives .claude-plugin/plugin.json, a denylist token fails a sync that lets the Cursor path through, and the effort agents are regenerated. CHANGES.md records both changes.
…ep (michael-denyer#275)

The OpenCode, Gemini CLI, and Prime Agent install sat behind one README line, and its update step said a git pull was enough, which never links new skill directories. Record the OpenCode 2.0.30 checks.
…e 0.9.87 (michael-denyer#277)

* Hold worktrees with ignored user files or reflog-only commits, release 0.9.87

The audit called a worktree safe when git worktree remove would delete an ignored file that exists nowhere else, or orphan a commit only the worktree's HEAD reflog reaches.

* Name the new audit checks in its header and narrow the reflog pointer
…e 0.9.88 (michael-denyer#278)

* Run code and exploration roles on a Sonnet worker tier, release 0.9.87

Aligns role defaults with upstream's two-model split: judgment and synthesis on opus, code delegates, explorers, investigators, reflect tooling and swarm workers on a new worker tier (sonnet). Adds the worker tier to the Codex and Copilot mappings, and the prove-it-works success-readback check from michael-denyer#276.

* Keep bug-fix, perf-issue, hillclimb, and the explorer roles on opus

Only feature, refactoring runs on the sonnet worker tier.
…e 0.9.89 (michael-denyer#281)

list_agents gains sessionFile, and the completion notice and foreground result gain a transcript line, so a user can tail -f a running background agent or pi --export a finished one (michael-denyer#279).
…ter line, and /pstack-agents, release 0.9.90 (michael-denyer#282)

Child tool calls and the latest message are read from the RPC stream and kept in memory, shown in list_agents, a pstack-agents footer line, and the /pstack-agents command, without being sent to the model (michael-denyer#279).
…ichael-denyer#280)

Build the Lever now requires one known-bad control per compared output and a refusal or inconclusive result when required input is missing.
…ael-denyer#284)

settleWorktree pins --untracked-files=normal so a user's status preference can no longer make an agent's new files look like a clean tree and delete them.
…nyer#285)

A transcript path with spaces, quotes, or a dollar sign now reaches tail -f and pi --export as one literal argument.
…ichael-denyer#290)

* Collapse the Pi, Copilot, and other-harness install sections and tighten the setup-pstack note

* Name the routing hook in the setup-pstack note

* Lead the Configure note with what the routing hook is for

* Drop the slash-command form from the Configure note

* Collapse the Claude Code and Codex install sections too

* Collapse the whole Install section instead of each harness

* Make the Install heading the toggle

* Use a plain h2 for the Install toggle

* Revert "Use a plain h2 for the Install toggle"

This reverts commit d0b80fc.

* Use bold text for the Install toggle so GitHub adds no permalink icon

* Revert "Use bold text for the Install toggle so GitHub adds no permalink icon"

This reverts commit d4ca024.

* Reapply "Use a plain h2 for the Install toggle"

This reverts commit a337e4f.

* Revert "Use a plain h2 for the Install toggle"

This reverts commit d0b80fc.

* Revert "Make the Install heading the toggle"

This reverts commit 1d1280c.

* Revert "Collapse the whole Install section instead of each harness"

This reverts commit 6cccbbb.
…release 0.9.94 (michael-denyer#291)

* Sync to upstream 7b353f7 (v0.15.27): add formal verification skills

Adds /create-formal-verification-skill and /maintain-formal-verification-skill.
A scoped substitution keeps the generated skill from taking the name verify,
which the port's /create-verification-skill writes (michael-denyer#71). setup-pstack offers
the formal skill as step 10, and the Codex, Pi, and Copilot mappings say where
each runtime keeps the generated skill.

Signed-off-by: Younes <[email protected]>

* docs: credit the formal verification skills and relate them to agent-formal-verify

Signed-off-by: Younes <[email protected]>

* Release 0.9.94: formal verification skills

Signed-off-by: Younes <[email protected]>

* Keep formal verification skills off the verify driver name

The create rule also bans a verify- prefix, which older generators wrote. The
maintain skill is told the project verify skill is not a formal check. Tests pin
both rules so an upstream rewording fails loudly. The pin records the full SHA.

Signed-off-by: Younes <[email protected]>

* Say Kani is the Rust verifier in the README

* Name the formal skill's Claude Code path and keep its term off the verify driver

A third substitution renames upstream's generic "verify skill" to "formal verification skill" in both formal skills, and the naming rule now gives the Claude Code path the other runtime mappings already give. The reference doc labels the upstream pin as v0.15.27 and later, matching CHANGES.md.

---------

Signed-off-by: Younes <[email protected]>
Co-authored-by: Michael Denyer <[email protected]>
…rt agents, release 0.9.95 (michael-denyer#294)

Claude Code 2.1.292 added an effort parameter to the Agent tool, so the ten generated effort agents and the plugin.json agents list are removed. Claude Code and Pi now pass a role's @Level as the dispatch's effort field, as Codex and Copilot already did. Requires Claude Code 2.1.292 or later for @Level. Closes michael-denyer#293.
LuckyProtein and others added 9 commits October 20, 2026 23:45
- Add a Muse build as a fifth native runtime: a `.muse-plugin/plugin.json` manifest whose skill list and VERSION the generator stamps, an inline SessionStart hook that runs the shared `session-start.sh muse`, a `muse-tools.md` mapping, and a `muse` block in `models.json`.
- The Muse hook injects the mandate plus each usable sheet line, read through `sheet_problems()`'s new per-role `SHEET_OK` and `SHEET_EFFORT_OK` rather than a second parser.
- `validateMuseManifest` requires the exact hook command `["sh", "hooks/session-start.sh", "muse"]`.
- One `tierModelNamesSection` template renders the Codex and Muse Model names sections, and `tierExamples` checks both models.json blocks directly.
- `tests/mapping-coverage.mjs` shares the mapping coverage check, and its corpus leaves out every runtime's mapping file.
- Release 0.9.96.
…97 (michael-denyer#297)

- Pass the Copilot and Muse SessionStart hooks directory to awk as `PSTACK_HOOKS` in the environment instead of `-v hooks=`. awk expands backslash escapes in a `-v` value, so a plugin root that contains a backslash made the hooks exit 0 without the mandate.
- Add a test that runs both hooks from a plugin root named `back\tslash` and checks that the output matches the normal root.
- Release 0.9.97.

Closes michael-denyer#296
…ichael-denyer#298)

Skills that read transcripts now name ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/projects/
instead of ~/.claude/projects/, so recall, reflect, automate-me, show-me-your-work,
and the Eval and Session pickup playbooks find transcripts when CLAUDE_CONFIG_DIR
is set. The five substitution rules carry the same form, so sync adds no fork.
tests/claude-config-dir.test.mjs rejects any other spelling outside CHANGES.md and tests/.
… the transcript directory encoding, release 0.9.99 (michael-denyer#300)

poteto-agent, automate-me, and the reflect reviewer prompts name user skills and
plugins under ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/. recall, automate-me, and Session
pickup say <encoded-cwd> turns every character other than a letter or digit into -.
A new ~/.cursor/skills/ substitution rule runs ahead of .cursor/skills/, so sync adds
no fork. Follows michael-denyer#298.
…GIN_CACHE_DIR, release 0.9.100 (michael-denyer#301)

skills/reflect/scripts/claude-project-dir.mjs prints Claude Code's transcripts
directory for the session's start directory, reproducing Claude Code 2.1.296's naming:
non-ASCII-alphanumerics become -, names past 200 characters gain a hash suffix, and a
valid CLAUDE_CODE_PROJECT_DIR_NAME replaces the name. recall, automate-me, reflect,
show-me-your-work, and the Eval and Session pickup playbooks call it with the primary
working directory. Plugins paths honour CLAUDE_CODE_PLUGIN_CACHE_DIR. Follows michael-denyer#300.
….101 (michael-denyer#303)

claude-project-dir.mjs finds this session's transcripts directory from
CLAUDE_CODE_SESSION_ID, matching <id>.jsonl or <id>/<id>.jsonl by name. 0.9.100's
skills passed the system prompt's primary working directory, which follows the
shell, so after a cd they got exit 1 or another project's transcripts. Callers now
run the script without an argument; an argument derives from that directory and
skips the session lookup. The CLAUDE_CONFIG_DIR trim is gone, as Claude Code does
not trim it. Follows michael-denyer#301.
…-denyer#304)

* fix(validate-skills): preserve angle-bracket link destinations

* test(validate-skills): cover angle links and real CLI rejection controls

* test(validate-skills): share the angle-bracket fixtures and split the CLI check

The new tests build their tree through one withSkillTree helper instead of
repeating the mkdtemp scaffold. The later-missing-link property is a library
test rather than a CLI assertion, and the CLI test keeps only exit codes and
output, with its fixture under a skill directory like the other fixtures.

---------

Co-authored-by: Michael Denyer <[email protected]>
Brings in upstream 0.9.80 through 0.9.102: the Muse port, effort as a
dispatch field, formal verification skills, /ketchup, /in-your-own-words,
/sharpen, the thermos skills, and the cursor/plugins pin at 7b353f7.
Keeps every Herdr pointer, the dispatcher, the Agent gate, routes, and
the Herdr CI job.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@TiewKH
TiewKH merged commit 1477fb3 into main Oct 23, 2026
15 checks passed
@TiewKH
TiewKH deleted the sync/pstack-claude-0.9.102 branch October 23, 2026 08:29
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.