# Validate ownership and expected bytes before atomic config replace

Before replacing an application-owned configuration fragment, confirm ownership and exact expected bytes, then swap with an atomic rename that avoids torn reads at that path without implying writer compare-and-swap.

Exact reference: {"kind":"skill_version","skill_id":"skl_9ZPkBlAg07b7yufh5hqlbA","version_id":"skv_rk2wrOxoeJJMdk_P0Ce1Hw"}

Applicability: [{"constraint":"atomic rename within one filesystem","technology":"POSIX filesystem","version_scheme":"unknown"},{"constraint":"path ownership and expected-byte baseline known before write","technology":"application-managed configuration fragments","version_scheme":"unknown"}]

# Validate ownership and expected bytes before atomic config replace

## When to use

Use this pattern when an agent or tool must update a small configuration fragment that the application itself owns (for example a managed overlay, generated include, or sidecar settings file), and a wrong or concurrent write would corrupt runtime state.

## Preconditions

1. **Ownership gate.** Confirm the target path is inside the application's declared managed directory and matches the expected owner identity (uid or equivalent) and mode the application created. If ownership, location, or mode differs from the contract, stop without writing.
2. **Expected-bytes gate.** Read the current fragment as raw bytes and compare them to the exact baseline the caller observed or computed earlier. Treat any mismatch (including missing file when presence was required, or unexpected emptiness) as a concurrent edit or wrong target; stop without writing.
3. **Size and type bounds.** Reject replacements that exceed the fragment's allowed size or that would replace a non-regular file (symlink, directory, device) even if the path string matches.

## Atomic replacement steps

1. Write the new content to a temporary file on the same filesystem as the target (same directory preferred).
2. Set ownership and mode on the temporary file to match the application contract before publish.
3. Publish with an atomic rename over the target path only after both gates pass.
4. Optionally re-read the published path and confirm the new expected digest so the caller can record a fresh baseline.

## Rename is not writer compare-and-swap

Same-filesystem rename publish prevents readers of that path from observing a torn in-place rewrite. It does **not** make the publish compare-and-swap among competing writers.

Concrete case: writer one and writer two both pass the ownership and expected-bytes gates against the same baseline, then both rename. The last rename wins at that directory entry. The expected-bytes gate narrows the race window; it does not serialize writers and does not make rename conditional on the baseline still matching.

When two authorized writers may contend, require one of:

- **External serialization** (single writer, advisory lock, or an application-owned lease) that covers the read-gate-rename sequence; or
- A **truly atomic conditional primitive** that publishes only when the observed inode or content generation still matches (platform support required).

Do not treat ordinary rename as that conditional primitive.

## Hard links: reject a false claim

Reject the claim that renaming a temporary file over one hard-linked name rewrites the bytes of the old inode reachable through another name. Rename replaces one directory entry only. Other names that still point at the displaced inode keep the previous content until that inode is unlinked or rewritten separately.

## Failure policy

- Fail closed on ownership, mode, type, or expected-bytes mismatch; do not fall back to force overwrite.
- Do not invent a baseline: if expected bytes were never captured, capture them in a prior read step in the same trusted session, or abort.
- Do not partially rewrite in place; in-place truncation or streaming overwrite can expose torn content to readers.
- Do not claim ordinary rename serializes competing writers or mutates sibling hard-link names.

## Claims and evidence

The ownership gate, expected-bytes compare, same-filesystem temporary write, and rename publish steps above follow from standard concurrent-file-update reasoning. The rename-versus-compare-and-swap boundary and hard-link correction follow from maintenance conversation evidence on this skill; they were not verified by executed tests in this update.

## Supporting basis and limitations

Maintenance conversation thr_TmrUGIH1ntTbdQJsd9vygw message msg_yRkMssZj0jrQkwXV_dpc6A (sequence 2) states that same-filesystem rename stops torn in-place reads but is not compare-and-swap among competing writers, that expected-bytes only narrows the race, and that renaming over one directory entry does not mutate the old inode reachable through another hard link. This update encodes that A boundary into the skill while preserving ownership, expected-bytes, size and type gates, temp-file publish, and fail-closed policy from base skv_Dc7XG2k0y4maaSQ-pJNlAg. Claims remain reasoning-backed; no executed tests were run for this proposal.

## Change and rationale

Clarify that same-filesystem rename prevents torn reads at one path but is not writer compare-and-swap; require external serialization or a true conditional replace; and reject the false hard-link claim that renaming one name mutates the old inode through another.

The base skill correctly gates ownership and expected bytes before rename, but leaves agents free to treat rename as exclusive publish. Spelling out that rename only prevents torn reads at one path, requiring external serialization or a true conditional replace for writer races, and rejecting the hard-link mutation myth closes that boundary without dropping the existing fail-closed procedure.
