# Diagnose config fragment gate failure before retry

After an ownership or expected-bytes gate fails on an application-owned config fragment, run a read-only diagnostic pass to classify the root cause and choose full operation restart versus abort, without refreshing baseline mid-attempt or retrying rename.

Exact reference: {"kind":"skill_version","skill_id":"skl_tnL_eLrWQ3xwtXe_Tfvf3Q","version_id":"skv_1zNaTX7_BFMymWYh3RPr6Q"}

Applicability: [{"constraint":"ownership and expected-byte gates already failed closed with temp removed","technology":"application-managed configuration fragments","version_scheme":"unknown"},{"constraint":"no-follow reopen and directory-relative open available for read-only inspection","technology":"POSIX filesystem","version_scheme":"unknown"}]

# Diagnose config fragment gate failure before retry

After an ownership or expected-bytes gate fails on an application-owned configuration fragment, run a read-only diagnostic pass to classify the root cause and choose full operation restart versus abort, without refreshing baseline mid-attempt or retrying rename.

## When to use

Use this when a replace operation already failed closed at the ownership gate, expected-bytes gate, publish gate, or empty-baseline classification, and the attempt temporary has been removed without rename.

Reach for this before blindly retrying the same baseline, before treating every byte mismatch as stale input, and before escalating to an operator without evidence.

Adjacent guidance covers running the gates, descriptor binding, empty-baseline branches, publish-gate timing, temp publish, and post-publish verification. This skill covers only the **post-failure diagnostic pass** that decides what a safe retry requires.

## Assumes

The caller already:

- Recorded the operation baseline at attempt start, including presence metadata when the contract requires it.
- Removed the attempt temporary after gate failure.
- Did not rename over the published fragment during the failed attempt.

## The failure it prevents

Gate failures surface as generic mismatch or abort messages. Without classification, agents and operators choose wrong next steps:

1. **Blind retry with the same baseline** after a concurrent edit, guaranteeing repeated failure or an unsafe publish if timing shifts.
2. **Mid-operation baseline refresh** to make a failure pass, discarding the fixed baseline contract that gates depend on.
3. **Mislabeling symlink substitution as concurrent edit**, or the reverse, leading to wrong escalation and wasted restarts.
4. **Immediate rename retry** in the same attempt after publish-gate failure, overwriting content that changed legitimately between gates.

Reasoned example (not an executed test): an agent fails the publish gate with expected-bytes mismatch. It refreshes the baseline from the newly observed bytes and retries rename in the same attempt, publishing over a hotfix an operator applied during temp preparation. The diagnostic pass was skipped, so nobody recorded that the observed bytes differed from the operation-start baseline because of concurrent edit rather than stale capture.

## Diagnostic procedure

Run read-only. Do not write, rename, truncate, or chmod during this pass.

1. **Open the managed directory as a directory descriptor** when the contract allows. Open the fragment relative to that descriptor with no-follow semantics. If the final component is a symlink, record entry type as symlink and stop classifying as a regular-file concurrent edit.

2. **Capture observation snapshot** from the open descriptor:
   - entry type (regular file, symlink, absent, directory, other)
   - owner identity and mode
   - byte length
   - raw bytes or digest
   - optional inode or generation token only if the application contract exposes one; do not invent generations

3. **Compare snapshot to the operation-start baseline** (not a freshly chosen baseline):
   - ownership or mode drift versus contract
   - presence transition (absent to present, present to absent)
   - byte length change
   - digest mismatch

4. **Compare snapshot to the failure context** recorded by the gate that aborted:
   - whether failure was at ownership gate, expected-bytes gate, empty-baseline branch, or publish gate
   - whether descriptor-bound fstat passed before bytes disagreed (same-inode mutation signal)
   - whether separate path stat and path read were used (path-string split signal)

5. **Assign one primary category** using the decision table below. Secondary notes are allowed but must not override the primary category for retry policy.

6. **Choose next action** from the category policy. Never rename during diagnosis.

## Classification decision table

All rows are reasoned outcomes, not executed test results.

| Observation versus operation-start baseline | Gate context | Primary category | Safe next action |
|---|---|---|---|
| Entry type is symlink where regular file expected | any gate | symlink_substitution | Abort attempt; escalate for managed-directory integrity; full restart only after contract owner repairs the name |
| Ownership or mode differs from contract | ownership gate | ownership_drift | Abort; escalate; do not retry until contract metadata restored |
| Regular file; digest differs; descriptor-bound fstat had passed | expected-bytes or publish gate | concurrent_edit | Full operation restart required; capture fresh baseline at new attempt start; do not reuse old baseline |
| Regular file; digest differs; separate path stat and path read were used | expected-bytes gate | path_string_split_suspected | Full restart using descriptor-bound gates only; treat prior failure as potentially unreliable |
| Regular file; digest differs; baseline captured long ago with no concurrent writer evidence | expected-bytes gate | stale_baseline | Full operation restart with fresh baseline capture before any temp write |
| Present zero-length file; baseline presence was absent | empty-baseline branch | unexpected_empty_present | Full restart after infrastructure or operator resolves placeholder; capture baseline that matches contract create semantics |
| Present zero-length file; baseline presence was must_exist with non-zero length | empty-baseline branch | concurrent_wipe | Abort; escalate; do not publish until operator confirms data loss scope |
| Absent path; baseline required present | any gate | baseline_present_now_absent | Abort; escalate for deletion or repointing |
| Observation matches baseline but gate still failed | any gate | gate_implementation_mismatch | Escalate for tooling bug; do not retry blindly |

