Skip to content

refactor(Scripts): make mutations transactional - #287

Open
kyleve wants to merge 6 commits into
codex/harden-simulator-ownershipfrom
codex/transactional-script-mutations
Open

refactor(Scripts): make mutations transactional#287
kyleve wants to merge 6 commits into
codex/harden-simulator-ownershipfrom
codex/transactional-script-mutations

Conversation

@kyleve

@kyleve kyleve commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Posted by an AI agent on kve's behalf.

Summary

  • add a reusable Ruby filesystem transaction for validated multi-path replacement and rollback
  • move icon validation/mutation out of embedded Python, preserve unknown manifest metadata, and add --dry-run
  • extract exact physical-device selection from devicectl JSON and make Where/install dry-runnable
  • validate Ledger bundle identity, terminate only the exact installed executable, and transactionally replace /Applications/Ledger.app
  • add adversarial failure injection at filesystem, process, device, and public-command boundaries

Why

This final layer covers commands that mutate tracked catalogs, install to physical hardware, or replace an application bundle. Their policy is now directly testable without automating destructive real operations.

Design decisions

  • FileTransaction validates every boundary before commit, rejects symlink/cross-filesystem replacement boundaries, keeps backups through commit, and reports cleanup or rollback failures
  • a failed rollback preserves either the original value or the complete intended replacement with its backup retained and the failure visible
  • icon manifests retain unknown top-level/per-icon metadata; malformed, truncated, and wrong-size PNGs fail before staging can commit
  • device selection accepts only exact name, UDID, or identifier matches among physical iOS/iPadOS devices
  • Ledger matches the full installed executable argv and validates both source and destination bundle IDs

Compatibility

Public paths, existing flags, defaults, output streams, and usage statuses remain stable. --dry-run is additive on mutating commands.

Adversarial coverage

  • failure before commit, after every apply boundary, during staged rename, rollback, cleanup, copy, and staging writes
  • missing/cross-filesystem/symlinked boundaries and malformed app bundles
  • add/remove rollback across both catalogs and the manifest; dry-run byte-for-byte preservation
  • Where unset/malformed team configuration, malformed/schema-shifted inventory, unusual device names, confirmation EOF, and every child failure status
  • Ledger exact/similar processes, graceful TERM, forced KILL, surviving-process refusal, and build/install/open failures
  • mutations for silent cleanup, incomplete icon rollback, destructive dry-run, and accepted source symlinks are all killed

Testing

  • 75 Ruby tests / 636 assertions
  • 62 Python tests
  • ./shellcheck, ./swiftformat --lint, ./attribution --check, ./snapshot-shards check
  • icon add/remove dry runs; Ledger real dry run; Where real dry run honestly refused the checkout's absent signing team before work
  • ./test StuffCoreTests passed
  • ./profile --tests-only --no-snapshots passed (2,119 tests)
  • ./flaky --suite-runs 1 --iterations 2 --no-update passed (2,120 tests observed)
  • ./test --everything passed (1,957 unit tests + 46 snapshot suites)
  • tuist test Ledger-macOS-Tests passed
  • CircleCI manual_full_gate passed on the exact stack tip: shared build, unit worker, and snapshot worker

Stack

Fourth and final PR; based on #288. The entire stack is rebased onto current main.

@kyleve kyleve changed the title codex/transactional script mutations refactor(Scripts): make mutations transactional Aug 17, 2026
Comment thread Tools/file_transaction.rb
add_operation(target: target, staged: nil)
end

def commit

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Posted by an AI agent on kve's behalf.

Review focus: this ordering is load-bearing. Apply failures roll back while every backup still exists; backup cleanup starts only after the whole replacement commits, and a cleanup failure reports the committed state instead of attempting a now-unsafe partial rollback.

@kyleve
kyleve force-pushed the codex/transactional-script-mutations branch 3 times, most recently from c6e3b12 to 5f0dae7 Compare August 19, 2026 02:58
@kyleve
kyleve force-pushed the codex/transactional-script-mutations branch from 5f0dae7 to ace4f75 Compare August 19, 2026 03:06
@kyleve
kyleve force-pushed the codex/transactional-script-mutations branch from ace4f75 to 77eaf54 Compare August 19, 2026 03:22
@kyleve
kyleve force-pushed the codex/transactional-script-mutations branch 3 times, most recently from f18daf5 to 6562984 Compare August 19, 2026 04:07
@kyleve
kyleve force-pushed the codex/transactional-script-mutations branch from 6562984 to ee96f79 Compare August 19, 2026 04:09
@kyleve
kyleve force-pushed the codex/transactional-script-mutations branch from ee96f79 to 2e4b0cf Compare August 19, 2026 04:14
@kyleve
kyleve force-pushed the codex/transactional-script-mutations branch from 2e4b0cf to 79c7c86 Compare August 19, 2026 04:20
@kyleve
kyleve force-pushed the codex/transactional-script-mutations branch from 79c7c86 to c6c0051 Compare August 19, 2026 04:37
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.

1 participant