Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bd5c34a
feat: make no-slop the canonical identity
Blakeolson21 Aug 13, 2026
b8bc3f3
no-slop(review): Fix legacy alias conflicts and installer parity
Blakeolson21 Aug 13, 2026
fb67db4
no-slop(review): Restore legacy aliases and signing identity
Blakeolson21 Aug 13, 2026
02bdab6
no-slop(review): Fix rename aliases and parity tests
Blakeolson21 Aug 13, 2026
976c81e
no-slop(review): Fix remaining rename alias gaps
Blakeolson21 Aug 14, 2026
7652fa4
no-slop(review): Harden rename alias lifecycle
Blakeolson21 Aug 14, 2026
63fb7f5
no-slop(review): Harden alias cleanup and recovery
Blakeolson21 Aug 14, 2026
196a485
no-slop(review): Harden root aliases and fixtures
Blakeolson21 Aug 14, 2026
0abec56
no-slop(review): Unify daemon root alias lookup
Blakeolson21 Aug 14, 2026
f4a49fc
no-slop(review): Harden rename alias conflict handling
Blakeolson21 Aug 14, 2026
53f0399
no-slop(review): Unify entrypoints and hook alias checks
Blakeolson21 Aug 14, 2026
69899ca
no-slop(review): Reject empty alias env conflicts
Blakeolson21 Aug 14, 2026
c4b1adc
no-slop(review): Reject empty alias conflicts
Blakeolson21 Aug 14, 2026
8a7b9f0
no-slop(review): Validate root aliases at entrypoint
Blakeolson21 Aug 14, 2026
7aaf3be
fix: stabilize gate aliases and reaper conflicts
Blakeolson21 Aug 14, 2026
39419c6
no-slop(document): Document rename compatibility aliases
Blakeolson21 Aug 14, 2026
ae06faf
fix: make alias compatibility tests portable
Blakeolson21 Aug 14, 2026
c3f91a7
no-slop(review): Fix identity alias fallback handling
Blakeolson21 Aug 14, 2026
a4f5164
no-slop(review): Fix legacy alias state handling
Blakeolson21 Aug 14, 2026
cadbf08
no-slop(review): Reject legacy recovery anchor conflicts
Blakeolson21 Aug 14, 2026
ff0c18c
no-slop(review): Preserve legacy alias invariants
Blakeolson21 Aug 14, 2026
c0d9688
no-slop(review): Preserve rename compatibility boundaries
Blakeolson21 Aug 14, 2026
822ccf0
no-slop(document): Fix stale identity doc reference
Blakeolson21 Aug 14, 2026
c5b121e
no-slop: apply CI fixes
Blakeolson21 Aug 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
run: go test -v -timeout=15m ./...

- name: Build
run: go build ./cmd/no-mistakes
run: go build ./cmd/no-slop

e2e:
runs-on: ubuntu-latest
Expand All @@ -96,7 +96,7 @@ jobs:
with:
go-version-file: go.mod

# The e2e suite drives the real no-mistakes binary against a fake
# The e2e suite drives the real no-slop binary against a fake
# agent through `git push -> daemon -> pipeline -> push to upstream`
# for claude, codex, and opencode. It builds the binary itself, so
# no separate build step is needed. Linux-only for now: opencode's
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Require no-mistakes
name: Require no-slop
run-name: "PR #${{ github.event.pull_request.number }} body compliance - ${{ github.event.action }} - event ${{ github.run_number }} (run ${{ github.run_id }})"

on:
Expand All @@ -21,42 +21,45 @@ permissions:
# an immutable per-event group so first-time-fork approvals can never collapse
# opened/edited checks. Keep synchronize/reopened coalescing as before.
concurrency:
group: no-mistakes-required-${{ github.event.pull_request.number }}-${{ (github.event.action == 'opened' || github.event.action == 'edited') && github.run_id || 'head-change' }}
group: no-slop-required-${{ github.event.pull_request.number }}-${{ (github.event.action == 'opened' || github.event.action == 'edited') && github.run_id || 'head-change' }}
cancel-in-progress: true

