§4 — Global-refine capability: landed record (2026-07-17)

Everything below shipped to imas-codex main on 2026-07-17. The surface decision (extend sn run, locked by the lead) and the derived-parent guidance (fix the gate's scoping and inject the parent/child relationship — don't paper over signals) were honoured as written.

Campaign engine — sn run --campaign (imas-codex a1c8ca1e)

PieceWhat landed
Defect-predicate selectorCampaignSpec: prose[:class] / audit[:substr] / quarantined / all. Banned-prose classes share one vocabulary with the docs benchmark; audit predicates match validation_issues tags. The audit-quarantined accepted names are selectable, so the docs pass clears their findings.
Reviewed manifestsn run --campaign <spec> --dry-run --campaign-manifest <path>.json — zero-mutation; total, per-predicate breakdown, batch plan, deterministic 20-name evidence sample. The lead approves the manifest, not a regex.
Budgeted batchingCampaignBudget: 100 names/batch default, per-batch cost cap (= drain cost limit), campaign ceiling halting between batches, --campaign-resume-from, abort check between batches.
Convergence gatePer batch: acceptance ≥ 0.90 within rotation cap, zero banned-prose reintroduction (grep-audit), zero name-axis drift. First miss halts the campaign with reasons + resume point.
ProvenanceDocsRevision snapshots (existing machinery) + per-name StandardNameChange (operation campaign_docs_refine).
Quarantine interactionQuarantine lifted before drain (pools skip quarantined names), re-validated after each batch — the plan's "invisible fixes" risk is closed mechanically.

44 new tests green; guardrails held: accepts drain through the normal pools only, no name-identity changes in docs campaigns, no full-catalog regeneration mode. Live dry-run manifest (read-only, campaign all): 2,332 accepted names → 24 batches of 100; per-predicate: typical-values prose 1,263 · estimator recipes 780 · procedural padding 676 · any audit finding 2,257 · audit-quarantined 179 (the plan's 129 was the sweep-day count).

Root-fix (a) — derived-parent parse gate (imas-codex 93276ebf)

Root cause: the full-name parse gate is validate_name_candidate (workers.py), which round-tripped every claimed name and quarantined on any parse failure before audits ran. The claim query returned neither origin nor child topology, so a derived family parent — a deliberately partial grammar peel — was indistinguishable from a broken standalone name.

Root-fix (b) — the 3 genuine pipeline-origin parse errors

NameActionOutcome
poloidal_neutral_internal_state_linear_momentum_fluxCanonical-order rename via sn editpoloidal_linear_neutral_internal_state_momentum_fluxaccepted 0.91
upper_bound_ion_charge_numberCanonical-order rename → ion_upper_bound_charge_number; inline review exhausted at 0.8375 (borderline; grammar confirmed clean) → sn rescore fresh quorumaccepted 0.96
normal_extent_of_magnetic_field_probeHint-steered recompose via sn edit (vocab-gap token normal_extent + DD source drift). The refine rotation collapsed the two probe arrays into one name; a lead-authorized scripted repair split them back: length_of_toroidal_magnetic_field_probe (accepted 0.9375, source b_field_phi_probe/length) and length_of_poloidal_magnetic_field_probe revived (quorum 0.85, sources b_field_pol_probe/length + legacy bpol_probe/length), lineage rewired to the shared predecessor, two human_edit change events recorded.both siblings accepted

Root-fix (c) — audit-quarantined accepted names fold into the selector

Covered by the quarantined campaign predicate (179 names selectable at dry-run time).

Curative revalidation — pending one command

sn run --revalidate claimed to clear legacy quarantines but its sweep matched only validation_status='pending'; fixed to include quarantined (imas-codex 68f8fa65). The graph-wide re-stamp under the fixed gate (436 quarantined names, of which 58 derived parents clear) is a pooled run the session's permission classifier blocks — it needs the lead to run: imas-codex sn run --source dd --revalidate --only validate.

Follow-up queued

campaign.py imports the banned-prose vocabulary from benchmark_roles.py — a benchmark module owns production selection vocab. Relocate to a neutral prose_policy module so the two consumers share it without the inverted dependency.