Skip to content

Releases: iap/pstack-hermes

pstack-hermes v0.4.4

Choose a tag to compare

@github-actions github-actions released this 06 Oct 08:45
b754848

Added

  • tools/check_action_inputs.py + CI step: fails when a step passes a with: key the pinned action does not declare. The runner only warns on such a key (Unexpected input(s)) and silently ignores the value - the class behind the syncLabels / sync-labels defect fixed above. Verified as a genuine gap before adding the gate: with the defect reintroduced, actionlint exits 0 and the full pytest suite passes unchanged. Resolves local actions from disk and pinned remote actions from raw.githubusercontent.com; a fetch failure is a tool error, never a pass. Unit tests inject the fetch, so they run offline; the CI step is the only networked consumer.
  • .github/dependabot.yml: weekly grouped updates for the github-actions ecosystem (updates both the pinned SHA and the # vN comment) and for uv (pyproject.toml + uv.lock). The repo pins everything; with no update bot the pins silently rot, which was the largest structural gap in the workflow layer.
  • tools/check_pins.py + CI step: fails when UPSTREAM_PIN is missing, duplicated, malformed or out of step across ci.yml / release.yml / publish-plugin.yml / upstream-drift-watch.yml. The lock-step rule was documented in two files and enforced by none; this makes it machine-checked and de-risks the re-pin procedure.
  • tools/check_action_shell.py + CI step: shellchecks every composite action's run: blocks. actionlint does not lint .github/actions/*/action.yml steps (verified against 1.7.12 by injecting a deliberate shell error), so the shared bash had no static check - a class that had already produced a real bug (see Fixed).
  • CI also gains: concurrency (superseded PR runs cancel; non-PR runs take a per-run group so every main push keeps its full run - tightened after the review below, see Fixed), timeout-minutes on every job, and 14-day retention on the build artifacts.
  • .github/actions/drift-issue-upsert/: shared composite action for the idempotent issue-by-title upsert both drift watchers need; the two callers' copies had already drifted apart (different jq expressions for the same intent).

Changed

  • Repository Actions policy tightened (settings, not files): allowed actions are now an allowlist - GitHub-owned actions plus astral-sh/setup-uv@* and oven-sh/setup-bun@* - with sha_pinning_required still on, and the default GITHUB_TOKEN can no longer create or approve pull requests. Introducing any other action now requires a deliberate settings change. CONTRIBUTING documents the policy and the "add to the allowlist first" rule; its UPSTREAM_PIN lock-step bullet is corrected from three files to four (publish-dist.yml was missing after the publisher rename).
  • Single-source installs. The package now installs from this one repository: the built tree is published to its dist branch, which is the repository's default branch, so hermes plugins install iap/pstack-hermes works root-level and hermes plugins update pstack updates natively. The separate dist repo is retired; no second repository is ever published. (A main-subdir install of pstack/ remains as a legacy pinned-style alternative.) dist also carries a scheduler stub so the weekly drift watchers keep firing despite the default-branch flip; manual recovery for dispatch-only workflows is gh workflow run <file> --ref main.
  • Re-pin to upstream c47b1284 (pstack v0.15.5); pstack/ rebuilt. Every converter anchor was re-anchored or pruned against the new upstream text (36 dead anchors at the new pin -> 0; T8-T14 + delegation), F16 retired (upstream now ships the slug-agnostic lane check itself), reflect's 4-column reviewer table adopted with the upstream budget key in the setup-written panel shape, and the two new upstream principles ported (principle-attack-the-premise, principle-test-behavior-not-implementation) - 45 -> 47 skills. Prose model defaults refreshed (grok-4.7-xhigh-fast, claude-opus-5-5-max); the shipped panel keeps its vendor-qualified verified slugs. UPSTREAM_PIN bumped in all four workflows (lock-step enforced by tools/check_pins.py); details and the triage correction (no skills/orchestrate ever existed) in docs/ADAPTATIONS.md section 4.
  • Docs / agent policy (Phase A, no package rebuild): AGENTS.md and docs/USING.md codify the stock-skills write surface — Hermes self-improvement (skill_manage / learning) targets local skills, skill taps, or a dist fork, not stock plugin skills. Stack forge freeze: Graphite (gt) default, GitHub (gh) fallback, GitLab (glab) halted. README Known limitations aligned (was incorrectly describing Graphite as optional-only).

Fixed

  • Dev-tree README skill counts corrected: the skills bullet said 45 (24 + 21 principle-*) while the generated package README and .build-provenance.txt already said 47 (24 + 23) after the v0.15.5 re-pin. Docs-only; pstack/ untouched (#80).
  • Label sync never ran (found while auditing every with: key against each action's declared inputs - the only such mismatch in the repo). labeler.yml passed syncLabels: true, but the input id is sync-labels: the runner logs Unexpected input(s) 'syncLabels' and the action falls back to its declared default (off), so stale labels were never removed on synchronize despite the step comment promising exactly that. Corrected to sync-labels (kebab-case; both v5 and the v7 that #69 landed declare it). Evidence: run 37394726141's log records the ignored input verbatim.
  • .github/actions/build-package was outside dependabot's scan. The root github-actions entry covers .github/workflows plus a repo-root action.yml, not .github/actions/*/action.yml - observed when #69's setup-uv bump updated every workflow and skipped the shared action, leaving its pin behind and on a path to silent rot, the exact failure mode dependabot.yml exists to prevent (AGENTS.md: pins are "bumped by dependabot, not by hand"). Added a directory-scoped entry (the actions/github-script pattern) and caught the pin up to the SHA the workflows now use.
  • CI concurrency, from the manual Macroscope review of PR #67: cancel-in-progress: false alone did not make the "main runs stay whole" claim true. By default only one run may be pending per concurrency group and a newer pending run cancels the older one, so two merges in quick succession could cancel a queued main run before it ever started and the intermediate commit would skip verify-determinism. Non-PR runs now take a per-run group (github.run_id); semantics verified against GitHub's concurrency documentation.
  • Drift watchers (High), from the same review: moving the issue upsert into its own composite step silently dropped its guard. The check step's no-drift exit 0s end only that step, so the upsert still ran with $RUNNER_TEMP/drift-body.md absent and gh issue comment/create --body-file failed - the workflow would fail on the common no-drift path (latent today, because upstream drift keeps the body-writing path active; it would start failing the week after a re-pin). Both watchers now emit drift=true from the check step only on the path that also writes the body, and the upsert step is conditioned on it; pinned for both watchers by tools/tests/test_workflow_review_guards.py.
  • Drift watchers: the "not creating a possible duplicate" guard could never fire. existing="$(gh ... || lookup_status=$?)" set the variable inside the subshell, so the parent always saw the initial 0; when gh issue list failed, the workflow proceeded with an empty result and CREATED a duplicate tracking issue - the exact failure the guard's message claims to prevent. Reproduced in bash before fixing; shellcheck SC2030/SC2031 flagged it once the shellcheck gate existed. The upsert now lives in the shared drift-issue-upsert action with the status captured outside the substitution, and one jq form for both callers.
  • Action version pins had drifted between workflows (actions/checkout at v4 in the drift watchers vs v7 elsewhere; astral-sh/setup-uv v5 vs v10). Unified; dependabot keeps them current from here.
  • Model panel no longer written into the plugin directory (#57). hermes plugins update replaces the installed package tree, so a config/models.json written next to plugin.json was silently discarded on every update - the user's per-role model choices reverted to the shipped defaults with no warning. setup-pstack now writes pstack-models.json in the hermes config directory beside config.yaml, which survives reinstalls, and the consuming skills (why, reflect, arena, interrogate) read that path while still tolerating a legacy in-package panel so existing customizations are migrated rather than ignored. The shipped default panel stays in the package - only the user override moves.
  • dist_checkout_check: the gate no longer substitutes its own .gitattributes for the tree's, which made it blind to the regression it exists to catch. stage_tree copied tools/assets/dist.gitattributes over whatever the dist tree actually held, so a published tree missing the rule - the publisher cp line deleted, or the rule stale - still validated clean. A staged tree must now carry the rule and match the tested one; the source pstack/ tree (which legitimately has none, since the publisher adds it) is still allowed. Both refusals are counterfactual-checked: dropping either guard fails a test.
  • dist_checkout_check: the source-tree exemption is an explicit --source-tree flag instead of a directory-name guess. A staged dist checkout is legitimately named pstack, so the name-based rule let a published tree with no attributes file at all validate clean - the same blind spot the previous entry closes, reached by another route.
  • dist_checkout_check: git output is decoded as UTF-8 with surrogateescape instead of the ambient locale codec. Under cp1252 a non-ASCII path came back mangled, stopped matching its staged key, and was skipped...
Read more

pstack-hermes v0.4.3

Choose a tag to compare

@github-actions github-actions released this 18 Sep 22:59
b4aa709

Added

  • publish-plugin.yml: CI publisher that publishes the validated built package to the plugin-only dist repo iap/pstack (build output; append-only commits so installed clones can fast-forward — history is never rewritten; skipped with a warning until PLUGIN_DIST_TOKEN is configured). The dist repo's tree root is the package, enabling the root install shorthand hermes plugins install iap/pstack --enable — no subdir — and in-place hermes plugins update pstack (root installs keep .git; verified against the hermes installer source). Requires the one-time PLUGIN_DIST_TOKEN secret (fine-grained PAT, contents: read/write on the dist repo only).
  • Agent-facing docs: AGENTS.md (harness identity, generated-tree rule, hermes-vs-Cursor vocabulary, primitive mapping) and a CONTRIBUTING rewrite (orientation, Bun setup, common-task recipes, publish stage).
  • docs/USING.md "Customizing skills": the three-route guidance (edit in place, fork the dist repo, skill tap) with the keep-hermes-vocabulary warning for end users.

Changed

  • README install routes reorganized: root install via the dist repo is primary; the iap/pstack-hermes/pstack subdir install is documented as the legacy route (still works). Update instructions split by route (in-place update for root installs; reinstall for subdir installs).

Fixed

  • Converter: T13_MAP's frontier-provider entry was anchored on text that only exists after the T13_MAP forge-wording entry and T14_MAP's first entry run — an ordering that can never match a clean pinned clone (the local 2026-09-14 build predated the map edit and its pstack/ was stale). Re-anchored the entry to the pinned paragraph, pruned the two subsumed entries (T13_MAP forge-wording line, T14_MAP first entry — their intent is carried by the full-paragraph provider-selection rewrite), and rebuilt from the clean pin: orchestrate.md and the package README now carry the T15 provider-selection wording, with the anchor audit passing against a fresh clone of 93b00b8.
  • T15b robustness (carried through the converter after a direct-to-generated-file edit was caught by the reproducibility gate): GitHub-native discovery now scopes itself to an explicit --prs pin instead of validating every PR in the repository as one stack, gh pr list passes an explicit --limit 100 so connected stacks beyond 30 PRs are not silently truncated, and auto-provider fallback is persisted into frontier.json as a fallback field (which providers were skipped) so a Graphite → GitHub fallback is coordinator-visible instead of silent. The GitLab provider remains reserved ("not implemented yet") pending a reviewed glab integration.

pstack-hermes v0.4.2

Choose a tag to compare

@github-actions github-actions released this 13 Sep 22:15
c3d9b51

Added

  • Docs: docs/ADAPTATIONS.md (adaptations ledger, primitive mapping, deliberately-not-ported), docs/RUNBOOK-upstream-drift.md (re-pin procedure), docs/USING.md (invocation model, first run, expectations). Review round: the upstream closure date corrected to 2026-09-10 (closed unmerged; the API attests no closer), and the panel-consumer claim now quotes the actual role-line phrases.
  • slug_drift.py --prose: scans skill markdown for backtick-quoted model-slug defaults (including vendor/model forms) once the provider catalog loads; model-drift-watch.yml passes --prose and reports prose-only findings as informational (exit 0) — a catalog tool error (exit 2) skips the scan, since the panel slugs are verified against the loaded catalog first (#25/#29)
  • CONTRIBUTING: document the GitHub alert-callout style for docs — and where it does not apply (#30)

Changed

  • Structure hygiene: pstack/ marked linguist-generated in .gitattributes (diffs collapse in review) and PR guidance now requires rebuilt from pin <sha> in the body; README documents the two version lines (package 0.14.8 vs repo v0.4.x) and corrects the transform range to T1–T13; the package README's Known limitations gains the optional-MCP-servers note (template change + rebuild); the PR template gains the matching conditional pstack/ rebuild-disclosure fields
  • Main README rewritten Hermes-first: first-screen unofficial-port identity (not affiliated with Cursor or Lauren Tan; Cursor users go upstream), install up front, Cursor dual-load demoted to a trailing incidental/unsupported note; layout line corrected T1–T11 to T1–T12
  • Converter package-README template: uv run --frozen regenerate command and a CLI-install section replacing the manual-copy path; T13 gains the missed orchestrate.md cursor-team-kit anchor — rebuilt package from pinned 93b00b8 now carries zero cursor-team-kit references in shipped skills
  • T13 conversion pass: residual Cursor-vendor coupling reworded across the package — cursor-team-kit references (a deslop pass, control-ui/control-cli), the cloud-agent fleet wording, and Graphite (gt) phrasing; T13_MAP wired into the conversion flow and the anchor audit (115/115)
  • PR template: replace the unrunnable python3 convert.py checkbox with the real uv run --frozen tools/convert.py --source <pstack-clone> --out pstack invocation (the script lives in tools/ and requires --source); add the tools/scanner_gate.py --package pstack line that actually enforces the banned-construct checkbox; note the gateway-restart warning in the doctor line as unrelated noise
  • SECURITY.md reporting triage: issues caused by this port (adaptations, exclusions, configuration, install) belong to this repository; upstream reports are reserved for genuine platform or original-project defects — including a Hermes defect that surfaces only while a plugin is installed
  • Issue chooser: the port-problem link now opens the Bug report form directly (issues/new?template=bug_report.yml) instead of the All-issues list

Fixed

  • Residual doc defects: the package README no longer says it rebuilds benny as "hermes cron/loop jobs" (the template is corrected at the source, so the generated line is right by construction), and the control-surface replacement is properly capitalised. The two dead T13 maps — T13_PRINCIPLE_MAP and T13_README_MAP, both defined but never applied or audited — are removed.

pstack-hermes v0.4.1

Choose a tag to compare

@github-actions github-actions released this 10 Sep 19:40
6aae3ee

Changed

  • T12: Cursor built-in /loop and /goal references reworded to hermes-native mechanisms — gateway cron jobs as the wake/scheduler (autonomous-run, autopilot-full, autopilot-stack, babysit, bug-fix, multi-phase-plan, shipping, visual-parity) and an armed goal.md in the agent store replacing the goal primitive; trigger phrases de-slashed ("loop until X"); plan checker (check-plan.mjs) marker aligned to accept the new mechanism

Removed

  • Executed pipeline-hardening plan doc dropped from docs/superpowers (#23). The plan shipped in v0.4.0 and the repo's own .gitignore already places agent session artifacts (plans/notes) outside the repo.

pstack-hermes v0.4.0

Choose a tag to compare

@github-actions github-actions released this 10 Sep 06:36
1c71c9b

Fixed

  • Delegation phrasing residuals: collapsed doubled delegate_task fragments in reflect (reviewers + synthesizer calls), reworded unbackticked Cursor leftovers (poteto-mode "omit Task model" -> inherit-parent semantics, how "Task subagent" -> delegate subagent)
  • README differences contract: replaced the stale "nothing else modified" claim with the actual pass register (T8/T9/T10, Phase-2A, T11) and a pointer at .build-provenance.txt as the authoritative record; documented the docs/guide/ exclusion; fixed off-by-one cross-reference (see 9 -> see 8)
  • Ban-list inconsistency: unified delegation-vocab ban list under bans.py (single source of truth, 6 tokens)
  • Model-slug drift: weekly CI re-verifies configured slugs against the live OpenRouter catalog
  • Panel dedup guard: rejects duplicate provider slugs inside a role array; inherit-parent selector exempt
  • Empty catalog guard: slug_drift.py raises on empty/malformed catalog instead of reporting every slug as missing
  • Malformed JSON: local input failures return exit 2 (tool error) instead of crashing with exit 1 (misclassified as drift)
  • Issue lookup failure: workflow fails instead of creating duplicate tracking tickets
  • Workflow concurrency: overlapping runs are serialized, not cancelled
  • Stale version reference: removed "hermes v0.20.5" from README template
  • Stale line numbers: removed source line number references that drift across versions
  • Roadmap promise: removed "expected in a future release" claim from README template

Added

  • tools/slug_drift.py — model-slug drift check against provider catalog
  • .github/workflows/model-drift-watch.yml — weekly model-slug drift watch
  • ## Environment section in PR template (OS / Shell / Hermes version)
  • Update instructions in README (uninstall + reinstall workflow)

Changed

  • convert.py: 4 specific-first DELEGATION_MAP pairs + T9_MAP[19] anchor updated to the collapsed intermediate text (anchor audit 78 -> 82)
  • PR template: replaced hand-enumerated 2-token ban list with reference to tools/bans.py
  • CONTRIBUTING.md: updated ban-list documentation to reflect 6-token set
  • README.md: clarified install command (shorthand form required)

pstack v0.14.4-hermes.2

Choose a tag to compare

@iap iap released this 03 Sep 21:18
fca043c

pstack v0.14.4-hermes.2 — the pstack method (Lauren Tan, MIT) ported to Hermes Agent as a self-contained agent-plugins-v1 package.

45 skills (23 workflow/mode + 21 principle-* + hermesbot): the poteto-mode router, verification playbooks, 21 engineering principles, verification-skill generation, decision trails, and a hermes-native bot control surface (webhook subscriptions, signed notifications, peer gateways) filling the excluded make-bot-ui slot.

Install

hermes plugins install iap/pstack-hermes/pstack --enable

(or hermes plugins install pstack once the index entry merges)

Verification

  • install-scanner clean (package subdir; the repo root intentionally ships dev tooling)
  • cross-platform byte-determinism proven in CI (ubuntu + windows)
  • committed-package freshness gate, provenance pinned to upstream 799151d
  • pinned-ref smoke test documented on the index PR

Attribution: upstream pstack © Lauren Tan (MIT); port modifications © the pstack-hermes-port contributors.