August 5, 2026
AI Agent Artifacts Should Be Written Atomically, Even If the Run Is Not
Why temporary files, atomic replacement, hashes, and event logs make financial ML research runs easier to trust.

By Ted Park
3 min read
An AI-assisted research run can generate a convincing report and still leave unreliable evidence on disk.
The failure may be mundane: a process stops halfway through a JSON write, a reader opens a file while it is being replaced, or a previous artifact survives next to a partially updated run.
For a financial ML research agent, I want each exported artifact to appear as a complete file or not appear at all.
That is why the public QuantSigma agent builder writes through a temporary file and then replaces the destination.
The pattern is small:
render complete content in memory -> write temporary file in destination directory -> close temporary file -> replace destination path
It does not make an entire multi-file run transactional. It does make every individual artifact safer for readers.
The Half-Written File Problem
The builder exports several related files:
agent_builder_report.md agent_spec.json experiment_run_contract.json agent_builder_state.json agent_builder_run_manifest.json agent_builder_events.jsonl
A naive implementation can open each final path and write directly to it.
If the process stops during a write, the final path may contain truncated JSON or a partial report. A dashboard, CI job, reviewer, or future agent can then mistake an incomplete file for a valid artifact.
This is worse than a missing file.
A missing file is an obvious failure. A syntactically plausible but incomplete file can create false confidence.
Write Beside the Destination, Then Replace
The current builder uses a temporary file in the destination directory.
It opens a NamedTemporaryFile with UTF-8 encoding and delete disabled, writes the complete text, closes the file, and calls tmp_path.replace(path).
Writing the temporary file in the same directory is intentional.
On a normal local filesystem, replacement within the same filesystem is the useful primitive. A reader should see the previous complete file or the new complete file, not the bytes arriving in the middle.
The temporary file is closed before replacement, so the final path is updated only after the content has been written.
Atomic Per File Is Not Atomic Per Run
The agent builder creates six artifacts. Replacing each one atomically does not turn all six replacements into a single transaction.
A process can still fail after writing the spec but before writing the contract. It can write a report and state snapshot but stop before the event log.
The honest guarantee is:
each file replacement is atomic the collection of files is not a database transaction
That distinction matters. Calling the whole run atomic would overstate what the implementation provides.
State, Manifest, and Events Cover Different Questions
Per-file atomic replacement becomes more useful when combined with three other artifacts.
The state snapshot answers: Which workflow steps completed?
The run manifest answers: Which exact spec, contract, report, and state files belong to this run?
It records SHA-256 hashes for those artifacts. If a file is modified later, its hash no longer matches the manifest.
The JSONL event log answers: In what order did the builder move through its steps?
These records do not magically create a distributed transaction. They make an incomplete or inconsistent run easier to detect and reject.
Compute First, Publish Second
The builder renders the report, spec, contract, state, event log, and manifest text before it begins writing the files.
That separates computation from publication:
build in-memory representations -> compute artifact hashes -> write complete files
This is preferable to mixing business logic with streaming writes to final destinations. Validation or rendering errors should happen before a reader sees a newly published path.
The manifest hashes are calculated from the exact text that the writer will publish. That keeps artifact identity tied to the serialized content, not to an in-memory object that may be rendered differently later.
Recovery Should Be Explicit
Because the group is not transactional, a consumer should not assume that the presence of one file means the run completed.
A safer reader can require:
- the expected artifact set exists
- the state reports the required completed steps
- the manifest schema and run id match
- recorded hashes match the current files
- event sequences are contiguous and ordered
- the experiment contract passes its own validator
If one of those checks fails, the run can be marked incomplete or quarantined instead of silently promoted.
This is the larger engineering pattern:
writers avoid partial files readers verify complete runs
Both sides matter.
Limits of the Pattern
Temporary-file replacement is not enough for every storage system.
Object stores, network filesystems, databases, and cross-filesystem moves have different consistency and durability behavior. If artifacts move to S3 or a remote registry, the publication protocol should use that system's guarantees instead of assuming local filesystem semantics.
The current implementation also does not call fsync, keep a transaction journal, or roll back previously replaced files after a later artifact fails.
Those may be appropriate extensions for a more demanding system.
The useful point is not that a small local writer solves every durability problem. It is that artifact publication is treated as an engineering boundary rather than an afterthought.
Tests and Public Boundary
I reran the focused CLI and agent-builder tests before preparing this note:
14 passed in 0.25s
The suite verifies run-scoped artifact creation, manifest hashes, ordered events, spec replay, validation-only behavior, and rejection of unsafe agent specs.
It does not currently prove crash recovery across every write position or filesystem. That is an important distinction and a useful next test boundary.
The public workflow still uses synthetic or public research data. It does not place broker orders, access accounts, expose private strategy logic, or prove profitability.
Atomic artifact writes protect the evidence trail. They do not turn an experiment into an investment claim.
Public implementation:
Agent builder writer: https://github.com/tedpark/agentic-quant-trading-python/blob/main/src/agentic_quant/research_os/agent_builder.py Agent-builder tests: https://github.com/tedpark/agentic-quant-trading-python/blob/main/tests/test_agent_builder.py QuantSigma: https://quantsigma.ai
This is a research engineering note, not investment advice.