jobs:
check:
name: PR must be raised via no-mistakes
name: PR must be raised via no-slop
runs-on: ubuntu-latest
# Known automation accounts are exempt so the release pipeline keeps working:
# - github-actions[bot] opens the release-please PR via GITHUB_TOKEN
# - dependabot[bot] opens dependency update PRs
# Other authors (human or bot) must raise PRs through `git push no-mistakes`.
# Other authors (human or bot) must raise PRs through `git push no-slop`.
if: >-
github.event.pull_request.user.login != 'github-actions[bot]' &&
github.event.pull_request.user.login != 'dependabot[bot]' &&
github.event.pull_request.user.login != 'release-please[bot]'
steps:
- name: Verify no-mistakes signature in PR body
- name: Verify no-slop signature in PR body
env:
PR_BODY: ${{ github.event.pull_request.body }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -eu
marker='Updates from [git push no-mistakes](https://github.com/kunchenguid/no-mistakes)'
if printf '%s' "${PR_BODY:-}" | grep -qF -- "$marker"; then
echo "Found no-mistakes signature in PR #${PR_NUMBER} body."
canonical_marker='Updates from [git push no-slop](https://github.com/Blakeolson21/no-slop)'
legacy_marker='Updates from [git push no-mistakes](https://github.com/Blakeolson21/no-slop)'
if printf '%s' "${PR_BODY:-}" | grep -qF -- "$canonical_marker" ||
printf '%s' "${PR_BODY:-}" | grep -qF -- "$legacy_marker"; then
echo "Found no-slop signature in PR #${PR_NUMBER} body."
exit 0
fi
{
echo "::error::This PR was not raised through no-mistakes."
echo "::error::This PR was not raised through no-slop."
echo
echo "Contributions to this repository must be submitted via 'git push no-mistakes'."
echo "Contributions to this repository must be submitted via 'git push no-slop'."
echo "That pipeline runs the required review/test/lint/CI steps and writes a"
echo "deterministic '## Pipeline' section into the PR body containing:"
echo "deterministic '## Pipeline' section into the PR body containing one of:"
echo
echo " $marker"
echo " $canonical_marker"
echo " $legacy_marker"
echo
echo "See CONTRIBUTING.md for setup and the full workflow."
echo
Expand Down
60 changes: 38 additions & 22 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ jobs:
DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
COMMIT="$(git rev-parse --short=7 HEAD)"
CGO_ENABLED=0 GOOS="$GOOS" GOARCH="$GOARCH" \
go build -ldflags "-X github.com/kunchenguid/no-mistakes/internal/buildinfo.Version=${TAG} -X github.com/kunchenguid/no-mistakes/internal/buildinfo.Commit=${COMMIT} -X github.com/kunchenguid/no-mistakes/internal/buildinfo.Date=${DATE} -X github.com/kunchenguid/no-mistakes/internal/buildinfo.TelemetryHost=${UMAMI_HOST} -X github.com/kunchenguid/no-mistakes/internal/buildinfo.TelemetryWebsiteID=${UMAMI_WEBSITE_ID}" \
-o "dist/no-mistakes" ./cmd/no-mistakes
go build -ldflags "-X github.com/Blakeolson21/no-slop/internal/buildinfo.Version=${TAG} -X github.com/Blakeolson21/no-slop/internal/buildinfo.Commit=${COMMIT} -X github.com/Blakeolson21/no-slop/internal/buildinfo.Date=${DATE} -X github.com/Blakeolson21/no-slop/internal/buildinfo.TelemetryHost=${UMAMI_HOST} -X github.com/Blakeolson21/no-slop/internal/buildinfo.TelemetryWebsiteID=${UMAMI_WEBSITE_ID}" \
-o "dist/no-slop" ./cmd/no-slop

# Import the Developer ID Application cert into an ephemeral keychain locked
# with a runtime-generated password, discover exactly one signing identity
Expand All @@ -87,9 +87,9 @@ jobs:
echo "::error::CSC_LINK/CSC_KEY_PASSWORD signing secrets are missing; refusing to publish an unsigned macOS artifact" >&2
exit 1
fi
KEYCHAIN_PATH="$RUNNER_TEMP/nm-signing.keychain-db"
KEYCHAIN_PATH="$RUNNER_TEMP/ns-signing.keychain-db"
KEYCHAIN_PASSWORD="$(openssl rand -base64 24)"
CERT_PATH="$RUNNER_TEMP/nm-developer-id.p12"
CERT_PATH="$RUNNER_TEMP/ns-developer-id.p12"
echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> "$GITHUB_ENV"

# Reconstruct the cert from the base64 secret into RUNNER_TEMP only.
Expand Down Expand Up @@ -127,10 +127,10 @@ jobs:
IDENTITY_HASH="$(printf '%s\n' "$IDENTITIES" | awk 'NR==1 {print $2}')"

codesign --force --timestamp --options runtime \
--identifier com.kunchenguid.no-mistakes \
--identifier com.kunchenguid.no-slop \
--keychain "$KEYCHAIN_PATH" \
--sign "$IDENTITY_HASH" \
"dist/no-mistakes"
"dist/no-slop"

# Strict verification gate: any missing or ambiguous property fails the
# release before the artifact is archived or uploaded.
Expand All @@ -140,7 +140,7 @@ jobs:
run: |
set -euo pipefail
TEAM_ID="9T2J7MNUP9"
BIN="dist/no-mistakes"
BIN="dist/no-slop"

case "$GOARCH" in
amd64) EXPECTED_ARCH="x86_64" ;;
Expand All @@ -156,7 +156,7 @@ jobs:
printf '%s\n' "$SIG"
grep -q 'Authority=Developer ID Application' <<<"$SIG"
grep -q "TeamIdentifier=$TEAM_ID" <<<"$SIG"
grep -q 'Identifier=com.kunchenguid.no-mistakes' <<<"$SIG"
grep -q 'Identifier=com.kunchenguid.no-slop' <<<"$SIG"
if grep -qi 'adhoc' <<<"$SIG"; then
echo "::error::signature is ad-hoc" >&2; exit 1
fi
Expand All @@ -179,7 +179,7 @@ jobs:
# The Team ID starts with a digit so codesign quotes it, but accept the
# unquoted form too so a codesign quirk cannot fail a valid release.
grep -Eq "leaf\[subject.OU][[:space:]]*=[[:space:]]*\"?$TEAM_ID\"?" <<<"$DR"
grep -q 'identifier "com.kunchenguid.no-mistakes"' <<<"$DR"
grep -q 'identifier "com.kunchenguid.no-slop"' <<<"$DR"
if grep -q 'cdhash H' <<<"$DR"; then
echo "::error::designated requirement is content-based (cdhash), not identity-based" >&2; exit 1
fi
Expand All @@ -197,20 +197,26 @@ jobs:
TAG: ${{ needs.release-please.outputs.tag_name }}
run: |
set -euo pipefail
ARCHIVE="dist/no-mistakes-${TAG}-${GOOS}-${GOARCH}.tar.gz"
tar -C dist -czf "$ARCHIVE" no-mistakes
ARCHIVE="dist/no-slop-${TAG}-${GOOS}-${GOARCH}.tar.gz"
LEGACY_ARCHIVE="dist/no-mistakes-${TAG}-${GOOS}-${GOARCH}.tar.gz"
tar -C dist -czf "$ARCHIVE" no-slop
cp dist/no-slop dist/no-mistakes
tar -C dist -czf "$LEGACY_ARCHIVE" no-mistakes
echo "ARCHIVE=$ARCHIVE" >> "$GITHUB_ENV"
echo "LEGACY_ARCHIVE=$LEGACY_ARCHIVE" >> "$GITHUB_ENV"

- name: Upload release asset
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ needs.release-please.outputs.tag_name }}
run: gh release upload "$TAG" "$ARCHIVE" --clobber
run: gh release upload "$TAG" "$ARCHIVE" "$LEGACY_ARCHIVE" --clobber

