# 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_w33uM8ZlKl1AzYq6iMOAHA"}

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 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.

# 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.
5. **Misreading partial descriptor binding as pure concurrent edit**, when path-based byte reads from the failed attempt cannot prove same-inode mutation even though descriptor-bound metadata checks passed.

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 **read through the same descriptor-bound open**
   - 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)
   - whether metadata and bytes used different binding styles in the same attempt (partial descriptor binding signal)

5. **Assign one primary category** using the decision table and overlapping-signal tie-break 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; descriptor-bound bytes used for mismatch | 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 |

## Overlapping gate-context signals

When gate context records **both** descriptor-bound fstat pass **and** separate path stat or path read for bytes in the same failed attempt, the concurrent_edit and path_string_split_suspected rows can both appear applicable. This is partial descriptor binding: metadata checked through a directory-relative no-follow open while bytes were compared through a path string.

Apply this tie-break (reasoned only, not an executed test):

1. **Always read diagnostic bytes descriptor-bound.** Never reuse path-based byte observations from the failed attempt for primary classification.

2. **Initial primary category when failed-attempt bytes were path-based:** path_string_split_suspected, even if descriptor-bound fstat passed on metadata. Path-based byte evidence cannot prove same-inode mutation.

3. **Reclassification after descriptor-bound diagnostic bytes:** when diagnostic digest is not equal to operation-start baseline and equal to the gate failure observation, primary category becomes **concurrent_edit**. Record a secondary note that the failed attempt used path-based byte reads and restart must use descriptor-bound gates only.

4. **Elapsed baseline age never overrides step 3.** Do not classify stale_baseline when descriptor-bound diagnostic bytes confirm digest mismatch against the operation-start baseline.

5. **When diagnostic digest matches operation-start baseline but gate failed on path-based bytes:** keep primary category path_string_split_suspected; the failed attempt likely observed a different inode or stale path resolution.

## 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.

## Worked example: partial descriptor binding with overlapping signals

Reasoned example (not an executed test).

**Setup.** Baseline captured non-empty bytes at operation start. Expected-bytes gate runs with descriptor-bound fstat on a directory-relative no-follow open for ownership and metadata, but compares bytes via a separate path-based read. Gate fails with digest mismatch. Gate context records both descriptor-bound fstat pass and separate path stat and path read. Agent aborts and removes temp.

**Diagnostic pass.** Reopen managed directory and fragment with no-follow semantics. Read bytes through the same descriptor-bound open. Observation snapshot shows regular file, matching ownership, digest not equal to operation-start baseline, digest equal to the gate failure observation.

**Initial classification.** path_string_split_suspected (failed-attempt bytes were path-based; metadata fstat pass alone is insufficient).

**Reclassification.** concurrent_edit after descriptor-bound diagnostic bytes confirm the on-disk fragment changed since operation start and match the gate observation.

**Secondary note.** Failed attempt used path-based byte reads; full restart must use descriptor-bound gates for both metadata and bytes.

**Wrong action avoided.** Classifying concurrent_edit immediately from fstat pass alone would trust path-based byte mismatch as same-inode mutation evidence. Classifying stale_baseline from elapsed time would ignore confirmed descriptor-bound digest drift.

**Correct action.** Full operation restart with descriptor-bound gates only; operator decides whether replacement intent still applies against current 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.
- **Not descriptor-bound gate implementation.** How to bind gates belongs in adjacent guidance; this skill only classifies failures when binding was partial.

## 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 classify concurrent_edit from failed-attempt path-based byte reads alone; require descriptor-bound diagnostic bytes or gate context showing descriptor-bound byte comparison.
- 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 overlapping-signal tie-break and partial-binding worked example follow from maintenance conversation thr_XSQsZb5V-NEZ3ha-EyEI9w sequences 1 and 2. All examples are reasoned timelines only; no filesystem or concurrency tests were executed for this skill.

## Supporting basis and limitations

Reasoning from maintenance conversations thr_dih-OceC1FecAn1tkspWtg sequence 1, thr_ZbdD3NWrGMZZxxE2KWI-XQ sequence 1, and thr_XSQsZb5V-NEZ3ha-EyEI9w sequences 1 and 2. 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 are reasoned examples only.

## Change and rationale

Update adds tie-break rules and a worked example for partial descriptor binding when concurrent_edit and path_string_split_suspected signals overlap. Closes ambiguity identified in thr_XSQsZb5V-NEZ3ha-EyEI9w without duplicating gate execution or post-publish verification procedures.


## Supporting basis and limitations

Reasoned analysis from maintenance conversation thr_XSQsZb5V-NEZ3ha-EyEI9w sequences 1 and 2. The opening question documented overlapping concurrent_edit and path_string_split_suspected signals when ownership uses directory-relative no-follow open but bytes use path read. Sequence 2 concluded byte evidence from a path read cannot be treated as authoritative same-inode mutation even when fstat passed on a different open, and that descriptor-bound diagnostic bytes may reclassify to concurrent_edit when digest matches gate observation and differs from operation-start baseline. No filesystem or concurrency tests were executed for this update; all tie-break outcomes and the worked example are reasoned only.

## Change and rationale

Add tie-break rules and a worked example for partial descriptor binding when concurrent_edit and path_string_split_suspected signals overlap in the same failed attempt.

Revision 1 leaves ambiguous which primary category applies when metadata checks use descriptor-bound opens but byte comparison used a path read. Maintenance conversation thr_XSQsZb5V-NEZ3ha-EyEI9w identified operator confusion at this boundary. Explicit tie-breaking and a reasoned partial-binding example reduce misclassification without duplicating adjacent gate implementation guidance.
