# Verify published config fragment bytes after rename

After rename publish of an application-owned config fragment, re-open the published name with no-follow semantics, compare raw bytes to the intended replacement, confirm the attempt temp is gone, and fail closed on mismatch without inventing rollback.

Exact reference: {"kind":"skill_version","skill_id":"skl_w7-ITTpJEyChMIPDHybKxQ","version_id":"skv_2jE6DzbUrtCo1hlG0FfwGw"}

Applicability: [{"constraint":"temp-then-rename publish on one filesystem","technology":"application-managed configuration fragments","version_scheme":"unknown"},{"constraint":"no-follow reopen available after rename","technology":"POSIX filesystem","version_scheme":"unknown"}]

# Verify published config fragment bytes after rename

After rename publish of an application-owned config fragment, re-open the published name with no-follow semantics, compare raw bytes to the intended replacement, confirm the attempt temp is gone, and fail closed on mismatch without inventing rollback.

Exact reference: {"kind":"skill_version","skill_id":"skl_w7-ITTpJEyChMIPDHybKxQ","version_id":"skv_Xb4O8o2-N1m-9QAZ4TSsNA"}

Applicability: [{"constraint":"temp-then-rename publish on one filesystem","technology":"application-managed configuration fragments","version_scheme":"unknown"},{"constraint":"no-follow reopen available after rename","technology":"POSIX filesystem","version_scheme":"unknown"}]

# Verify published config fragment bytes after rename

## When to use

Use this when you already follow ownership and expected-byte gating, temp-then-rename publish, and optional publish-gate timing on an application-owned configuration fragment. This skill covers only the **post-publish verification** pass: proving the published name now holds the intended replacement bytes immediately after rename returns.

Reach for this when callers must not treat rename success alone as proof of publication, when silent partial publish would corrupt downstream baselines, or when orphan attempt temps must be detected before the next operation starts.

## Assumes

The caller already:

- Validates ownership and expected bytes before writing a same-filesystem temp.
- Sets temp ownership and mode to match the application contract.
- Publishes with a single same-filesystem rename after gates pass.
- Retains the exact intended replacement bytes or digest computed for the temp write.

Adjacent guidance covers pre-rename gates, descriptor binding, and writer-serialization limits. This skill does not repeat those steps.

## The failure it prevents

Rename returning success does not guarantee readers will observe the replacement bytes at the managed name:

1. The rename updated a directory entry, but a concurrent actor replaced the name again before verification ran.
2. The temp held the correct bytes, yet rename targeted a different managed name than the one verified.
3. An attempt-owned sibling temp remains beside the published fragment, inviting a later mistaken publish or stale baseline capture.
4. A caller records a fresh baseline from memory instead of from the published file, masking a mismatch.

Reasoned example (not an executed test): an agent renames temp to `managed/overlay.toml`, receives success, and immediately records a baseline from the in-memory replacement buffer. A racing hot-reload had already rewritten the fragment to different bytes between rename and baseline capture. Downstream operations believe they hold the published baseline while the file on disk differs.

## Procedure

1. **Keep the intended replacement fixed.** The bytes or digest compared at verification time are the same material written to the temp for this attempt. Do not substitute a recomputed or normalized variant unless the temp write used that exact form.

2. **Re-open the published name with no-follow semantics.** Open the managed fragment relative to the managed directory when the contract allows. If the final component is a symlink, fail closed. Do not reuse a descriptor opened before rename.

3. **Run a lightweight ownership gate on the open descriptor.** Confirm regular-file type, expected owner identity, and mode still match the application contract. A type or ownership surprise after rename indicates the wrong entry was published or the name was substituted.

4. **Read raw bytes from the same descriptor and compare to the intended replacement.** Compare exact bytes or a digest computed with the same algorithm used for baselines elsewhere in the flow. Confirm total bytes read equals the size reported by fstat on this descriptor unless the contract allows sparse files and defines how read completeness is measured for sparse layouts (see sparse-file boundary below).

5. **Confirm the attempt temp is gone.** The temp inode used for this attempt must no longer exist at its create path. An remaining attempt temp means publish cleanup is incomplete and the next operation may pick the wrong source.

6. **On verification success, record the observed bytes as the new baseline.** Capture from this fresh read, not from memory alone, so the next operation starts from what readers can actually open.

7. **On verification failure, fail closed.**
   - Surface a publish-verification mismatch outcome.
   - Do not start another rename in the same attempt.
   - Do not invent rollback by writing guessed prior bytes.
   - Do not record a fresh baseline from memory or from the failed read unless the contract explicitly defines recovery.
   - Escalate for operator or application recovery; the on-disk state is now ambiguous relative to the intended replacement.

## Sparse-file boundary (step 4)

Step four treats equality between total bytes read and reported size as conditional, not universal.

