From 66d12133ed99e581c971b624ce3937fce8c53c37 Mon Sep 17 00:00:00 2001 From: justyn-clark Date: Sat, 26 Sep 2026 19:19:21 -0700 Subject: [PATCH 1/2] ci: require canonical SMALL progress with development changes --- .github/workflows/ci.yml | 10 +++++ .small/plan.small.yml | 3 ++ .small/progress.small.yml | 87 +++++++++++++++++++++++++++++++++++++ .small/workspace.small.yml | 2 +- README.md | 2 +- scripts/check-small-sync.sh | 18 ++++++++ 6 files changed, 120 insertions(+), 2 deletions(-) create mode 100755 scripts/check-small-sync.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7512a48..870c789 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,14 @@ jobs: with: go-version: '1.26.x' check-latest: true + - name: Require canonical SMALL progress with development changes + if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main') + shell: bash + env: + BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }} + run: | + git fetch --no-tags --depth=1 origin "$BASE_SHA" + git diff --name-only "$BASE_SHA" HEAD | ./scripts/check-small-sync.sh - name: Format run: test -z "$(gofmt -l cmd internal examples)" - name: Vet @@ -56,6 +64,8 @@ jobs: shasum -a 256 -c selected.txt tar -xzf "$archive" ./small version + - name: Validate canonical SMALL state + run: "$RUNNER_TEMP/small/small" check --strict - name: SMALL v1 and collaborative v2 compatibility run: ./scripts/small-proof.sh "$RUNNER_TEMP/loopexec" "$RUNNER_TEMP/small/small" .artifacts/small - name: Upload proof receipts diff --git a/.small/plan.small.yml b/.small/plan.small.yml index 665355f..22b8476 100644 --- a/.small/plan.small.yml +++ b/.small/plan.small.yml @@ -97,3 +97,6 @@ tasks: - id: task-32 title: Release v0.4.0 shared model-call budgets with offline adapter proof and migration guide status: completed + - id: task-33 + title: Enforce canonical SMALL progress for LoopExec development changes in CI + status: completed diff --git a/.small/progress.small.yml b/.small/progress.small.yml index da8cdb0..affa873 100644 --- a/.small/progress.small.yml +++ b/.small/progress.small.yml @@ -1967,3 +1967,90 @@ entries: status: completed task_id: task-32 timestamp: "2026-09-27T01:14:24.284407000Z" + - command: 'git add .small/plan.small.yml .small/progress.small.yml .small/workspace.small.yml && git commit -m ''chore: sync canonical SMALL history through v0.4.0''' + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T021052.553804000Z.txt + command_sha256: 8c8fd2926bd9557347b87fc48aafb2c26f536b1d638112451b7d91fc2c80e617 + command_summary: 'git add .small/plan.small.yml .small/progress.small.yml .small/workspace.small.yml && git commit -m ''chore: sync canonical SMALL history through v0.4.0''' + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-32 + timestamp: "2026-09-27T02:10:52.553804000Z" + - command: git branch codex/sync-small-history-2026-09 48c0ed1 && git push -u origin codex/sync-small-history-2026-09 + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T021107.370959000Z.txt + command_sha256: 9b8aebea3971b2603148d278f1e6405c2c5e77346e1f1f2057248f935da0d68d + command_summary: git branch codex/sync-small-history-2026-09 48c0ed1 && git push -u origin codex/sync-small-history-2026-09 + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-32 + timestamp: "2026-09-27T02:11:07.370959000Z" + - command: gh pr create --repo justyn-clark/loopexec --base main --head codex/sync-small-history-2026-09 --title 'Sync canonical SMALL history through v0.4.0' --body-file /private/tmp/loopexec-small-sync-pr.md + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T021137.863122000Z.txt + command_sha256: 2bb9c38713e5de2f6f89d4f8ed00a8649799332e6a187d8b0e5ae31ad759e414 + command_summary: gh pr create --repo justyn-clark/loopexec --base main --head codex/sync-small-history-2026-09 --title 'Sync canonical SMALL history through v0.4.0' --body-file /private/tmp/loopexec-small-sync-pr.md + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-32 + timestamp: "2026-09-27T02:11:37.863122000Z" + - command: gh pr merge 5 --repo justyn-clark/loopexec --merge + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T021340.636037000Z.txt + command_sha256: 4cf280422c858edda1e3196a6696f1a24534f3d434a3a4c7a00fc89e4c63030a + command_summary: gh pr merge 5 --repo justyn-clark/loopexec --merge + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-32 + timestamp: "2026-09-27T02:13:40.636037000Z" + - evidence: Added task task-33 via small plan --add + notes: Enforce canonical SMALL progress for LoopExec development changes in CI + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: pending + task_id: task-33 + timestamp: "2026-09-27T02:15:02.269538000Z" + - evidence: Adding repository CI gate for development diffs without canonical SMALL progress, plus strict validation of tracked SMALL state + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: in_progress + task_id: task-33 + timestamp: "2026-09-27T02:15:19.592283000Z" + - command: cp /private/tmp/loopexec-small-ci-gate.sh scripts/check-small-sync.sh && chmod +x scripts/check-small-sync.sh && python3 /private/tmp/loopexec-small-ci-edit.py + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T021558.379425000Z.txt + command_sha256: f91b3afe84ff8e646906202dbf2a749894ca880cc2483b4699535f7502647b93 + command_summary: cp /private/tmp/loopexec-small-ci-gate.sh scripts/check-small-sync.sh && chmod +x scripts/check-small-sync.sh && python3 /private/tmp/loopexec-small-ci-edit.py + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-33 + timestamp: "2026-09-27T02:15:58.379425000Z" + - command: /private/tmp/loopexec-small-gate-proof.sh && git diff --check && small check --strict + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T021640.375841000Z.txt + command_sha256: 6e2fdd321db6785f83324da9626904265a92d048ebb930b73637ec91bde1296b + command_summary: /private/tmp/loopexec-small-gate-proof.sh && git diff --check && small check --strict + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-33 + timestamp: "2026-09-27T02:16:40.375841000Z" + - command: /private/tmp/loopexec-small-v11-check.sh + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T021724.398581000Z.txt + command_sha256: 6062ea9d96dd8d05fd36e7d125d24b031a82824093d669ca89d95d61bce0c9e9 + command_summary: /private/tmp/loopexec-small-v11-check.sh + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-33 + timestamp: "2026-09-27T02:17:24.398581000Z" + - evidence: Added CI co-change gate requiring .small/progress.small.yml for source or documentation PR/main diffs, plus pinned SMALL v1.1.0 strict check; local negative/positive gate proof, git diff check, and pinned CLI strict validation passed + notes: PR and remote CI publication are the remaining transport steps; canonical development evidence is recorded before commit. + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-33 + timestamp: "2026-09-27T02:17:48.523074000Z" diff --git a/.small/workspace.small.yml b/.small/workspace.small.yml index d3b4b2d..ce4dd2c 100644 --- a/.small/workspace.small.yml +++ b/.small/workspace.small.yml @@ -2,6 +2,6 @@ small_version: "1.0.0" owner: agent kind: repo-root created_at: "2026-01-20T23:56:04Z" -updated_at: "2026-09-27T01:14:24.300136Z" +updated_at: "2026-09-27T02:18:20.28901Z" run: replay_id: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 diff --git a/README.md b/README.md index f53d2b4..8d0a408 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Requires Go 1.26 or newer. For a pinned install, use `@v0.4.0`. Prebuilt archive `loopexec --version` prints the installed version; `loopexec version --json` emits its machine-readable identity. See the [release notes](docs/releases/v0.4.0.md) for compatibility and platform limits. -SMALL is optional. The [SMALL integration guide](docs/small-integration.md) covers SMALL CLI v1.1.0 with legacy v1 artifacts and opt-in collaborative v2 sessions; LoopExec remains the loop governor. +SMALL is optional for LoopExec consumers. This repository uses the tracked `.small/` files for its own development audit; CI requires a canonical progress update with source or documentation changes and validates the tracked state. The [SMALL integration guide](docs/small-integration.md) covers SMALL CLI v1.1.0 with legacy v1 artifacts and opt-in collaborative v2 sessions; LoopExec remains the loop governor. ## 60-second proof diff --git a/scripts/check-small-sync.sh b/scripts/check-small-sync.sh new file mode 100755 index 0000000..64cf904 --- /dev/null +++ b/scripts/check-small-sync.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +changed=0 +progress=0 +while IFS= read -r file; do + case "$file" in + .small/progress.small.yml) progress=1 ;; + .small/*) ;; + '') ;; + *) changed=1 ;; + esac +done + +if (( changed && !progress )); then + echo 'Development changes require an accompanying .small/progress.small.yml update from the SMALL CLI.' >&2 + exit 1 +fi From 99e5596fb1c3b8adaf7d191639d09c79617021ad Mon Sep 17 00:00:00 2001 From: justyn-clark Date: Sat, 26 Sep 2026 19:24:31 -0700 Subject: [PATCH 2/2] fix(ci): parse canonical SMALL check as YAML block --- .github/workflows/ci.yml | 3 ++- .small/progress.small.yml | 45 ++++++++++++++++++++++++++++++++++++++ .small/workspace.small.yml | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 870c789..7e84dd1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,8 @@ jobs: tar -xzf "$archive" ./small version - name: Validate canonical SMALL state - run: "$RUNNER_TEMP/small/small" check --strict + run: | + "$RUNNER_TEMP/small/small" check --strict - name: SMALL v1 and collaborative v2 compatibility run: ./scripts/small-proof.sh "$RUNNER_TEMP/loopexec" "$RUNNER_TEMP/small/small" .artifacts/small - name: Upload proof receipts diff --git a/.small/progress.small.yml b/.small/progress.small.yml index affa873..b4cc960 100644 --- a/.small/progress.small.yml +++ b/.small/progress.small.yml @@ -2054,3 +2054,48 @@ entries: status: completed task_id: task-33 timestamp: "2026-09-27T02:17:48.523074000Z" + - command: 'git add .github/workflows/ci.yml README.md scripts/check-small-sync.sh .small/plan.small.yml .small/progress.small.yml .small/workspace.small.yml && git commit -m ''ci: require canonical SMALL progr...' + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T021922.035424000Z.txt + command_sha256: 55ce193a0c4ad84ed9b80ba1354f1977853e676c6a30face856a9b40f4a4dce9 + command_summary: 'git add .github/workflows/ci.yml README.md scripts/check-small-sync.sh .small/plan.small.yml .small/progress.small.yml .small/workspace.small.yml && git commit -m ''ci: require canonical SMALL progr...' + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-33 + timestamp: "2026-09-27T02:19:22.035424000Z" + - command: git branch codex/require-small-progress 66d1213 && git push -u origin codex/require-small-progress + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T021937.639949000Z.txt + command_sha256: 8969e1e1c2c8a523adbf83b330b6984d4a1584a56f368d870648743589b183f2 + command_summary: git branch codex/require-small-progress 66d1213 && git push -u origin codex/require-small-progress + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-33 + timestamp: "2026-09-27T02:19:37.639949000Z" + - command: gh pr create --repo justyn-clark/loopexec --base main --head codex/require-small-progress --title 'Require canonical SMALL progress in LoopExec CI' --body-file /private/tmp/loopexec-small-gate-pr.md + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T022014.953278000Z.txt + command_sha256: a611632f5ef184b333e52afeb5a59a1165527aa6d00b65d4f280b55828a12fe9 + command_summary: gh pr create --repo justyn-clark/loopexec --base main --head codex/require-small-progress --title 'Require canonical SMALL progress in LoopExec CI' --body-file /private/tmp/loopexec-small-gate-pr.md + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-33 + timestamp: "2026-09-27T02:20:14.953278000Z" + - command: python3 /private/tmp/loopexec-small-yaml-fix.py && ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml")' && git diff --check && /private/tmp/loopexec-small-v11-ci/small check --strict + command_ref: .small-cache/logs/f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96/commands/20260927T022325.360311000Z.txt + command_sha256: 54c89a3833cdb2827cc430b7dc09eee31a737005fdac4230d5e42e5030874a9b + command_summary: python3 /private/tmp/loopexec-small-yaml-fix.py && ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml")' && git diff --check && /private/tmp/loopexec-small-v11-ci/small check --strict + evidence: Command completed successfully + notes: 'apply: exit code 0' + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-33 + timestamp: "2026-09-27T02:23:25.360311000Z" + - evidence: Corrected YAML quoting in the new canonical SMALL CI validation step after GitHub rejected workflow parsing; local YAML parse, diff check, and pinned SMALL v1.1.0 strict check pass + replayId: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96 + status: completed + task_id: task-33 + timestamp: "2026-09-27T02:23:47.528293000Z" diff --git a/.small/workspace.small.yml b/.small/workspace.small.yml index ce4dd2c..2765fcd 100644 --- a/.small/workspace.small.yml +++ b/.small/workspace.small.yml @@ -2,6 +2,6 @@ small_version: "1.0.0" owner: agent kind: repo-root created_at: "2026-01-20T23:56:04Z" -updated_at: "2026-09-27T02:18:20.28901Z" +updated_at: "2026-09-27T02:23:47.536891Z" run: replay_id: f6bbda15d790df6d023dea340edd1b85ccac89c82db362652a1b656981e82d96