Pins every action to the latest release SHA within its current major, so
no untested major bump rides along: checkout v4.4.0, setup-go v5.6.0,
upload-artifact v4.6.2, download-artifact v4.3.0, action-gh-release v2.6.2.
Adds a `workflows` CI job running actionlint and zizmor. actionlint comes
from `go install` (module proxy checksums cover integrity); zizmor has no
published checksums, so its release tarball is pinned by version and
verified against a recorded sha256. The gate uses --min-severity=low, which
fails on low and above while tolerating the one informational
superfluous-actions advisory.
zizmor only collects from .github/workflows: pointing it at .gitea/workflows
yields "no inputs collected", and when both directories are passed it audits
only .github and still exits 0. The gate therefore passes explicit *.yml
paths, which is the only form that actually audits the Gitea workflows.
Auditing them for the first time surfaced seven findings, now fixed:
credential persistence on checkout (persist-credentials: false), setup-go
caching on the release path (cache: false), and missing top-level
permissions (contents: read, with contents: write narrowed to the GitHub
release job that needs it).
The release workflow targeted mroberts/sush, which does not exist
(`tea releases list --repo mroberts/sush` returns "not found"), so the
release step would fail after building the binaries. Present since the
workflow was added in a7a561f.
Also bump softprops/action-gh-release to v2 in the unused .github
workflow; actionlint rejects v1 as too old to run.
In a colocated jj repo, jj does not maintain git's index for git's own
consumption. git can therefore report an unmodified tracked file as a
whole-file add: for tests/integration/test_texttoentities_endpoint.py in
the IO repo, `git ls-tree HEAD` and `git ls-files -s` both showed the same
blob, yet `git status` reported `AM` and `git diff --cached --unified=0`
emitted a single `@@ -0,0 +1,330 @@` hunk.
shush treats every line in that hunk as agent-changed, so `--changes-only`
stripped all six comments from a file the agent had never touched (`jj diff`
confirmed 0 insertions). Diffing against HEAD instead of the index does not
help: it is poisoned the same way.
jj is authoritative when present, so DetectRepo now prefers `jj root` and
the three change queries route to `jj diff --git --context=0`. jj has no
staging area, so --staged, --unstaged and --changes-only all resolve to the
working-copy change; GetChangesOnly short-circuits so files are not
duplicated across the staged and unstaged passes.
Empty line ranges are overloaded to mean "process the whole file" (untracked
semantics). A deletion-only change parses to zero ranges, which would have
made shush strip an entire file whose only edit removed lines, so such files
are now skipped. New files still get correct full-file ranges from jj's
`@@ -0,0 +1,N @@` hunk, so they do not need the fallback.
Pagers are disabled explicitly on every git and jj invocation so output
stays machine-parseable regardless of the user's config.
tea releases create fails if a release already exists, leaving stale
binaries on tag re-push. Delete any existing release for the tag first
so re-runs self-heal.
Emits Claude Code PostToolUse JSON so automated comment removal is
announced in-context instead of appearing as a silent mutation.
--install-hook now writes 'shush --changes-only --hook-output'.
Bump version to 0.6.0.
Strip pass was eating JSDoc/Javadoc blocks. Add default preserve
patterns for /** blocks, /*! banners, /// and //! line docs.
Opt out by overriding preserve in .shush.toml.