- uses: actions/upload-artifact@v7
with:
name: archive-${{ matrix.goos }}-${{ matrix.goarch }}
path: ${{ env.ARCHIVE }}
path: |
${{ env.ARCHIVE }}
${{ env.LEGACY_ARCHIVE }}

# Tear down the ephemeral keychain on success and failure alike.
- name: Clean up signing keychain
Expand All @@ -220,7 +226,7 @@ jobs:
if [ -n "${KEYCHAIN_PATH:-}" ]; then
security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true
fi
rm -f "$RUNNER_TEMP/nm-developer-id.p12" 2>/dev/null || true
rm -f "$RUNNER_TEMP/ns-developer-id.p12" 2>/dev/null || true

build-and-upload:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -259,37 +265,47 @@ jobs:
mkdir -p dist
DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
COMMIT="$(git rev-parse --short=7 HEAD)"
BIN="no-mistakes"
BIN="no-slop"
LEGACY_BIN="no-mistakes"
OUT="dist/${BIN}"
if [ "$GOOS" = "windows" ]; then
BIN="${BIN}.exe"
LEGACY_BIN="${LEGACY_BIN}.exe"
OUT="dist/${BIN}"
fi
CGO_ENABLED=0 GOOS="$GOOS" GOARCH="$GOARCH" \
go build -ldflags "-X github.com/kunchenguid/no-mistakes/internal/buildinfo.Version=${TAG} -X github.com/kunchenguid/no-mistakes/internal/buildinfo.Commit=${COMMIT} -X github.com/kunchenguid/no-mistakes/internal/buildinfo.Date=${DATE} -X github.com/kunchenguid/no-mistakes/internal/buildinfo.TelemetryHost=${UMAMI_HOST} -X github.com/kunchenguid/no-mistakes/internal/buildinfo.TelemetryWebsiteID=${UMAMI_WEBSITE_ID}" \
-o "$OUT" ./cmd/no-mistakes
go build -ldflags "-X github.com/Blakeolson21/no-slop/internal/buildinfo.Version=${TAG} -X github.com/Blakeolson21/no-slop/internal/buildinfo.Commit=${COMMIT} -X github.com/Blakeolson21/no-slop/internal/buildinfo.Date=${DATE} -X github.com/Blakeolson21/no-slop/internal/buildinfo.TelemetryHost=${UMAMI_HOST} -X github.com/Blakeolson21/no-slop/internal/buildinfo.TelemetryWebsiteID=${UMAMI_WEBSITE_ID}" \
-o "$OUT" ./cmd/no-slop
cp "$OUT" "dist/${LEGACY_BIN}"
if [ "$GOOS" = "windows" ]; then
ARCHIVE="dist/no-mistakes-${TAG}-${GOOS}-${GOARCH}.zip"
ARCHIVE="dist/no-slop-${TAG}-${GOOS}-${GOARCH}.zip"
LEGACY_ARCHIVE="dist/no-mistakes-${TAG}-${GOOS}-${GOARCH}.zip"
(
cd dist
zip -q "$(basename "$ARCHIVE")" "$BIN"
zip -q "$(basename "$LEGACY_ARCHIVE")" "$LEGACY_BIN"
)
else
ARCHIVE="dist/no-mistakes-${TAG}-${GOOS}-${GOARCH}.tar.gz"
ARCHIVE="dist/no-slop-${TAG}-${GOOS}-${GOARCH}.tar.gz"
LEGACY_ARCHIVE="dist/no-mistakes-${TAG}-${GOOS}-${GOARCH}.tar.gz"
tar -C dist -czf "$ARCHIVE" "$BIN"
tar -C dist -czf "$LEGACY_ARCHIVE" "$LEGACY_BIN"
fi
echo "ARCHIVE=$ARCHIVE" >> "$GITHUB_ENV"
echo "LEGACY_ARCHIVE=$LEGACY_ARCHIVE" >> "$GITHUB_ENV"

- name: Upload release asset
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ needs.release-please.outputs.tag_name }}
run: gh release upload "$TAG" "$ARCHIVE" --clobber
run: gh release upload "$TAG" "$ARCHIVE" "$LEGACY_ARCHIVE" --clobber

- uses: actions/upload-artifact@v7
with:
name: archive-${{ matrix.goos }}-${{ matrix.goarch }}
path: ${{ env.ARCHIVE }}
path: |
${{ env.ARCHIVE }}
${{ env.LEGACY_ARCHIVE }}

checksums:
runs-on: ubuntu-latest
Expand All @@ -314,7 +330,7 @@ jobs:
set -euo pipefail
(
cd dist
sha256sum no-mistakes-* > ../checksums.txt
sha256sum no-slop-* no-mistakes-* > ../checksums.txt
)

- name: Upload checksums
Expand Down
2 changes: 1 addition & 1 deletion .no-mistakes.yaml → .no-slop.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# no-mistakes' own dogfood config.
# no-slop's own dogfood config.
# Local Test is intentionally empty: the Test step is targeted validation of the
# requested intent (agent-driven smallest relevant checks + evidence), never a
# repository-wide regression suite. Broad race-enabled Go coverage stays in
Expand Down
Loading
Loading