fix(code-index): hold the head-open claim across the clone successor copy - #1863
Conversation
`HeadOpening` is the exclusive claim on one generation's text projection:
`advance_artifact_text_serving` parks every other wake while a claim is
live. `open_published_text_artifact` broke that claim from the inside. It
called `retain_clone_successor_retry` before `begin_clone_successor`, so
the slot became `CloneSuccessorPending` for the whole copy of the prior
lexical artifact, with the slot lock released. `CloneSuccessorPending` is
one of the states the park loop breaks out of, so a concurrent wake took a
second `HeadOpening` on top of the running open. Two wakes then drove the
same clone staging database, and whichever open resolved second found the
slot already reset by the other's claim.
The losing wake reported `Contract("clone-successor retry requires an
active head-open claim")`, which the clone lanes map to `Internal`, so
`tracedecay_redundancy` answered `reason_code=search_failed
retryable=false`. The earlier fix mapped `AuthorityUnavailable` to
`generation_unverified` on the assumption that the remaining refusals were
transient authority failures; they were this contract violation, and a
retryable verdict would only have hidden it.
Keep the slot in `HeadOpening` for the copy. A successful begin resolves
the claim to `BuildingCloneSuccessor` anyway, so the marker only mattered
when the begin failed: the owners installed just above would otherwise let
the next wake short-circuit on a plain `Idle` and never owe the successor
again. Park it on that path only.
Evidence: with the redundancy journey pinned to two CPUs under busy-loop
load, `graph_query_test::redundancy_pull_request_scope_shares_one_budget_and_resumes_changed_families`
failed 10 of 20 iterations before this change and 20 of 20 pass after. The
new scheduler test drives four concurrent wakes from
`CloneSuccessorPending`; without the fix it reports `lane authority is
unavailable: no such table: clone_successor_state`, the second wake having
dropped the table the first was still writing.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cacf79a8d2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // The claim still owns `HeadOpening`, so this only | ||
| // parks the marker; the begin failure is the one | ||
| // worth reporting. | ||
| let _ = self.text_projection_build.retain_clone_successor_retry(); |
There was a problem hiding this comment.
Propagate the retry-state contract failure
If retain_clone_successor_retry() observes anything other than HeadOpening—the exact ownership invariant this patch is intended to protect—it returns a Contract error, but this let _ discards that evidence and reports the unrelated begin_clone_successor error instead. In the Idle case, the claim guard also leaves the slot idle, so later wakes see ready owners and can permanently skip the owed successor. Propagate or combine the parking failure rather than suppressing it.
AGENTS.md reference: AGENTS.md:L152-L154
Useful? React with 👍 / 👎.
| return match self.begin_clone_successor( | ||
| descriptor, | ||
| prior, | ||
| sealed_identity, | ||
| source, |
There was a problem hiding this comment.
Preserve backfilling status while holding the clone claim
When opening a published artifact without clone fingerprints, the owners are already ready while this corpus-sized copy runs under HeadOpening. clone_successor_progress() classifies HeadOpening as Idle, so concurrent dashboard/MCP freshness reads report the missing successor as Partial rather than Backfilling for the duration of the copy; the existing status test confirms that an idle missing successor maps to Partial. Keep the state untakeable while still identifying this as clone backfill, or teach the progress reader to distinguish this clone-opening claim.
AGENTS.md reference: AGENTS.md:L9-L12
Useful? React with 👍 / 👎.
The redundancy and similar tools still answered
search_failed(retryable: false) on the first try after a generation bump, even with the discard and classifier fixes from #1848 (run 35455290631,graph_query_test.rs:1621).Root cause:
open_published_text_artifactparked the slot atCloneSuccessorPendingbeforebegin_clone_successorcopied the prior lexical artifact, with the slot lock released.advance_artifact_text_servingleaves its park loop on that state, so a concurrent wake took a secondHeadOpeningon top of the running open and both drove the same clone staging database. The open that resolved second found the slot reset and failed withContract("clone-successor retry requires an active head-open claim"), which the executor's catch-all maps to a non-retryablesearch_failed. That is also theno such table: clone_successor_statesymptom seen earlier: one open dropped the table under the other.Fix: the head-open claim spans the copy. The retry marker is parked only when the begin fails, since a successful begin resolves the claim to
BuildingCloneSuccessoranyway. One production hunk plus a test that drives four concurrent wakes fromCloneSuccessorPending.Evidence: journey pinned to 2 CPUs under load failed 10 of 20 before, 0 of 20 after. The new test caught the defect 3 of 10 runs with the fix reverted and passes 10 of 10 with it. fmt, clippy
-D warningson the crate, and commit lint are clean.🤖 Generated with Claude Code