iap/pstack
v0.15.5MIT
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.
Changelog
All notable changes to the pstack-hermes port tooling will be documented in this file.
[Unreleased]
Changed
docs/agent/review-ops.mdrewritten as an explicit review loop: Qodo first, then manual CodeRabbit (.coderabbit.yamldisables auto-review), SHA-bound "clean", finding-vs-recommendation triage, GraphQL-first thread tooling with a documented REST fallback (list/reply only; resolution stays GraphQL), a per-round ledger, and a loop budget with escalation.docs/agent/review-ops.mdcorrected the Qodo contract: Qodo reviews the open PR automatically and is not re-run per push, so its review commit is recorded but not treated as a current-head verdict; CodeRabbit remains the SHA-bound per-head gate, and the one-request-per-SHA rule is explicitly CodeRabbit-only. Agents in the automatic setup must not post/agentic_review.- New
docs/agent/dev-ops.md(router rows inAGENTS.mdanddocs/agent/README.md): scope discipline (no drive-by edits; out-of-scope work becomes an issue or separate PR) and parallel-work rules (parallel reads/triage, one writer per file, never parallelize rebase/rebuild/push). - Agent docs consolidated:
AGENTS.mdis now a short always-on contract plus a router; the work loop, hermes vocabulary table and verify prose live only underdocs/agent/. Root-layout drift removed fromAGENTS.md,CONTRIBUTING.md, the PR template and tooling help text (pstack/subdirectory paths,$PWD/pstackdoctor target, atomic-swap claim), andREADME.mdis correctly classified as converter output. tools/check_docs.py(+test_check_docs.py, CIlint-and-testsstep): gates router links,docs/agent/layout.mdvs.gitattributes,UPSTREAM_PINdeclarer lists vscheck_pins.py, stalepstack/paths, andpublish-distcopy sources. Added to the local verify block.- Drop
after-install.md: converter no longer emits it; first-run guidance stays in package README /docs/USING.md. Publish/release/CI package lists and root-layout obsolete cleanup updated. Next convert refresh clears the stale provenance fix line. - Agent docs job flow (hermes-guide style): short always-on
AGENTS.md; deep ops underdocs/agent/only (layout,convert-adapt,upstream-drift,review-ops+ router). Removed redundantdocs/AGENTS.mdand thedocs/RUNBOOK-upstream-drift.mdstub. One owner per fact: convert/verify inconvert-adapt, layout paths inlayout, CONTRIBUTING keeps Setup/Actions/PR/release. Root-layout facts corrected (skills//config/at repo root; threeUPSTREAM_PINdeclarers). - Restructure round for the native-hermes install model: the README leads with the native
hermes pluginsinstall/update path (development tree now onmaster), the issue forms are project-only — the dual-load platform dropdown is replaced by an install-route field and the upstream-method contact link now points at this repo's user guide — anddocs/MODELS.mddocuments the provisional upstream-name → hermes-default model mapping (code/judgment/reviewer roles) alongside the shipped panel. - The
masterrename is wired end to end: CI and publish triggers filter onmaster, the drift-watcher scheduler stub dispatchesref=master(source asset and dist copy), and the CONTRIBUTING/AGENTS install-route references are updated. The dist default-branch shims are now documented as a set — scheduler, labeler, dependabot — with their re-bootstrap sources.
Fixed
tools/convert.pyrewrites stalepstack/skills/...references toskills/...for the repo-root layout and records the count in provenance;tools/assets/hermesbot/SKILL.mdno longer duplicates the webhook-subscribe step. Both had been hand-edited in the generated tree, so a rebuild reverted them. The copied Comment Sicko persona now goes through the normal text pass, so a Windows clone withautocrlf=truecannot ship CRLF.- Rebuilt the committed package from pin
c47b1284: drops the two upstream-removedskills/how/references/prompts, picks up the current README install/update wording, and matches the converter exactly again. dist_checkout_check.py --source-treeno longer requires the repository-root.gitattributesto be byte-identical to the legacy dist asset; the root rule carrieslinguist-generatedmetadata, so the CI build job could never pass. It also stages only the pathspublish-dist.ymlships, since tooling, docs and.venvwere tripping the untracked-file refusal. The autocrlf clone remains the assertion.test_release_delivery.pyfixture no longer deletes the orphan tree and then reads the files back:git checkout --orphanalready keeps the package, so only the provenance file is force-removed and rewritten.tools/check_action_inputs.pyno longer dies on a stale Windows WinINET registry proxy (SSL: UNEXPECTED_EOF_WHILE_READING). The default opener now uses environment proxies only (--system-proxyopts back in), transient TLS/connection/5xx failures retry with backoff, and--transport autofalls back togh apiwhenghis available. Unresolved actions remain a tool error (exit 2), never a pass. Theghfallback now takes the ref from the parseduses:reference instead of re-splitting the raw URL, so refs containing/(e.g.feature/windows) resolve to the right file.tools/check_docs.pycloses review gaps: stale root generated-file paths (pstack/plugin.json,pstack/README.md,pstack/.gitattributes) are flagged like the subdirectory paths; a barepstack/package path is rejected inAGENTS.md/CONTRIBUTING.mdwhile upstream-clone references stay legal;publish-distcopy sources inside an inline conditional (if [ -d assets ]; then cp -a assets "$dist/"; fi) are checked;AGENTS.mdjoins theUPSTREAM_PINdeclarer scan; and everylinguist-generatedmarker must appear in a generated/copiedlayout.mdrow.LICENSErestored to every generated-surface list (AGENTS.md,CONTRIBUTING.md, PR template,docs/agent/layout.md);tools/convert.pywrites it and.gitattributesmarks it generated, but the rewrite had dropped it.AGENTS.mdrestores the package-identity guardrail dropped in the rewrite: keepiap/pstack-hermes, never create or rename a repository for an install alias (#100), and update mechanics live in the package README. The.github/row no longer hard-codes the declarer count.CONTRIBUTING.mdcorrected to the root layout and to threeUPSTREAM_PINdeclarers (upstream-drift-watchwas removed); the release wording no longer pins a release line.- Labeler restored after the default-branch flip:
pull_request_targetfires only from the default branch, so it had silently stopped labeling PRs.distnow carries the labeler workflow and its config (the action resolvesconfiguration-pathvia the API at the default-branch ref - the first shim run 404'd without it) plus the dependabot config (target-branch: master). Verified live: a probe PR received its labels again, and the drift-watcher stub dispatchesref=master. labels-bootstrapcould never succeed: the job has no checkout, so itsgh labelcalls failed with "not a git repository" (both recorded runs failed the same way). It now passesGH_REPOexplicitly, so the ensure-labels recovery path works.
[0.4.4] - 2026-10-06
Added
tools/check_action_inputs.py+ CI step: fails when a step passes awith: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 thesyncLabels/sync-labelsdefect 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 thegithub-actionsecosystem (updates both the pinned SHA and the# vNcomment) and foruv(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 whenUPSTREAM_PINis missing, duplicated, malformed or out of step acrossci.yml/release.yml/publish-plugin.yaml/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'srun:blocks. actionlint does not lint.github/actions/*/action.ymlsteps (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-minuteson 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@*andoven-sh/setup-bun@*- withsha_pinning_requiredstill on, and the defaultGITHUB_TOKENcan 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; itsUPSTREAM_PINlock-step bullet is corrected from three files to four (publish-dist.ymlwas missing after the publisher rename). - Single-source installs. The package now installs from this one repository: the built tree is published to its
distbranch, which is the repository's default branch, sohermes plugins install iap/pstack-hermesworks root-level andhermes plugins update pstackupdates natively. The separate dist repo is retired; no second repository is ever published. (Amain-subdir install ofpstack/remains as a legacy pinned-style alternative.)distalso carries a scheduler stub so the weekly drift watchers keep firing despite the default-branch flip; manual recovery for dispatch-only workflows isgh 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 upstreambudgetkey 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_PINbumped in all four workflows (lock-step enforced bytools/check_pins.py); details and the triage correction (noskills/orchestrateever existed) tracked in issue #94. - Docs / agent policy (Phase A, no package rebuild):
AGENTS.mdanddocs/USING.mdcodify 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.txtalready 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.ymlpassedsyncLabels: true, but the input id issync-labels: the runner logsUnexpected input(s) 'syncLabels'and the action falls back to its declared default (off), so stale labels were never removed onsynchronizedespite the step comment promising exactly that. Corrected tosync-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-packagewas outside dependabot's scan. The rootgithub-actionsentry covers.github/workflowsplus a repo-rootaction.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 modedependabot.ymlexists to prevent (AGENTS.md: pins are "bumped by dependabot, not by hand"). Added a directory-scoped entry (theactions/github-scriptpattern) 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: falsealone 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 skipverify-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.mdabsent andgh issue comment/create --body-filefailed - 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 emitdrift=truefrom the check step only on the path that also writes the body, and the upsert step is conditioned on it; pinned for both watchers bytools/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; whengh issue listfailed, 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 shareddrift-issue-upsertaction with the status captured outside the substitution, and one jq form for both callers. - Action version pins had drifted between workflows (
actions/checkoutat v4 in the drift watchers vs v7 elsewhere;astral-sh/setup-uvv5 vs v10). Unified; dependabot keeps them current from here. - Model panel no longer written into the plugin directory (#57).
hermes plugins updatereplaces the installed package tree, so aconfig/models.jsonwritten next toplugin.yamlwas silently discarded on every update - the user's per-role model choices reverted to the shipped defaults with no warning.setup-pstacknow writespstack-models.jsonin the hermes config directory besideconfig.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.gitattributesfor the tree's, which made it blind to the regression it exists to catch.stage_treecopiedtools/assets/dist.gitattributesover whatever the dist tree actually held, so a published tree missing the rule - the publishercpline deleted, or the rule stale - still validated clean. A staged tree must now carry the rule and match the tested one; the sourcepstack/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-treeflag instead of a directory-name guess. A staged dist checkout is legitimately namedpstack, 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 withsurrogateescapeinstead of the ambient locale codec. Under cp1252 a non-ASCII path came back mangled, stopped matching its staged key, and was skipped as "absent" - so its CRLF and byte-identity assertions never ran while the gate reported clean.dist_checkout_check: a package file git never tracks (typically excluded by a packaged.gitignore) is now refused rather than skipped, since it would otherwise never be verified while the gate reported clean.dist_checkout_check: a git failure now exits 2 as documented instead of propagating aRuntimeErrortraceback at exit 1; a tracked file with no staged counterpart is reported as unverified rather than silently skipped; deadBINARY_SUFFIXESis removed; and the shippeddist.gitattributesgained its missing trailing newline.- Reworded the
*.png binaryjustification inpublish-plugin.yaml: it claimedtext=autowould corruptassets/logo.png, but git's own content sniffing already prevents that and only a deliberate*.png textrule corrupts it. The line is kept as intent, not as the thing currently doing the work. upstream-drift-watch: the job now runs at all. Itsgh issue list/comment/createcalls carry no--repo, soghresolves the target from the git checkout - and the job had noactions/checkout, so every run failed withfailed to run git: fatal: not a git repository. It has failed this way on every run since 2026-09-14, silently, because the last success was 2026-09-07 when upstream had not yet moved past the pin. The checkout is pinned by SHA withpersist-credentials: false, matchingmodel-drift-watch.yml. Also dropped the blobless--filter=blob:noneclone (this job needs two commits ofpstack/; the promisor repo only made the diff depend on network at diff time), and the drift diff exit status is now checked rather than used only as a condition, so a failed diff is reported as one. This is the guard that should have raised #53 (pstack is at v0.15.5 upstream; the pin is still v0.14.8). Only the blobless attempt was verified as usable, so when the shallow fallback also failed,set -eaborted at the fetch and the run logged two copies offatal: not a git repositorywith nothing pointing at the real fault. Both attempts are now checked the same way, and a total failure exits with the clone error itself. This job has failed this way on every run since 2026-09-14 — silently, because the last success was 2026-09-07 when upstream had not yet moved past the pin. It is the guard that exists to report upstream drift, and issue #53 is the drift it should have raised (pstack is now at v0.15.5 upstream; the pin is still v0.14.8).
Added
tools/dist_checkout_check.py: regression check for the property the build gates are structurally unable to see. Thebuildjob validates the sourcepstack/directory, where files are LF because the converter wrote them that way, so it cannot catch a line-ending or binary-asset regression introduced by the dist publish step. This stages the package the waypublish-plugin.yamldoes, clones it withcore.autocrlf=true(the Windows default, and whathermes plugins installdoes), then asserts every tracked text file checked out LF and every non-text file byte-identical. Wired into thebuildjob and re-run against the staged tree inpublish-plugin.yamlbefore it commits, so a bad tree is never published. The attributes rule moved totools/assets/dist.gitattributes, which the publisher copies verbatim, so the rule and the test that guards it cannot drift apart.
Fixed
- Coverage gap: the check classified a file as text only when it had a known extension or a listed name, and as binary only when its bytes contained a NUL. This package ships extension-less text files (LICENSE and the watch-pr launcher), which matched neither test and were therefore silently skipped - the checker reported a clean tree without ever looking at 2 of 134 files. Text is now the default and binary requires a NUL byte, so the two branches are mutually exclusive and exhaustive and every tracked file is checked.
- Dist repo line endings:
publish-plugin.yamlnow writes a.gitattributes(* text=auto eol=lf,*.png binary) into the publishediap/pstacktree. The dist repo is consumed byhermes plugins installas a git clone, so on a consumer withcore.autocrlf=true(the Windows default) every text file - including the user-editableconfig/models.json- was checked out as CRLF, andhermes plugins update's stash/pull/reapply then rewrote it again, drifting the package away from its own LF-only contract. Measured on a forced checkout withautocrlf=true: 38 CRLF before, 0 after,assets/logo.pngbyte-identical either way. test_validate_encoding.pyfixture: wrote the LF-onlySKILL.mdfixture withwrite_text, which translates\ntoos.linesepon Windows, so the assertion failed there for a platform reason rather than a product reason. Now useswrite_byteswith explicit\n.check_encodingitself was correct and is unchanged; this only makes the fixture platform-independent. (lint-and-testsruns onubuntu-latestonly, so thewindows-latestbuild matrix never exercised this test.)
[0.4.3] - 2026-09-18
Added
publish-plugin.yaml: CI publisher that publishes the validated built package to the plugin-only dist repoiap/pstack(build output; append-only commits so installed clones can fast-forward — history is never rewritten; skipped with a warning untilPLUGIN_DIST_TOKENis configured; every real publish is taggedpstack-<date>-<sha>, because the plugin catalog admits only repos with real tags). The dist repo's tree root is the package, enabling the root install shorthandhermes plugins install iap/pstack --enable— no subdir — and in-placehermes plugins update pstack(root installs keep.git; verified against the hermes installer source). Requires the one-timePLUGIN_DIST_TOKENsecret (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": three routes by intent (edit in place for small tweaks, fork the dist repo for owned variants, skill taps for adding new skills alongside) with the keep-hermes-vocabulary warning for end users.validate.check_conflict_markers: static-stage gate banning unambiguous VCS conflict-marker line-starts package-wide (a bare=======stays legal as a setext underline; node_modules exempt), with regression tests.
Changed
- README install routes reorganized: root install via the dist repo is primary; the
iap/pstack-hermes/pstacksubdir 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 theT13_MAPforge-wording entry andT14_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 itspstack/was stale). Re-anchored the entry to the pinned paragraph, pruned the two subsumed entries (T13_MAPforge-wording line,T14_MAPfirst entry — their intent is carried by the full-paragraph provider-selection rewrite), and rebuilt from the clean pin:orchestrate.mdand the package README now carry the T15 provider-selection wording, with the anchor audit passing against a fresh clone of93b00b8. - 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
--prspin instead of validating every PR in the repository as one stack,gh pr listpasses an explicit--limit 100so connected stacks beyond 30 PRs are not silently truncated, and auto-provider fallback is persisted intofrontier.jsonas afallbackfield (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 reviewedglabintegration.
[0.4.2] - 2026-09-13
Added
- Docs:
docs/RUNBOOK-upstream-drift.md(re-pin procedure),docs/USING.md(invocation model, first run, expectations). Adaptation decisions tracked in issues #94/#95. 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.ymlpasses--proseand 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/markedlinguist-generatedin.gitattributes(diffs collapse in review) and PR guidance now requiresrebuilt from pin <sha>in the body; README documents the two version lines (package0.14.8vs repov0.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 conditionalpstack/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 --frozenregenerate command and a CLI-install section replacing the manual-copy path; T13 gains the missed orchestrate.mdcursor-team-kitanchor — rebuilt package from pinned93b00b8now carries zerocursor-team-kitreferences in shipped skills - T13 conversion pass: residual Cursor-vendor coupling reworded across the package —
cursor-team-kitreferences (a deslop pass,control-ui/control-cli), the cloud-agent fleet wording, and Graphite (gt) phrasing;T13_MAPwired into the conversion flow and the anchor audit (115/115) - PR template: replace the unrunnable
python3 convert.pycheckbox with the realuv run --frozen tools/convert.py --source <pstack-clone> --out pstackinvocation (the script lives intools/and requires--source); add thetools/scanner_gate.py --package pstackline 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_MAPandT13_README_MAP, both defined but never applied or audited — are removed.
[0.4.1] - 2026-09-10
Changed
- T12: Cursor built-in
/loopand/goalreferences 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 armedgoal.mdin 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.gitignorealready places agent session artifacts (plans/notes) outside the repo.
[0.4.0] - 2026-09-09
Fixed
- Delegation phrasing residuals: collapsed doubled
delegate_taskfragments in reflect (reviewers + synthesizer calls), reworded unbackticked Cursor leftovers (poteto-mode "omit Taskmodel" -> 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.txtas the authoritative record; documented thedocs/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-parentselector exempt - Empty catalog guard:
slug_drift.pyraises 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## Environmentsection in PR template (OS / Shell / Hermes version)- Update instructions in README (uninstall + reinstall workflow)
Changed
- convert.py: 4 specific-first
DELEGATION_MAPpairs +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)
[0.3.0] - 2026-09-09
Added
- Initial converter/validator tooling
- Atomic builds with rollback
- Fail-loud anchor audit
- Scanner gate with shared banned-construct source of truth
- CI: 2-OS matrix, SHA gates, determinism proof, unit tests, lint
- Weekly upstream-drift watch