Skip to content

fix: replace non-atomic write_text() with atomic helpers in map_step_runner (#454) - #455

Merged
azalio merged 1 commit into
mainfrom
claude/compassionate-cerf-2uztvr
Sep 13, 2026
Merged

azalio merged 1 commit into
mainfrom
claude/compassionate-cerf-2uztvr

Conversation

@azalio

@azalio azalio commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes #454 — eight functions in map_step_runner.py.jinja used Path.write_text() directly, which truncates the file before writing. A process crash between truncation and the final write leaves the file permanently corrupted with no recovery path.

Changes

Replace all non-atomic write_text() calls with the existing crash-safe helpers:

  • _write_json_file(path, payload)tempfile.mkstemp + os.replace
  • _write_text_file(path, content) — same mechanism via atomic_write_text

Functions fixed

Function File Impact
refresh_blueprint_affected_files blueprint.json Critical — primary workflow state
record_diagnostics_baseline diagnostics_baseline.json High
record_test_baseline (4 paths) test_baseline.json High
record_subtask_baseline subtask_baseline_<id>.json High
build_escalation_outcome escalation .md artifact Medium
create_approval_hold approval_hold_<id>.md Medium
decide_approval_hold approval_hold_<id>.md Medium

The corresponding JSON store writes in the last three functions already used _write_json_file() correctly; only the human-readable .md reports were missing atomic protection.

Verification

🤖 Generated with Claude Code

https://claude.ai/code/session_01H5N7oWn43kXwk2N8vyEvNe


Generated by Claude Code

Summary by CodeRabbit

  • Refactor
    • Standardized how generated JSON and text reports are written.
    • Preserved existing formatting and file-encoding behavior across blueprint, baseline, artifact, escalation, and approval-hold outputs.
    • No changes to user-facing functionality or public interfaces.

…_step_runner

Eight functions used Path.write_text() directly, which truncates the file
before writing — leaving corrupted state if the process crashes mid-write.

Replace all occurrences with the existing atomic helpers:
- _write_json_file(path, payload) for JSON writes
- _write_text_file(path, content) for text writes

Both helpers use tempfile.mkstemp + os.replace, making writes crash-safe.

Functions fixed:
- refresh_blueprint_affected_files (blueprint.json — critical state file)
- record_diagnostics_baseline (diagnostics_baseline.json)
- record_test_baseline (4 early-return paths in test_baseline.json)
- record_subtask_baseline (subtask_baseline_<id>.json)
- build_escalation_outcome (escalation artifact .md)
- create_approval_hold (approval_hold_<id>.md)
- decide_approval_hold (approval_hold_<id>.md)

Fixes #454. Related: #448 #450 #452.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H5N7oWn43kXwk2N8vyEvNe
@azalio
azalio merged commit 64d2c36 into main Sep 13, 2026
1 check passed
@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 949b09ba-6520-4924-bc44-f14952b045fb

📥 Commits

Reviewing files that changed from the base of the PR and between 35619a3 and 99c58de.

📒 Files selected for processing (3)
  • .map/scripts/map_step_runner.py
  • src/mapify_cli/templates/map/scripts/map_step_runner.py
  • src/mapify_cli/templates_src/map/scripts/map_step_runner.py.jinja

📝 Walkthrough

Walkthrough

The map step runner replaces direct JSON and text writes with _write_json_file and _write_text_file in the source template and generated scripts.

Changes

Atomic artifact writes

Layer / File(s) Summary
JSON payload writes
.map/scripts/map_step_runner.py, src/mapify_cli/templates/map/scripts/map_step_runner.py, src/mapify_cli/templates_src/map/scripts/map_step_runner.py.jinja
Blueprint, baseline, failure, and changed-files payloads now use _write_json_file.
Rendered text writes
.map/scripts/map_step_runner.py, src/mapify_cli/templates/map/scripts/map_step_runner.py, src/mapify_cli/templates_src/map/scripts/map_step_runner.py.jinja
Escalation blocker and approval-hold reports now use _write_text_file.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: High

Suggested reviewers: yvasiyarov

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/compassionate-cerf-2uztvr

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit hops where state files lie,
Atomic helpers guard each byte nearby.
JSON paths now write with care,
Text reports cross safely through the air.
No broken files await the dawn,
The map runs cleanly onward on.

Comment @coderabbitai help to get the list of available commands.

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.

bug: non-atomic write_text() calls in map_step_runner corrupt state files on crash

2 participants