From 0942b2ef409ba4abee3a473e286a26a9d9852545 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Tue, 15 Sep 2026 18:28:45 -0700 Subject: [PATCH] Block handoffs from a dirty working tree Unrelated tracked changes could ride along with a handoff. Refuse to send when git status --porcelain is non-empty, list the offending files, and keep the draft so it can be fixed and resent. SWARMFORGE_ALLOW_DIRTY=1 overrides. By specifier. --- specifier-prompt.md | 15 ++++++++------- swarmforge/scripts/swarm_handoff.bb | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/specifier-prompt.md b/specifier-prompt.md index 1043f79..61b76ed 100644 --- a/specifier-prompt.md +++ b/specifier-prompt.md @@ -459,13 +459,14 @@ At the end of each session, update this file: - Note the current `master` HEAD commit. - State the next feature to work on. -Current `master` HEAD: `c8ceb82` (merged architect's thread-query-bounds job — -`GET /posts/:txid/thread` now counts likes only for the thread's txids via -`countLikesForTxids` and prefix-scans `postChildren` per parent through a new -`PostQuery.listChildTxids` seam, so its work is proportional to the thread -rather than the database. Spec: -`psf-memo-db/specs/thread-query-performance.feature`. Verified psf-memo-db unit -(357) + property (44) + acceptance (all 11 suites) + lint all passing). +Current `master` HEAD: `a5f8967` (thread-query-bounds merged at `c8ceb82`, then +a process-improvement pass on this branch: the architect now always notifies +the specifier; acceptance LevelDB temp dirs are cleaned up; the handoff daemon +is self-healing; APS is single-sourced at `tmp/aps`; acceptance generation is +incremental; `verify.sh` emits a machine-readable verification record; +`mutate-file.sh` guards differential under-selection; and `clean-builds.sh` +keeps mutation worker copies small. Run `swarmforge/scripts/state.sh` to refresh +these HEAD lines.) Next action: **TBD** — current direction is front-end improvements to `psf-memo-client` (UI/UX polish, accessibility, performance, responsiveness, state handling, error surfacing). See `specs/feature-backlog.md`. diff --git a/swarmforge/scripts/swarm_handoff.bb b/swarmforge/scripts/swarm_handoff.bb index e96da88..38ccf56 100755 --- a/swarmforge/scripts/swarm_handoff.bb +++ b/swarmforge/scripts/swarm_handoff.bb @@ -302,6 +302,20 @@ (fs/move tmp-file outbox-file) outbox-file)) +(defn dirty-files [] + (->> (:out (command "." "git" "status" "--porcelain")) + str/split-lines + (remove str/blank?))) + +(defn guard-clean-tree! [] + (let [dirty (dirty-files)] + (when (and (seq dirty) (not (System/getenv "SWARMFORGE_ALLOW_DIRTY"))) + (binding [*out* *err*] + (println "HANDOFF BLOCKED: working tree has uncommitted changes.") + (doseq [line dirty] (println " " line)) + (println "Commit or stash them, or set SWARMFORGE_ALLOW_DIRTY=1 to send anyway.")) + (System/exit 3)))) + (defn error-report [draft errors] (binding [*out* *err*] (println "HANDOFF INVALID:" (str draft)) @@ -328,6 +342,7 @@ (when (seq all-errors) (error-report draft all-errors) (System/exit 2)) + (guard-clean-tree!) (let [outbox-file (write-handoff! {:headers headers :recipients (:recipients validation) :canonical-commit (:canonical-commit validation)