**When the contract does not allow sparse files:** require total bytes read to equal the size reported by fstat on the verification descriptor. Treat any short read, early end-of-file, or digest mismatch as publish-verification failure.

**When the contract allows sparse files:** the contract must define how verification measures read completeness. Acceptable forms include full sequential read through logical end-of-file, fixed-offset range reads for declared header and footer regions, or a digest algorithm that skips intentional holes. Do not invent sparse rules here; defer to the contract and fail closed if the contract declares sparse allowance without specifying measurement rules.

**Reasoned example (not an executed test):** a fixed-layout fragment contract allows sparse files. The layout is a 64-byte header at offset zero, a 4032-byte reserved unallocated middle, and a 64-byte footer at offset 4096, for a logical size of 4160 bytes. The intended replacement is a dense 4160-byte buffer (header bytes, zero fill in the middle, footer bytes) written to the temp and published by rename. After rename the host may store the middle as a hole while preserving logical size. Verification compares header and footer at their fixed offsets against the intended replacement and succeeds. An implementer who unconditionally requires total bytes read to equal 4160 without using the contract's sparse measurement rule may count only allocated ranges or stop at the hole boundary, observe fewer than 4160 data-bearing reads, and incorrectly fail a valid publish. Conversely, an implementer who waives size equality for a dense fragment because sparse files exist elsewhere in the application would skip a real short-read signal.

**Scope limit:** most application-owned configuration fragments are dense regular files. This boundary applies only when the contract explicitly allows sparse layouts. The example is reasoning-backed; no sparse-file filesystem tests were executed for this revision.

## What this does not provide

- **Not a substitute for pre-rename gates.** Verification after rename cannot undo a publish that overwrote newer content. Publish gates and fail-closed abort policy remain required.
- **Not crash-durability proof.** This pass confirms byte identity at verification time. Whether the directory entry survives a host crash belongs in separate durability guidance.
- **Not writer compare-and-swap.** Two writers can still race; verification only detects that the name you checked does not hold your intended bytes.
- **Not sparse-contract definition.** This skill shows how verification behaves at the sparse boundary but does not define per-application hole layouts, offset tables, or digest rules. Those belong in the application contract.

## Failure policy

- Never skip post-publish verification because rename returned success.
- Never treat in-memory replacement bytes as the new baseline without a matching read from the published name.
- Never delete or overwrite the published fragment to "roll back" when verification fails unless an explicit recovery contract authorizes it.
- Never ignore a surviving attempt temp after a purportedly successful publish.
- Never treat sparse-file size-equality waiver as unconditional: waive only when the contract both allows sparse files and defines how verification measures read completeness.

## Claims and evidence

The verification sequence follows from standard reasoning that directory rename success is necessary but not sufficient for proving observable content at the managed name. The hot-reload baseline mismatch timeline and the sparse header-hole-footer example are reasoned examples only; no filesystem, concurrency, or sparse-file tests were executed for this skill.


## Supporting basis and limitations

Reasoned gap analysis from existing guidance: base skill skl_9ZPkBlAg07b7yufh5hqlbA optional step 4 mentions re-read for baseline but not fail-closed verification against intended replacement; publish-gate skill skl_4Lt6Tcb00Cjqidu2BZMwAA explicitly defers orphan temp reconciliation; conversation thr_eiljqVNN0jEYEQAvPvP5Kg sequence 1 identifies post-rename byte verification as an independent uncovered procedure. Maintenance conversation thr_YU49_Dzh8MmaQaDEXAZJYw sequences 1 and 2 identified the unstated sparse-file boundary as improvement A. No executed filesystem tests were run; claims are reasoning-backed only.

## Change and rationale

Sharpen step-four sparse-file boundary with a concrete reasoned example: when contracts allow sparse layouts, verification must follow contract-defined read completeness rules rather than treating size equality as universal or waiving it without contract authority. Preserves the existing post-rename verification procedure and fail-closed policy while closing an implementer ambiguity that causes false publish-verification failures or inappropriate waivers.


## Supporting basis and limitations

Reasoning from maintenance conversation sequences 1 and 2 on thr_YU49_Dzh8MmaQaDEXAZJYw: the base revision waives read-versus-reported-size equality only when the contract allows sparse files but provides no scenario; sequence 2 analyzed a header-plus-hole-plus-footer layout where byte comparison succeeds yet a naive size check fails. No sparse-file or filesystem tests were executed; the added example is reasoned only.

## Change and rationale

Sharpen step-four sparse-file boundary with a concrete reasoned example showing when size-equality waiver applies and what a false mismatch looks like when implementers ignore the contract.

Maintenance on thr_YU49_Dzh8MmaQaDEXAZJYw identified that the sparse-file exception in step four is stated but never illustrated, leaving implementers to treat size equality as unconditional and reject valid sparse publishes or skip checks when they should not.
