- The pre-compact hook read only a checkpoint that started with `git commit`,
so every plan in the new `git add … && git commit` form rebuilt nothing, and
an empty match also skipped the session-state refresh. It now finds the
commit anywhere in the span and always refreshes; first test for the hook.
- A sub-bullet that carries its own command stays a criterion (folding it
left the command unrun); the shallowest bullet sets the base indent.
- Only a MINOR/SUGGESTION /code-review finding outside the range is released
from forbidding ALLOW: a MAJOR one may be a break cited at an unchanged
caller.
- `reuse` is an improvement category; the session-spec template stages too;
a negated bash 3.2 constraint, an env prefix and `bash -c` are handled.
- Stale comment, Declined-to-Judge wording and rule-key counts brought in line.
Tests fail on 7c11c2a first (9 of 24).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Extends the PreCompact hook with a sibling block that refreshes
.session-state.local.json's updated_at when status is in_progress or
partial. Per-project: runs after the existing progress.json mutation,
inside the same loop iteration.
Design:
- Only refreshes existing state files; creation is the writer's job
(ultraexecute Phase 8 / 2.55 / 4 + future helper command).
- Monotonic guard: only updated_at is touched. project, status,
next_session_brief_path, next_session_label remain owned by the writer.
- Skips status in {completed, failed, stopped} — the latter two are
operator-action-required and silently bumping updated_at would mask
alert state.
- Always exit 0; never blocks compaction.
[skip-docs] rationale: README + CLAUDE.md updates land in Step 11.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three changes in one commit:
1. NEW lib/util/atomic-write.mjs — exports atomicWriteJson(path, obj),
the canonical tmp+rename pattern. Reused by pre-compact-flush.mjs and
(in subsequent steps) by the new session-state writer.
2. NEW tests/lib/atomic-write.test.mjs — 4 unit tests covering
round-trip, no-orphan-tmp, overwrite-atomic, pretty-print formatting.
3. REFACTOR hooks/scripts/pre-compact-flush.mjs — replace the inline
atomicWrite() with the imported atomicWriteJson(). Also fixes a
pre-existing syntax error (leading whitespace + stray --resume token
outside the comment block) that silently broke the hook from v3.1.0
onward — PreCompact runtime is fail-open and swallowed the error.
File reformatted with standard zero-indent JS.
163 → 167 tests, 0 fail.
Step 2 of /ultracontinue v3.3.0 (project 2026-05-01-ultracontinue).