Skip to content

Commit a3abc75

Browse files
authored
Harden Daily SPDD rotation cache persistence and fail fast on unwritable cache-memory (#35359)
1 parent fec3245 commit a3abc75

3 files changed

Lines changed: 61 additions & 1 deletion

File tree

.github/workflows/daily-spdd-spec-planner.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ Use cache-memory at `/tmp/gh-aw/cache-memory/spdd-daily/rotation.json` to rotate
9393
- Track `last_index`, `last_files`, `last_run`
9494
- Process up to 5 files per run
9595
- Continue from next file on the next run
96-
- If cache is missing, initialize from the start of the sorted file list
96+
- Run a write preflight in `/tmp/gh-aw/cache-memory/spdd-daily/` and treat any permission/write failure as a setup error (do not continue)
97+
- If reading `rotation.json` returns a miss, confirm the file is truly absent before initializing from index 0
98+
- If `rotation.json` exists but cannot be read/written, do not reinitialize; report the setup error so existing rotation state is preserved
9799
- Persist rotation state using the `write` tool at that exact path (do not use shell write commands for cache updates)
98100

99101
### SPDD Evaluation Rules

actions/setup/sh/setup_cache_memory_git.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,40 @@ INTEGRITY="${GH_AW_MIN_INTEGRITY:-none}"
2828
# All integrity levels in descending order (highest first)
2929
LEVELS=("merged" "approved" "unapproved" "none")
3030

31+
ensure_writable_dir() {
32+
local dir="$1"
33+
local purpose="$2"
34+
local probe_file=""
35+
local mkdir_err
36+
local chmod_err
37+
local write_err
38+
mkdir_err="$(mktemp /tmp/gh-aw-cache-mkdir-err.XXXXXX)"
39+
chmod_err="$(mktemp /tmp/gh-aw-cache-chmod-err.XXXXXX)"
40+
write_err="$(mktemp /tmp/gh-aw-cache-write-err.XXXXXX)"
41+
42+
if ! mkdir -p "$dir" 2>"$mkdir_err"; then
43+
echo "ERROR: cache-memory setup error: failed to create ${purpose} (${dir})" >&2
44+
cat "$mkdir_err" >&2 || true
45+
rm -f "$mkdir_err" "$chmod_err" "$write_err" 2>/dev/null || true
46+
exit 1
47+
fi
48+
49+
if ! chmod u+rwx "$dir" 2>"$chmod_err"; then
50+
echo "ERROR: cache-memory setup error: ${purpose} is not writable (${dir})" >&2
51+
cat "$chmod_err" >&2 || true
52+
rm -f "$mkdir_err" "$chmod_err" "$write_err" 2>/dev/null || true
53+
exit 1
54+
fi
55+
56+
if ! probe_file="$(mktemp "${dir}/gh-aw-write-check.XXXXXX" 2>"$write_err")"; then
57+
echo "ERROR: cache-memory setup error: ${purpose} is not writable (${dir})" >&2
58+
cat "$write_err" >&2 || true
59+
rm -f "$mkdir_err" "$chmod_err" "$write_err" 2>/dev/null || true
60+
exit 1
61+
fi
62+
rm -f "$probe_file" "$mkdir_err" "$chmod_err" "$write_err" 2>/dev/null || true
63+
}
64+
3165
initialize_cache_memory_git_repo() {
3266
# No git repo yet — either a fresh cache or a legacy flat-file cache.
3367
# Initialize a git repository with an empty baseline commit on the highest-trust
@@ -262,3 +296,9 @@ if [ "$IS_CACHE_HIT" = "true" ]; then
262296
"$_run_id" "$_timestamp" "$_post_file_count" > "cache-hit-history.json"
263297
echo "Cache hit history updated (run: $_run_id, files: $_post_file_count)"
264298
fi
299+
300+
# Preflight write checks for known cache-memory paths required by daily planners.
301+
# Fail fast here so agent runs do not continue after a hidden permission problem.
302+
ensure_writable_dir "$CACHE_DIR" "cache-memory root directory"
303+
ensure_writable_dir "${CACHE_DIR}/spdd-daily" "Daily SPDD rotation cache directory"
304+
echo "Cache memory preflight write checks passed"

actions/setup/sh/setup_cache_memory_git_test.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,24 @@ assert "integrity branch exists after recovery" \
249249
"git -C '${D}' rev-parse --verify none >/dev/null 2>&1"
250250
echo ""
251251

252+
# ── Test 14: Daily SPDD rotation directory preflight is created and writable ──
253+
echo "Test 14: Daily SPDD rotation cache directory is writable"
254+
D="${WORKSPACE}/test14"
255+
make_cache_dir "${D}" "data.json"
256+
set +e
257+
OUTPUT="$(run_script "${D}" none)"
258+
EXIT_CODE=$?
259+
set -e
260+
assert "preflight exits successfully" \
261+
"[ '${EXIT_CODE}' -eq 0 ]"
262+
assert "spdd-daily directory created" \
263+
"[ -d '${D}/spdd-daily' ]"
264+
assert "spdd-daily directory writable" \
265+
"[ -w '${D}/spdd-daily' ]"
266+
assert "preflight success message logged" \
267+
"printf '%s' \"${OUTPUT}\" | grep -q 'Cache memory preflight write checks passed'"
268+
echo ""
269+
252270
# ── Summary ──────────────────────────────────────────────────────────────────
253271
echo "Tests passed: ${TESTS_PASSED}"
254272
echo "Tests failed: ${TESTS_FAILED}"

0 commit comments

Comments
 (0)