Skip to content

fix: scaffold refresh under the status lock, atomic per file, one log line per transition - #377

Merged
TheAmericanMaker merged 1 commit into
mainfrom
fix/refresh-scaffold-lock
Sep 16, 2026
Merged

TheAmericanMaker merged 1 commit into
mainfrom
fix/refresh-scaffold-lock

Conversation

@TheAmericanMaker

Copy link
Copy Markdown
Member

Summary

Closes #356. Verified on main: refreshScaffold takes no lock, writes with copyFile, and appends a THREAD_LOG line unconditionally (the new lock test and the third-run dedupe assertion fail there).

  • The whole refresh runs under the status lock (workflow/status.yaml.lock — the one updateStatusAtomically takes), so a completion cannot re-read a pipeline this is rewriting.
  • Every packaged file is read before any is written; a template that cannot be read leaves the scaffold untouched. Each file then lands through atomicWriteFile. A failure between two files still leaves a partial refresh — documented; re-running completes it, the copy being idempotent.
  • The THREAD_LOG line is keyed on the version transition: unversioned → 0.25.0 once, a same-version restore 0.25.0 → 0.25.0 once, repeats add nothing. RefreshScaffoldResult.threadLogEntryAppended tells both surfaces which happened; Pi's feedback line and the MCP structured content say so.

Test plan

  • tests/refresh-scaffold.test.mjs: a refresh started while the lock is held writes nothing until it is released, then restores; the second run logs its (new) transition, the third adds no line; no .tmp files remain.
  • npm run build + npm test — 925 pass.

🤖 Generated with Claude Code

… line per transition

refreshScaffold overwrote framework files with copyFile outside any lock,
so a completion re-reading the pipeline inside the status lock could see a
half-written or replaced one; a template file that could not be read failed
the refresh partway; every run appended a THREAD_LOG line. The refresh now
holds the status lock, reads every packaged file before writing any, writes
each through atomicWriteFile, and logs each version transition once; both
surfaces say whether a line was appended.

Closes #356

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@TheAmericanMaker
TheAmericanMaker merged commit 99a4f67 into main Sep 16, 2026
5 checks passed
@TheAmericanMaker
TheAmericanMaker deleted the fix/refresh-scaffold-lock branch September 16, 2026 01:34
@TheAmericanMaker TheAmericanMaker mentioned this pull request Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refreshScaffold runs outside the status lock, copies non-atomically, and duplicates its THREAD_LOG line

1 participant