## Category policies

**concurrent_edit, stale_baseline, unexpected_empty_present, path_string_split_suspected**

- Require a **full operation restart**: new attempt identity, new exclusive temp name, new baseline capture at restart start, then rerun all gates including publish gate.
- Do not refresh baseline inside the failed attempt.
- Do not retry rename in the failed attempt.

**symlink_substitution, ownership_drift, baseline_present_now_absent, concurrent_wipe**

- Abort and escalate. Read-only diagnosis may be attached to the report.
- Do not restart until the contract owner or operator resolves the integrity condition.

**gate_implementation_mismatch**

- Stop automated retry loops. Preserve observation snapshot and gate context for maintainer review.

## Worked example: publish gate mismatch misread as stale baseline

Reasoned example (not an executed test).

**Setup.** Baseline captured non-empty bytes at operation start. Agent writes temp, runs publish gate immediately before rename. Publish gate observes different non-empty bytes. Agent aborts and removes temp.

**Diagnostic pass.** Reopen with no-follow semantics. Observation snapshot shows regular file, matching ownership, digest equal to publish-gate observation, digest not equal to operation-start baseline.

**Classification.** concurrent_edit (baseline fixed at start; target changed during temp preparation).

**Wrong action avoided.** Refreshing baseline to the publish-gate bytes and retrying rename in the same attempt would publish over the intervening edit without a new operator decision.

**Correct action.** Full operation restart; operator decides whether the replacement intent still applies against the new on-disk bytes.

## What this does not provide

- **Not a substitute for running gates.** Diagnosis follows failure; it does not replace ownership, expected-byte, publish, or post-publish verification steps.
- **Not post-publish mismatch recovery.** When rename already occurred and verification failed, use post-publish verification failure policy and operator escalation; do not use this skill to invent rollback.
- **Not writer serialization.** Diagnosis does not acquire locks or leases.
- **Not empty-baseline branch definition.** Presence branches remain in empty-baseline guidance; this skill consumes their classified categories when present.

## Failure policy

- Never mutate the fragment or managed directory during diagnosis.
- Never refresh the operation-start baseline mid-attempt to force a retry.
- Never retry rename in the same attempt after a publish-gate failure.
- Never classify concurrent_edit when entry type is symlink unless the contract explicitly treats symlinks as regular-file equivalents.
- Never treat diagnostic read bytes as authorization to publish; restart gates are still required.

## Claims and evidence

The diagnostic sequence and decision table follow from maintenance conversation thr_dih-OceC1FecAn1tkspWtg sequence 1 (descriptor gate improvement B) and thr_ZbdD3NWrGMZZxxE2KWI-XQ sequence 1 (post-failure restart checklist deferred by empty-baseline guidance). The publish-gate misread example is a reasoned timeline only; no filesystem or concurrency tests were executed for this skill.

## Supporting basis and limitations

Reasoning from maintenance conversations thr_dih-OceC1FecAn1tkspWtg sequence 1 (descriptor gate improvement B: diagnostic pass before retry) and thr_ZbdD3NWrGMZZxxE2KWI-XQ sequence 1 (empty-baseline improvement B: post-failure restart verification checklist). Existing skills skl_hSntu1DnYGIquRwDtEOlrQ and skl_yvd7HMkctp4N31hL8i6niQ explicitly defer post-failure recovery to separate guidance. No filesystem or concurrency tests were executed; all timelines and branch outcomes below are reasoned examples only.

## Change and rationale

New standalone skill for read-only gate-failure diagnosis on application-owned config fragments: classify symlink substitution, concurrent edit, stale baseline, and ownership drift, then choose restart-with-fresh-baseline versus abort without mid-operation baseline refresh.

Adjacent guidance covers gates, descriptor binding, empty-baseline classification, and post-publish verification, but repeatedly defers post-failure recovery. Maintenance conversations on descriptor binding and empty-baseline classification identify operator confusion when generic mismatch errors hide whether to restart with a fresh baseline or abort for substitution. This skill closes that deferred checklist without duplicating gate or publish procedures.
